Added: Allowing specifying periodicity properly;

- add <basis> and <periodic> to <connection> tags.
  will only connect a given basis in a periodic fashion
  (ie disable coordinate checks)
This commit is contained in:
Arne Morten Kvarving 2016-05-16 02:58:44 +02:00 committed by Knut Morten Okstad
parent a172307315
commit a5812724a2
5 changed files with 142 additions and 33 deletions

View File

@ -68,6 +68,45 @@ SIM2D::SIM2D (IntegrandBase* itg, unsigned char n, bool check) : SIMgeneric(itg)
} }
bool SIM2D::addConnection (int master, int slave, int mIdx,
int sIdx, int orient, int basis, bool coordCheck)
{
if (orient < 0 || orient > 1) {
std::cerr <<" *** SIM2D::addConnection: Invalid orientation "<< orient <<"."
<< std::endl;
return false;
}
int lmaster = this->getLocalPatchIndex(master);
int lslave = this->getLocalPatchIndex(slave);
if (lmaster > 0 && lslave > 0)
{
IFEM::cout <<"\tConnecting P"<< slave <<" E"<< sIdx
<<" to P"<< master <<" E"<< mIdx
<<" reversed? "<< orient << std::endl;
ASMs2D* spch = static_cast<ASMs2D*>(myModel[lslave-1]);
ASMs2D* mpch = static_cast<ASMs2D*>(myModel[lmaster-1]);
std::set<int> bases;
if (basis == 0)
for (size_t b = 1; b <= spch->getNoBasis(); ++b)
bases.insert(b);
else
bases = utl::getDigits(basis);
for (const int& b : bases)
if (!spch->connectPatch(sIdx,*mpch,mIdx,orient,b,coordCheck))
return false;
}
else
adm.dd.ghostConnections.insert(DomainDecomposition::Interface{master, slave, mIdx, sIdx, orient, 1});
return true;
}
bool SIM2D::parseGeometryTag (const TiXmlElement* elem) bool SIM2D::parseGeometryTag (const TiXmlElement* elem)
{ {
IFEM::cout <<" Parsing <"<< elem->Value() <<">"<< std::endl; IFEM::cout <<" Parsing <"<< elem->Value() <<">"<< std::endl;
@ -157,13 +196,19 @@ bool SIM2D::parseGeometryTag (const TiXmlElement* elem)
const TiXmlElement* child = elem->FirstChildElement("connection"); const TiXmlElement* child = elem->FirstChildElement("connection");
for (; child; child = child->NextSiblingElement()) for (; child; child = child->NextSiblingElement())
{ {
int master = 0, slave = 0, mEdge = 0, sEdge = 0; int master = 0, slave = 0, mEdge = 0, sEdge = 0, orient = 0, basis = 0;
bool rever = false; bool rever = false, periodic = false;
utl::getAttribute(child,"master",master); utl::getAttribute(child,"master",master);
utl::getAttribute(child,"medge",mEdge); if (!utl::getAttribute(child,"midx",mEdge))
utl::getAttribute(child,"medge",mEdge);
utl::getAttribute(child,"slave",slave); utl::getAttribute(child,"slave",slave);
utl::getAttribute(child,"sedge",sEdge); if (!utl::getAttribute(child,"sidx",sEdge))
utl::getAttribute(child,"reverse",rever); utl::getAttribute(child,"sedge",sEdge);
if (!utl::getAttribute(child,"orient",orient))
if (utl::getAttribute(child,"reverse",rever) && rever)
orient = 1;
utl::getAttribute(child,"basis",basis);
utl::getAttribute(child,"periodic",periodic);
if (master == slave || if (master == slave ||
master < 1 || master > nGlPatches || master < 1 || master > nGlPatches ||
@ -173,24 +218,17 @@ bool SIM2D::parseGeometryTag (const TiXmlElement* elem)
<< master <<" "<< slave << std::endl; << master <<" "<< slave << std::endl;
return false; return false;
} }
int lmaster = this->getLocalPatchIndex(master);
int lslave = this->getLocalPatchIndex(slave);
if (lmaster > 0 && lslave > 0) if (!this->addConnection(master,slave,mEdge,sEdge,orient,basis,!periodic))
{ {
IFEM::cout <<"\tConnecting P"<< lslave <<" E"<< sEdge std::cerr <<" *** SIM2D::parse: Error establishing connection."
<<" to P"<< lmaster <<" E"<< mEdge << std::endl;
<<" reversed? "<< rever << std::endl; return false;
ASMs2D* spch = static_cast<ASMs2D*>(myModel[lslave-1]);
ASMs2D* mpch = static_cast<ASMs2D*>(myModel[lmaster-1]);
if (!spch->connectPatch(sEdge,*mpch,mEdge,rever))
return false;
else if (opt.discretization == ASM::SplineC1)
top.push_back(Interface(static_cast<ASMs2DC1*>(mpch),mEdge,
static_cast<ASMs2DC1*>(spch),sEdge,rever));
} }
else
adm.dd.ghostConnections.insert(DomainDecomposition::Interface{master, slave, mEdge, sEdge, rever?1:0, 1}); if (opt.discretization == ASM::SplineC1)
top.push_back(Interface(static_cast<ASMs2DC1*>(this->getPatch(master,true)),mEdge,
static_cast<ASMs2DC1*>(this->getPatch(slave,true)),sEdge,orient));
} }
// Second pass for C1-continuous patches, to set up additional constraints // Second pass for C1-continuous patches, to set up additional constraints

View File

@ -70,6 +70,17 @@ public:
virtual bool readPatches(std::istream& isp, PatchVec& patches, virtual bool readPatches(std::istream& isp, PatchVec& patches,
const char* whiteSpace) const; const char* whiteSpace) const;
//! \brief Connect two patches.
//! \param master Master patch
//! \param slave Slave patch
//! \param mEdge Edge on master
//! \param sEdge Edge on slave
//! \param orient Orientation flag for connection (1 for reversed)
//! \param basis Which bases to connect (0 for all)
//! \param coordCheck False to turn off coordinate checks
bool addConnection(int master, int slave, int mEdge, int sEdge,
int orient, int basis = 0, bool coordCheck = true);
//! \brief Evaluates the primary solution at the given point. //! \brief Evaluates the primary solution at the given point.
//! \param[in] psol Primary solution vector //! \param[in] psol Primary solution vector
//! \param[in] u First parameter of the point to evaluate at //! \param[in] u First parameter of the point to evaluate at

View File

@ -46,6 +46,44 @@ SIM3D::SIM3D (IntegrandBase* itg, unsigned char n, bool check) : SIMgeneric(itg)
} }
bool SIM3D::addConnection (int master, int slave, int mIdx,
int sIdx, int orient, int basis, bool coordCheck)
{
if (orient < 0 || orient > 7) {
std::cerr <<" *** SIM3D::addConnection: Invalid orientation "<< orient <<"."
<< std::endl;
return false;
}
int lmaster = this->getLocalPatchIndex(master);
int lslave = this->getLocalPatchIndex(slave);
if (lmaster > 0 && lslave > 0)
{
IFEM::cout <<"\tConnecting P"<< slave <<" F"<< sIdx
<<" to P"<< master <<" F"<< mIdx
<<" orient "<< orient << std::endl;
ASMs3D* spch = static_cast<ASMs3D*>(myModel[lslave-1]);
ASMs3D* mpch = static_cast<ASMs3D*>(myModel[lmaster-1]);
std::set<int> bases;
if (basis == 0)
for (size_t b = 1; b <= spch->getNoBasis(); ++b)
bases.insert(b);
else
bases = utl::getDigits(basis);
for (const int& b : bases)
if (!spch->connectPatch(sIdx,*mpch,mIdx,orient,b,coordCheck))
return false;
}
else
adm.dd.ghostConnections.insert(DomainDecomposition::Interface{master, slave, mIdx, sIdx, orient, 2});
return true;
}
bool SIM3D::parseGeometryTag (const TiXmlElement* elem) bool SIM3D::parseGeometryTag (const TiXmlElement* elem)
{ {
IFEM::cout <<" Parsing <"<< elem->Value() <<">"<< std::endl; IFEM::cout <<" Parsing <"<< elem->Value() <<">"<< std::endl;
@ -138,12 +176,15 @@ bool SIM3D::parseGeometryTag (const TiXmlElement* elem)
const TiXmlElement* child = elem->FirstChildElement("connection"); const TiXmlElement* child = elem->FirstChildElement("connection");
for (; child; child = child->NextSiblingElement()) for (; child; child = child->NextSiblingElement())
{ {
int master = 0, slave = 0, mFace = 0, sFace = 0, orient = 0; int master = 0, slave = 0, mFace = 0, sFace = 0, orient = 0, basis = 0;
bool periodic = false;
utl::getAttribute(child,"master",master); utl::getAttribute(child,"master",master);
utl::getAttribute(child,"mface",mFace); utl::getAttribute(child,"mface",mFace);
utl::getAttribute(child,"slave",slave); utl::getAttribute(child,"slave",slave);
utl::getAttribute(child,"sface",sFace); utl::getAttribute(child,"sface",sFace);
utl::getAttribute(child,"orient",orient); utl::getAttribute(child,"orient",orient);
utl::getAttribute(child,"basis",basis);
utl::getAttribute(child,"periodic",periodic);
if (master == slave || if (master == slave ||
master < 1 || master > nGlPatches || master < 1 || master > nGlPatches ||
@ -153,18 +194,14 @@ bool SIM3D::parseGeometryTag (const TiXmlElement* elem)
<< master <<" "<< slave << std::endl; << master <<" "<< slave << std::endl;
return false; return false;
} }
int lmaster = this->getLocalPatchIndex(master);
int lslave = this->getLocalPatchIndex(slave); if (!this->addConnection(master, slave, mFace, sFace,
if (lmaster > 0 && lslave > 0) { orient, basis, !periodic))
IFEM::cout <<"\tConnecting P"<< lslave <<" F"<< sFace {
<<" to P"<< lmaster <<" F"<< mFace std::cerr <<" *** SIM3D::parse: Error establishing connection."
<<" orient "<< orient << std::endl; << std::endl;
ASMs3D* spch = static_cast<ASMs3D*>(myModel[lslave-1]); return false;
ASMs3D* mpch = static_cast<ASMs3D*>(myModel[lmaster-1]); }
if (!spch->connectPatch(sFace,*mpch,mFace,orient))
return false;
} else
adm.dd.ghostConnections.insert(DomainDecomposition::Interface{master, slave, mFace, sFace, orient, 2});
} }
} }

