38#include <boost/algorithm/string/predicate.hpp>
49 : m_meshGraph(meshGraph), m_session(pSession)
61 auto it = set.begin(), end = set.end();
62 for (
int i = 0; it != end; ++it, ++i)
84 auto it = boundaryRegions.begin(), end = boundaryRegions.end();
86 for (; it != end; ++it, ++i)
88 ids.insert(it->first);
91 int np = comm->GetSize();
92 int ip = comm->GetRank();
96 while (involved && half_size < np)
103 int receiver = ip - half_size;
108 sender_size[0] = idsArray.size();
109 comm->Send(receiver, sender_size);
112 comm->Send(receiver, idsArray);
122 int sender = ip + half_size;
128 comm->Recv(sender, sender_size);
132 comm->Recv(sender, other_ids);
135 ids.insert(other_ids.begin(), other_ids.end());
148 comm->Bcast(nIds, 0);
161 comm->Bcast(idsArray, 0);
163 return std::set<int>(idsArray.begin(), idsArray.end());
174 if (comm->IsSerial())
189 for (
auto &it : allids)
194 comm->CommCreateIf(this_rank_participates);
196 ASSERTL0(
bool(comm_region) ==
bool(this_rank_participates),
197 "Rank should be in communicator but wasn't or is in "
198 "communicator but shouldn't be.");
200 if (this_rank_participates)
212 ASSERTL0(conditions,
"Unable to find CONDITIONS tag in file.");
214 TiXmlElement *boundaryRegions =
215 conditions->FirstChildElement(
"BOUNDARYREGIONS");
236 TiXmlElement *boundaryRegions =
237 conditions->FirstChildElement(
"BOUNDARYREGIONS");
239 boundaryRegions,
m_session->GetTimeLevel());
240 ASSERTL0(boundaryRegions,
"Unable to find BOUNDARYREGIONS block.");
243 TiXmlElement *boundaryRegionsElement =
244 boundaryRegions->FirstChildElement(
"B");
246 while (boundaryRegionsElement)
251 int err = boundaryRegionsElement->QueryIntAttribute(
"ID", &indx);
252 ASSERTL0(err == TIXML_SUCCESS,
"Unable to read attribute ID.");
254 TiXmlNode *boundaryRegionChild = boundaryRegionsElement->FirstChild();
259 while (boundaryRegionChild &&
260 boundaryRegionChild->Type() != TiXmlNode::TINYXML_TEXT)
262 boundaryRegionChild = boundaryRegionChild->NextSibling();
266 "Unable to read variable definition body.");
267 std::string boundaryRegionStr =
268 boundaryRegionChild->ToText()->ValueStr();
270 std::string::size_type indxBeg =
271 boundaryRegionStr.find_first_of(
'[') + 1;
272 std::string::size_type indxEnd =
273 boundaryRegionStr.find_last_of(
']') - 1;
276 (std::string(
"Error reading boundary region definition:") +
280 std::string indxStr =
281 boundaryRegionStr.substr(indxBeg, indxEnd - indxBeg + 1);
283 if (!indxStr.empty())
290 "Boundary region " + indxStr +
291 " defined more than "
294 m_meshGraph->GetCompositeList(indxStr, *boundaryRegion);
295 if (boundaryRegion->size() > 0)
303 err = boundaryRegionsElement->QueryStringAttribute(
"NAME", &
name);
304 if (err == TIXML_SUCCESS)
310 boundaryRegionsElement =
311 boundaryRegionsElement->NextSiblingElement(
"B");
327 TiXmlElement *boundaryConditionsElement =
328 conditions->FirstChildElement(
"BOUNDARYCONDITIONS");
330 boundaryConditionsElement,
m_session->GetTimeLevel());
332 "Boundary conditions must be specified.");
334 TiXmlElement *regionElement =
335 boundaryConditionsElement->FirstChildElement(
"REGION");
338 while (regionElement)
343 int boundaryRegionID;
344 int err = regionElement->QueryIntAttribute(
"REF", &boundaryRegionID);
346 "Error reading boundary region reference.");
349 "Boundary region '" + std::to_string(boundaryRegionID) +
350 "' appears multiple times.");
353 std::string boundaryRegionIDStr;
354 std::ostringstream boundaryRegionIDStrm(boundaryRegionIDStr);
355 boundaryRegionIDStrm << boundaryRegionID;
359 regionElement = regionElement->NextSiblingElement(
"REGION");
364 "Boundary region " + std::to_string(boundaryRegionID) +
371 TiXmlElement *conditionElement = regionElement->FirstChildElement();
372 std::vector<std::string> vars =
m_session->GetVariables();
374 while (conditionElement)
377 std::string conditionType = conditionElement->Value();
378 std::string attrData;
379 bool isTimeDependent =
false;
382 TiXmlAttribute *attr = conditionElement->FirstAttribute();
384 std::vector<std::string>::iterator iter;
385 std::string attrName;
387 attrData = conditionElement->Attribute(
"VAR");
389 if (!attrData.empty())
391 iter =
std::find(vars.begin(), vars.end(), attrData);
394 (std::string(
"Cannot find variable: ") + attrData).c_str());
397 if (conditionType ==
"N")
399 if (attrData.empty())
402 for (
auto &varIter : vars)
407 (*boundaryConditions)[varIter] = neumannCondition;
414 std::string equation, userDefined, filename;
419 attrName = attr->Name();
421 if (attrName ==
"VAR")
425 else if (attrName ==
"USERDEFINEDTYPE")
428 attrData = attr->Value();
430 "USERDEFINEDTYPE attribute must have "
431 "associated value.");
433 userDefined = attrData;
435 boost::iequals(attrData,
"TimeDependent");
437 else if (attrName ==
"VALUE")
440 (std::string(
"Unknown attribute: ") +
444 attrData = attr->Value();
446 "VALUE attribute must be specified.");
450 else if (attrName ==
"FILE")
453 (std::string(
"Unknown attribute: ") +
457 attrData = attr->Value();
459 "FILE attribute must be specified.");
466 (std::string(
"Unknown boundary "
467 "condition attribute: ") +
477 userDefined, filename,
478 boundaryRegionComm));
479 neumannCondition->SetIsTimeDependent(isTimeDependent);
480 (*boundaryConditions)[*iter] = neumannCondition;
488 (*boundaryConditions)[*iter] = neumannCondition;
492 else if (conditionType ==
"D")
494 if (attrData.empty())
497 for (
auto &varIter : vars)
502 (*boundaryConditions)[varIter] = dirichletCondition;
509 std::string equation, userDefined, filename;
514 attrName = attr->Name();
516 if (attrName ==
"VAR")
520 else if (attrName ==
"USERDEFINEDTYPE")
524 attrData = attr->Value();
526 "USERDEFINEDTYPE attribute must have "
527 "associated value.");
529 userDefined = attrData;
531 boost::iequals(attrData,
"TimeDependent");
533 else if (attrName ==
"VALUE")
536 (std::string(
"Unknown attribute: ") +
540 attrData = attr->Value();
542 "VALUE attribute must have associated "
547 if (!boost::iequals(attrData,
"0") &&
548 (boost::iequals(userDefined,
550 boost::iequals(userDefined,
553 isTimeDependent =
true;
556 else if (attrName ==
"FILE")
559 (std::string(
"Unknown attribute: ") +
563 attrData = attr->Value();
565 "FILE attribute must be specified.");
572 (std::string(
"Unknown boundary "
573 "condition attribute: ") +
583 userDefined, filename,
584 boundaryRegionComm));
585 dirichletCondition->SetIsTimeDependent(isTimeDependent);
586 (*boundaryConditions)[*iter] = dirichletCondition;
594 (*boundaryConditions)[*iter] = dirichletCondition;
598 else if (conditionType ==
"R")
600 if (attrData.empty())
603 for (
auto &varIter : vars)
608 (*boundaryConditions)[varIter] = robinCondition;
616 std::string equation1, equation2, userDefined;
617 std::string filename;
619 bool primcoeffset =
false;
624 attrName = attr->Name();
626 if (attrName ==
"VAR")
630 else if (attrName ==
"USERDEFINEDTYPE")
634 attrData = attr->Value();
636 "USERDEFINEDTYPE attribute must have "
637 "associated value.");
639 userDefined = attrData;
641 boost::iequals(attrData,
"TimeDependent");
643 else if (attrName ==
"VALUE")
646 attrData = attr->Value();
648 "VALUE attributes must have "
649 "associated values.");
651 equation1 = attrData;
653 else if (attrName ==
"PRIMCOEFF")
656 attrData = attr->Value();
658 "PRIMCOEFF attributes must have "
659 "associated values.");
661 equation2 = attrData;
665 else if (attrName ==
"FILE")
667 attrData = attr->Value();
669 "FILE attribute must be specified.");
676 (std::string(
"Unknown boundary "
677 "condition attribute: ") +
684 if (primcoeffset ==
false)
686 ASSERTL0(
false,
"PRIMCOEFF must be specified in a "
687 "Robin boundary condition");
693 userDefined, filename, boundaryRegionComm));
694 (*boundaryConditions)[*iter] = robinCondition;
702 robinCondition->SetIsTimeDependent(isTimeDependent);
703 (*boundaryConditions)[*iter] = robinCondition;
707 else if (conditionType ==
"P")
709 if (attrData.empty())
711 ASSERTL0(
false,
"Periodic boundary conditions should "
712 "be explicitely defined");
719 std::string userDefined;
720 std::vector<unsigned int> periodicBndRegionIndex;
723 attrName = attr->Name();
725 if (attrName ==
"VAR")
729 else if (attrName ==
"USERDEFINEDTYPE")
732 attrData = attr->Value();
734 "USERDEFINEDTYPE attribute must have "
735 "associated value.");
737 userDefined = attrData;
739 boost::iequals(attrData,
"TimeDependent");
741 else if (attrName ==
"VALUE")
743 attrData = attr->Value();
745 "VALUE attribute must have associated "
748 int beg = attrData.find_first_of(
"[");
749 int end = attrData.find_first_of(
"]");
750 std::string periodicBndRegionIndexStr =
751 attrData.substr(beg + 1, end - beg - 1);
754 (std::string(
"Error reading periodic "
755 "boundary region definition "
756 "for boundary region: ") +
757 boundaryRegionIDStrm.str())
761 periodicBndRegionIndexStr.c_str(),
762 periodicBndRegionIndex);
766 (periodicBndRegionIndex.size() == 1),
768 "Unable to read periodic boundary "
769 "condition for boundary region: ") +
770 boundaryRegionIDStrm.str())
777 AllocateSharedPtr(periodicBndRegionIndex[0],
779 boundaryRegionComm));
780 (*boundaryConditions)[*iter] = periodicCondition;
784 ASSERTL0(
false,
"Periodic boundary conditions should "
785 "be explicitely defined");
789 else if (conditionType ==
"C")
791 ASSERTL0(
false,
"Cauchy type boundary conditions not "
795 conditionElement = conditionElement->NextSiblingElement();
799 regionElement = regionElement->NextSiblingElement(
"REGION");
#define ASSERTL0(condition, msg)
static void GetXMLElementTimeLevel(TiXmlElement *&element, const size_t timeLevel, const bool enableCheck=true)
Get XML elment time level (Parallel-in-Time)
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
static bool GenerateSeqVector(const std::string &str, std::vector< unsigned int > &out)
Takes a comma-separated compressed string and converts it to entries in a vector.
std::map< int, LibUtilities::CommSharedPtr > m_boundaryCommunicators
BoundaryRegionCollection m_boundaryRegions
void ReadBoundaryConditions(TiXmlElement *conditions)
void CreateBoundaryComms()
void Read(TiXmlElement *conditions)
Read segments (and general MeshGraph) given TiXmlDocument.
BoundaryConditions(void)=default
LibUtilities::SessionReaderSharedPtr m_session
BoundaryConditionCollection m_boundaryConditions
std::map< int, std::string > m_boundaryLabels
MeshGraphSharedPtr m_meshGraph
The mesh graph to use for referencing geometry info.
void ReadBoundaryRegions(TiXmlElement *regions)
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
std::map< int, BoundaryRegionShPtr > BoundaryRegionCollection
std::shared_ptr< BoundaryRegion > BoundaryRegionShPtr
std::shared_ptr< BoundaryConditionBase > BoundaryConditionShPtr
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
std::shared_ptr< BoundaryConditionMap > BoundaryConditionMapShPtr
Array< OneD, int > ToArray(const std::set< int > &set)
std::set< int > ShareAllBoundaryIDs(const BoundaryRegionCollection &boundaryRegions, LibUtilities::CommSharedPtr comm)
InputIterator find(InputIterator first, InputIterator last, InputIterator startingpoint, const EqualityComparable &value)