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 namespace Nektar
42 {
43  namespace SpatialDomains
44  {
46  : m_meshGraph(meshGraph),
47  m_session (pSession)
48 
49  {
50  Read(m_session->GetElement("Nektar/Conditions"));
51  }
52 
53 
55  {
56  }
57 
59  {
60  }
61 
62 
63  /**
64  *
65  */
66  void BoundaryConditions::Read(TiXmlElement *conditions)
67  {
68  ASSERTL0(conditions, "Unable to find CONDITIONS tag in file.");
69 
70  TiXmlElement *boundaryRegions = conditions->FirstChildElement("BOUNDARYREGIONS");
71 
72  if(boundaryRegions)
73  {
74  ReadBoundaryRegions(conditions);
75 
76  ReadBoundaryConditions(conditions);
77  }
78  }
79 
80 
81  /**
82  *
83  */
84  void BoundaryConditions::ReadBoundaryRegions(TiXmlElement *conditions)
85  {
86  // ensure boundary regions only read once per class definition
87  if(m_boundaryRegions.size() != 0)
88  {
89  return;
90  }
91 
92  TiXmlElement *boundaryRegions = conditions->FirstChildElement("BOUNDARYREGIONS");
93  ASSERTL0(boundaryRegions, "Unable to find BOUNDARYREGIONS block.");
94 
95  // See if we have boundary regions defined.
96  TiXmlElement *boundaryRegionsElement = boundaryRegions->FirstChildElement("B");
97 
98  while (boundaryRegionsElement)
99  {
100  /// All elements are of the form: "<B ID="#"> ... </B>", with
101  /// ? being the element type.
102  int indx;
103  int err = boundaryRegionsElement->QueryIntAttribute("ID", &indx);
104  ASSERTL0(err == TIXML_SUCCESS, "Unable to read attribute ID.");
105 
106  TiXmlNode* boundaryRegionChild = boundaryRegionsElement->FirstChild();
107  // This is primarily to skip comments that may be present.
108  // Comments appear as nodes just like elements.
109  // We are specifically looking for text in the body
110  // of the definition.
111  while(boundaryRegionChild && boundaryRegionChild->Type() != TiXmlNode::TINYXML_TEXT)
112  {
113  boundaryRegionChild = boundaryRegionChild->NextSibling();
114  }
115 
116  ASSERTL0(boundaryRegionChild, "Unable to read variable definition body.");
117  std::string boundaryRegionStr = boundaryRegionChild->ToText()->ValueStr();
118 
119  std::string::size_type indxBeg = boundaryRegionStr.find_first_of('[') + 1;
120  std::string::size_type indxEnd = boundaryRegionStr.find_last_of(']') - 1;
121 
122  ASSERTL0(indxBeg <= indxEnd, (std::string("Error reading boundary region definition:") + boundaryRegionStr).c_str());
123 
124  std::string indxStr = boundaryRegionStr.substr(indxBeg, indxEnd - indxBeg + 1);
125 
126  if (!indxStr.empty())
127  {
128  // Extract the composites from the string and return them in a list.
130 
131  ASSERTL0(m_boundaryRegions.count(indx) == 0,
132  "Boundary region "+indxStr+ " defined more than "
133  "once!");
134 
135  m_meshGraph->GetCompositeList(indxStr, *boundaryRegion);
136  m_boundaryRegions[indx] = boundaryRegion;
137  }
138 
139  boundaryRegionsElement = boundaryRegionsElement->NextSiblingElement("B");
140  }
141  }
142 
143 
144  /**
145  *
146  */
147  void BoundaryConditions::ReadBoundaryConditions(TiXmlElement *conditions)
148  {
149  // Protect against multiple reads.
150  if(m_boundaryConditions.size() != 0)
151  {
152  return;
153  }
154 
155  // Read REGION tags
156  TiXmlElement *boundaryConditionsElement = conditions->FirstChildElement("BOUNDARYCONDITIONS");
157  ASSERTL0(boundaryConditionsElement, "Boundary conditions must be specified.");
158 
159  TiXmlElement *regionElement = boundaryConditionsElement->FirstChildElement("REGION");
160 
161  // Read R (Robin), D (Dirichlet), N (Neumann), P (Periodic) C(Cauchy) tags
162  while (regionElement)
163  {
165 
166  int boundaryRegionID;
167  int err = regionElement->QueryIntAttribute("REF", &boundaryRegionID);
168  ASSERTL0(err == TIXML_SUCCESS, "Error reading boundary region reference.");
169 
170  ASSERTL0(m_boundaryConditions.count(boundaryRegionID) == 0,
171  "Boundary region '" + boost::lexical_cast<std::string>(boundaryRegionID)
172  + "' appears multiple times.");
173 
174  // Find the boundary region corresponding to this ID.
175  std::string boundaryRegionIDStr;
176  std::ostringstream boundaryRegionIDStrm(boundaryRegionIDStr);
177  boundaryRegionIDStrm << boundaryRegionID;
178 
179  ASSERTL0(m_boundaryRegions.count(boundaryRegionID) == 1,
180  "Boundary region " + boost::lexical_cast<
181  string>(boundaryRegionID)+ " not found");
182 
183  TiXmlElement *conditionElement = regionElement->FirstChildElement();
184  std::vector<std::string> vars = m_session->GetVariables();
185 
186  while (conditionElement)
187  {
188  // Check type.
189  std::string conditionType = conditionElement->Value();
190  std::string attrData;
191  bool isTimeDependent = false;
192 
193  // All have var specified, or else all variables are zero.
194  TiXmlAttribute *attr = conditionElement->FirstAttribute();
195 
197  std::string attrName;
198 
199  attrData = conditionElement->Attribute("VAR");
200 
201  if (!attrData.empty())
202  {
203  iter = std::find(vars.begin(), vars.end(), attrData);
204  ASSERTL0(iter != vars.end(),
205  (std::string("Cannot find variable: ")
206  + attrData).c_str());
207  }
208 
209  if (conditionType == "N")
210  {
211  if (attrData.empty())
212  {
213  // All variables are Neumann and are set to zero.
214  for (std::vector<std::string>::iterator varIter = vars.begin();
215  varIter != vars.end(); ++varIter)
216  {
218  (*boundaryConditions)[*varIter] = neumannCondition;
219  }
220  }
221  else
222  {
223  // Use the iterator from above, which must point to the variable.
224  attr = attr->Next();
225 
226  if (attr)
227  {
228  std::string equation, userDefined, filename;
229 
230  while(attr)
231  {
232 
233  attrName = attr->Name();
234 
235  if (attrName=="USERDEFINEDTYPE")
236  {
237  // Do stuff for the user defined attribute
238  attrData = attr->Value();
239  ASSERTL0(!attrData.empty(),
240  "USERDEFINEDTYPE attribute must have associated value.");
241 
242  m_session->SubstituteExpressions(attrData);
243 
244  userDefined = attrData;
245  isTimeDependent = boost::iequals(attrData,"TimeDependent");
246  }
247  else if(attrName=="VALUE")
248  {
249  attrData = attr->Value();
250  ASSERTL0(!attrData.empty(),
251  "VALUE attribute must be specified.");
252 
253  m_session->SubstituteExpressions(attrData);
254 
255  equation = attrData;
256  }
257  else if(attrName=="FILE")
258  {
259  attrData = attr->Value();
260  ASSERTL0(!attrData.empty(), "FILE attribute must be specified.");
261 
262  m_session->SubstituteExpressions(attrData);
263 
264  filename = attrData;
265  }
266  else
267  {
268  ASSERTL0(false,
269  (std::string("Unknown boundary condition attribute: ") + attrName).c_str());
270  }
271  attr = attr->Next();
272  }
273 
274  BoundaryConditionShPtr neumannCondition(MemoryManager<NeumannBoundaryCondition>::AllocateSharedPtr(m_session, equation, userDefined, filename));
275  neumannCondition->SetIsTimeDependent(isTimeDependent);
276  (*boundaryConditions)[*iter] = neumannCondition;
277  }
278  else
279  {
280  // This variable's condition is zero.
282  (*boundaryConditions)[*iter] = neumannCondition;
283  }
284  }
285  }
286  else if (conditionType == "D")
287  {
288  if (attrData.empty())
289  {
290  // All variables are Dirichlet and are set to zero.
291  for (std::vector<std::string>::iterator varIter = vars.begin();
292  varIter != vars.end(); ++varIter)
293  {
295  (*boundaryConditions)[*varIter] = dirichletCondition;
296  }
297  }
298  else
299  {
300  // Use the iterator from above, which must point to the variable.
301  attr = attr->Next();
302 
303  if (attr)
304  {
305  std::string equation, userDefined, filename;
306 
307  while(attr)
308  {
309  attrName = attr->Name();
310 
311  if (attrName=="USERDEFINEDTYPE") {
312 
313  // Do stuff for the user defined attribute
314  attrData = attr->Value();
315  ASSERTL0(!attrData.empty(), "USERDEFINEDTYPE attribute must have associated value.");
316 
317  m_session->SubstituteExpressions(attrData);
318 
319  userDefined = attrData;
320  isTimeDependent = boost::iequals(attrData,"TimeDependent");
321  }
322  else if(attrName=="VALUE")
323  {
324  attrData = attr->Value();
325  ASSERTL0(!attrData.empty(), "VALUE attribute must have associated value.");
326 
327  m_session->SubstituteExpressions(attrData);
328 
329  equation = attrData;
330  }
331  else if(attrName=="FILE")
332  {
333  attrData = attr->Value();
334  ASSERTL0(!attrData.empty(), "FILE attribute must be specified.");
335 
336  m_session->SubstituteExpressions(attrData);
337 
338  filename = attrData;
339  }
340  else
341  {
342  ASSERTL0(false,
343  (std::string("Unknown boundary condition attribute: ") + attrName).c_str());
344  }
345  attr = attr->Next();
346  }
347 
348  BoundaryConditionShPtr dirichletCondition(MemoryManager<DirichletBoundaryCondition>::AllocateSharedPtr(m_session, equation, userDefined, filename));
349  dirichletCondition->SetIsTimeDependent(isTimeDependent);
350  (*boundaryConditions)[*iter] = dirichletCondition;
351  }
352  else
353  {
354  // This variable's condition is zero.
356  (*boundaryConditions)[*iter] = dirichletCondition;
357  }
358  }
359  }
360  else if (conditionType == "R") // Read du/dn + PRIMCOEFF u = VALUE
361  {
362  if (attrData.empty())
363  {
364  // All variables are Robin and are set to zero.
365  for (std::vector<std::string>::iterator varIter = vars.begin();
366  varIter != vars.end(); ++varIter)
367  {
369  (*boundaryConditions)[*varIter] = robinCondition;
370  }
371  }
372  else
373  {
374  // Use the iterator from above, which must
375  // point to the variable. Read the A and
376  // B attributes.
377  attr = attr->Next();
378 
379  if (attr)
380  {
381  std::string attrName1;
382  std::string attrData1;
383  std::string equation1, equation2, userDefined;
384  std::string filename;
385 
386  bool primcoeffset = false;
387 
388  while(attr){
389 
390  attrName1 = attr->Name();
391 
392  if (attrName1=="USERDEFINEDTYPE") {
393 
394  // Do stuff for the user defined attribute
395  attrData1 = attr->Value();
396  ASSERTL0(!attrData1.empty(), "USERDEFINEDTYPE attribute must have associated value.");
397 
398  m_session->SubstituteExpressions(attrData1);
399  userDefined = attrData1;
400  isTimeDependent = boost::iequals(attrData,"TimeDependent");
401  }
402  else if(attrName1 == "VALUE"){
403 
404  attrData1 = attr->Value();
405  ASSERTL0(!attrData1.empty(), "VALUE attributes must have associated values.");
406 
407  m_session->SubstituteExpressions(attrData1);
408 
409  equation1 = attrData1;
410  }
411  else if(attrName1 == "PRIMCOEFF")
412  {
413 
414  attrData1 = attr->Value();
415  ASSERTL0(!attrData1.empty(), "PRIMCOEFF attributes must have associated values.");
416 
417  m_session->SubstituteExpressions(attrData1);
418 
419  equation2 = attrData1;
420 
421  primcoeffset = true;
422  }
423  else if(attrName1=="FILE")
424  {
425  attrData1 = attr->Value();
426  ASSERTL0(!attrData1.empty(), "FILE attribute must be specified.");
427 
428  m_session->SubstituteExpressions(attrData1);
429 
430  filename = attrData1;
431  }
432  else
433  {
434  ASSERTL0(false, (std::string("Unknown boundary condition attribute: ") + attrName1).c_str());
435 
436  }
437  attr = attr->Next();
438  }
439  if(primcoeffset == false)
440  {
441  ASSERTL0(false,"PRIMCOEFF must be specified in a Robin boundary condition");
442  }
443 
444  BoundaryConditionShPtr robinCondition(MemoryManager<RobinBoundaryCondition>::AllocateSharedPtr(m_session, equation1, equation2, userDefined, filename));
445  (*boundaryConditions)[*iter] = robinCondition;
446  }
447  else
448  {
449  // This variable's condition is zero.
451  robinCondition->SetIsTimeDependent(isTimeDependent);
452  (*boundaryConditions)[*iter] = robinCondition;
453  }
454  }
455  }
456  else if (conditionType == "P")
457  {
458  if (attrData.empty())
459  {
460  attr = attr->Next();
461 
462  if (attr)
463  {
464  attrName = attr->Name();
465 
466  ASSERTL0(attrName == "VALUE", (std::string("Unknown attribute: ") + attrName).c_str());
467 
468  attrData = attr->Value();
469  ASSERTL0(!attrData.empty(), "VALUE attribute must have associated value.");
470 
471  int beg = attrData.find_first_of("[");
472  int end = attrData.find_first_of("]");
473  std::string periodicBndRegionIndexStr = attrData.substr(beg+1,end-beg-1);
474  ASSERTL0(beg < end, (std::string("Error reading periodic boundary region definition for boundary region: ")
475  + boundaryRegionIDStrm.str()).c_str());
476 
477  vector<unsigned int> periodicBndRegionIndex;
478  bool parseGood = ParseUtils::GenerateSeqVector(periodicBndRegionIndexStr.c_str(), periodicBndRegionIndex);
479 
480  ASSERTL0(parseGood && (periodicBndRegionIndex.size()==1), (std::string("Unable to read periodic boundary condition for boundary region: ")
481  + boundaryRegionIDStrm.str()).c_str());
482 
483  BoundaryConditionShPtr periodicCondition(MemoryManager<PeriodicBoundaryCondition>::AllocateSharedPtr(periodicBndRegionIndex[0]));
484 
485  for (std::vector<std::string>::iterator varIter = vars.begin();
486  varIter != vars.end(); ++varIter)
487  {
488  (*boundaryConditions)[*varIter] = periodicCondition;
489  }
490  }
491  else
492  {
493  ASSERTL0(false, "Periodic boundary conditions should be explicitely defined");
494  }
495  }
496  else
497  {
498  // Use the iterator from above, which must point to the variable.
499  // Read the VALUE attribute. It is the next and only other attribute.
500  attr = attr->Next();
501 
502  if (attr)
503  {
504  attrName = attr->Name();
505 
506  ASSERTL0(attrName == "VALUE", (std::string("Unknown attribute: ") + attrName).c_str());
507 
508  attrData = attr->Value();
509  ASSERTL0(!attrData.empty(), "VALUE attribute must have associated value.");
510 
511  int beg = attrData.find_first_of("[");
512  int end = attrData.find_first_of("]");
513  std::string periodicBndRegionIndexStr = attrData.substr(beg+1,end-beg-1);
514  ASSERTL0(beg < end, (std::string("Error reading periodic boundary region definition for boundary region: ") + boundaryRegionIDStrm.str()).c_str());
515 
516  vector<unsigned int> periodicBndRegionIndex;
517  bool parseGood = ParseUtils::GenerateSeqVector(periodicBndRegionIndexStr.c_str(), periodicBndRegionIndex);
518 
519  ASSERTL0(parseGood && (periodicBndRegionIndex.size()==1), (std::string("Unable to read periodic boundary condition for boundary region: ") + boundaryRegionIDStrm.str()).c_str());
520 
521  BoundaryConditionShPtr periodicCondition(MemoryManager<PeriodicBoundaryCondition>::AllocateSharedPtr(periodicBndRegionIndex[0]));
522  (*boundaryConditions)[*iter] = periodicCondition;
523  }
524  else
525  {
526  ASSERTL0(false, "Periodic boundary conditions should be explicitely defined");
527  }
528  }
529  }
530  else if (conditionType == "C")
531  {
532  NEKERROR(ErrorUtil::ewarning, "Cauchy type boundary conditions not implemented.");
533  }
534 
535  conditionElement = conditionElement->NextSiblingElement();
536  }
537 
538  m_boundaryConditions[boundaryRegionID] = boundaryConditions;
539  regionElement = regionElement->NextSiblingElement("REGION");
540  }
541  }
542  }
543 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mod...
Definition: ErrorUtil.hpp:158
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...
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:84
void Read(TiXmlElement *conditions)
Read segments (and general MeshGraph) given TiXmlDocument.
Definition: Conditions.cpp:66
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:147
boost::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:442
boost::shared_ptr< BoundaryRegion > BoundaryRegionShPtr
Definition: Conditions.h:204