View File

@ -65,6 +65,17 @@ public:
virtual bool readPatches(std::istream& isp, PatchVec& patches, virtual bool readPatches(std::istream& isp, PatchVec& patches,
const char* whiteSpace) const; const char* whiteSpace) const;
//! \brief Connect two patches.
//! \param master Master patch
//! \param slave Slave patch
//! \param mFace Face on master
//! \param sFace Face on slave
//! \param orient Orientation flag for connection
//! \param basis Which bases to connect (0 for all)
//! \param coordCheck False to turn off coordinate checks
bool addConnection(int master, int slave, int mFace, int sFace,
int orient, int basis = 0, bool coordCheck = true);
//! \brief Evaluates the primary solution at the given point. //! \brief Evaluates the primary solution at the given point.
//! \param[in] psol Primary solution vector //! \param[in] psol Primary solution vector
//! \param[in] u First parameter of the point to evaluate at //! \param[in] u First parameter of the point to evaluate at

View File

@ -91,6 +91,18 @@ public:
//! \brief Returns a list of prioritized XML-tags. //! \brief Returns a list of prioritized XML-tags.
virtual const char** getPrioritizedTags() const; virtual const char** getPrioritizedTags() const;
//! \brief Connect two patches.
//! \param master Master patch
//! \param slave Slave patch
//! \param mIdx Index on master
//! \param sIdx Index on slave
//! \param orient Orientation flag
//! \param basis Which bases to connect (0 for all)
//! \param coordCheck False to turn off coordinate checks.
virtual bool addConnection(int master, int slave, int mIdx, int sIdx,
int orient, int basis = 0, bool coordCheck = true)
{ return false; }
protected: protected:
//! \brief Parses the "set" attribute of a material XML-tag. //! \brief Parses the "set" attribute of a material XML-tag.
//! \param[in] elem The XML element extract the set name from //! \param[in] elem The XML element extract the set name from