NANDRAD Data Model Library  Version 2.0
NANDRAD
NANDRAD_Utilities.h
1 /* The NANDRAD data model library.
2 
3  Copyright (c) 2012-today, Institut für Bauklimatik, TU Dresden, Germany
4 
5  Primary authors:
6  Andreas Nicolai <andreas.nicolai -[at]- tu-dresden.de>
7  Anne Paepcke <anne.paepcke -[at]- tu-dresden.de>
8 
9  This library is part of SIM-VICUS (https://github.com/ghorwin/SIM-VICUS)
10 
11  This library is free software: you can redistribute it and/or modify
12  it under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  This library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  GNU General Public License for more details.
20 */
21 
22 #ifndef NANDRAD_UtilitiesH
23 #define NANDRAD_UtilitiesH
24 
25 #include <string>
26 #include <map>
27 
28 #include <tinyxml.h>
29 
30 #include <IBK_Path.h>
31 #include <IBK_Time.h>
32 #include <IBK_LinearSpline.h>
33 #include <IBK_StringUtils.h>
34 #include <IBK_point.h>
35 
36 #include <IBKMK_Vector3D.h>
37 
38 #include "NANDRAD_Constants.h"
39 
40 namespace IBK {
41  class Unit;
42  class Parameter;
43  class IntPara;
44  class Flag;
45 }
46 
47 class TiXmlDocument;
48 class TiXmlElement;
49 
50 namespace NANDRAD {
51 
52 /*! Attempts to open an XML file, hereby substituting placeholders in the file name and checking if
53  the top-level XML tag matches the requested tag name.
54 */
55 TiXmlElement * openXMLFile(const std::map<std::string,IBK::Path> &pathPlaceHolders, const IBK::Path & filename,
56  const std::string & parentXmlTag, TiXmlDocument & doc);
57 
58 /*! Reads a linear spline from XML element (with proper error handling). */
59 void readLinearSplineElement(const TiXmlElement * element,
60  IBK::LinearSpline & spl, std::string & name, IBK::Unit * xunit, IBK::Unit * yunit);
61 
62 /*! Writes a linear spline into XML format.
63  \code
64  <IBK:LinearSpline name="MySpline">
65  <X unit="m">0 1 1.4 2 </X>
66  <Y unit="C">1 2 3.4 5 </Y>
67  </IBK:LinearSpline>
68  \endcode
69 */
70 void writeLinearSplineElement(TiXmlElement * parent, const std::string & name, const IBK::LinearSpline & spl, const std::string & xunit, const std::string & yunit);
71 
72 /*! Reads an IBK::Parameter from XML element (with proper error handling). */
73 void readParameterElement(const TiXmlElement * element, IBK::Parameter & p);
74 
75 /*! Reads an IBK::IntPara from XML element (with proper error handling). */
76 void readIntParaElement(const TiXmlElement * element, IBK::IntPara & p);
77 
78 /*! Reads an IBK::Flag from XML element (with proper error handling). */
79 void readFlagElement(const TiXmlElement * element, IBK::Flag & f);
80 
81 template <typename T>
82 void readVector(const TiXmlElement * element, const std::string & name, std::vector<T> & vec) {
83  FUNCID(NANDRAD::readVector);
84  std::string text = element->GetText();
85  text = IBK::replace_string(text, ",", " ");
86  try {
87  IBK::string2vector(text, vec);
88  } catch (IBK::Exception & ex) {
89  throw IBK::Exception( ex, IBK::FormatString(XML_READ_ERROR).arg(element->Row()).arg(
90  IBK::FormatString("Error reading vector element '%1'.").arg(name) ), FUNC_ID);
91  }
92 }
93 
94 /*! Special implementation for double-type vectors. */
95 template <>
96 void readVector(const TiXmlElement * element, const std::string & name, std::vector<double> & vec);
97 
98 
99 template <typename T>
100 void writeVector(TiXmlElement * parent, const std::string & name, const std::vector<T> & vec) {
101  if (!vec.empty()) {
102  TiXmlElement * child = new TiXmlElement(name);
103  parent->LinkEndChild(child);
104 
105  std::stringstream vals;
106  for (unsigned int i=0; i<vec.size(); ++i) {
107  vals << vec[i];
108  if (i<vec.size()-1) vals << ",";
109  }
110  TiXmlText * text = new TiXmlText( vals.str() );
111  child->LinkEndChild( text );
112  }
113 }
114 
115 
116 template <typename T>
117 T readPODAttributeValue(const TiXmlElement * element, const TiXmlAttribute * attrib) {
118  FUNCID(NANDRAD::readPODAttributeValue);
119  try {
120  return IBK::string2val<T>(attrib->ValueStr());
121  } catch (IBK::Exception & ex) {
122  throw IBK::Exception( ex, IBK::FormatString(XML_READ_ERROR).arg(element->Row()).arg(
123  IBK::FormatString("Error reading '"+attrib->NameStr()+"' attribute.") ), FUNC_ID);
124  }
125 }
126 
127 template <typename T>
128 T readPODElement(const TiXmlElement * element, const std::string & eName) {
129  FUNCID(NANDRAD::readPODElement);
130  try {
131  return IBK::string2val<T>(element->GetText());
132  } catch (IBK::Exception & ex) {
133  throw IBK::Exception( ex, IBK::FormatString(XML_READ_ERROR).arg(element->Row()).arg(
134  IBK::FormatString("Error reading '"+eName+"' tag.") ), FUNC_ID);
135  }
136 }
137 
138 /*! Read an IBK:Unit tag. */
139 IBK::Unit readUnitElement(const TiXmlElement * element, const std::string & eName);
140 /*! Read an IBK:Time tag. */
141 IBK::Time readTimeElement(const TiXmlElement * element, const std::string & eName);
142 
143 /*! Writes out a vector of Vector3D elements. */
144 TiXmlElement * writeVector3D(TiXmlElement * parent, const std::string & name, const std::vector<IBKMK::Vector3D> & vec);
145 
146 /*! Reads a vector of Vector3D elements. */
147 void readVector3D(const TiXmlElement * element, const std::string & name, std::vector<IBKMK::Vector3D> & vec);
148 
149 
150 template <typename T>
151 void readPoint2D(const TiXmlElement * element, const std::string & name, IBK::point2D<T> & p) {
152  FUNCID(NANDRAD::readPoint2D);
153  std::string text = element->GetText();
154  try {
155  typename std::vector<T> vec;
156  IBK::string2vector(text, vec);
157  if (vec.size() != 2)
158  throw IBK::Exception("Size mismatch, expected 2 numbers separated by , .", FUNC_ID);
159  p.m_x = vec[0];
160  p.m_y = vec[1];
161  }
162  catch (IBK::Exception & ex) {
163  throw IBK::Exception( ex, IBK::FormatString(XML_READ_ERROR).arg(element->Row()).arg(
164  IBK::FormatString("Error reading point2D element '%1'.").arg(name) ), FUNC_ID);
165  }
166 }
167 
168 /*! Special implementation for double-type point2D. */
169 template <>
170 void readPoint2D(const TiXmlElement * element, const std::string & name, IBK::point2D<double> & p);
171 
172 template <typename T>
173 void writePoint2D(TiXmlElement * parent, const std::string & name, const IBK::point2D<T> & p) {
174  TiXmlElement * child = new TiXmlElement(name);
175  parent->LinkEndChild(child);
176 
177  std::stringstream vals;
178  vals << p.m_x << " " << p.m_y;
179  TiXmlText * text = new TiXmlText( vals.str() );
180  child->LinkEndChild( text );
181 }
182 
183 
184 } // namespace NANDRAD
185 
186 #endif // NANDRAD_UtilitiesH
void readParameterElement(const TiXmlElement *element, IBK::Parameter &p)
Reads an IBK::Parameter from XML element (with proper error handling).
IBK::Time readTimeElement(const TiXmlElement *element, const std::string &eName)
Read an IBK:Time tag.
TiXmlElement * openXMLFile(const std::map< std::string, IBK::Path > &pathPlaceHolders, const IBK::Path &filename, const std::string &parentXmlTag, TiXmlDocument &doc)
Attempts to open an XML file, hereby substituting placeholders in the file name and checking if the t...
Contains global constants for the Nandrad data model.
void readIntParaElement(const TiXmlElement *element, IBK::IntPara &p)
Reads an IBK::IntPara from XML element (with proper error handling).
TiXmlElement * writeVector3D(TiXmlElement *parent, const std::string &name, const std::vector< IBKMK::Vector3D > &vec)
Writes out a vector of Vector3D elements.
IBK::Unit readUnitElement(const TiXmlElement *element, const std::string &eName)
Read an IBK:Unit tag.
void writeLinearSplineElement(TiXmlElement *parent, const std::string &name, const IBK::LinearSpline &spl, const std::string &xunit, const std::string &yunit)
Writes a linear spline into XML format.
void readVector3D(const TiXmlElement *element, const std::string &name, std::vector< IBKMK::Vector3D > &vec)
Reads a vector of Vector3D elements.
void readFlagElement(const TiXmlElement *element, IBK::Flag &f)
Reads an IBK::Flag from XML element (with proper error handling).
void readLinearSplineElement(const TiXmlElement *element, IBK::LinearSpline &spl, std::string &name, IBK::Unit *xunit, IBK::Unit *yunit)
Reads a linear spline from XML element (with proper error handling).
The namespace NANDRAD contains the data model classes that make up the NANDRAD solver input data...