38#include <boost/algorithm/string/predicate.hpp>
51 : m_meshGraph(meshGraph), m_session(pSession)
71 auto it = set.begin(), end = set.end();
72 for (
int i = 0; it != end; ++it, ++i)
94 auto it = boundaryRegions.begin(), end = boundaryRegions.end();
96 for (; it != end; ++it, ++i)
98 ids.insert(it->first);
101 int np = comm->GetSize();
102 int ip = comm->GetRank();
105 bool involved =
true;
106 while (involved && half_size < np)
113 int receiver = ip - half_size;
118 sender_size[0] = idsArray.size();
119 comm->Send(receiver, sender_size);
122 comm->Send(receiver, idsArray);
132 int sender = ip + half_size;
138 comm->Recv(sender, sender_size);
142 comm->Recv(sender, other_ids);
145 ids.insert(other_ids.begin(), other_ids.end());
158 comm->Bcast(nIds, 0);
171 comm->Bcast(idsArray, 0);
173 return std::set<int>(idsArray.begin(), idsArray.end());
184 if (comm->IsSerial())
199 for (
auto &it : allids)
204 comm->CommCreateIf(this_rank_participates);
206 ASSERTL0(
bool(comm_region) ==
bool(this_rank_participates),
207 "Rank should be in communicator but wasn't or is in "
208 "communicator but shouldn't be.");
210 if (this_rank_participates)
222 ASSERTL0(conditions,
"Unable to find CONDITIONS tag in file.");
224 TiXmlElement *boundaryRegions =
225 conditions->FirstChildElement(
"BOUNDARYREGIONS");
246 TiXmlElement *boundaryRegions =
247 conditions->FirstChildElement(
"BOUNDARYREGIONS");
249 boundaryRegions,
m_session->GetTimeLevel());
250 ASSERTL0(boundaryRegions,
"Unable to find BOUNDARYREGIONS block.");
253 TiXmlElement *boundaryRegionsElement =
254 boundaryRegions->FirstChildElement(
"B");
256 while (boundaryRegionsElement)
261 int err = boundaryRegionsElement->QueryIntAttribute(
"ID", &indx);
262 ASSERTL0(err == TIXML_SUCCESS,
"Unable to read attribute ID.");
264 TiXmlNode *boundaryRegionChild = boundaryRegionsElement->FirstChild();
269 while (boundaryRegionChild &&
270 boundaryRegionChild->Type() != TiXmlNode::TINYXML_TEXT)
272 boundaryRegionChild = boundaryRegionChild->NextSibling();
276 "Unable to read variable definition body.");
277 std::string boundaryRegionStr =
278 boundaryRegionChild->ToText()->ValueStr();
280 std::string::size_type indxBeg =
281 boundaryRegionStr.find_first_of(
'[') + 1;
282 std::string::size_type indxEnd =
283 boundaryRegionStr.find_last_of(
']') - 1;
286 (std::string(
"Error reading boundary region definition:") +
290 std::string indxStr =
291 boundaryRegionStr.substr(indxBeg, indxEnd - indxBeg + 1);
293 if (!indxStr.empty())
300 "Boundary region " + indxStr +
301 " defined more than "
304 m_meshGraph->GetCompositeList(indxStr, *boundaryRegion);
305 if (boundaryRegion->size() > 0)
313 err = boundaryRegionsElement->QueryStringAttribute(
"NAME", &
name);
314 if (err == TIXML_SUCCESS)
320 boundaryRegionsElement =
321 boundaryRegionsElement->NextSiblingElement(
"B");
337 TiXmlElement *boundaryConditionsElement =
338 conditions->FirstChildElement(
"BOUNDARYCONDITIONS");
340 boundaryConditionsElement,
m_session->GetTimeLevel());
342 "Boundary conditions must be specified.");
344 TiXmlElement *regionElement =
345 boundaryConditionsElement->FirstChildElement(
"REGION");
348 while (regionElement)
353 int boundaryRegionID;
354 int err = regionElement->QueryIntAttribute(
"REF", &boundaryRegionID);
356 "Error reading boundary region reference.");
359 "Boundary region '" + std::to_string(boundaryRegionID) +
360 "' appears multiple times.");
363 std::string boundaryRegionIDStr;
364 std::ostringstream boundaryRegionIDStrm(boundaryRegionIDStr);
365 boundaryRegionIDStrm << boundaryRegionID;
369 regionElement = regionElement->NextSiblingElement(
"REGION");
375 boost::lexical_cast<string>(boundaryRegionID) +
382 TiXmlElement *conditionElement = regionElement->FirstChildElement();
383 std::vector<std::string> vars =
m_session->GetVariables();
385 while (conditionElement)
388 std::string conditionType = conditionElement->Value();
389 std::string attrData;
390 bool isTimeDependent =
false;
393 TiXmlAttribute *attr = conditionElement->FirstAttribute();
395 std::vector<std::string>::iterator iter;
396 std::string attrName;
398 attrData = conditionElement->Attribute(
"VAR");
400 if (!attrData.empty())
402 iter =
std::find(vars.begin(), vars.end(), attrData);
405 (std::string(
"Cannot find variable: ") + attrData).c_str());
408 if (conditionType ==
"N")
410 if (attrData.empty())
413 for (
auto &varIter : vars)
418 (*boundaryConditions)[varIter] = neumannCondition;
425 std::string equation, userDefined, filename;
430 attrName = attr->Name();
432 if (attrName ==
"VAR")
436 else if (attrName ==
"USERDEFINEDTYPE")
439 attrData = attr->Value();
441 "USERDEFINEDTYPE attribute must have "
442 "associated value.");
444 userDefined = attrData;
446 boost::iequals(attrData,
"TimeDependent");
448 else if (attrName ==
"VALUE")
451 (std::string(
"Unknown attribute: ") +
455 attrData = attr->Value();
457 "VALUE attribute must be specified.");
461 else if (attrName ==
"FILE")
464 (std::string(
"Unknown attribute: ") +
468 attrData = attr->Value();
470 "FILE attribute must be specified.");
477 (std::string(
"Unknown boundary "
478 "condition attribute: ") +
488 userDefined, filename,
489 boundaryRegionComm));
490 neumannCondition->SetIsTimeDependent(isTimeDependent);
491 (*boundaryConditions)[*iter] = neumannCondition;
499 (*boundaryConditions)[*iter] = neumannCondition;
503 else if (conditionType ==
"D")
505 if (attrData.empty())
508 for (
auto &varIter : vars)
513 (*boundaryConditions)[varIter] = dirichletCondition;
520 std::string equation, userDefined, filename;
525 attrName = attr->Name();
527 if (attrName ==
"VAR")
531 else if (attrName ==
"USERDEFINEDTYPE")
535 attrData = attr->Value();
537 "USERDEFINEDTYPE attribute must have "
538 "associated value.");
540 userDefined = attrData;
542 boost::iequals(attrData,
"TimeDependent");
544 else if (attrName ==
"VALUE")
547 (std::string(
"Unknown attribute: ") +
551 attrData = attr->Value();
553 "VALUE attribute must have associated "
558 if (!boost::iequals(attrData,
"0") &&
559 (boost::iequals(userDefined,
561 boost::iequals(userDefined,
564 isTimeDependent =
true;
567 else if (attrName ==
"FILE")
570 (std::string(
"Unknown attribute: ") +
574 attrData = attr->Value();
576 "FILE attribute must be specified.");
583 (std::string(
"Unknown boundary "
584 "condition attribute: ") +
594 userDefined, filename,
595 boundaryRegionComm));
596 dirichletCondition->SetIsTimeDependent(isTimeDependent);
597 (*boundaryConditions)[*iter] = dirichletCondition;
605 (*boundaryConditions)[*iter] = dirichletCondition;
609 else if (conditionType ==
"R")
611 if (attrData.empty())
614 for (
auto &varIter : vars)
619 (*boundaryConditions)[varIter] = robinCondition;
627 std::string equation1, equation2, userDefined;
628 std::string filename;
630 bool primcoeffset =
false;
635 attrName = attr->Name();
637 if (attrName ==
"VAR")
641 else if (attrName ==
"USERDEFINEDTYPE")
645 attrData = attr->Value();
647 "USERDEFINEDTYPE attribute must have "
648 "associated value.");
650 userDefined = attrData;
652 boost::iequals(attrData,
"TimeDependent");
654 else if (attrName ==
"VALUE")
657 attrData = attr->Value();
659 "VALUE attributes must have "
660 "associated values.");
662 equation1 = attrData;
664 else if (attrName ==
"PRIMCOEFF")
667 attrData = attr->Value();
669 "PRIMCOEFF attributes must have "
670 "associated values.");
672 equation2 = attrData;
676 else if (attrName ==
"FILE")
678 attrData = attr->Value();
680 "FILE attribute must be specified.");
687 (std::string(
"Unknown boundary "
688 "condition attribute: ") +
695 if (primcoeffset ==
false)
697 ASSERTL0(
false,
"PRIMCOEFF must be specified in a "
698 "Robin boundary condition");
704 userDefined, filename, boundaryRegionComm));
705 (*boundaryConditions)[*iter] = robinCondition;
713 robinCondition->SetIsTimeDependent(isTimeDependent);
714 (*boundaryConditions)[*iter] = robinCondition;
718 else if (conditionType ==
"P")
720 if (attrData.empty())
722 ASSERTL0(
false,
"Periodic boundary conditions should "
723 "be explicitely defined");
730 std::string userDefined;
731 vector<unsigned int> periodicBndRegionIndex;
734 attrName = attr->Name();
736 if (attrName ==
"VAR")
740 else if (attrName ==
"USERDEFINEDTYPE")
743 attrData = attr->Value();
745 "USERDEFINEDTYPE attribute must have "
746 "associated value.");
748 userDefined = attrData;
750 boost::iequals(attrData,
"TimeDependent");
752 else if (attrName ==
"VALUE")
754 attrData = attr->Value();
756 "VALUE attribute must have associated "
759 int beg = attrData.find_first_of(
"[");
760 int end = attrData.find_first_of(
"]");
761 std::string periodicBndRegionIndexStr =
762 attrData.substr(beg + 1, end - beg - 1);
765 (std::string(
"Error reading periodic "
766 "boundary region definition "
767 "for boundary region: ") +
768 boundaryRegionIDStrm.str())
772 periodicBndRegionIndexStr.c_str(),
773 periodicBndRegionIndex);
777 (periodicBndRegionIndex.size() == 1),
779 "Unable to read periodic boundary "
780 "condition for boundary region: ") +
781 boundaryRegionIDStrm.str())
788 AllocateSharedPtr(periodicBndRegionIndex[0],
790 boundaryRegionComm));
791 (*boundaryConditions)[*iter] = periodicCondition;
795 ASSERTL0(
false,
"Periodic boundary conditions should "
796 "be explicitely defined");
800 else if (conditionType ==
"C")
802 ASSERTL0(
false,
"Cauchy type boundary conditions not "
806 conditionElement = conditionElement->NextSiblingElement();
810 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
~BoundaryConditions(void)
void ReadBoundaryConditions(TiXmlElement *conditions)
void CreateBoundaryComms()
void Read(TiXmlElement *conditions)
Read segments (and general MeshGraph) given TiXmlDocument.
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)