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:
Knut Morten Okstad 2017-06-12 06:17:35 +02:00
parent ad5bf4ed56
commit ddb389d5fd
2 changed files with 85 additions and 125 deletions

View File

@ -326,63 +326,61 @@ protected:
#endif #endif
template<> /*!
void NodalConstraintProcessor<SIM1D>::apply(SIM1D& sim, TopologySet& myEntitys, \brief Helper function to create a NodalConstraintASMHelper instance.
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);
}
}
}
}
static NodalConstraintASMHelper* get2DHelper(ASMbase* pch) static NodalConstraintASMHelper* get2DHelper(ASMbase* pch)
{ {
ASMs2D* spch = dynamic_cast<ASMs2D*>(pch); ASMs2D* spch = dynamic_cast<ASMs2D*>(pch);
if (spch) if (spch)
return new NodalConstraintASMs2DHelper(spch); return new NodalConstraintASMs2DHelper(spch);
#ifdef HAS_LRSPLINE #ifdef HAS_LRSPLINE
else {
ASMu2D* upch = dynamic_cast<ASMu2D*>(pch); ASMu2D* upch = dynamic_cast<ASMu2D*>(pch);
if (upch) if (upch)
return new NodalConstraintASMu2DHelper(upch); return new NodalConstraintASMu2DHelper(upch);
}
#endif #endif
return nullptr; return nullptr;
} }
template<> template<> bool SIMNodalConstraint<SIM1D>::applyConstraint()
void NodalConstraintProcessor<SIM2D>::apply(SIM2D& sim, TopologySet& myEntitys,
const ConstraintVec& vConstr)
{ {
for (const auto& it3 : vConstr) { for (const auto& it3 : vertConstraints) {
TopologySet::const_iterator it = myEntitys.find(it3.topset); TopologySet::const_iterator it = SIM1D::myEntitys.find(it3.topset);
if (it != myEntitys.end()) { if (it != SIM1D::myEntitys.end()) {
std::unique_ptr<NodalConstraintASMHelper> helper(get2DHelper(sim.getPatch(it3.patch))); 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); int idx = helper->getCorner(it3.vertex, it3.basis);
for (const auto& it2 : it->second) { 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) if (it2.idim == 2)
helper2->constrainPatch(it3.comp, it3.basis, idx); helper2->constrainPatch(it3.comp, it3.basis, idx);
else if (it2.idim == 1) // Edge constraints else if (it2.idim == 1) // Edge constraints
@ -392,28 +390,25 @@ void NodalConstraintProcessor<SIM2D>::apply(SIM2D& sim, TopologySet& myEntitys,
} }
} }
} }
return true;
} }
template<> template<> bool SIMNodalConstraint<SIM3D>::applyConstraint()
void NodalConstraintProcessor<SIM3D>::apply(SIM3D& sim, TopologySet& myEntitys,
const ConstraintVec& vConstr)
{ {
for (const auto& it3 : vConstr) { for (const auto& it3 : vertConstraints) {
TopologySet::const_iterator it = myEntitys.find(it3.topset); TopologySet::const_iterator it = SIM3D::myEntitys.find(it3.topset);
if (it != myEntitys.end()) { if (it != SIM3D::myEntitys.end()) {
ASMs3D* pch = static_cast<ASMs3D*>(sim.getPatch(it3.patch)); ASMs3D* pch = static_cast<ASMs3D*>(this->getPatch(it3.patch));
if (!pch) if (!pch)
continue; continue;
NodalConstraintASMs3DHelper helper(pch); NodalConstraintASMs3DHelper helper(pch);
int idx = helper.getCorner(it3.vertex, it3.basis); int idx = helper.getCorner(it3.vertex, it3.basis);
for (const auto& it2 : it->second) { for (const auto& it2 : it->second) {
// vertex constraints ASMs3D* pch2 = static_cast<ASMs3D*>(this->getPatch(it2.patch));
ASMs3D* pch2 = static_cast<ASMs3D*>(sim.getPatch(it2.patch));
if (!pch2) if (!pch2)
continue; continue;
NodalConstraintASMs3DHelper helper2(pch2); NodalConstraintASMs3DHelper helper2(pch2);
if (it2.idim == 3) if (it2.idim == 3)
helper2.constrainPatch(it3.comp, it3.basis, idx); helper2.constrainPatch(it3.comp, it3.basis, idx);
else if (it2.idim == 2) // Face constraints else if (it2.idim == 2) // Face constraints
@ -425,4 +420,5 @@ void NodalConstraintProcessor<SIM3D>::apply(SIM3D& sim, TopologySet& myEntitys,
} }
} }
} }
return true;
} }

View File

@ -11,8 +11,8 @@
//! //!
//============================================================================== //==============================================================================
#ifndef _SIM_NODALCONSTRAINT_H_ #ifndef _SIM_NODAL_CONSTRAINT_H_
#define _SIM_NODALCONSTRAINT_H_ #define _SIM_NODAL_CONSTRAINT_H_
#include "IFEM.h" #include "IFEM.h"
#include "SIM1D.h" #include "SIM1D.h"
@ -21,12 +21,6 @@
#include "Utilities.h" #include "Utilities.h"
#include "tinyxml.h" #include "tinyxml.h"
class ASMbase;
class ASMs1D;
class ASMs2D;
class ASMs3D;
class ASMu2D;
//! \brief Describes a topologyset constrained to a vertex. //! \brief Describes a topologyset constrained to a vertex.
struct TopSetToVertex { struct TopSetToVertex {
@ -40,87 +34,57 @@ struct TopSetToVertex {
TopSetToVertex() : basis(1), patch(1), vertex(1), comp(1) {} TopSetToVertex() : basis(1), patch(1), vertex(1), comp(1) {}
}; };
typedef std::vector<TopSetToVertex> ConstraintVec; //!< Convenience type
//! \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);
//! \brief Inherit this class to equip your SIM with nodal constraints. //! \brief Inherit this class to equip your SIM with nodal constraints.
template<class Dim> template<class Dim> class SIMNodalConstraint : public Dim
class SIMNodalConstraint : public Dim { {
public: ConstraintVec vertConstraints; //!< Registered vertex constraints
//! \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) {}
//! \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() {} virtual ~SIMNodalConstraint() {}
//! \copydoc SIMbase::preprocessBeforeAsmInit(int&) protected:
//! \details Sets up the nodal constraints. //! \brief Sets up the nodal constraints.
virtual bool preprocessBeforeAsmInit(int&) virtual bool preprocessBeforeAsmInit(int&) { return this->applyConstraint(); }
{
NodalConstraintProcessor<Dim>::apply(*this, this->myEntitys,
vertConstraints);
return true;
}
using Dim::parse; using Dim::parse;
//! \brief Parses a data section from an XML element. //! \brief Parses a data section from an XML element.
virtual bool parse(const TiXmlElement* elem) virtual bool parse(const TiXmlElement* elem)
{ {
if (!strcasecmp(elem->Value(),"constraintovertex")) { 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
return this->Dim::parse(elem); 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; 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 #endif