changed: unify some methods in ASMu2D and ASMu2Dmx

same approach as in ASMs2D and ASMs2Dmx is now used
This commit is contained in:
Arne Morten Kvarving
2015-11-25 19:17:49 +01:00
committed by Knut Morten Okstad
parent 77e43fd18d
commit b3ac7b8188
4 changed files with 82 additions and 77 deletions

View File

@@ -570,44 +570,44 @@ void ASMu2D::closeEdges (int dir, int basis, int master)
*/
void ASMu2D::constrainEdge (int dir, bool open, int dof, int code, char)
std::vector<int> ASMu2D::getEdgeNodes(int dir, int basis) const
{
constrainEdge(dir,open,dof,code,0,lrspline.get());
const LR::LRSplineSurface* srf = getBasis(basis);
size_t ofs = 0;
for (int i=1; i < basis; ++i)
ofs += getNoNodes(i);
std::vector<int> result;
if (dir > -3 && dir < 3) {
const std::vector<LR::parameterEdge> map = {LR::SOUTH, LR::WEST, LR::WEST, /* dummy*/ LR::EAST, LR::NORTH};
std::vector<LR::Basisfunction*> edgeFunctions;
srf->getEdgeFunctions(edgeFunctions, map[dir+2]);
result.resize(edgeFunctions.size());
std::transform(edgeFunctions.begin(), edgeFunctions.end(),
result.begin(), [ofs](LR::Basisfunction* a) { return a->getId()+ofs+1; });
}
return result;
}
void ASMu2D::constrainEdge(int dir, bool open, int dof, int code, size_t ofs,
LR::LRSplineSurface* spline)
void ASMu2D::constrainEdge (int dir, bool open, int dof, int code, char basis)
{
std::vector<LR::Basisfunction*> edgeFunctions;
static const std::map<int, LR::parameterEdge> m =
{{ 1, LR::EAST},
{-1, LR::WEST},
{ 2, LR::NORTH},
{-2, LR::SOUTH}};
LR::parameterEdge edge = m.find(dir)->second;
Go::SplineCurve* curve = nullptr;
if (code > 0)
curve = spline->edgeCurve(edge, edgeFunctions);
else
spline->getEdgeFunctions(edgeFunctions, edge);
if (curve)
dirich.push_back(DirichletEdge(curve,dof,code));
std::vector<int> nodes = getEdgeNodes(dir, basis);
// Skip the first and last function if we are requesting an open boundary.
// I here assume the edgeFunctions are ordered such that the physical
// end points are represented by the first and last edgeFunction.
if (!open)
this->prescribe(edgeFunctions.front()->getId()+1+ofs,dof,code);
this->prescribe(nodes.front(),dof,code);
for (size_t i = 1; i < edgeFunctions.size()-1; i++)
if (this->prescribe(edgeFunctions[i]->getId()+ofs+1,dof,-code) == 0 && code > 0)
dirich.back().nodes.push_back(std::make_pair(i+1,edgeFunctions[i]->getId()+ofs+1));
for (size_t i = 1; i < nodes.size()-1; i++)
if (this->prescribe(nodes[i],dof,-code) == 0 && code > 0)
dirich.back().nodes.push_back(std::make_pair(i,nodes[i]));
if (!open)
this->prescribe(edgeFunctions.back()->getId()+ofs+1,dof,code);
this->prescribe(nodes.back(),dof,code);
if (code > 0)
if (dirich.back().nodes.empty())
@@ -634,34 +634,48 @@ size_t ASMu2D::constrainEdgeLocal (int dir, bool open, int dof, int code,
}
void ASMu2D::constrainCorner (int I, int J, int dof, int code, char)
int ASMu2D::getCorner(int I, int J, int basis) const
{
std::vector<LR::Basisfunction*> edgeFunctions;
const LR::LRSplineSurface* srf = getBasis(basis);
// Note: Corners are identified by "coordinates" {-1,-1} {-1,1} {1,-1} {1,1}.
if (I < 0) {
if (J < 0)
lrspline->getEdgeFunctions(edgeFunctions, LR::SOUTH_WEST);
srf->getEdgeFunctions(edgeFunctions, LR::SOUTH_WEST);
else if (J > 0)
lrspline->getEdgeFunctions(edgeFunctions, LR::NORTH_WEST);
srf->getEdgeFunctions(edgeFunctions, LR::NORTH_WEST);
}
else if (I > 0) {
if (J < 0)
lrspline->getEdgeFunctions(edgeFunctions, LR::SOUTH_EAST);
srf->getEdgeFunctions(edgeFunctions, LR::SOUTH_EAST);
else if (J > 0)
lrspline->getEdgeFunctions(edgeFunctions, LR::NORTH_EAST);
srf->getEdgeFunctions(edgeFunctions, LR::NORTH_EAST);
}
if (edgeFunctions.empty())
if (edgeFunctions.empty()) {
std::cerr <<" *** ASMu2D::constrainCorner: Invalid corner I,J="
<< I <<","<< J << std::endl;
else
this->prescribe(edgeFunctions.front()->getId()+1,dof,code);
return 0;
}
if (edgeFunctions.size() > 1)
std::cerr <<" ** ASMu2D::constrainCorner: "<< edgeFunctions.size()
<<" corners returned from LRSplineSurface::getEdgeFunctions()"
<< std::endl;
return edgeFunctions.front()->getId()+1;
}
void ASMu2D::constrainCorner (int I, int J, int dof, int code, char)
{
int corner = getCorner(I, J, 1);
if (corner == 0)
return;
else
this->prescribe(corner,dof,code);
}
@@ -1745,3 +1759,9 @@ bool ASMu2D::updateDirichlet (const std::map<int,RealFunc*>& func,
// evaluation of the Dirichlet functions (since they are interpolatory)
return this->ASMbase::updateDirichlet(func,vfunc,time,g2l);
}
size_t ASMu2D::getNoNodes (int) const
{
return lrspline->nBasisFunctions();
}

View File

@@ -48,6 +48,11 @@ public:
//! \brief Returns the spline surface representing this patch.
LR::LRSplineSurface* getSurface() { return lrspline.get(); }
//! \brief Returns the spline surface representing the basis of this patch.
virtual const LR::LRSplineSurface* getBasis(int = 1) const { return lrspline.get(); }
//! \brief Returns the spline surface representing the basis of this patch.
virtual LR::LRSplineSurface* getBasis(int = 1) { return lrspline.get(); }
// Methods for model generation and refinement
// ===========================================
@@ -97,6 +102,9 @@ public:
//! \param[out] p3 Order in third (w) direction
virtual bool getOrder(int& p1, int& p2, int& p3) const;
//! \brief Returns the total number of nodes in this patch.
virtual size_t getNoNodes(int basis = 0) const;
//! \brief Checks that the patch is modelled in a right-hand-side system.
virtual bool checkRightHandSystem();
@@ -221,6 +229,13 @@ public:
virtual bool updateDirichlet(const std::map<int,RealFunc*>& func,
const std::map<int,VecFunc*>& vfunc, double time,
const std::map<int,int>* g2l = nullptr);
//! \brief Obtain node index for a given corner.
int getCorner(int I, int J, int basis=1) const;
//! \brief Obtain node indices for a given edge
std::vector<int> getEdgeNodes(int dir, int basis=1) const;
protected:
//! \brief Evaluates an integral over the interior patch domain.
//! \param integrand Object with problem-specific data and methods
@@ -406,16 +421,6 @@ protected:
: curve(sc), dof(d), code(c) {}
};
//! \brief Constrains all DOFs on a given boundary edge.
//! \param[in] dir Parameter direction defining the edge to constrain
//! \param[in] open If \e true, exclude the end points of the edge
//! \param[in] dof Which DOFs to constrain at each node on the edge
//! \param[in] code Inhomogeneous dirichlet condition code
//! \param[in] ofs Offset for nodes (multiple bases).
//! \param[in] spline LRSpline to use for node numbers.
virtual void constrainEdge(int dir, bool open, int dof, int code,
size_t ofs, LR::LRSplineSurface* spline);
std::shared_ptr<LR::LRSplineSurface> lrspline; //!< Pointer to the LR-spline surface object
std::vector<Matrix> bezierExtract; //!< Bezier extraction matrices

