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
|
#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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user