38#include <boost/algorithm/string/predicate.hpp>
45namespace SpatialDomains
53 : m_meshGraph(meshGraph), m_session(pSession)
73 auto it = set.begin(), end = set.end();
74 for (
int i = 0; it != end; ++it, ++i)
96 auto it = boundaryRegions.begin(), end = boundaryRegions.end();
98 for (; it != end; ++it, ++i)
99 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());
156 comm->Bcast(nIds, 0);
165 comm->Bcast(idsArray, 0);
167 return std::set<int>(idsArray.begin(), idsArray.end());
178 if (comm->IsSerial())
193 for (
auto &it : allids)
198 comm->CommCreateIf(this_rank_participates);
200 ASSERTL0(
bool(comm_region) ==
bool(this_rank_participates),
201 "Rank should be in communicator but wasn't or is in "
202 "communicator but shouldn't be.");
204 if (this_rank_participates)
216 ASSERTL0(conditions,
"Unable to find CONDITIONS tag in file.");
218 TiXmlElement *boundaryRegions =
219 conditions->FirstChildElement(
"BOUNDARYREGIONS");
240 TiXmlElement *boundaryRegions =
241 conditions->FirstChildElement(
"BOUNDARYREGIONS");
243 boundaryRegions,
m_session->GetTimeLevel());
244 ASSERTL0(boundaryRegions,
"Unable to find BOUNDARYREGIONS block.");
247 TiXmlElement *boundaryRegionsElement =
248 boundaryRegions->FirstChildElement(
"B");
250 while (boundaryRegionsElement)
255 int err = boundaryRegionsElement->QueryIntAttribute(
"ID", &indx);
256 ASSERTL0(err == TIXML_SUCCESS,
"Unable to read attribute ID.");
258 TiXmlNode *boundaryRegionChild = boundaryRegionsElement->FirstChild();
263 while (boundaryRegionChild &&
264 boundaryRegionChild->Type() != TiXmlNode::TINYXML_TEXT)
266 boundaryRegionChild = boundaryRegionChild->NextSibling();
270 "Unable to read variable definition body.");
271 std::string boundaryRegionStr =
272 boundaryRegionChild->ToText()->ValueStr();
274 std::string::size_type indxBeg =
275 boundaryRegionStr.find_first_of(
'[') + 1;
276 std::string::size_type indxEnd =
277 boundaryRegionStr.find_last_of(
']') - 1;
280 (std::string(
"Error reading boundary region definition:") +
284 std::string indxStr =
285 boundaryRegionStr.substr(indxBeg, indxEnd - indxBeg + 1);
287 if (!indxStr.empty())
294 "Boundary region " + indxStr +
295 " defined more than "
298 m_meshGraph->GetCompositeList(indxStr, *boundaryRegion);
299 if (boundaryRegion->size() > 0)
307 err = boundaryRegionsElement->QueryStringAttribute(
"NAME", &
name);
308 if (err == TIXML_SUCCESS)
314 boundaryRegionsElement =
315 boundaryRegionsElement->NextSiblingElement(
"B");
331 TiXmlElement *boundaryConditionsElement =
332 conditions->FirstChildElement(
"BOUNDARYCONDITIONS");
334 boundaryConditionsElement,
m_session->GetTimeLevel());
336 "Boundary conditions must be specified.");
338 TiXmlElement *regionElement =
339 boundaryConditionsElement->FirstChildElement(
"REGION");
342 while (regionElement)
347 int boundaryRegionID;
348 int err = regionElement->QueryIntAttribute(
"REF", &boundaryRegionID);
350 "Error reading boundary region reference.");
353 "Boundary region '" +
354 boost::lexical_cast<std::string>(boundaryRegionID) +
355 "' appears multiple times.");
358 std::string boundaryRegionIDStr;
359 std::ostringstream boundaryRegionIDStrm(boundaryRegionIDStr);
360 boundaryRegionIDStrm << boundaryRegionID;
364 regionElement = regionElement->NextSiblingElement(
"REGION");
370 boost::lexical_cast<string>(boundaryRegionID) +
377 TiXmlElement *conditionElement = regionElement->FirstChildElement();
378 std::vector<std::string> vars =
m_session->GetVariables();
380 while (conditionElement)
383 std::string conditionType = conditionElement->Value();
384 std::string attrData;
385 bool isTimeDependent =
false;
388 TiXmlAttribute *attr = conditionElement->FirstAttribute();
390 std::vector<std::string>::iterator iter;
391 std::string attrName;
393 attrData = conditionElement->Attribute(
"VAR");
395 if (!attrData.empty())
397 iter =
std::find(vars.begin(), vars.end(), attrData);
400 (std::string(
"Cannot find variable: ") + attrData).c_str());
403 if (conditionType ==
"N")
405 if (attrData.empty())
408 for (
auto &varIter : vars)
413 (*boundaryConditions)[varIter] = neumannCondition;
420 std::string equation, userDefined, filename;
425 attrName = attr->Name();
427 if (attrName ==
"VAR")
431 else if (attrName ==
"USERDEFINEDTYPE")
434 attrData = attr->Value();
436 "USERDEFINEDTYPE attribute must have "
437 "associated value.");
439 userDefined = attrData;
441 boost::iequals(attrData,
"TimeDependent");
443 else if (attrName ==
"VALUE")
446 (std::string(
"Unknown attribute: ") +
450 attrData = attr->Value();
452 "VALUE attribute must be specified.");
456 else if (attrName ==
"FILE")
459 (std::string(
"Unknown attribute: ") +
463 attrData = attr->Value();
465 "FILE attribute must be specified.");
472 (std::string(
"Unknown boundary "
473 "condition attribute: ") +
483 userDefined, filename,
484 boundaryRegionComm));
485 neumannCondition->SetIsTimeDependent(isTimeDependent);
486 (*boundaryConditions)[*iter] = neumannCondition;
494 (*boundaryConditions)[*iter] = neumannCondition;
498 else if (conditionType ==
"D")
500 if (attrData.empty())
503 for (
auto &varIter : vars)
508 (*boundaryConditions)[varIter] = dirichletCondition;
515 std::string equation, userDefined, filename;
520 attrName = attr->Name();
522 if (attrName ==
"VAR")
526 else if (attrName ==
"USERDEFINEDTYPE")
530 attrData = attr->Value();
532 "USERDEFINEDTYPE attribute must have "
533 "associated value.");
535 userDefined = attrData;
537 boost::iequals(attrData,
"TimeDependent");
539 else if (attrName ==
"VALUE")
542 (std::string(
"Unknown attribute: ") +
546 attrData = attr->Value();
548 "VALUE attribute must have associated "
553 if (!boost::iequals(attrData,
"0") &&
554 (boost::iequals(userDefined,
556 boost::iequals(userDefined,
559 isTimeDependent =
true;
562 else if (attrName ==
"FILE")
565 (std::string(
"Unknown attribute: ") +
569 attrData = attr->Value();
571 "FILE attribute must be specified.");
578 (std::string(
"Unknown boundary "
579 "condition attribute: ") +
589 userDefined, filename,
590 boundaryRegionComm));
591 dirichletCondition->SetIsTimeDependent(isTimeDependent);
592 (*boundaryConditions)[*iter] = dirichletCondition;
600 (*boundaryConditions)[*iter] = dirichletCondition;
604 else if (conditionType ==
"R")
606 if (attrData.empty())
609 for (
auto &varIter : vars)
614 (*boundaryConditions)[varIter] = robinCondition;
622 std::string equation1, equation2, userDefined;
623 std::string filename;
625 bool primcoeffset =
false;
630 attrName = attr->Name();
632 if (attrName ==
"VAR")
636 else if (attrName ==
"USERDEFINEDTYPE")
640 attrData = attr->Value();
642 "USERDEFINEDTYPE attribute must have "
643 "associated value.");
645 userDefined = attrData;
647 boost::iequals(attrData,
"TimeDependent");
649 else if (attrName ==
"VALUE")
652 attrData = attr->Value();
654 "VALUE attributes must have "
655 "associated values.");
657 equation1 = attrData;
659 else if (attrName ==
"PRIMCOEFF")
662 attrData = attr->Value();
664 "PRIMCOEFF attributes must have "
665 "associated values.");
667 equation2 = attrData;
671 else if (attrName ==
"FILE")
673 attrData = attr->Value();
675 "FILE attribute must be specified.");
682 (std::string(
"Unknown boundary "
683 "condition attribute: ") +
690 if (primcoeffset ==
false)
692 ASSERTL0(
false,
"PRIMCOEFF must be specified in a "
693 "Robin boundary condition");
699 userDefined, filename, boundaryRegionComm));
700 (*boundaryConditions)[*iter] = robinCondition;
708 robinCondition->SetIsTimeDependent(isTimeDependent);
709 (*boundaryConditions)[*iter] = robinCondition;
713 else if (conditionType ==
"P")
715 if (attrData.empty())
717 ASSERTL0(
false,
"Periodic boundary conditions should "
718 "be explicitely defined");
725 std::string userDefined;
726 vector<unsigned int> periodicBndRegionIndex;
729 attrName = attr->Name();
731 if (attrName ==
"VAR")
735 else if (attrName ==
"USERDEFINEDTYPE")
738 attrData = attr->Value();
740 "USERDEFINEDTYPE attribute must have "
741 "associated value.");
743 userDefined = attrData;
745 boost::iequals(attrData,
"TimeDependent");
747 else if (attrName ==
"VALUE")
749 attrData = attr->Value();
751 "VALUE attribute must have associated "
754 int beg = attrData.find_first_of(
"[");
755 int end = attrData.find_first_of(
"]");
756 std::string periodicBndRegionIndexStr =
757 attrData.substr(beg + 1, end - beg - 1);
760 (std::string(
"Error reading periodic "
761 "boundary region definition "
762 "for boundary region: ") +
763 boundaryRegionIDStrm.str())
767 periodicBndRegionIndexStr.c_str(),
768 periodicBndRegionIndex);
772 (periodicBndRegionIndex.size() == 1),
774 "Unable to read periodic boundary "
775 "condition for boundary region: ") +
776 boundaryRegionIDStrm.str())
783 AllocateSharedPtr(periodicBndRegionIndex[0],
785 boundaryRegionComm));
786 (*boundaryConditions)[*iter] = periodicCondition;
790 ASSERTL0(
false,
"Periodic boundary conditions should "
791 "be explicitely defined");
795 else if (conditionType ==
"C")
797 ASSERTL0(
false,
"Cauchy type boundary conditions not "
801 conditionElement = conditionElement->NextSiblingElement();
805 regionElement = regionElement->NextSiblingElement(
"REGION");
#define ASSERTL0(condition, msg)
static void GetXMLElementTimeLevel(TiXmlElement *&element, const size_t timeLevel, const bool disableCheck=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)
The above copyright notice and this permission notice shall be included.