View File

@@ -53,7 +53,16 @@ ASMu2Dmx::ASMu2Dmx (const ASMu2Dmx& patch,
}
LR::LRSplineSurface* ASMu2Dmx::getBasis (int basis) const
const LR::LRSplineSurface* ASMu2Dmx::getBasis (int basis) const
{
if (basis < 1 || basis > (int)m_basis.size())
return nullptr;
return m_basis[basis-1].get();
}
LR::LRSplineSurface* ASMu2Dmx::getBasis (int basis)
{
if (basis < 1 || basis > (int)m_basis.size())
return nullptr;
@@ -554,27 +563,6 @@ bool ASMu2Dmx::evalSolution (Matrix& sField, const IntegrandBase& integrand,
}
void ASMu2Dmx::constrainEdge (int dir, bool open, int dof, int code, char basis)
{
size_t ofs = std::accumulate(nb.begin(),nb.begin()+basis-1, 0);
ASMu2D::constrainEdge(dir,open,dof,code,ofs,m_basis[basis-1].get());
}
Vec3 ASMu2Dmx::getCoord (size_t inod) const
{
int node = inod, i = 0;
while (node > m_basis[i]->nBasisFunctions())
node -= m_basis[i++]->nBasisFunctions();
LR::Basisfunction* basis = m_basis[i]->getBasisfunction(node-1);
if (!basis)
return Vec3();
return Vec3(&(*basis->cp()),nsd);
}
//! \brief Expand the basis coefficients of a spline surface.
//! \details Used for solution transfer during refinement.
//! \param[in] basis The surface to extend

View File

@@ -39,7 +39,10 @@ public:
virtual ~ASMu2Dmx() { lrspline = nullptr; geo = nullptr; }
//! \brief Returns the spline surface representing the basis of this patch.
virtual LR::LRSplineSurface* getBasis(int basis = 1) const;
virtual LR::LRSplineSurface* getBasis(int basis = 1);
//! \brief Returns the spline surface representing the basis of this patch.
virtual const LR::LRSplineSurface* getBasis(int basis = 1) const;
// Methods for model generation
// ============================
@@ -69,17 +72,6 @@ public:
//! \brief Returns the classification of a node.
//! \param[in] inod 1-based node index local to current patch
virtual char getNodeType(size_t inod) const;
//! \brief Returns the global coordinates for the given node.
//! \param[in] inod 1-based node index local to current patch
virtual Vec3 getCoord(size_t inod) const;
//! \brief Constrains all DOFs on a given boundary edge.
//! \param[in] dir Parameter direction defining the edge to constrain
//! \param[in] open If \e true, exclude the end points of the edge
//! \param[in] dof Which DOFs to constrain at each node on the edge
//! \param[in] code Inhomogeneous dirichlet condition code
//! \param[in] basis Which basis to constrain the edge for
virtual void constrainEdge(int dir, bool open, int dof, int code, char basis);
//! \brief Initializes the patch level MADOF array for mixed problems.
virtual void initMADOF(const int* sysMadof);