G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
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
32namespace 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>
73inline std::istringstream &
74operator>>(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
101template <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
112namespace gismo {
113
114template<class T>
115inline 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
133template<class Z>
134inline 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
143template<>
144inline 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
177template <typename Z>
178typename util::enable_if<std::numeric_limits<Z>::is_integer, bool>::type
179gsGetValue(std::istream & is, Z & var)
180{ return gsGetInt<Z>(is,var); }
181
182template <typename T>
183typename util::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
184gsGetValue(std::istream & is, T & var)
185{ return gsGetReal<T>(is,var); }
186
187namespace internal {
188
189typedef rapidxml::xml_node<char> gsXmlNode;
190typedef rapidxml::xml_attribute<char> gsXmlAttribute;
191typedef rapidxml::xml_document<char> gsXmlTree;
192
193
195template<class Object>
196class gsXml
197{
198private:
199 gsXml() { }// Disallow instantization
200public:
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
231inline 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
254inline 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
273inline gsXmlNode* searchLabel(const std::string label,
274 gsXmlNode* root,
275 const char* tag_name = NULL,
276 const bool print_warning = true) {
277 for (gsXmlNode* child = root->first_node(tag_name); child;
278 child = child->next_sibling(tag_name)) {
279 const gsXmlAttribute* label_attr = child->first_attribute("label");
280 if (label_attr && !strcmp(label_attr->value(), label.c_str()) ) return child;
281 }
282 if (print_warning) {
283 gsWarn << "gsXmlUtils: No object with label = " << label << " found.\n";
284 }
285 return NULL;
286}
287
291template<class Object>
292Object * getByLabel(gsXmlNode * node, const std::string & label)
293{
294 std::string tag = internal::gsXml<Object>::tag();
295 gsXmlNode * nd = searchNode(node, "label", label, tag.c_str());
296 if (nd)
297 {
298 return internal::gsXml<Object>::get(nd);
299 }
300 std::cerr<<"gsXmlUtils Warning: "<< internal::gsXml<Object>::tag()
301 <<" with label="<<label<<" not found.\n";
302 return NULL;
303}
304
305
306
310template<class Object>
311Object * getById(gsXmlNode * node, const int & id)
312{
313 std::string tag = internal::gsXml<Object>::tag();
314 gsXmlNode * nd = searchId(id, node, tag.c_str());
315 if (nd)
316 {
317 return internal::gsXml<Object>::get(nd);
318 }
319 std::cerr<<"gsXmlUtils Warning: "<< internal::gsXml<Object>::tag()
320 <<" with id="<<id<<" not found.\n";
321 return NULL;
322}
324GISMO_EXPORT char * makeValue( const std::string & value, gsXmlTree & data);
325
327template<class T>
328char * makeValue(const gsMatrix<T> & value, gsXmlTree & data,
329 bool transposed);
330
332GISMO_EXPORT gsXmlAttribute * makeAttribute( const std::string & name,
333 const std::string & value, gsXmlTree & data);
334
336GISMO_EXPORT gsXmlAttribute * makeAttribute( const std::string & name,
337 const unsigned & value, gsXmlTree & data);
338
340GISMO_EXPORT gsXmlNode * makeNode( const std::string & name, gsXmlTree & data);
341
343GISMO_EXPORT gsXmlNode * makeNode( const std::string & name,
344 const std::string & value, gsXmlTree & data);
345
347GISMO_EXPORT gsXmlNode * makeComment(const std::string &, gsXmlTree & data);
348
350GISMO_EXPORT std::string to_string(const unsigned & i);
351
354GISMO_EXPORT int countByTag(const std::string & tag, gsXmlNode * root );
355
358GISMO_EXPORT int countByTagType(const std::string & tag,
359 const std::string & type,
360 gsXmlNode * root );
361
364GISMO_EXPORT gsXmlNode * firstByTag(const std::string & tag,
365 gsXmlNode * root );
366
369GISMO_EXPORT gsXmlNode * firstByTagType(const std::string & tag,
370 const std::string & type,
371 gsXmlNode * root );
372
373// Helper which finds a node matching \a tag and \a type in the XML
374// tree
375//GISMO_EXPORT gsXmlNode * anyByTagType(const std::string & tag,
376// const std::string & type,
377// gsXmlNode * root );
378
380GISMO_EXPORT gsXmlNode * anyByTag(const std::string & tag,
381 gsXmlNode * root );
382
383GISMO_EXPORT void getBoundaries(gsXmlNode * node,
384 std::map<int, int> & ids,
385 std::vector< patchSide > & result);
386
387GISMO_EXPORT void getInterfaces(gsXmlNode* node,
388 const int d,
389 std::map<int, int>& ids,
390 std::vector< boundaryInterface > & result);
391
392GISMO_EXPORT void appendBoxTopology(const gsBoxTopology& topology,
393 gsXmlNode* node,
394 std::map<index_t, index_t> id_map,
395 gsXmlTree& data);
396
398template<class T>
399gsXmlNode * makeNode( const std::string & name,
400 const gsMatrix<T> & value, gsXmlTree & data,
401 bool transposed = false );
402
404template <class T>
405void getMatrixFromXml(gsXmlNode* node, unsigned const& rows,
406 unsigned const& cols, gsMatrix<T>& result,
407 const std::string& base_type_flag = "ascii");
408
410template<class T>
411gsXmlNode * putMatrixToXml ( gsMatrix<T> const & mat,
412 gsXmlTree & data, std::string name = "Matrix");
413
415template<class T>
416void getSparseEntriesFromXml ( gsXmlNode * node,
417 gsSparseEntries<T> & result );
418
420template<class T>
421gsXmlNode * putSparseMatrixToXml ( gsSparseMatrix<T> const & mat,
422 gsXmlTree & data, std::string name = "SparseMatrix");
423
424}// end namespace internal
425
426}// end namespace gismo
427
428#ifndef GISMO_BUILD_LIB
429#include GISMO_HPP_HEADER(gsXml.hpp)
430#endif
Defines a topological arrangement of a collection of "boxes" (e.g., parameter domains that map to phy...
Definition gsBoxTopology.h:39
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
Class that provides a container for triplets (i,j,value) to be filled in a sparse matrix.
Definition gsSparseMatrix.h:34
Sparse matrix class, based on gsEigen::SparseMatrix.
Definition gsSparseMatrix.h:139
#define gsWarn
Definition gsDebug.h:50
Handles shared library creation and other class attributes.
Provides forward declarations of types and structs.
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
Object * getByLabel(gsXmlNode *node, const std::string &label)
Definition gsXml.h:292
int countByTagType(const std::string &tag, const std::string &type, gsXmlNode *root)
Definition gsXml.cpp:97
gsXmlNode * putSparseMatrixToXml(gsSparseMatrix< T > const &mat, gsXmlTree &data, std::string name="SparseMatrix")
Helper to insert sparse matrices into XML.
Definition gsXml.hpp:111
void appendBoxTopology(const gsBoxTopology &topology, gsXmlNode *node, std::map< index_t, index_t > id_map, gsXmlTree &data)
Appends a box topology into node, used for gsMultiPatch and gsMultiBasis.
Definition gsXml.cpp:186
int countByTag(const std::string &tag, gsXmlNode *root)
Definition gsXml.cpp:81
gsXmlNode * searchLabel(const std::string label, gsXmlNode *root, const char *tag_name=NULL, const bool print_warning=true)
Definition gsXml.h:273
gsXmlNode * makeComment(const std::string &comment, gsXmlTree &data)
Helper to create an XML comment node.
Definition gsXml.cpp:68
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
gsXmlNode * firstByTagType(const std::string &tag, const std::string &type, gsXmlNode *root)
Definition gsXml.cpp:133
gsXmlNode * firstByTag(const std::string &tag, gsXmlNode *root)
Definition gsXml.cpp:119
gsXmlNode * putMatrixToXml(gsMatrix< T > const &mat, gsXmlTree &data, std::string name="Matrix")
Helper to insert matrices into XML.
Definition gsXml.hpp:103
char * makeValue(const std::string &value, gsXmlTree &data)
Helper to allocate XML value.
Definition gsXml.cpp:32
void getSparseEntriesFromXml(gsXmlNode *node, gsSparseEntries< T > &result)
Helper to fetch sparse entries.
Definition gsXml.hpp:133
std::string to_string(const unsigned &i)
Helper to convert small unsigned to string.
Definition gsXml.cpp:74
gsXmlNode * searchNode(gsXmlNode *root, const std::string &attr_name, const std::string &value, const char *tag_name=NULL)
Definition gsXml.h:231
gsXmlNode * makeNode(const std::string &name, gsXmlTree &data)
Helper to allocate XML node.
Definition gsXml.cpp:54
gsXmlAttribute * makeAttribute(const std::string &name, const std::string &value, gsXmlTree &data)
Helper to allocate XML attribute.
Definition gsXml.cpp:37
gsXmlNode * searchId(const int id, gsXmlNode *root, const char *tag_name=NULL, const bool print_warning=true)
Definition gsXml.h:254
Object * getById(gsXmlNode *node, const int &id)
Definition gsXml.h:311
The G+Smo namespace, containing all definitions for the library.