changed: unify some methods in ASMu2D and ASMu2Dmx
same approach as in ASMs2D and ASMs2Dmx is now used
This commit is contained in:
committed by
Knut Morten Okstad
parent
77e43fd18d
commit
b3ac7b8188
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user