Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Conditions.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: BoundaryConditions.cpp
4 //
5 // For more information, please see: http://www.nektar.info/
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description:
33 //
34 //
35 ////////////////////////////////////////////////////////////////////////////////
36 
39 #include <tinyxml.h>
40 
41 using namespace std;
42 
43 namespace Nektar
44 {
45  namespace SpatialDomains
46  {
47  BoundaryConditions::BoundaryConditions(const LibUtilities::SessionReaderSharedPtr &pSession, const MeshGraphSharedPtr &meshGraph)
48  : m_meshGraph(meshGraph),
49  m_session (pSession)
50 
51  {
52  Read(m_session->GetElement("Nektar/Conditions"));
53  }
54 
55 
57  {
58  }
59 
61  {
62  }
63 
64 
65  /**
66  *
67  */
68  void BoundaryConditions::Read(TiXmlElement *conditions)
69  {
70  ASSERTL0(conditions, "Unable to find CONDITIONS tag in file.");
71 
72  TiXmlElement *boundaryRegions = conditions->FirstChildElement("BOUNDARYREGIONS");
73 
74  if(boundaryRegions)
75  {
76  ReadBoundaryRegions(conditions);
77 
78  ReadBoundaryConditions(conditions);
79  }
80  }
81 
82 
83  /**
84  *
85  */
86  void BoundaryConditions::ReadBoundaryRegions(TiXmlElement *conditions)
87  {
88  // ensure boundary regions only read once per class definition
89  if(m_boundaryRegions.size() != 0)
90  {
91  return;
92  }
93 
94  TiXmlElement *boundaryRegions = conditions->FirstChildElement("BOUNDARYREGIONS");
95  ASSERTL0(boundaryRegions, "Unable to find BOUNDARYREGIONS block.");
96 
97  // See if we have boundary regions defined.
98  TiXmlElement *boundaryRegionsElement = boundaryRegions->FirstChildElement("B");
99 
100  while (boundaryRegionsElement)
101  {
102  /// All elements are of the form: "<B ID="#"> ... </B>", with
103  /// ? being the element type.
104  int indx;
105  int err = boundaryRegionsElement->QueryIntAttribute("ID", &indx);
106  ASSERTL0(err == TIXML_SUCCESS, "Unable to read attribute ID.");
107 
108  TiXmlNode* boundaryRegionChild = boundaryRegionsElement->FirstChild();
109  // This is primarily to skip comments that may be present.
110  // Comments appear as nodes just like elements.
111  // We are specifically looking for text in the body
112  // of the definition.
113  while(boundaryRegionChild && boundaryRegionChild->Type() != TiXmlNode::TINYXML_TEXT)
114  {
115  boundaryRegionChild = boundaryRegionChild->NextSibling();
116  }
117 
118  ASSERTL0(boundaryRegionChild, "Unable to read variable definition body.");
119  std::string boundaryRegionStr = boundaryRegionChild->ToText()->ValueStr();
120 
121  std::string::size_type indxBeg = boundaryRegionStr.find_first_of('[') + 1;
122  std::string::size_type indxEnd = boundaryRegionStr.find_last_of(']') - 1;
123 
124  ASSERTL0(indxBeg <= indxEnd, (std::string("Error reading boundary region definition:") + boundaryRegionStr).c_str());
125 
126  std::string indxStr = boundaryRegionStr.substr(indxBeg, indxEnd - indxBeg + 1);
127 
128  if (!indxStr.empty())
129  {
130  // Extract the composites from the string and return them in a list.
132 
133  ASSERTL0(m_boundaryRegions.count(indx) == 0,
134  "Boundary region "+indxStr+ " defined more than "
135  "once!");
136 
137  m_meshGraph->GetCompositeList(indxStr, *boundaryRegion);
138  m_boundaryRegions[indx] = boundaryRegion;
139  }
140 
141  boundaryRegionsElement = boundaryRegionsElement->NextSiblingElement("B");
142  }
143  }
144 
145 
146  /**
147  *
148  */
149  void BoundaryConditions::ReadBoundaryConditions(TiXmlElement *conditions)
150  {
151  // Protect against multiple reads.
152  if(m_boundaryConditions.size() != 0)
153  {
154  return;
155  }
156 
157  // Read REGION tags
158  TiXmlElement *boundaryConditionsElement = conditions->FirstChildElement("BOUNDARYCONDITIONS");
159  ASSERTL0(boundaryConditionsElement, "Boundary conditions must be specified.");
160 
161  TiXmlElement *regionElement = boundaryConditionsElement->FirstChildElement("REGION");
162 
163  // Read R (Robin), D (Dirichlet), N (Neumann), P (Periodic) C(Cauchy) tags
164  while (regionElement)
165  {
167 
168  int boundaryRegionID;
169  int err = regionElement->QueryIntAttribute("REF", &boundaryRegionID);
170  ASSERTL0(err == TIXML_SUCCESS, "Error reading boundary region reference.");
171 
172  ASSERTL0(m_boundaryConditions.count(boundaryRegionID) == 0,
173  "Boundary region '" + boost::lexical_cast<std::string>(boundaryRegionID)
174  + "' appears multiple times.");
175 
176  // Find the boundary region corresponding to this ID.
177  std::string boundaryRegionIDStr;
178  std::ostringstream boundaryRegionIDStrm(boundaryRegionIDStr);
179  boundaryRegionIDStrm << boundaryRegionID;
180 
181  ASSERTL0(m_boundaryRegions.count(boundaryRegionID) == 1,
182  "Boundary region " + boost::lexical_cast<
183  string>(boundaryRegionID)+ " not found");
184 
185  TiXmlElement *conditionElement = regionElement->FirstChildElement();
186  std::vector<std::string> vars = m_session->GetVariables();
187 
188  while (conditionElement)
189  {
190  // Check type.
191  std::string conditionType = conditionElement->Value();
192  std::string attrData;
193  bool isTimeDependent = false;
194 
195  // All have var specified, or else all variables are zero.
196  TiXmlAttribute *attr = conditionElement->FirstAttribute();
197 
199  std::string attrName;
200 
201  attrData = conditionElement->Attribute("VAR");
202 
203  if (!attrData.empty())
204  {
205  iter = std::find(vars.begin(), vars.end(), attrData);
206  ASSERTL0(iter != vars.end(),
207  (std::string("Cannot find variable: ")
208  + attrData).c_str());
209  }
210 
211  if (conditionType == "N")
212  {
213  if (attrData.empty())
214  {
215  // All variables are Neumann and are set to zero.
216  for (std::vector<std::string>::iterator varIter = vars.begin();
217  varIter != vars.end(); ++varIter)
218  {
220  (*boundaryConditions)[*varIter] = neumannCondition;
221  }
222  }
223  else
224  {
225  // Use the iterator from above, which must point to the variable.
226  attr = attr->Next();
227 
228  if (attr)
229  {
230  std::string equation, userDefined, filename;
231 
232  while(attr)
233  {
234 
235  attrName = attr->Name();
236 
237  if (attrName=="USERDEFINEDTYPE")
238  {
239  // Do stuff for the user defined attribute
240  attrData = attr->Value();
241  ASSERTL0(!attrData.empty(),
242  "USERDEFINEDTYPE attribute must have associated value.");
243 
244  m_session->SubstituteExpressions(attrData);
245 
246  userDefined = attrData;
247  isTimeDependent = boost::iequals(attrData,"TimeDependent");
248  }
249  else if(attrName=="VALUE")
250  {
251  attrData = attr->Value();
252  ASSERTL0(!attrData.empty(),
253  "VALUE attribute must be specified.");
254 
255  m_session->SubstituteExpressions(attrData);
256 
257  equation = attrData;
258  }
259  else if(attrName=="FILE")
260  {
261  attrData = attr->Value();
262  ASSERTL0(!attrData.empty(), "FILE attribute must be specified.");
263 
264  m_session->SubstituteExpressions(attrData);
265 
266  filename = attrData;
267  }
268  else
269  {
270  ASSERTL0(false,
271  (std::string("Unknown boundary condition attribute: ") + attrName).c_str());
272  }
273  attr = attr->Next();
274  }
275 
276  BoundaryConditionShPtr neumannCondition(MemoryManager<NeumannBoundaryCondition>::AllocateSharedPtr(m_session, equation, userDefined, filename));
277  neumannCondition->SetIsTimeDependent(isTimeDependent);
278  (*boundaryConditions)[*iter] = neumannCondition;
279  }
280  else
281  {
282  // This variable's condition is zero.
284  (*boundaryConditions)[*iter] = neumannCondition;
285  }
286  }
287  }
288  else if (conditionType == "D")
289  {
290  if (attrData.empty())
291  {
292  // All variables are Dirichlet and are set to zero.
293  for (std::vector<std::string>::iterator varIter = vars.begin();
294  varIter != vars.end(); ++varIter)
295  {
297  (*boundaryConditions)[*varIter] = dirichletCondition;
298  }
299  }
300  else
301  {
302  // Use the iterator from above, which must point to the variable.
303  attr = attr->Next();
304 
305  if (attr)
306  {
307  std::string equation, userDefined, filename;
308 
309  while(attr)
310  {
311  attrName = attr->Name();
312 
313  if (attrName=="USERDEFINEDTYPE") {
314 
315  // Do stuff for the user defined attribute
316  attrData = attr->Value();
317  ASSERTL0(!attrData.empty(), "USERDEFINEDTYPE attribute must have associated value.");
318 
319  m_session->SubstituteExpressions(attrData);
320 
321  userDefined = attrData;
322  isTimeDependent = boost::iequals(attrData,"TimeDependent");
323  }
324  else if(attrName=="VALUE")
325  {
326  attrData = attr->Value();
327  ASSERTL0(!attrData.empty(), "VALUE attribute must have associated value.");
328 
329  m_session->SubstituteExpressions(attrData);
330 
331  equation = attrData;
332  }
333  else if(attrName=="FILE")
334  {
335  attrData = attr->Value();
336  ASSERTL0(!attrData.empty(), "FILE attribute must be specified.");
337 
338  m_session->SubstituteExpressions(attrData);
339 
340  filename = attrData;
341  }
342  else
343  {
344  ASSERTL0(false,
345  (std::string("Unknown boundary condition attribute: ") + attrName).c_str());
346  }
347  attr = attr->Next();
348  }
349 
350  BoundaryConditionShPtr dirichletCondition(MemoryManager<DirichletBoundaryCondition>::AllocateSharedPtr(m_session, equation, userDefined, filename));
351  dirichletCondition->SetIsTimeDependent(isTimeDependent);
352  (*boundaryConditions)[*iter] = dirichletCondition;
353  }
354  else
355  {
356  // This variable's condition is zero.
358  (*boundaryConditions)[*iter] = dirichletCondition;
359  }
360  }
361  }
362  else if (conditionType == "R") // Read du/dn + PRIMCOEFF u = VALUE
363  {
364  if (attrData.empty())
365  {
366  // All variables are Robin and are set to zero.
367  for (std::vector<std::string>::iterator varIter = vars.begin();
368  varIter != vars.end(); ++varIter)
369  {
371  (*boundaryConditions)[*varIter] = robinCondition;
372  }
373  }
374  else
375  {
376  // Use the iterator from above, which must
377  // point to the variable. Read the A and
378  // B attributes.
379  attr = attr->Next();
380 
381  if (attr)
382  {
383  std::string attrName1;
384  std::string attrData1;
385  std::string equation1, equation2, userDefined;
386  std::string filename;
387 
388  bool primcoeffset = false;
389 
390  while(attr){
391 
392  attrName1 = attr->Name();
393 
394  if (attrName1=="USERDEFINEDTYPE") {
395 
396  // Do stuff for the user defined attribute
397  attrData1 = attr->Value();
398  ASSERTL0(!attrData1.empty(), "USERDEFINEDTYPE attribute must have associated value.");
399 
400  m_session->SubstituteExpressions(attrData1);
401  userDefined = attrData1;
402  isTimeDependent = boost::iequals(attrData,"TimeDependent");
403  }
404  else if(attrName1 == "VALUE"){
405 
406  attrData1 = attr->Value();
407  ASSERTL0(!attrData1.empty(), "VALUE attributes must have associated values.");
408 
409  m_session->SubstituteExpressions(attrData1);
410 
411  equation1 = attrData1;
412  }
413  else if(attrName1 == "PRIMCOEFF")
414  {
415 
416  attrData1 = attr->Value();
417  ASSERTL0(!attrData1.empty(), "PRIMCOEFF attributes must have associated values.");
418 
419  m_session->SubstituteExpressions(attrData1);
420 
421  equation2 = attrData1;
422 
423  primcoeffset = true;
424  }
425  else if(attrName1=="FILE")
426  {
427  attrData1 = attr->Value();
428  ASSERTL0(!attrData1.empty(), "FILE attribute must be specified.");
429 
430  m_session->SubstituteExpressions(attrData1);
431 
432  filename = attrData1;
433  }
434  else
435  {
436  ASSERTL0(false, (std::string("Unknown boundary condition attribute: ") + attrName1).c_str());
437 
438  }
439  attr = attr->Next();
440  }
441  if(primcoeffset == false)
442  {
443  ASSERTL0(false,"PRIMCOEFF must be specified in a Robin boundary condition");
444  }
445 
446  BoundaryConditionShPtr robinCondition(MemoryManager<RobinBoundaryCondition>::AllocateSharedPtr(m_session, equation1, equation2, userDefined, filename));
447  (*boundaryConditions)[*iter] = robinCondition;
448  }
449  else
450  {
451  // This variable's condition is zero.
453  robinCondition->SetIsTimeDependent(isTimeDependent);
454  (*boundaryConditions)[*iter] = robinCondition;
455  }
456  }
457  }
458  else if (conditionType == "P")
459  {
460  if (attrData.empty())
461  {
462  attr = attr->Next();
463 
464  if (attr)
465  {
466  attrName = attr->Name();
467 
468  ASSERTL0(attrName == "VALUE", (std::string("Unknown attribute: ") + attrName).c_str());
469 
470  attrData = attr->Value();
471  ASSERTL0(!attrData.empty(), "VALUE attribute must have associated value.");
472 
473  int beg = attrData.find_first_of("[");
474  int end = attrData.find_first_of("]");
475  std::string periodicBndRegionIndexStr = attrData.substr(beg+1,end-beg-1);
476  ASSERTL0(beg < end, (std::string("Error reading periodic boundary region definition for boundary region: ")
477  + boundaryRegionIDStrm.str()).c_str());
478 
479  vector<unsigned int> periodicBndRegionIndex;
480  bool parseGood = ParseUtils::GenerateSeqVector(periodicBndRegionIndexStr.c_str(), periodicBndRegionIndex);
481 
482  ASSERTL0(parseGood && (periodicBndRegionIndex.size()==1), (std::string("Unable to read periodic boundary condition for boundary region: ")
483  + boundaryRegionIDStrm.str()).c_str());
484 
485  BoundaryConditionShPtr periodicCondition(MemoryManager<PeriodicBoundaryCondition>::AllocateSharedPtr(periodicBndRegionIndex[0]));
486 
487  for (std::vector<std::string>::iterator varIter = vars.begin();
488  varIter != vars.end(); ++varIter)
489  {
490  (*boundaryConditions)[*varIter] = periodicCondition;
491  }
492  }
493  else
494  {
495  ASSERTL0(false, "Periodic boundary conditions should be explicitely defined");
496  }
497  }
498  else
499  {
500  // Use the iterator from above, which must point to the variable.
501  // Read the VALUE attribute. It is the next and only other attribute.
502  attr = attr->Next();
503 
504  if (attr)
505  {
506  attrName = attr->Name();
507 
508  ASSERTL0(attrName == "VALUE", (std::string("Unknown attribute: ") + attrName).c_str());
509 
510  attrData = attr->Value();
511  ASSERTL0(!attrData.empty(), "VALUE attribute must have associated value.");
512 
513  int beg = attrData.find_first_of("[");
514  int end = attrData.find_first_of("]");
515  std::string periodicBndRegionIndexStr = attrData.substr(beg+1,end-beg-1);
516  ASSERTL0(beg < end, (std::string("Error reading periodic boundary region definition for boundary region: ") + boundaryRegionIDStrm.str()).c_str());
517 
518  vector<unsigned int> periodicBndRegionIndex;
519  bool parseGood = ParseUtils::GenerateSeqVector(periodicBndRegionIndexStr.c_str(), periodicBndRegionIndex);
520 
521  ASSERTL0(parseGood && (periodicBndRegionIndex.size()==1), (std::string("Unable to read periodic boundary condition for boundary region: ") + boundaryRegionIDStrm.str()).c_str());
522 
523  BoundaryConditionShPtr periodicCondition(MemoryManager<PeriodicBoundaryCondition>::AllocateSharedPtr(periodicBndRegionIndex[0]));
524  (*boundaryConditions)[*iter] = periodicCondition;
525  }
526  else
527  {
528  ASSERTL0(false, "Periodic boundary conditions should be explicitely defined");
529  }
530  }
531  }
532  else if (conditionType == "C")
533  {
534  NEKERROR(ErrorUtil::ewarning, "Cauchy type boundary conditions not implemented.");
535  }
536 
537  conditionElement = conditionElement->NextSiblingElement();
538  }
539 
540  m_boundaryConditions[boundaryRegionID] = boundaryConditions;
541  regionElement = regionElement->NextSiblingElement("REGION");
542  }
543  }
544  }
545 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:188
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mod...
Definition: ErrorUtil.hpp:185
BoundaryRegionCollection m_boundaryRegions
Definition: Conditions.h:258
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
STL namespace.
boost::shared_ptr< SessionReader > SessionReaderSharedPtr
Definition: MeshPartition.h:51
static bool GenerateSeqVector(const char *const str, std::vector< unsigned int > &vec)
Definition: ParseUtils.hpp:79
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
void ReadBoundaryRegions(TiXmlElement *regions)
Definition: Conditions.cpp:86
void Read(TiXmlElement *conditions)
Read segments (and general MeshGraph) given TiXmlDocument.
Definition: Conditions.cpp:68
boost::shared_ptr< BoundaryConditionMap > BoundaryConditionMapShPtr
Definition: Conditions.h:214
LibUtilities::SessionReaderSharedPtr m_session
Definition: Conditions.h:256
BoundaryConditionCollection m_boundaryConditions
Definition: Conditions.h:259
MeshGraphSharedPtr m_meshGraph
The mesh graph to use for referencing geometry info.
Definition: Conditions.h:255
InputIterator find(InputIterator first, InputIterator last, InputIterator startingpoint, const EqualityComparable &value)
Definition: StdRegions.hpp:315
boost::shared_ptr< BoundaryConditionBase > BoundaryConditionShPtr
Definition: Conditions.h:208
void ReadBoundaryConditions(TiXmlElement *conditions)
Definition: Conditions.cpp:149
boost::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:442
boost::shared_ptr< BoundaryRegion > BoundaryRegionShPtr
Definition: Conditions.h:204