Changed: Simplified the SIMNodalConstraint class a bit by moving the
static method of the separate helper class into a class member.
This commit is contained in:
parent
ad5bf4ed56
commit
ddb389d5fd
|
@ -326,63 +326,61 @@ protected:
|
|||
#endif
|
||||
|
||||
|
||||
template<>
|
||||
void NodalConstraintProcessor<SIM1D>::apply(SIM1D& sim, TopologySet& myEntitys,
|
||||
const ConstraintVec& vConstr)
|
||||
{
|
||||
for (const auto& it3 : vConstr) {
|
||||
TopologySet::const_iterator it = myEntitys.find(it3.topset);
|
||||
if (it != myEntitys.end()) {
|
||||
ASMs1D* pch = static_cast<ASMs1D*>(sim.getPatch(it3.patch));
|
||||
if (!pch)
|
||||
continue;
|
||||
NodalConstraintASMs1DHelper helper(pch);
|
||||
int idx = pch->getNodeID(helper.getCorner(it3.vertex, it3.basis));
|
||||
for (const auto& it2 : it->second) {
|
||||
// vertex constraints
|
||||
ASMs1D* pch2 = static_cast<ASMs1D*>(sim.getPatch(it2.patch));
|
||||
if (!pch2)
|
||||
continue;
|
||||
NodalConstraintASMs1DHelper helper2(pch2);
|
||||
|
||||
if (it2.idim == 1)
|
||||
helper2.constrainPatch(it3.comp, it3.basis, idx);
|
||||
else if (it2.idim == 0)
|
||||
helper.constrainVertex(it2.item, it3.comp, it3.basis, idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Helper function to create a NodalConstraintASMHelper instance.
|
||||
*/
|
||||
|
||||
static NodalConstraintASMHelper* get2DHelper(ASMbase* pch)
|
||||
{
|
||||
ASMs2D* spch = dynamic_cast<ASMs2D*>(pch);
|
||||
if (spch)
|
||||
return new NodalConstraintASMs2DHelper(spch);
|
||||
|
||||
#ifdef HAS_LRSPLINE
|
||||
else {
|
||||
ASMu2D* upch = dynamic_cast<ASMu2D*>(pch);
|
||||
if (upch)
|
||||
return new NodalConstraintASMu2DHelper(upch);
|
||||
}
|
||||
ASMu2D* upch = dynamic_cast<ASMu2D*>(pch);
|
||||
if (upch)
|
||||
return new NodalConstraintASMu2DHelper(upch);
|
||||
#endif
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
void NodalConstraintProcessor<SIM2D>::apply(SIM2D& sim, TopologySet& myEntitys,
|
||||
const ConstraintVec& vConstr)
|
||||
template<> bool SIMNodalConstraint<SIM1D>::applyConstraint()
|
||||
{
|
||||
for (const auto& it3 : vConstr) {
|
||||
TopologySet::const_iterator it = myEntitys.find(it3.topset);
|
||||
if (it != myEntitys.end()) {
|
||||
std::unique_ptr<NodalConstraintASMHelper> helper(get2DHelper(sim.getPatch(it3.patch)));
|
||||
for (const auto& it3 : vertConstraints) {
|
||||
TopologySet::const_iterator it = SIM1D::myEntitys.find(it3.topset);
|
||||
if (it != SIM1D::myEntitys.end()) {
|
||||
ASMs1D* pch = static_cast<ASMs1D*>(this->getPatch(it3.patch));
|
||||
if (!pch)
|
||||
continue;
|
||||
NodalConstraintASMs1DHelper helper(pch);
|
||||
int idx = pch->getNodeID(helper.getCorner(it3.vertex, it3.basis));
|
||||
for (const auto& it2 : it->second) {
|
||||
ASMs1D* pch2 = static_cast<ASMs1D*>(this->getPatch(it2.patch));
|
||||
if (!pch2)
|
||||
continue;
|
||||
NodalConstraintASMs1DHelper helper2(pch2);
|
||||
if (it2.idim == 1)
|
||||
helper2.constrainPatch(it3.comp, it3.basis, idx);
|
||||
else if (it2.idim == 0) // vertex constraints
|
||||
helper.constrainVertex(it2.item, it3.comp, it3.basis, idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<> bool SIMNodalConstraint<SIM2D>::applyConstraint()
|
||||
{
|
||||
for (const auto& it3 : vertConstraints) {
|
||||
TopologySet::const_iterator it = SIM2D::myEntitys.find(it3.topset);
|
||||
if (it != SIM2D::myEntitys.end()) {
|
||||
std::unique_ptr<NodalConstraintASMHelper> helper(get2DHelper(this->getPatch(it3.patch)));
|
||||
int idx = helper->getCorner(it3.vertex, it3.basis);
|
||||
for (const auto& it2 : it->second) {
|
||||
std::unique_ptr<NodalConstraintASMHelper> helper2(get2DHelper(sim.getPatch(it2.patch)));
|
||||
std::unique_ptr<NodalConstraintASMHelper> helper2(get2DHelper(this->getPatch(it2.patch)));
|
||||
if (it2.idim == 2)
|
||||
helper2->constrainPatch(it3.comp, it3.basis, idx);
|
||||
else if (it2.idim == 1) // Edge constraints
|
||||
|
@ -392,28 +390,25 @@ void NodalConstraintProcessor<SIM2D>::apply(SIM2D& sim, TopologySet& myEntitys,
|
|||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
void NodalConstraintProcessor<SIM3D>::apply(SIM3D& sim, TopologySet& myEntitys,
|
||||
const ConstraintVec& vConstr)
|
||||
template<> bool SIMNodalConstraint<SIM3D>::applyConstraint()
|
||||
{
|
||||
for (const auto& it3 : vConstr) {
|
||||
TopologySet::const_iterator it = myEntitys.find(it3.topset);
|
||||
if (it != myEntitys.end()) {
|
||||
ASMs3D* pch = static_cast<ASMs3D*>(sim.getPatch(it3.patch));
|
||||
for (const auto& it3 : vertConstraints) {
|
||||
TopologySet::const_iterator it = SIM3D::myEntitys.find(it3.topset);
|
||||
if (it != SIM3D::myEntitys.end()) {
|
||||
ASMs3D* pch = static_cast<ASMs3D*>(this->getPatch(it3.patch));
|
||||
if (!pch)
|
||||
continue;
|
||||
NodalConstraintASMs3DHelper helper(pch);
|
||||
int idx = helper.getCorner(it3.vertex, it3.basis);
|
||||
for (const auto& it2 : it->second) {
|
||||
// vertex constraints
|
||||
ASMs3D* pch2 = static_cast<ASMs3D*>(sim.getPatch(it2.patch));
|
||||
ASMs3D* pch2 = static_cast<ASMs3D*>(this->getPatch(it2.patch));
|
||||
if (!pch2)
|
||||
continue;
|
||||
NodalConstraintASMs3DHelper helper2(pch2);
|
||||
|
||||
if (it2.idim == 3)
|
||||
helper2.constrainPatch(it3.comp, it3.basis, idx);
|
||||
else if (it2.idim == 2) // Face constraints
|
||||
|
@ -425,4 +420,5 @@ void NodalConstraintProcessor<SIM3D>::apply(SIM3D& sim, TopologySet& myEntitys,
|
|||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
//!
|
||||
//==============================================================================
|
||||
|
||||
#ifndef _SIM_NODALCONSTRAINT_H_
|
||||
#define _SIM_NODALCONSTRAINT_H_
|
||||
#ifndef _SIM_NODAL_CONSTRAINT_H_
|
||||
#define _SIM_NODAL_CONSTRAINT_H_
|
||||
|
||||
#include "IFEM.h"
|
||||
#include "SIM1D.h"
|
||||
|
@ -21,12 +21,6 @@
|
|||
#include "Utilities.h"
|
||||
#include "tinyxml.h"
|
||||
|
||||
class ASMbase;
|
||||
class ASMs1D;
|
||||
class ASMs2D;
|
||||
class ASMs3D;
|
||||
class ASMu2D;
|
||||
|
||||
|
||||
//! \brief Describes a topologyset constrained to a vertex.
|
||||
struct TopSetToVertex {
|
||||
|
@ -40,87 +34,57 @@ struct TopSetToVertex {
|
|||
TopSetToVertex() : basis(1), patch(1), vertex(1), comp(1) {}
|
||||
};
|
||||
|
||||
|
||||
//! \brief Helper class for constraining entities to a node
|
||||
template<class Dim>
|
||||
class NodalConstraintProcessor {
|
||||
public:
|
||||
//! \brief Convenience typedef
|
||||
typedef std::vector<TopSetToVertex> ConstraintVec;
|
||||
|
||||
//! \brief Apply nodal constraints
|
||||
//! \param sim The simulator to apply the constraints to
|
||||
//! \param myEntitys The topologysets of the simulator
|
||||
//! \param vertConstraints Constraints to apply
|
||||
static void apply(Dim& sim, TopologySet& myEntitys,
|
||||
const ConstraintVec& vertConstraints);
|
||||
};
|
||||
|
||||
//! \brief Specialization for 1D
|
||||
template<>
|
||||
void NodalConstraintProcessor<SIM1D>::apply(SIM1D& sim, TopologySet& myEntitys,
|
||||
const ConstraintVec& vConstr);
|
||||
|
||||
|
||||
//! \brief Specialization for 2D
|
||||
template<>
|
||||
void NodalConstraintProcessor<SIM2D>::apply(SIM2D& sim, TopologySet& myEntitys,
|
||||
const ConstraintVec& vConstr);
|
||||
|
||||
//! \brief Specialization for 3D
|
||||
template<>
|
||||
void NodalConstraintProcessor<SIM3D>::apply(SIM3D& sim, TopologySet& myEntitys,
|
||||
const ConstraintVec& vConstr);
|
||||
typedef std::vector<TopSetToVertex> ConstraintVec; //!< Convenience type
|
||||
|
||||
|
||||
//! \brief Inherit this class to equip your SIM with nodal constraints.
|
||||
template<class Dim>
|
||||
class SIMNodalConstraint : public Dim {
|
||||
public:
|
||||
//! \brief Default constructor.
|
||||
//! \param[in] n1 Dimension of the primary solution field
|
||||
//! \param[in] check If \e true, ensure the model is in a right-hand system
|
||||
SIMNodalConstraint(const SIMbase::CharVec& unf,
|
||||
bool checkRHS=false) :
|
||||
Dim(unf,checkRHS) {}
|
||||
template<class Dim> class SIMNodalConstraint : public Dim
|
||||
{
|
||||
ConstraintVec vertConstraints; //!< Registered vertex constraints
|
||||
|
||||
//! \brief Empty destructor
|
||||
public:
|
||||
//! \brief The constructor forwards to the parent class constructor.
|
||||
SIMNodalConstraint(const std::vector<unsigned char>& unf) : Dim(unf) {}
|
||||
//! \brief Empty destructor.
|
||||
virtual ~SIMNodalConstraint() {}
|
||||
|
||||
//! \copydoc SIMbase::preprocessBeforeAsmInit(int&)
|
||||
//! \details Sets up the nodal constraints.
|
||||
virtual bool preprocessBeforeAsmInit(int&)
|
||||
{
|
||||
NodalConstraintProcessor<Dim>::apply(*this, this->myEntitys,
|
||||
vertConstraints);
|
||||
return true;
|
||||
}
|
||||
protected:
|
||||
//! \brief Sets up the nodal constraints.
|
||||
virtual bool preprocessBeforeAsmInit(int&) { return this->applyConstraint(); }
|
||||
|
||||
using Dim::parse;
|
||||
//! \brief Parses a data section from an XML element.
|
||||
virtual bool parse(const TiXmlElement* elem)
|
||||
{
|
||||
if (!strcasecmp(elem->Value(),"constraintovertex")) {
|
||||
vertConstraints.resize(vertConstraints.size()+1);
|
||||
utl::getAttribute(elem,"set",vertConstraints.back().topset);
|
||||
utl::getAttribute(elem,"patch",vertConstraints.back().patch);
|
||||
utl::getAttribute(elem,"vertex",vertConstraints.back().vertex);
|
||||
utl::getAttribute(elem,"comp",vertConstraints.back().comp);
|
||||
utl::getAttribute(elem,"basis",vertConstraints.back().basis);
|
||||
IFEM::cout << "\tConstraining set \"" << vertConstraints.back().topset
|
||||
<< "\" to P"<< vertConstraints.back().patch << "V"
|
||||
<< vertConstraints.back().vertex
|
||||
<< " in direction " << vertConstraints.back().comp;
|
||||
if (vertConstraints.back().basis > 1)
|
||||
IFEM::cout << " (basis " << vertConstraints.back().basis << ")";
|
||||
IFEM::cout << std::endl;
|
||||
} else
|
||||
if (strcasecmp(elem->Value(),"constraintovertex"))
|
||||
return this->Dim::parse(elem);
|
||||
|
||||
TopSetToVertex topset;
|
||||
utl::getAttribute(elem,"set",topset.topset);
|
||||
utl::getAttribute(elem,"patch",topset.patch);
|
||||
utl::getAttribute(elem,"vertex",topset.vertex);
|
||||
utl::getAttribute(elem,"comp",topset.comp);
|
||||
utl::getAttribute(elem,"basis",topset.basis);
|
||||
vertConstraints.push_back(topset);
|
||||
IFEM::cout <<"\tConstraining set \""<< topset.topset
|
||||
<<"\" to P"<< topset.patch <<" V"<< topset.vertex
|
||||
<<" in direction "<< topset.comp;
|
||||
if (topset.basis > 1)
|
||||
IFEM::cout <<" (basis "<< topset.basis <<")";
|
||||
IFEM::cout << std::endl;
|
||||
return true;
|
||||
}
|
||||
protected:
|
||||
std::vector<TopSetToVertex> vertConstraints; //!< Registered vertex constraints
|
||||
|
||||
private:
|
||||
//! \brief Applies the nodal constraints on the defined topology sets.
|
||||
bool applyConstraint();
|
||||
};
|
||||
|
||||
//! \brief Specialization for 1D
|
||||
template<> bool SIMNodalConstraint<SIM1D>::applyConstraint();
|
||||
//! \brief Specialization for 2D
|
||||
template<> bool SIMNodalConstraint<SIM2D>::applyConstraint();
|
||||
//! \brief Specialization for 3D
|
||||
template<> bool SIMNodalConstraint<SIM3D>::applyConstraint();
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue
Block a user