G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsXmlGenericUtils.hpp
Go to the documentation of this file.
1
14#pragma once
15
17
18namespace gismo {
19
20namespace internal {
21
22template<class Object>
23Object * getTensorBasisFromXml ( gsXmlNode * node)
24{
25 // Note: we do not check for the Object tag here, to allow some
26 // freedom (eg. BSplineBasis instead of TensorBSplineBasis1
27 GISMO_ASSERT( !strcmp( node->name(),"Basis"), "Invalid tag when \"Basis\" was expected.");
28
29 // Component container
30 std::vector<typename Object::CoordinateBasis* > bb;
31
32 // Special case of reading a 1D tensor basis
33 if ( !strcmp(node->first_attribute("type")->value(),
34 gsXml<typename Object::CoordinateBasis>::type().c_str() ) ) // to do in derived
35 {
36 bb.push_back( gsXml<typename Object::CoordinateBasis>::get(node) );
37 return Object::New( bb );
38 }
39
40 const unsigned d = Object::Dim;
41 gsXmlNode * tmp = node->first_node("Basis");
42 if ( tmp )
43 {
44 for ( unsigned i = 0; i!=d; ++i)
45 {
46 bb.push_back( gsXml<typename Object::CoordinateBasis>::get(tmp) );
47 tmp = tmp->next_sibling("Basis");
48 }
49 }
50 else
51 {
52 GISMO_ASSERT( d == 1, "Wrong data in the xml file.");
53 bb.push_back( gsXml<typename Object::CoordinateBasis>::get(node) );
54 }
55
56 //gsDebugVar( bb.size() );
57 return Object::New( bb );
58}
59
60template<class Object>
61gsXmlNode * putTensorBasisToXml ( Object const & obj, gsXmlTree & data)
62{
63 // Write the component bases
64 static const unsigned d = Object::Dim;
65 if (d==1)
66 return gsXml<typename Object::CoordinateBasis>::put(obj.component(0), data);
67
68 // Add a new node (without data)
69 gsXmlNode* tp_node = internal::makeNode("Basis" , data);
70 tp_node->append_attribute( makeAttribute("type",
71 internal::gsXml<Object>::type().c_str(), data) );
72
73 for ( unsigned i = 0; i!=d; ++i )
74 {
75 gsXmlNode* tmp =
76 internal::gsXml< typename Object::CoordinateBasis >::put(obj.component(i), data );
77 tmp->append_attribute( makeAttribute("index", i, data) );
78 tp_node->append_node(tmp);
79 }
80
81 // All set, return the basis
82 return tp_node;
83}
84
85template<class Object>
86Object * getRationalBasisFromXml ( gsXmlNode * node)
87{
88 GISMO_ASSERT( ( !strcmp( node->name(),"Basis") )
89 && ( !strcmp(node->first_attribute("type")->value(),
90 internal::gsXml<Object>::type().c_str() ) ),
91 "Something is wrong with the XML data: There should be a node with a "
92 <<internal::gsXml<Object>::type().c_str()<<" Basis.");
93
94 // Read source basis
95 gsXmlNode * tmp = node->first_node("Basis");
96 typename Object::SourceBasis * src = gsXml<typename Object::SourceBasis>::get(tmp) ;
97
98 // Read weights
99 tmp = node->first_node("weights");
100 gsMatrix<typename Object::Scalar_t> weights;
101 gsXmlAttribute* format = tmp->first_attribute("format");
102 std::string format_flag = format ? format->value() : "ascii";
103 getMatrixFromXml<typename Object::Scalar_t>(tmp, src->size(), 1, weights,
104 format_flag);
105 return new Object(src, give(weights));
106}
107
108template<class Object>
109Object * getHTensorBasisFromXml ( gsXmlNode * node)
110{
111 GISMO_ASSERT( ( !strcmp( node->name(),"Basis") )
112 && ( !strcmp(node->first_attribute("type")->value(),
113 internal::gsXml<Object>::type().c_str() ) ),
114 "Something is wrong with the XML data: There should be a node with a "<<
115 internal::gsXml<Object>::type().c_str()<<" Basis.");
116
117 typedef typename Object::Scalar_t T;
118 static const int d = Object::Dim;
119
120 // Read max level
121 //unsigned lvl = atoi( node->first_attribute("levels")->value() );
122 gsXmlNode * tmp = node->first_node("Basis");
123 GISMO_ASSERT( tmp , "Expected to find a basis node.");
124
125 // Read the Tensor-product basis
126 gsTensorBSplineBasis<d,T> * tp =
127 gsXml<gsTensorBSplineBasis<d,T> >::get(tmp);
128
129 // Initialize the HBSplineBasis
130 std::istringstream str;
131
132 // Insert all boxes
133 unsigned c;
134 std::vector<index_t> all_boxes;
135 for (tmp = node->first_node("box");
136 tmp; tmp = tmp->next_sibling("box"))
137 {
138 all_boxes.push_back(atoi( tmp->first_attribute("level")->value() ));
139 str.clear();
140 str.str( tmp->value() );
141 for( unsigned i = 0; i < 2*d; i++)
142 {
143 str>> c;
144 all_boxes.push_back(c);
145 }
146 }
147
148 gsXmlAttribute * manualLevels = node->first_attribute("manualLevels");
149 bool ml = manualLevels && !strcmp(manualLevels->value(),"true");
150 Object * hbs = new Object(*tp, ml);
151 delete tp;
152
153 if (ml)
154 {
155 index_t lvl = 1;
156 const gsXmlAttribute * id_at;
157 for (gsXmlNode * child = node->first_node("Basis");
158 child; child = child->next_sibling("Basis"))
159 {
160 id_at = child->first_attribute("level");
161 if (id_at && atoi(id_at->value()) == lvl )
162 {
163 ++lvl;
164 auto tb = memory::make_unique(
165 internal::gsXml<gsTensorBSplineBasis<d,T> >::get(child) );
166 hbs->addLevel( give(*tb) );
167 }
168 }
169 }
170
171 hbs->refineElements(all_boxes);
172 return hbs;
173}
174
175template<class Object>
176gsXmlNode * putHTensorBasisToXml ( Object const & obj, gsXmlTree & data)
177{
178 //typedef typename Object::Scalar_t T;
179 const int d = obj.dim();
180
181 // Add a new node (without data)
182 gsXmlNode* tp_node = internal::makeNode("Basis" , data);
183
184 tp_node->append_attribute( makeAttribute("type",
185 internal::gsXml<Object>::type().c_str(), data) );
186
187 //tp_node->append_attribute( makeAttribute( "levels",2 ,data )); // deprecated
188
189 gsXmlNode * tmp;
190 if (obj.manualLevels())
191 {
192 tp_node->append_attribute( makeAttribute("manualLevels","true", data) );
193 for (index_t l = 0; l != obj.numLevels(); l++)
194 {
195 tmp = putTensorBasisToXml(obj.tensorLevel(l), data);
196 tmp->append_attribute( makeAttribute("level", to_string(l), data ) );
197 tp_node->append_node(tmp);
198 }
199 }
200 else
201 {
202 tp_node->append_attribute( makeAttribute("manualLevels","false", data) );
203 // Write the component bases
204 tmp = putTensorBasisToXml(obj.tensorLevel(0), data);
205 tp_node->append_node(tmp);
206 }
207
208
209 //Output boxes
210 gsMatrix<index_t> box(1,2*d);
211
212 for( typename Object::hdomain_type::const_literator lIter =
213 obj.tree().beginLeafIterator(); lIter.good() ; lIter.next() )
214 {
215 if ( lIter->level > 0 )
216 {
217 box.leftCols(d) = lIter.lowerCorner().transpose();
218 box.rightCols(d) = lIter.upperCorner().transpose();
219
220 tmp = putMatrixToXml( box, data, "box" );
221
222 tmp->append_attribute( makeAttribute("level", to_string(lIter->level), data ) );
223 tp_node->append_node(tmp);
224 }
225 }
226
227/*
228// Write box history (deprecated)
229typename Object::boxHistory const & boxes = obj.get_inserted_boxes();
230
231for(unsigned int i = 0; i < boxes.size(); i++)
232{
233box.leftCols(d) = boxes[i].lower.transpose();
234box.rightCols(d) = boxes[i].upper.transpose();
235
236tmp = putMatrixToXml( box, data, "box" );
237tmp->append_attribute( makeAttribute("level", to_string(boxes[i].level), data ) );
238tp_node->append_node(tmp);
239}
240*/
241
242 // All set, return the basis
243 return tp_node;
244}
245
246
247template<class Object>
248gsXmlNode * putRationalBasisToXml ( Object const & obj, gsXmlTree & data)
249{
250 // Add a new node
251 gsXmlNode* rat_node = internal::makeNode("Basis" , data);
252 rat_node->append_attribute( makeAttribute("type",
253 internal::gsXml< Object >::type().c_str(), data) );
254
255 // Write the source basis
256 gsXmlNode* tmp =
257 internal::gsXml< typename Object::SourceBasis >::put(obj.source(), data );
258 rat_node->append_node(tmp);
259
260 // Write the weights
261 tmp = putMatrixToXml( obj.weights(), data, "weights" );
262 rat_node->append_node(tmp);
263
264 // All done, return the node
265 return rat_node;
266}
267
268
269
270
271/*
272template<class Object>
273Object * getById(gsXmlNode * node, const int & id)
274{
275 std::string tag = internal::gsXml<Object>::tag();
276 for (gsXmlNode * child = node->first_node(tag.c_str());
277 child; child = child->next_sibling(tag.c_str()))
278 {
279 if ( atoi(child->first_attribute("id")->value() ) == id )
280 return internal::gsXml<Object>::get(child);
281 }
282 std::cerr<<"gsXmlUtils Warning: "<< internal::gsXml<Object>::tag()
283 <<" with id="<<id<<" not found.\n";
284 return NULL;
285}
286*/
287
288
289// Helper to get the tag of an id
290// std::string getTag(gsXmlNode * node, const int & id)
291// {
292// for (gsXmlNode * child = node->first_node();
293// child; child = child->next_sibling() )
294// if ( atoi(child->first_attribute("id")->value() ) == id )
295// return child->name();
296
297// std::cerr<<"gsXmlUtils Warning: Tag with id="<<id<<" not found.\n";
298// return "";
299// }
300
301
302
303
305//template<class Object>
306//Object * getGeometryFromXml ( gsXmlNode * node);
307template<class Object>
308Object * getGeometryFromXml ( gsXmlNode * node)
309{
310 //gsWarn<<"Reading "<< gsXml<Object>::type() <<" Geometry..\n";
311 assert ( ( !strcmp( node->name(),"Geometry") ) &&
312 ( !strcmp(node->first_attribute("type")->value(), gsXml<Object>::type().c_str() ) ) );
313
314 gsXmlNode * tmp = node->first_node("Basis");
315
316 // to do: avoid copy object here (remove Ptr)
317 typename Object::Basis::Ptr b( gsXml<typename Object::Basis>::get(tmp) );
318
319 //gsWarn<<"Read basis from node "<< tmp <<", got "<< *b <<"\n";
320
321 tmp = node->first_node("coefs");
322 GISMO_ASSERT( tmp, "Did not find any coefficients for "<< gsXml<Object>::type().c_str() );
323 gsXmlAttribute * at_geodim = tmp->first_attribute("geoDim");
324 GISMO_ASSERT( at_geodim , "geoDim attribute not found in Geometry XML tag");
325 unsigned geoDim = atoi(at_geodim->value() ) ;
326
327 //gsWarn<<"Read mat "<< b->size()<<"x"<< geoDim <<"\n";
328
329 // Read the Coefficients and store them in a matrix
330 gsMatrix<typename Object::Scalar_t> coefficient_matrix;
331 gsXmlAttribute* format = tmp->first_attribute("format");
332 std::string format_flag = format ? format->value() : "ascii";
333 getMatrixFromXml<typename Object::Scalar_t>(
334 tmp, b->size(), geoDim, coefficient_matrix, format_flag);
335
336
337 gsXmlAttribute* coef_order = tmp->first_attribute("order");
338 if (nullptr != coef_order)
339 if (!strcmp(coef_order->value(), "coordinates")) {
340 coefficient_matrix.transposeInPlace();
341 coefficient_matrix.resize(b->size(), geoDim);
342 }
343
344 // Looking for transformations
345 tmp = node->first_node("transform");
347 if ( tmp )
348 {
349 for (gsXmlNode * tr = tmp->first_node();
350 tr; tr= tr->next_sibling() )
351 {
352 std::string val( tr->name() );
353
354 if (val == "translation")
355 {
356 getMatrixFromXml<typename Object::Scalar_t>(tmp, 3, 1 ,a);
357 // coefficient_matrix->rowwise() += a->transpose(); // TO DO
358 }
359 if (val == "rotation" ) // 3d
360 {
361 getMatrixFromXml<typename Object::Scalar_t>(tmp, 4, 1, a);
362 gsEigen::Transform<typename Object::Scalar_t,3,gsEigen::Affine>
363 rot( gsEigen::AngleAxis<typename Object::Scalar_t>
364 ( a(3,0), a.template block<3,1>(0,0).normalized() ) );
365 coefficient_matrix = (coefficient_matrix. rowwise().homogeneous() *
366 rot.matrix().transpose() ).leftCols(3) ;
367
368 }
369 if (val == "scale")
370 {
371
372 }
373 else
374 {
375 gsWarn<< "Unidentified transform tag in XML.\n";
376 }
377 }
378 }
379
380 Object * result = new Object(*b, coefficient_matrix);
381 return result;
382}
383
385//template<class Object>
386//gsXmlNode * putGeometryToXml ( Object const & obj, gsXmlTree & data);
387template<class Object>
388gsXmlNode * putGeometryToXml ( Object const & obj, gsXmlTree & data)
389{
390 // Make a new XML Geometry node
391 gsXmlNode * bs = internal::makeNode("Geometry", data);
392 bs->append_attribute( makeAttribute("type",
393 internal::gsXml<Object>::type().c_str(), data) );
394
395 // Add the basis
396 gsXmlNode* tmp =
397 internal::gsXml< typename Object::Basis >::put(obj.basis(), data);
398 if ( ! tmp )
399 {
400 gsWarn<<"XML Warning: Writing basis failed.\n";
401 return NULL;
402 }
403
404 bs->append_node(tmp);
405
406 // Write the coefficient matrix
407 tmp = putMatrixToXml( obj.coefs(), data, "coefs" );
408 tmp->append_attribute( makeAttribute("geoDim", obj.geoDim(), data) );
409 bs->append_node(tmp);
410 return bs;
411}
412
413template < class T >
414gsXmlNode * putFunctionExprToXml(const gsFunctionExpr<T> & obj, gsXmlNode * result, gsXmlTree & data)
415{
416 std::string typeStr = gsXml<gsFunctionExpr<T> >::type();
417 gsXmlAttribute * type = internal::makeAttribute("type", typeStr, data);
418 result->append_attribute(type);
419 gsXmlAttribute * dim = internal::makeAttribute("dim", obj.domainDim(),
420 data);
421 result->append_attribute(dim);
422 // set value
423 const short_t tdim = obj.targetDim();
424 if ( tdim == 1)
425 {
426 result->value( makeValue(obj.expression(), data) );
427 }
428 else
429 {
430 gsXmlNode * cnode;
431 for (short_t c = 0; c!=tdim; ++c)
432 {
433 cnode = makeNode("c", obj.expression(c), data);
434 result->append_node(cnode);
435 }
436 }
437 return result;
438}
439
440template < class T >
441gsXmlNode * putConstantFunctionToXml(const gsConstantFunction<T> & obj,gsXmlNode * result, gsXmlTree & data)
442{
443 std::string typeStr = "FunctionExpr";
444 gsXmlAttribute * type = internal::makeAttribute("type", typeStr, data);
445 result->append_attribute(type);
446 gsXmlAttribute * dim = internal::makeAttribute("dim", obj.domainDim(),
447 data);
448 result->append_attribute(dim);
449
450 // set value
451 gsMatrix<T> value = obj.value();
452 result->value( makeValue( value, data, true) );
453 return result;
454}
455
456template < class T >
457gsXmlNode * putFunctionToXml ( const typename gsFunctionSet<T>::Ptr & obj, gsXmlTree & data, int index)
458{
459 gsXmlNode * result = internal::makeNode("Function", data);
460 if (typeid(*obj) == typeid(gsFunctionExpr<T> ))
461 {
462 gsFunctionExpr<T> * ptr2 =
463 dynamic_cast<gsFunctionExpr<T> *>(obj.get());
464 result = putFunctionExprToXml(*ptr2, result, data);
465 }
466 else if (typeid(*obj) == typeid(gsConstantFunction<T> ))
467 {
468 gsConstantFunction<T> * ptr2 =
469 dynamic_cast<gsConstantFunction<T> *>(obj.get());
470 result = putConstantFunctionToXml(*ptr2, result, data);
471 }
472 gsXmlAttribute * indexNode = internal::makeAttribute("index", index,
473 data);
474 result->append_attribute(indexNode);
475 return result;
476}
477
478
479
480
481
482}// end namespace internal
483
484}// end namespace gismo
Class defining a multivariate (real or vector) function given by a string mathematical expression.
Definition gsFunctionExpr.h:52
short_t targetDim() const
Dimension of the target space.
Definition gsFunctionExpr.hpp:474
short_t domainDim() const
Dimension of the (source) domain.
Definition gsFunctionExpr.hpp:468
memory::shared_ptr< gsFunctionSet > Ptr
Shared pointer for gsFunctionSet.
Definition gsFunctionSet.h:223
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
#define short_t
Definition gsConfig.h:35
#define index_t
Definition gsConfig.h:32
Provides declaration of ConstantFunction class.
#define gsWarn
Definition gsDebug.h:50
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
gsXmlNode * putGeometryToXml(Object const &obj, gsXmlTree &data)
Helper to put geometries to XML.
Definition gsXmlGenericUtils.hpp:388
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
std::string to_string(const unsigned &i)
Helper to convert small unsigned to string.
Definition gsXml.cpp:74
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
Object * getGeometryFromXml(gsXmlNode *node)
Helper to fetch geometries.
Definition gsXmlGenericUtils.hpp:308
unique_ptr< T > make_unique(T *x)
Definition gsMemory.h:198
The G+Smo namespace, containing all definitions for the library.
S give(S &x)
Definition gsMemory.h:266