G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsXml.h
Go to the documentation of this file.
1 
14 #pragma once
15 
17 #include <gsCore/gsExport.h>
18 
19 // Default memory sizes
20 // #define RAPIDXML_STATIC_POOL_SIZE ( 64*1024 )
21 // #define RAPIDXML_DYNAMIC_POOL_SIZE ( 64*1024 )
22 
23 #include <rapidxml/rapidxml.hpp> // External file
24 #include <rapidxml/rapidxml_print.hpp> // External file
25 //#include <rapidxml/rapidxml_utils.hpp> // External file
26 //#include <rapidxml/rapidxml_iterators.hpp> // External file
27 
28 #include <cstring>
29 
30 /*
31 // Forward declare rapidxml structures
32 namespace rapidxml
33 {
34  template<class Ch> class xml_node;
35  template<class Ch> class xml_attribute;
36  template<class Ch> class xml_document;
37 }
38 */
39 
40 #define GSXML_COMMON_FUNCTIONS(obj) \
41  static bool has(gsXmlNode * node) \
42  { return firstByTag(tag(), node) != 0;} \
43  static bool hasAny(gsXmlNode * node) \
44  { return anyByTag(tag(), node) != 0;} \
45  static bool count(gsXmlNode * node) \
46  { return countByTag(tag(), node) != 0; } \
47  static obj * getFirst (gsXmlNode * node) \
48  { return get(firstByTag(tag(), node)); } \
49  static obj * getAny (gsXmlNode * node) \
50  { return get(anyByTag(tag(), node)); } \
51  static obj * getId (gsXmlNode * node, int id) \
52  { return getById< obj >(node, id); } \
53  static obj * getLabel(gsXmlNode * node, const std::string & label) \
54  { return getByLabel< obj >(node, label); }
55 
56 #define GSXML_GET_POINTER(obj) \
57  static obj * get (gsXmlNode * node) \
58  { obj * result = new obj; \
59  get_into(node, *result); \
60  return result; }
61 
62 #define GSXML_GET_INTO(obj) \
63  static void get_into (gsXmlNode * node, obj & result) \
64  { result = *get(node); }
65 
66 #define TMPLA2(t1,t2) t1,t2
67 #define TMPLA3(t1,t2,t3) t1,t2,t3
68 #define TMPLA4(t1,t2,t3,t4) t1,t2,t3,t4
69 
70 #ifdef gsGmp_ENABLED
71 // Specialize file I/O to floating point format
72 #include<sstream>
73 inline std::istringstream &
74 operator>>(std::istringstream & is, mpq_class & var)
75 {
76  // read as decimal
77  std::string dn;
78  if ( !(is >> dn) ) return is;
79  const std::string::size_type comma( dn.find(".") );
80  if( comma != std::string::npos )
81  {
82  const std::string::size_type exp = dn.size() - comma - 1;
83  const mpz_class num( dn.erase(comma,1), 10);
84  mpz_class den;
85  mpz_ui_pow_ui(den.get_mpz_t(),10,exp);
86  var = mpq_class(num, den);
87  }
88  else // integer or rational
89  var.set_str(dn,10);
90 
91  //read as machine float
92  //double tmp;
93  //is >> tmp;
94  //var = tmp;
95 
96  var.canonicalize();// remove common factors
97  return is;
98 }
99 
100 #include <fstream>// for paraview
101 template <class U> inline std::ofstream & operator<<
102 (std::ofstream &fs, __gmp_expr<U,U> & var)
103 {
104  fs<<var.get_d();
105  // write as rational
106  //os << var.get_str(10);
107  return fs;
108 }
109 
110 #endif
111 
112 namespace gismo {
113 
114 template<class T>
115 inline bool gsGetReal(std::istream & is, T & var)
116 {
117  GISMO_STATIC_ASSERT(!std::numeric_limits<T>::is_integer,
118  "The second parameter needs to be an integer type.");
119  std::string dn;
120  if ( !(is >> dn) ) return false;
121  const std::string::size_type slh( dn.find("/") );
122  if( slh != std::string::npos )
123  {
124  var = strtod(dn.substr(0,slh).c_str(), NULL) /
125  strtod(dn.substr(slh+1).c_str(), NULL) ;
126  }
127  else // integer or decimal
128  var = strtod(dn.c_str(), NULL);
129 
130  return true;
131 }
132 
133 template<class Z>
134 inline bool gsGetInt(std::istream & is, Z & var)
135 {
136  GISMO_STATIC_ASSERT(std::numeric_limits<Z>::is_integer,
137  "The second parameter needs to be an integer type.");
138  //return static_cast<bool>(is >> var); //C++11
139  return !(is >> var).fail();
140 }
141 
142 #ifdef gsGmp_ENABLED
143 template<>
144 inline bool gsGetReal(std::istream & is, mpq_class & var)
145 {
146  // read as decimal
147  bool ok = true;
148  std::string dn;
149  if ( !(is >> dn) ) return false;
150  const std::string::size_type comma( dn.find(".") );
151  if( comma != std::string::npos )
152  {
153  const std::string::size_type exp = dn.size() - comma - 1;
154  const mpz_class num( dn.erase(comma,1), 10);// will throw on error
155  mpz_class den;
156  mpz_ui_pow_ui(den.get_mpz_t(),10,exp);
157  var = mpq_class(num, den);
158  }
159  else // integer or rational
160  {
161  if ('+'==dn[0]) dn.erase(0, 1);
162  ok = (0==var.set_str(dn,10));
163  }
164 
165  // read as machine float
166  //double tmp;
167  //is >> tmp;
168  //var = tmp;
169 
170  var.canonicalize();// remove common factors
171  return ok;
172 }
173 #endif
174 
175 //Note: automatic deduction of number traits, however using gsGetReal,
176 //gsGetInt can reveal type mistakes, so they are preferable
177 template <typename Z>
178 typename util::enable_if<std::numeric_limits<Z>::is_integer, bool>::type
179 gsGetValue(std::istream & is, Z & var)
180 { return gsGetInt<Z>(is,var); }
181 
182 template <typename T>
183 typename util::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
184 gsGetValue(std::istream & is, T & var)
185 { return gsGetReal<T>(is,var); }
186 
187 namespace internal {
188 
189 typedef rapidxml::xml_node<char> gsXmlNode;
190 typedef rapidxml::xml_attribute<char> gsXmlAttribute;
191 typedef rapidxml::xml_document<char> gsXmlTree;
192 
193 
195 template<class Object>
196 class gsXml
197 {
198 private:
199  gsXml() { }// Disallow instantization
200 public:
201 
202  static std::string tag ();
203 /* { // Next line will produce compile-time error
204  // when class is not specialized for Object
205  Object::Object_does_not_exist_ERROR;
206  return "";
207  }
208 */
209  static std::string type ();
210  static Object * get (gsXmlNode * node);
211  static void get_into (gsXmlNode * node, Object & result);
212  static gsXmlNode * put (const Object & obj, gsXmlTree & data);
213 
214  // Common operations
215  static bool has (gsXmlNode * node);
216  static bool count (gsXmlNode * node);
217  static Object * getFirst (gsXmlNode * node);
218  //static void getFirst_into (gsXmlNode * node);
219  static Object * getAny (gsXmlNode * node);
220  //static void getAny_into (gsXmlNode * node);
221  static Object * getId (gsXmlNode * node, int id);
222  //static void getId_into (gsXmlNode * node, int id, Object & result);
223  static Object * getLabel(gsXmlNode * node, const std::string & label);
224 };
225 
231 inline gsXmlNode * searchNode(gsXmlNode * root,
232  const std::string & attr_name,
233  const std::string & value,
234  const char *tag_name = NULL )
235 {
236  for (gsXmlNode * child = root->first_node(tag_name);
237  child; child = child->next_sibling(tag_name))
238  {
239  const gsXmlAttribute * attribute = child->first_attribute(attr_name.c_str());
240  if ( attribute && !strcmp(attribute->value(),value.c_str()) )
241  return child;
242  else if ( attribute && "time"==attr_name && atof(value.c_str()) == atof(attribute->value()) )
243  return child;
244  }
245  gsWarn <<"gsXmlUtils: No "<< tag_name <<" object with attribute '"<<attr_name<<" = "<< value<<"' found.\n";
246  return NULL;
247 }
248 
254 inline gsXmlNode* searchId(const int id, gsXmlNode* root,
255  const char* tag_name = NULL,
256  const bool print_warning = true) {
257  for (gsXmlNode* child = root->first_node(tag_name); child;
258  child = child->next_sibling(tag_name)) {
259  const gsXmlAttribute* id_at = child->first_attribute("id");
260  if (id_at && atoi(id_at->value()) == id) return child;
261  }
262  if (print_warning) {
263  gsWarn << "gsXmlUtils: No object with id = " << id << " found.\n";
264  }
265  return NULL;
266 }
267 
271 template<class Object>
272 Object * getByLabel(gsXmlNode * node, const std::string & label)
273 {
274  std::string tag = internal::gsXml<Object>::tag();
275  gsXmlNode * nd = searchNode(node, "label", label, tag.c_str());
276  if (nd)
277  {
278  return internal::gsXml<Object>::get(nd);
279  }
280  std::cerr<<"gsXmlUtils Warning: "<< internal::gsXml<Object>::tag()
281  <<" with label="<<label<<" not found.\n";
282  return NULL;
283 }
284 
285 
286 
290 template<class Object>
291 Object * getById(gsXmlNode * node, const int & id)
292 {
293  std::string tag = internal::gsXml<Object>::tag();
294  gsXmlNode * nd = searchId(id, node, tag.c_str());
295  if (nd)
296  {
297  return internal::gsXml<Object>::get(nd);
298  }
299  std::cerr<<"gsXmlUtils Warning: "<< internal::gsXml<Object>::tag()
300  <<" with id="<<id<<" not found.\n";
301  return NULL;
302 }
304 GISMO_EXPORT char * makeValue( const std::string & value, gsXmlTree & data);
305 
307 template<class T>
308 char * makeValue(const gsMatrix<T> & value, gsXmlTree & data,
309  bool transposed);
310 
312 GISMO_EXPORT gsXmlAttribute * makeAttribute( const std::string & name,
313  const std::string & value, gsXmlTree & data);
314 
316 GISMO_EXPORT gsXmlAttribute * makeAttribute( const std::string & name,
317  const unsigned & value, gsXmlTree & data);
318 
320 GISMO_EXPORT gsXmlNode * makeNode( const std::string & name, gsXmlTree & data);
321 
323 GISMO_EXPORT gsXmlNode * makeNode( const std::string & name,
324  const std::string & value, gsXmlTree & data);
325 
327 GISMO_EXPORT gsXmlNode * makeComment(const std::string &, gsXmlTree & data);
328 
330 GISMO_EXPORT std::string to_string(const unsigned & i);
331 
334 GISMO_EXPORT int countByTag(const std::string & tag, gsXmlNode * root );
335 
338 GISMO_EXPORT int countByTagType(const std::string & tag,
339  const std::string & type,
340  gsXmlNode * root );
341 
344 GISMO_EXPORT gsXmlNode * firstByTag(const std::string & tag,
345  gsXmlNode * root );
346 
349 GISMO_EXPORT gsXmlNode * firstByTagType(const std::string & tag,
350  const std::string & type,
351  gsXmlNode * root );
352 
353 // Helper which finds a node matching \a tag and \a type in the XML
354 // tree
355 //GISMO_EXPORT gsXmlNode * anyByTagType(const std::string & tag,
356 // const std::string & type,
357 // gsXmlNode * root );
358 
360 GISMO_EXPORT gsXmlNode * anyByTag(const std::string & tag,
361  gsXmlNode * root );
362 
363 GISMO_EXPORT void getBoundaries(gsXmlNode * node,
364  std::map<int, int> & ids,
365  std::vector< patchSide > & result);
366 
367 GISMO_EXPORT void getInterfaces(gsXmlNode* node,
368  const int d,
369  std::map<int, int>& ids,
370  std::vector< boundaryInterface > & result);
371 
372 GISMO_EXPORT void appendBoxTopology(const gsBoxTopology& topology,
373  gsXmlNode* node,
374  gsXmlTree& data);
375 
377 template<class T>
378 gsXmlNode * makeNode( const std::string & name,
379  const gsMatrix<T> & value, gsXmlTree & data,
380  bool transposed = false );
381 
383 template <class T>
384 void getMatrixFromXml(gsXmlNode* node, unsigned const& rows,
385  unsigned const& cols, gsMatrix<T>& result,
386  const std::string& base_type_flag = "ascii");
387 
389 template<class T>
390 gsXmlNode * putMatrixToXml ( gsMatrix<T> const & mat,
391  gsXmlTree & data, std::string name = "Matrix");
392 
394 template<class T>
395 void getSparseEntriesFromXml ( gsXmlNode * node,
396  gsSparseEntries<T> & result );
397 
399 template<class T>
400 gsXmlNode * putSparseMatrixToXml ( gsSparseMatrix<T> const & mat,
401  gsXmlTree & data, std::string name = "SparseMatrix");
402 
403 }// end namespace internal
404 
405 }// end namespace gismo
406 
407 #ifndef GISMO_BUILD_LIB
408 #include GISMO_HPP_HEADER(gsXml.hpp)
409 #endif
Class that provides a container for triplets (i,j,value) to be filled in a sparse matrix...
Definition: gsSparseMatrix.h:33
gsXmlNode * anyByTag(const std::string &tag, gsXmlNode *root)
Helper to get any object (by tag) if one exists in the XML tree.
Definition: gsXml.cpp:155
int countByTagType(const std::string &tag, const std::string &type, gsXmlNode *root)
Definition: gsXml.cpp:97
int countByTag(const std::string &tag, gsXmlNode *root)
Definition: gsXml.cpp:81
gsXmlNode * firstByTag(const std::string &tag, gsXmlNode *root)
Definition: gsXml.cpp:119
Object * getById(gsXmlNode *node, const int &id)
Definition: gsXml.h:291
gsXmlNode * searchId(const int id, gsXmlNode *root, const char *tag_name=NULL, const bool print_warning=true)
Definition: gsXml.h:254
Handles shared library creation and other class attributes.
gsXmlNode * searchNode(gsXmlNode *root, const std::string &attr_name, const std::string &value, const char *tag_name=NULL)
Definition: gsXml.h:231
std::string to_string(const unsigned &i)
Helper to convert small unsigned to string.
Definition: gsXml.cpp:74
#define gsWarn
Definition: gsDebug.h:50
gsXmlNode * putSparseMatrixToXml(gsSparseMatrix< T > const &mat, gsXmlTree &data, std::string name="SparseMatrix")
Helper to insert sparse matrices into XML.
Definition: gsXml.hpp:111
gsXmlNode * makeComment(const std::string &comment, gsXmlTree &data)
Helper to create an XML comment node.
Definition: gsXml.cpp:68
Object * getByLabel(gsXmlNode *node, const std::string &label)
Definition: gsXml.h:272
gsXmlAttribute * makeAttribute(const std::string &name, const std::string &value, gsXmlTree &data)
Helper to allocate XML attribute.
Definition: gsXml.cpp:37
Provides forward declarations of types and structs.
gsXmlNode * makeNode(const std::string &name, gsXmlTree &data)
Helper to allocate XML node.
Definition: gsXml.cpp:54
char * makeValue(const std::string &value, gsXmlTree &data)
Helper to allocate XML value.
Definition: gsXml.cpp:32
gsXmlNode * putMatrixToXml(gsMatrix< T > const &mat, gsXmlTree &data, std::string name="Matrix")
Helper to insert matrices into XML.
Definition: gsXml.hpp:103
gsXmlNode * firstByTagType(const std::string &tag, const std::string &type, gsXmlNode *root)
Definition: gsXml.cpp:133
void getSparseEntriesFromXml(gsXmlNode *node, gsSparseEntries< T > &result)
Helper to fetch sparse entries.
Definition: gsXml.hpp:133
void appendBoxTopology(const gsBoxTopology &topology, gsXmlNode *node, gsXmlTree &data)
Appends a box topology into node, used for gsMultiPatch and gsMultiBasis.
Definition: gsXml.cpp:186
Defines a topological arrangement of a collection of &quot;boxes&quot; (e.g., parameter domains that map to phy...
Definition: gsBoxTopology.h:38
void getMatrixFromXml(gsXmlNode *node, unsigned const &rows, unsigned const &cols, gsMatrix< T > &result, const std::string &base_type_flag="ascii")
Helper to fetch matrices.
Definition: gsXml.hpp:71