39 #include <boost/algorithm/string/predicate.hpp> 45 namespace SpatialDomains
50 BoundaryConditions::BoundaryConditions(
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.num_elements();
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");
242 ASSERTL0(boundaryRegions,
"Unable to find BOUNDARYREGIONS block.");
245 TiXmlElement *boundaryRegionsElement =
246 boundaryRegions->FirstChildElement(
"B");
248 while (boundaryRegionsElement)
253 int err = boundaryRegionsElement->QueryIntAttribute(
"ID", &indx);
254 ASSERTL0(err == TIXML_SUCCESS,
"Unable to read attribute ID.");
256 TiXmlNode *boundaryRegionChild = boundaryRegionsElement->FirstChild();
261 while (boundaryRegionChild &&
262 boundaryRegionChild->Type() != TiXmlNode::TINYXML_TEXT)
264 boundaryRegionChild = boundaryRegionChild->NextSibling();
268 "Unable to read variable definition body.");
269 std::string boundaryRegionStr =
270 boundaryRegionChild->ToText()->ValueStr();
272 std::string::size_type indxBeg =
273 boundaryRegionStr.find_first_of(
'[') + 1;
274 std::string::size_type indxEnd =
275 boundaryRegionStr.find_last_of(
']') - 1;
278 (std::string(
"Error reading boundary region definition:") +
282 std::string indxStr =
283 boundaryRegionStr.substr(indxBeg, indxEnd - indxBeg + 1);
285 if (!indxStr.empty())
292 "Boundary region " + indxStr +
293 " defined more than " 296 m_meshGraph->GetCompositeList(indxStr, *boundaryRegion);
297 if (boundaryRegion->size() > 0)
303 boundaryRegionsElement =
304 boundaryRegionsElement->NextSiblingElement(
"B");
320 TiXmlElement *boundaryConditionsElement =
321 conditions->FirstChildElement(
"BOUNDARYCONDITIONS");
323 "Boundary conditions must be specified.");
325 TiXmlElement *regionElement =
326 boundaryConditionsElement->FirstChildElement(
"REGION");
329 while (regionElement)
334 int boundaryRegionID;
335 int err = regionElement->QueryIntAttribute(
"REF", &boundaryRegionID);
337 "Error reading boundary region reference.");
340 "Boundary region '" +
341 boost::lexical_cast<std::string>(boundaryRegionID) +
342 "' appears multiple times.");
345 std::string boundaryRegionIDStr;
346 std::ostringstream boundaryRegionIDStrm(boundaryRegionIDStr);
347 boundaryRegionIDStrm << boundaryRegionID;
351 regionElement = regionElement->NextSiblingElement(
"REGION");
357 boost::lexical_cast<
string>(boundaryRegionID) +
364 TiXmlElement *conditionElement = regionElement->FirstChildElement();
365 std::vector<std::string> vars =
m_session->GetVariables();
367 while (conditionElement)
370 std::string conditionType = conditionElement->Value();
371 std::string attrData;
372 bool isTimeDependent =
false;
375 TiXmlAttribute *attr = conditionElement->FirstAttribute();
377 std::vector<std::string>::iterator iter;
378 std::string attrName;
380 attrData = conditionElement->Attribute(
"VAR");
382 if (!attrData.empty())
384 iter =
std::find(vars.begin(), vars.end(), attrData);
387 (std::string(
"Cannot find variable: ") + attrData).c_str());
390 if (conditionType ==
"N")
392 if (attrData.empty())
395 for (
auto &varIter : vars)
400 (*boundaryConditions)[varIter] = neumannCondition;
407 std::string equation, userDefined, filename;
412 attrName = attr->Name();
414 if (attrName ==
"VAR")
418 else if (attrName ==
"USERDEFINEDTYPE")
421 attrData = attr->Value();
423 "USERDEFINEDTYPE attribute must have " 424 "associated value.");
427 m_session->SubstituteExpressions(attrData);
429 userDefined = attrData;
431 boost::iequals(attrData,
"TimeDependent");
433 else if (attrName ==
"VALUE")
436 (std::string(
"Unknown attribute: ") +
440 attrData = attr->Value();
442 "VALUE attribute must be specified.");
444 m_session->SubstituteExpressions(attrData);
448 else if (attrName ==
"FILE")
451 (std::string(
"Unknown attribute: ") +
455 attrData = attr->Value();
457 "FILE attribute must be specified.");
459 m_session->SubstituteExpressions(attrData);
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 m_session->SubstituteExpressions(attrData);
531 userDefined = attrData;
533 boost::iequals(attrData,
"TimeDependent");
535 else if (attrName ==
"VALUE")
538 (std::string(
"Unknown attribute: ") +
542 attrData = attr->Value();
544 "VALUE attribute must have associated " 547 m_session->SubstituteExpressions(attrData);
551 else if (attrName ==
"FILE")
554 (std::string(
"Unknown attribute: ") +
558 attrData = attr->Value();
560 "FILE attribute must be specified.");
562 m_session->SubstituteExpressions(attrData);
569 (std::string(
"Unknown boundary " 570 "condition attribute: ") +
580 userDefined, filename,
581 boundaryRegionComm));
582 dirichletCondition->SetIsTimeDependent(isTimeDependent);
583 (*boundaryConditions)[*iter] = dirichletCondition;
591 (*boundaryConditions)[*iter] = dirichletCondition;
595 else if (conditionType ==
"R")
597 if (attrData.empty())
600 for (
auto &varIter : vars)
605 (*boundaryConditions)[varIter] = robinCondition;
613 std::string equation1, equation2, userDefined;
614 std::string filename;
616 bool primcoeffset =
false;
621 attrName = attr->Name();
623 if (attrName ==
"VAR")
627 else if (attrName ==
"USERDEFINEDTYPE")
631 attrData = attr->Value();
633 "USERDEFINEDTYPE attribute must have " 634 "associated value.");
636 m_session->SubstituteExpressions(attrData);
637 userDefined = attrData;
639 boost::iequals(attrData,
"TimeDependent");
641 else if (attrName ==
"VALUE")
644 attrData = attr->Value();
646 "VALUE attributes must have " 647 "associated values.");
649 m_session->SubstituteExpressions(attrData);
651 equation1 = attrData;
653 else if (attrName ==
"PRIMCOEFF")
656 attrData = attr->Value();
658 "PRIMCOEFF attributes must have " 659 "associated values.");
661 m_session->SubstituteExpressions(attrData);
663 equation2 = attrData;
667 else if (attrName ==
"FILE")
669 attrData = attr->Value();
671 "FILE attribute must be specified.");
673 m_session->SubstituteExpressions(attrData);
680 (std::string(
"Unknown boundary " 681 "condition attribute: ") +
688 if (primcoeffset ==
false)
690 ASSERTL0(
false,
"PRIMCOEFF must be specified in a " 691 "Robin boundary condition");
697 userDefined, filename, boundaryRegionComm));
698 (*boundaryConditions)[*iter] = robinCondition;
706 robinCondition->SetIsTimeDependent(isTimeDependent);
707 (*boundaryConditions)[*iter] = robinCondition;
711 else if (conditionType ==
"P")
713 if (attrData.empty())
715 ASSERTL0(
false,
"Periodic boundary conditions should " 716 "be explicitely defined");
723 std::string userDefined;
724 vector<unsigned int> periodicBndRegionIndex;
727 attrName = attr->Name();
729 if (attrName ==
"VAR")
733 else if (attrName ==
"USERDEFINEDTYPE")
736 attrData = attr->Value();
738 "USERDEFINEDTYPE attribute must have " 739 "associated value.");
741 m_session->SubstituteExpressions(attrData);
742 userDefined = attrData;
744 boost::iequals(attrData,
"TimeDependent");
746 else if (attrName ==
"VALUE")
748 attrData = attr->Value();
750 "VALUE attribute must have associated " 753 int beg = attrData.find_first_of(
"[");
754 int end = attrData.find_first_of(
"]");
755 std::string periodicBndRegionIndexStr =
756 attrData.substr(beg + 1, end - beg - 1);
759 (std::string(
"Error reading periodic " 760 "boundary region definition " 761 "for boundary region: ") +
762 boundaryRegionIDStrm.str())
766 periodicBndRegionIndexStr.c_str(),
767 periodicBndRegionIndex);
771 (periodicBndRegionIndex.size() == 1),
773 "Unable to read periodic boundary " 774 "condition for boundary region: ") +
775 boundaryRegionIDStrm.str())
782 AllocateSharedPtr(periodicBndRegionIndex[0],
784 boundaryRegionComm));
785 (*boundaryConditions)[*iter] = periodicCondition;
789 ASSERTL0(
false,
"Periodic boundary conditions should " 790 "be explicitely defined");
794 else if (conditionType ==
"C")
796 ASSERTL0(
false,
"Cauchy type boundary conditions not " 800 conditionElement = conditionElement->NextSiblingElement();
804 regionElement = regionElement->NextSiblingElement(
"REGION");
#define ASSERTL0(condition, msg)
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
BoundaryRegionCollection m_boundaryRegions
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
void CreateBoundaryComms()
std::map< int, LibUtilities::CommSharedPtr > m_boundaryCommunicators
std::shared_ptr< BoundaryConditionMap > BoundaryConditionMapShPtr
std::shared_ptr< BoundaryRegion > BoundaryRegionShPtr
Array< OneD, int > ToArray(const std::set< int > &set)
std::map< int, BoundaryRegionShPtr > BoundaryRegionCollection
std::set< int > ShareAllBoundaryIDs(const BoundaryRegionCollection &boundaryRegions, LibUtilities::CommSharedPtr comm)
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::shared_ptr< BoundaryConditionBase > BoundaryConditionShPtr
void ReadBoundaryRegions(TiXmlElement *regions)
void Read(TiXmlElement *conditions)
Read segments (and general MeshGraph) given TiXmlDocument.
LibUtilities::SessionReaderSharedPtr m_session
BoundaryConditionCollection m_boundaryConditions
~BoundaryConditions(void)
MeshGraphSharedPtr m_meshGraph
The mesh graph to use for referencing geometry info.
InputIterator find(InputIterator first, InputIterator last, InputIterator startingpoint, const EqualityComparable &value)
void ReadBoundaryConditions(TiXmlElement *conditions)
std::shared_ptr< SessionReader > SessionReaderSharedPtr
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. ...