G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsXmlUtils.hpp
Go to the documentation of this file.
1 
14 #pragma once
15 
16 #include <fstream>
17 
18 //#include <gsCore/gsForwardDeclarations.h>
19 #include <gsCore/gsLinearAlgebra.h>
20 #include <gsCore/gsBasis.h>
21 #include <gsCore/gsRationalBasis.h>
22 #include <gsCore/gsFunctionExpr.h>
23 #include <gsCore/gsMultiPatch.h>
24 #include <gsCore/gsMultiBasis.h>
25 #include <gsCore/gsBoundary.h>
26 
27 #include <gsNurbs/gsNurbsBasis.h>
28 #include <gsNurbs/gsNurbs.h>
29 #include <gsNurbs/gsTensorNurbs.h>
30 
31 #include <gsHSplines/gsHBSpline.h>
32 #include <gsHSplines/gsTHBSpline.h>
33 
36 #include <gsModeling/gsSolid.h>
38 
39 #include <gsUtils/gsMesh/gsMesh.h>
40 
41 //#include <gsTrBezier/gsTriangularBezierBasis.h>
42 //#include <gsTrBezier/gsTriangularBezier.h>
43 #include <gsPde/gsPoissonPde.h>
44 #include <gsPde/gsSurfacePoissonPde.h>
45 
46 
48 
49 namespace gismo {
50 
51 namespace internal {
52 
53 /*
54  * Getting Xml data
55  */
56 
58 template<class T>
59 class gsXml< gsSolid<T> >
60 {
61 private:
62  gsXml() { }
63 public:
64  GSXML_COMMON_FUNCTIONS(gsSolid<T>);
65  static std::string tag () { return "Solid"; }
66  static std::string type () { return ""; }
67 
68  static gsSolid<T> * get (gsXmlNode * node)
69  {
70  GISMO_ASSERT( !strcmp( node->name(),"Solid"),
71  "Something went wrong. Expected Solid tag." );
72 
73  gsSolid<T> * m = new gsSolid<T>;
74 
75  int n = atoi ( node->first_attribute("vertices")->value() ) ;
76  int nVol = atoi ( node->first_attribute("volumes")->value() ) ;
77  T x,y, z;
78  gsXmlNode * tmp = node->first_node("Vertex");
79  std::istringstream str;
80  str.str( tmp->value() );
81 
82  int nf;
83  int vertID;
84  int trimID;
85  int ntest(0);
86  std::vector< std::vector< gsSolidHeVertex<T>* > > vert;
87 
88  // get vertices
89  for (int i=0; i<n; ++i)
90  {
91  ntest++;
92  gsGetReal(str, x);
93  gsGetReal(str, y);
94  gsGetReal(str, z);
95  m->addHeVertex(x,y,z);
96  }
97  GISMO_ASSERT( ntest==n,
98  "Number of vertices does not match the Solid tag." );
99 
100  // get faces and surfaces
101  gsXmlNode * toplevel = node->parent();// the geometry patches should be siblings of node
102  n = atoi ( node->first_attribute("faces")->value() ) ;
103  tmp = node->first_node("Face");
104  std::istringstream strf;
105  strf.str( tmp->value() );
106  ntest = 0;
107  for (int iface=0; iface<n; iface++)
108  {
109  vert.clear();
110  ntest++;
111  size_t nLoops = 0;
112  do
113  {
114  nLoops++;
115  vert.push_back(std::vector< gsSolidHeVertex<T>* >());
116  gsGetInt(strf, nf);
117  // read num vertices on this loop
118  for (int ivert=0; ivert<nf; ivert++) // read vertices
119  {
120  gsGetInt(strf, vertID);
121  vert[nLoops-1].push_back(m->vertex[vertID]);
122  }
123  // next number is either:
124  // * the trim surface id,
125  // * -1 to indicate that the surface is automatically computed, or
126  // * -2 to indicate that there are further internal loops
127  gsGetInt(strf, trimID);
128  } while(trimID <= -2); // -2 indicates that there are vertices remaining
129  if (trimID>-1)
130  m->addFace(vert, getById< gsTrimSurface<T> >( toplevel, trimID ) );
131  else if (trimID==-1 && nLoops == 1)
132  m->addFace(vert[0]);
133  else if (trimID==0 && nLoops == 1)
134  GISMO_ERROR("Faces must have unequal 0 as id (last value: increase from 1 or use -1 for all)"); // otherwise SEGFAULT happens
135  else if (trimID==-1)
136  {
137  gsWarn<<"\nAutomatic creation of trimmed surfaces is only supported for a single loop\n";
138  }
139  else
140  {
141  gsWarn<<"\n ID of the trimmed surface trimID=" <<trimID<<" is invalid (must be >=-1)\n";
142  }
143  }
144  m->setHeMate();
145  // read in volumes. (optional)
146  gsXmlNode * nodeVol = node->first_node("Volume");
147  if(nodeVol == NULL)
148  {
149  GISMO_ASSERT(nVol == 1, "More than one volume but faces for volumes not specified");
150  m->addVolume(m->face);
151  }
152  else
153  {
154  // set volumes if more than one
155  std::istringstream strVol;
156  strVol.str( nodeVol->value() );
157  std::vector<gsSolidHalfFace<T> *> volFaces;
158  for(int i = 0; i < nVol; i++)
159  {
160  volFaces.clear();
161  int numFaces;
162  gsGetInt(strVol, numFaces);
163  for(int j = 0; j < numFaces; j++)
164  {
165  int faceId;
166  gsGetInt(strVol, faceId);
167  volFaces.push_back(m->face[faceId]);
168  }
169  m->addVolume(volFaces);
170  }
171  }
172  assert(ntest==n);// check if the number of surfaces in the input file is correct
173 
174  return m;
175  }
176 
177  static gsXmlNode * put (const gsSolid<T> & obj,
178  gsXmlTree & data )
179  {
180  // Make Vertex node
181  size_t nVert = obj.vertex.size();
182  gsMatrix<T> vert(nVert, 3);
183  for(size_t i = 0; i < nVert; i++)
184  {
185  vert.row(i) = obj.vertex[i]->coords;
186  }
187  gsXmlNode * nodeVertex = putMatrixToXml(vert, data, "Vertex");
188  // Make Face node
189  size_t nFace = obj.face.size();
190  std::ostringstream strf;
191  std::vector<int> faceVerts;
192  for(size_t i = 0; i < nFace; i++)
193  {
194  size_t nLoops = obj.face[i]->loop.size();
195  for(size_t loopIdx = 0; loopIdx < nLoops; loopIdx++)
196  {
197  faceVerts.clear();
198  gsSolidHalfEdge<T> *eFirst = obj.face[i]->loop[loopIdx];
199  gsSolidHalfEdge<T> *e = eFirst;
200  do // loop over boundary of face, collecting vertex ids
201  {
202  faceVerts.push_back(e->source->getId());
203  e = e->next;
204  } while(e != eFirst);
205  size_t nfv = faceVerts.size();
206  // write # vertices, vertex ids
207  strf << nfv << " ";
208  for(size_t j = 0; j < nfv; j++)
209  {
210  strf << faceVerts[j] << " ";
211  }
212  // if we aren't done, write a -2 to indicate that there are more loops
213  if(loopIdx < nLoops - 1) strf << -2 << " ";
214  }
215  // write trim surf id (may as well make it the same as the face id)
216  strf << i << "\n";
217  }
218  gsXmlNode* nodeFace = internal::makeNode("Face", strf.str(), data);
219  // Make Volume node
220  int nVol = obj.nVolumes();
221  std::ostringstream strVol;
222  for(int i = 0; i < nVol; i++)
223  {
224  size_t nVolF = obj.volume[i]->face.size();
225  strVol << nVolF << " ";
226  for(size_t j = 0; j < nVolF; j++)
227  {
228  strVol << obj.volume[i]->face[j]->getId();
229  if(j < nVolF - 1) strVol << " ";
230  }
231  strVol << "\n";
232  }
233  gsXmlNode * nodeVolume = internal::makeNode("Volume", strVol.str(), data);
234  // Create solid
235  gsXmlNode * nodeSolid = internal::makeNode("Solid", data);
236  // Set attributes for # vertices, edges, faces, volumes.
237  nodeSolid->append_attribute(makeAttribute("vertices", nVert, data));
238  nodeSolid->append_attribute(makeAttribute("faces", nFace, data));
239  nodeSolid->append_attribute(makeAttribute("volumes", nVol, data));
240  //if multiple solids are being written someone else will have to decide the id
241  //nodeSolid->append_attribute(makeAttribute("id", 0, data));
242  nodeSolid->append_node(nodeVertex);
243  nodeSolid->append_node(nodeFace);
244  nodeSolid->append_node(nodeVolume);
245 
246  // write trimmed surfaces to the root
247  for(size_t i = 0; i < nFace; i++)
248  {
249  gsXmlNode* nodeTS = gsXml< gsTrimSurface<T> >::put(*(obj.face[i]->surf), data);
250  data.appendToRoot(nodeTS);
251  }
252 
253  return nodeSolid;
254  }
255 };
256 
257 
259 template<class T>
260 class gsXml< gsMesh<T> >
261 {
262 private:
263  gsXml() { }
264 public:
265  GSXML_COMMON_FUNCTIONS(gsMesh<T>);
266  static std::string tag () { return "Mesh"; }
267  static std::string type () { return "off"; }
268 
269  static gsMesh<T> * get (gsXmlNode * node)
270  {
271  assert( ( !strcmp( node->name(),"Mesh") )
272  && ( !strcmp(node->first_attribute("type")->value(),"off") ) );
273 
274  gsMesh<T> * m = new gsMesh<T>;
275  std::istringstream str;
276  str.str( node->value() );
277 
278  unsigned n = atoi ( node->first_attribute("vertices")->value() ) ;
279  T x,y, z;
280  for (unsigned i=0; i<n; ++i)
281  {
282  gsGetReal(str, x);
283  gsGetReal(str, y);
284  gsGetReal(str, z);
285  m->addVertex(x,y,z);
286  }
287 
288  n = atoi ( node->first_attribute("faces")->value() ) ;
289  unsigned c = 0;
290  std::vector<int> face;
291  for (unsigned i=0; i<n; ++i)
292  {
293  gsGetInt(str, c);
294  face.resize(c);
295  for (unsigned j=0; j<c; ++j)
296  gsGetInt(str, face[j]);
297  m->addFace(face);
298  }
299  m->cleanMesh();
300  return m;
301  }
302 
303  static gsXmlNode * put (const gsMesh<T> &,
304  gsXmlTree & )
305  {
306  return NULL;
307  }
308 };
309 
310 
312 template<class T>
313 class gsXml< gsMatrix<T> >
314 {
315 private:
316  gsXml() { }
317  typedef gsMatrix<T> Object;
318 
319 public:
320  GSXML_COMMON_FUNCTIONS(Object);
321  static std::string tag () { return "Matrix"; }
322  static std::string type() { return ""; }
323 
324  GSXML_GET_POINTER(Object);
325 
326  static void get_into (gsXmlNode * node, Object & obj)
327  {
328  GISMO_ASSERT( !strcmp( node->name(),"Matrix"),
329  "Something went wrong. Expected Matrix tag." );
330 
331  unsigned rows = atoi(node->first_attribute("rows")->value());
332  unsigned cols = atoi(node->first_attribute("cols")->value());
333  gsXmlAttribute *format = node->first_attribute("format");
334  std::string format_flag = format ? format->value() : "ascii";
335  getMatrixFromXml<T>(node, rows, cols, obj, format_flag);
336  }
337 
338  static gsXmlNode * put (const gsMatrix<T> & obj,
339  gsXmlTree & data )
340  {
341  gsXmlNode * mat_data = putMatrixToXml(obj,data);
342  // Record matrix dimensions
343  mat_data->append_attribute(
344  makeAttribute("rows", obj.rows(), data) );
345  mat_data->append_attribute(
346  makeAttribute("cols", obj.cols(), data) );
347 
348  return mat_data;
349  }
350 };
351 
352 
354 template<class T>
355 class gsXml< gsSparseMatrix<T> >
356 {
357 private:
358  gsXml() { }
359  typedef gsSparseMatrix<T> Object;
360 
361 public:
362  GSXML_COMMON_FUNCTIONS(Object);
363  static std::string tag () { return "SparseMatrix"; }
364  static std::string type() { return ""; }
365 
366  GSXML_GET_POINTER(Object);
367 
368  static void get_into (gsXmlNode * node, Object & obj)
369  {
370  GISMO_ASSERT( !strcmp( node->name(),"SparseMatrix"),
371  "Something went wrong. Expected SparseMatrix tag." );
372 
373  const index_t rows = atoi ( node->first_attribute("rows")->value() ) ;
374  const index_t cols = atoi ( node->first_attribute("cols")->value() ) ;
375 
376  gsSparseEntries<T> entries;
377  getSparseEntriesFromXml<T>(node, entries);
378 
379  obj.resize(rows,cols);
380  obj.setFrom(entries);
381  }
382 
383  static gsXmlNode * put (const gsSparseMatrix<T> & obj,
384  gsXmlTree & data )
385  {
386  gsXmlNode * mat_data = putSparseMatrixToXml(obj,data);
387 
388  mat_data->append_attribute(
389  makeAttribute("rows", obj.rows(), data) );
390  mat_data->append_attribute(
391  makeAttribute("cols", obj.cols(), data) );
392 
393  return mat_data;
394  }
395 };
396 
397 /*
398  * Getting Bases from XML data
399  */
400 
402 template<class T>
403 class gsXml< gsNurbsBasis<T> >
404 {
405 private:
406  gsXml() { }
407 public:
408  GSXML_COMMON_FUNCTIONS(gsNurbsBasis<T>);
409  static std::string tag () { return "Basis"; }
410  static std::string type () { return "NurbsBasis"; }
411 
412  static gsNurbsBasis<T> * get (gsXmlNode * node)
413  {
414  return getRationalBasisFromXml<gsNurbsBasis<T> >(node);
415  }
416 
417  static gsXmlNode * put (const gsNurbsBasis<T> & obj,
418  gsXmlTree & data )
419  {
420  return putRationalBasisToXml(obj,data);
421  }
422 };
423 
424 
426 template<short_t d, class T>
427 class gsXml< gsTensorNurbsBasis<d,T> >
428 {
429 private:
430  gsXml() { }
431 public:
432  GSXML_COMMON_FUNCTIONS(gsTensorNurbsBasis<TMPLA2(d,T)>);
433  static std::string tag () { return "Basis"; }
434  static std::string type () { return "TensorNurbsBasis"+to_string(d); }
435 
436  static gsTensorNurbsBasis<d,T> * get (gsXmlNode * node)
437  {
438  return getRationalBasisFromXml< gsTensorNurbsBasis<d,T> >(node);
439  }
440 
441  static gsXmlNode * put (const gsTensorNurbsBasis<d,T> & obj,
442  gsXmlTree & data )
443  {
444  return putRationalBasisToXml< gsTensorNurbsBasis<d,T> >(obj,data);
445  }
446 };
447 
448 
450 template<class T>
451 class gsXml< gsNurbs<T> >
452 {
453 private:
454  gsXml() { }
455 public:
456  GSXML_COMMON_FUNCTIONS(gsNurbs<T>);
457  static std::string tag () { return "Geometry"; }
458  static std::string type () { return "Nurbs"; }
459 
460  static gsNurbs<T> * get (gsXmlNode * node)
461  {
462  return getGeometryFromXml< gsNurbs<T> >(node);
463  }
464 
465  static gsXmlNode * put (const gsNurbs<T> & obj,
466  gsXmlTree & data )
467  {
468  return putGeometryToXml(obj,data);
469  }
470 };
471 
473 template<short_t d, class T>
474 class gsXml< gsTensorNurbs<d,T> >
475 {
476 private:
477  gsXml() { }
478 public:
479  GSXML_COMMON_FUNCTIONS(gsTensorNurbs<TMPLA2(d,T)>);
480  static std::string tag () { return "Geometry"; }
481  static std::string type () { return "TensorNurbs"+to_string(d); }
482 
483  static gsTensorNurbs<d,T> * get (gsXmlNode * node)
484  {
485  return getGeometryFromXml< gsTensorNurbs<d,T> >( node );
486  }
487 
488  static gsXmlNode * put (const gsTensorNurbs<d,T> & obj,
489  gsXmlTree & data )
490  {
491  return putGeometryToXml(obj,data);
492  }
493 };
494 
496 template<class T>
497 class gsXml< gsTrimSurface<T> >
498 {
499 private:
500  gsXml() { }
501 public:
502  GSXML_COMMON_FUNCTIONS(gsTrimSurface<T>);
503  static std::string tag () { return "TrimSurface"; }
504  static std::string type () { return ""; }
505 
506  static gsTrimSurface<T> * get (gsXmlNode * node)
507  {
508  assert( !strcmp( node->name(),"TrimSurface") );
509 
510  gsXmlNode * tmp = node->first_node("Geometry");
511  gsSurface<T> * geo = gsXml<gsSurface<T> >::get (tmp) ;
512 
513  tmp = node->first_node("PlanarDomain");
514  gsPlanarDomain<T> * pd = gsXml<gsPlanarDomain<T> >::get (tmp) ;
515 
516  return new gsTrimSurface<T>( geo, pd );
517  }
518 
519  static gsXmlNode * put (const gsTrimSurface<T> & obj,
520  gsXmlTree & data )
521  {
522  gsXmlNode* nodeTS = internal::makeNode("TrimSurface", data);
523  gsXmlNode* nodeGeom = gsXml< gsGeometry<T> >::put(*(obj.getTP()), data);
524  gsXmlNode* nodeDom = gsXml< gsPlanarDomain<T> >::put(obj.domain(), data);
525 
526  nodeTS->append_node(nodeGeom);
527  nodeTS->append_node(nodeDom);
528  return nodeTS;
529  }
530 };
531 
533 template<class T>
534 class gsXml< gsGeometry<T> >
535 {
536 private:
537  gsXml() { }
538 public:
539  GSXML_COMMON_FUNCTIONS(gsGeometry<T>);
540  static std::string tag () { return "Geometry"; }
541  static std::string type () { return ""; }
542 
543  static gsGeometry<T> * get (gsXmlNode * node)
544  {
545  GISMO_ASSERT( ( !strcmp( node->name(),"Geometry") ),
546  "Something went wrong, was waiting for a Geometry tag.\n" );
547 
548  gsXmlAttribute * gtype = node->first_attribute("type");
549  if ( ! gtype )
550  {
551  gsWarn<< "Geometry without a type in the xml file\n";
552  return NULL;
553  }
554  std::string s = gtype->value() ;
555 
556  if ( s == "BSpline" )
557  return gsXml< gsBSpline<T> >::get(node);
558  if ( s == "Nurbs" )
559  return gsXml< gsNurbs<T> >::get(node);
560  if ( s == "HBSpline2" )
561  return gsXml< gsHBSpline<2,T> >::get(node);
562  if ( s == "HBSpline3" )
563  return gsXml< gsHBSpline<3,T> >::get(node);
564  if ( s == "THBSpline1" )
565  return gsXml< gsTHBSpline<1,T> >::get(node);
566  if ( s == "THBSpline2" )
567  return gsXml< gsTHBSpline<2,T> >::get(node);
568  if ( s == "THBSpline3" )
569  return gsXml< gsTHBSpline<3,T> >::get(node);
570 
571 
572  if ( s == "TensorBSpline1" )
573  return gsXml< gsTensorBSpline<1,T> >::get(node);
574  if ( s == "TensorBSpline2" )
575  return gsXml< gsTensorBSpline<2,T> >::get(node);
576  if ( s == "TensorBSpline3" )
577  return gsXml< gsTensorBSpline<3,T> >::get(node);
578  if ( s == "TensorBSpline4" )
579  return gsXml< gsTensorBSpline<4,T> >::get(node);
580  if ( s == "TensorNurbs2" )
581  return gsXml< gsTensorNurbs<2,T> >::get(node);
582  if ( s == "TensorNurbs3" )
583  return gsXml< gsTensorNurbs<3,T> >::get(node);
584  if ( s == "TensorNurbs4" )
585  return gsXml< gsTensorNurbs<4,T> >::get(node);
586 
587  //if ( s == "TrimSurface" )
588  // return gsXml< gsTrimSurface<T> >::get(node);
589 
590  //if ( s == "TriangularBezier2" )
591  // return gsXml< gsTriangularBezier<2,T> >::get(node);
592 
593  gsWarn<<"gsXmlUtils: getGeometry: No known geometry \""<<s<<"\". Error.\n";
594  return NULL;
595  }
596 
597 
598  static gsXmlNode * put (const gsGeometry<T> & obj,
599  gsXmlTree & data)
600  {
601  const gsGeometry<T> * ptr = & obj;
602 
603  if ( const gsBSpline<T> * g =
604  dynamic_cast<const gsBSpline<T> *>( ptr ) )
605  return gsXml< gsBSpline<T> >::put(*g,data);
606 
607  if ( const gsNurbs<T> * g =
608  dynamic_cast<const gsNurbs<T> *>( ptr ) )
609  return gsXml< gsNurbs<T> >::put(*g,data);
610 
611  if ( const gsTensorBSpline<2,T> * g =
612  dynamic_cast<const gsTensorBSpline<2,T> *>( ptr ) )
613  return gsXml< gsTensorBSpline<2,T> >::put(*g,data);
614 
615  if ( const gsTensorBSpline<3,T> * g =
616  dynamic_cast<const gsTensorBSpline<3,T> *>( ptr ) )
617  return gsXml< gsTensorBSpline<3,T> >::put(*g,data);
618 
619  if ( const gsTensorBSpline<4,T> * g =
620  dynamic_cast<const gsTensorBSpline<4,T> *>( ptr ) )
621  return gsXml< gsTensorBSpline<4,T> >::put(*g,data);
622 
623  if ( const gsTensorNurbs<2,T> * g =
624  dynamic_cast<const gsTensorNurbs<2,T> *>( ptr ) )
625  return gsXml< gsTensorNurbs<2,T> >::put(*g,data);
626 
627  if ( const gsTensorNurbs<3,T> * g =
628  dynamic_cast<const gsTensorNurbs<3,T> *>( ptr ) )
629  return gsXml< gsTensorNurbs<3,T> >::put(*g,data);
630 
631  if ( const gsTensorNurbs<4,T> * g =
632  dynamic_cast<const gsTensorNurbs<4,T> *>( ptr ) )
633  return gsXml< gsTensorNurbs<4,T> >::put(*g,data);
634 
635  if ( const gsTHBSpline<1,T> * g =
636  dynamic_cast<const gsTHBSpline<1,T> *>( ptr ) )
637  return gsXml< gsTHBSpline<1,T> >::put(*g,data);
638 
639  if ( const gsTHBSpline<2,T> * g =
640  dynamic_cast<const gsTHBSpline<2,T> *>( ptr ) )
641  return gsXml< gsTHBSpline<2,T> >::put(*g,data);
642 
643  if ( const gsTHBSpline<3,T> * g =
644  dynamic_cast<const gsTHBSpline<3,T> *>( ptr ) )
645  return gsXml< gsTHBSpline<3,T> >::put(*g,data);
646 
647  if ( const gsTrimSurface<T> * g =
648  dynamic_cast<const gsTrimSurface<T> *>( ptr ) )
649  return gsXml< gsTrimSurface<T> >::put(*g,data);
650 
651  if ( const gsHBSpline<1,T> * g =
652  dynamic_cast<const gsHBSpline<1,T> *>( ptr ) )
653  return gsXml< gsHBSpline<1,T> >::put(*g,data);
654 
655  if ( const gsHBSpline<2,T> * g =
656  dynamic_cast<const gsHBSpline<2,T> *>( ptr ) )
657  return gsXml< gsHBSpline<2,T> >::put(*g,data);
658 
659  if ( const gsHBSpline<3,T> * g =
660  dynamic_cast<const gsHBSpline<3,T> *>( ptr ) )
661  return gsXml< gsHBSpline<3,T> >::put(*g,data);
662 
663  //if ( const gsTriangularBezier<2,T> * g =
664  // dynamic_cast<const gsTriangularBezier<2,T> *>( ptr ) )
665  // return gsXml< gsTriangularBezier<2,T> >::put(*g,data);
666 
667  gsWarn<<"gsXmlUtils: put Geometry: No known object "<< obj <<"Error.\n";
668  return NULL;
669  }
670 
671 };
672 
673 
675 template<class T>
676 class gsXml< gsCurve<T> >
677 {
678 private:
679  gsXml() { }
680 public:
681  GSXML_COMMON_FUNCTIONS(gsCurve<T>);
682  static std::string tag () { return "Geometry"; }
683  static std::string type () { return ""; }
684 
685  static gsCurve<T> * get (gsXmlNode * node)
686  {
687  GISMO_ASSERT( ( !strcmp( node->name(),"Geometry") ),
688  "Something went wrong, was waiting for a Geometry tag.\n" );
689 
690  gsXmlAttribute * gtype = node->first_attribute("type");
691  if ( ! gtype )
692  {
693  gsWarn<< "Geometry without a type in the xml file\n";
694  return NULL;
695  }
696  std::string s = gtype->value() ;
697 
698  if ( s == "BSpline" )
699  return gsXml< gsBSpline<T> >::get(node);
700  if ( s == "Nurbs" )
701  return gsXml< gsNurbs<T> >::get(node);
702 
703  gsWarn<<"gsXmlUtils: getCurve: No known curve \""<<s<<"\". Error.\n";
704  return NULL;
705  }
706 
707 
708  static gsXmlNode * put (const gsCurve<T> & obj,
709  gsXmlTree & data)
710  {
711  const gsGeometry<T> * ptr = & obj;
712 
713  if ( const gsBSpline<T> * g =
714  dynamic_cast<const gsBSpline<T> *>( ptr ) )
715  return gsXml< gsBSpline<T> >::put(*g,data);
716 
717  if ( const gsNurbs<T> * g =
718  dynamic_cast<const gsNurbs<T> *>( ptr ) )
719  return gsXml< gsNurbs<T> >::put(*g,data);
720 
721  if ( const gsHBSpline<1,T> * g =
722  dynamic_cast<const gsHBSpline<1,T> *>( ptr ) )
723  return gsXml< gsHBSpline<1,T> >::put(*g,data);
724 
725  gsWarn<<"gsXmlUtils: put Curve: No known object "<< obj <<"Error.\n";
726  return NULL;
727  }
728 
729 };
730 
732 template<class T>
733 class gsXml< gsSurface<T> >
734 {
735 private:
736  gsXml() { }
737 public:
738  GSXML_COMMON_FUNCTIONS(gsSurface<T>);
739  static std::string tag () { return "Geometry"; }
740  static std::string type () { return ""; }
741 
742  static gsSurface<T> * get (gsXmlNode * node)
743  {
744  GISMO_ASSERT( ( !strcmp( node->name(),"Geometry") ),
745  "Something went wrong, was waiting for a Geometry tag.\n" );
746 
747  gsXmlAttribute * gtype = node->first_attribute("type");
748  if ( ! gtype )
749  {
750  gsWarn<< "Geometry without a type in the xml file\n";
751  return NULL;
752  }
753  std::string s = gtype->value() ;
754 
755  if ( s == "HBSpline2" )
756  return gsXml< gsHBSpline<2,T> >::get(node);
757  if ( s == "THBSpline2" )
758  return gsXml< gsTHBSpline<2,T> >::get(node);
759 
760  if ( s == "TensorBSpline2" )
761  return gsXml< gsTensorBSpline<2,T> >::get(node);
762  if ( s == "TensorNurbs2" )
763  return gsXml< gsTensorNurbs<2,T> >::get(node);
764 
765  gsWarn<<"gsXmlUtils: getSurface: No known surface \""<<s<<"\". Error.\n";
766  return NULL;
767  }
768 
769  static gsXmlNode * put (const gsSurface<T> & obj,
770  gsXmlTree & data)
771  {
772  const gsGeometry<T> * ptr = & obj;
773 
774  if ( const gsTensorBSpline<2,T> * g =
775  dynamic_cast<const gsTensorBSpline<2,T> *>( ptr ) )
776  return gsXml< gsTensorBSpline<2,T> >::put(*g,data);
777 
778  if ( const gsTensorNurbs<2,T> * g =
779  dynamic_cast<const gsTensorNurbs<2,T> *>( ptr ) )
780  return gsXml< gsTensorNurbs<2,T> >::put(*g,data);
781 
782  if ( const gsTHBSpline<2,T> * g =
783  dynamic_cast<const gsTHBSpline<2,T> *>( ptr ) )
784  return gsXml< gsTHBSpline<2,T> >::put(*g,data);
785 
786  if ( const gsHBSpline<2,T> * g =
787  dynamic_cast<const gsHBSpline<2,T> *>( ptr ) )
788  return gsXml< gsHBSpline<2,T> >::put(*g,data);
789 
790  gsWarn<<"gsXmlUtils: put Geometry: No known object "<< obj <<"Error.\n";
791  return NULL;
792  }
793 };
794 
796 template<class T>
797 class gsXml< gsBasis<T> >
798 {
799 private:
800  gsXml() { }
801 public:
802  GSXML_COMMON_FUNCTIONS(gsBasis<T>);
803  static std::string tag () { return "Basis"; }
804  static std::string type () { return ""; }
805 
806  static gsBasis<T> * get (gsXmlNode * node)
807  {
808  GISMO_ASSERT( ( !strcmp( node->name(),"Basis") ), "Something went wrong, waiting for a basis." );
809 
810  gsXmlAttribute * btype = node->first_attribute("type");
811  if ( ! btype )
812  {
813  gsWarn<< "Basis without a type in the xml file.\n";
814  return NULL;
815  }
816  std::string s = btype->value() ;
817 
818  if ( s == "BSplineBasis" )
819  return gsXml< gsBSplineBasis<T> >::get(node);
820  if ( s == "NurbsBasis" )
821  return gsXml< gsNurbsBasis<T> >::get(node);
822 
823  if ( s == "HBSplineBasis" )
824  return gsXml< gsHBSplineBasis<1,T> >::get(node);
825  if ( s == "HBSplineBasis2" )
826  return gsXml< gsHBSplineBasis<2,T> >::get(node);
827  if ( s == "HBSplineBasis3" )
828  return gsXml< gsHBSplineBasis<3,T> >::get(node);
829  if ( s == "HBSplineBasis4" )
830  return gsXml< gsHBSplineBasis<4,T> >::get(node);
831 
832  if ( s == "THBSplineBasis" )
833  return gsXml< gsTHBSplineBasis<1,T> >::get(node);
834  if ( s == "THBSplineBasis2" )
835  return gsXml< gsTHBSplineBasis<2,T> >::get(node);
836  if ( s == "THBSplineBasis3" )
837  return gsXml< gsTHBSplineBasis<3,T> >::get(node);
838  if ( s == "THBSplineBasis4" )
839  return gsXml< gsTHBSplineBasis<4,T> >::get(node);
840 
841  //if ( s == "gsTriangularBezierBasis2" )
842  // return gsXml< gsTriangularBezierBasis<2,T> >::get(node);
843 
844  if ( s == "TensorBSplineBasis2" )
845  return gsXml< gsTensorBSplineBasis<2, T> >::get(node);
846  if ( s == "TensorBSplineBasis3" )
847  return gsXml< gsTensorBSplineBasis<3, T> >::get(node);
848  if ( s == "TensorBSplineBasis4" )
849  return gsXml< gsTensorBSplineBasis<4, T> >::get(node);
850 
851  if ( s == "TensorNurbsBasis2" )
852  return gsXml< gsTensorNurbsBasis<2, T> >::get(node);
853  if ( s == "TensorNurbsBasis3" )
854  return gsXml< gsTensorNurbsBasis<3, T> >::get(node);
855  if ( s == "TensorNurbsBasis4" )
856  return gsXml< gsTensorNurbsBasis<4, T> >::get(node);
857 
858  gsWarn<<"gsXmlUtils: getBasis: No known basis \""<<s<<"\". Error.\n";
859  return NULL;
860  }
861 
862  static gsXmlNode * put (const gsBasis<T> & obj,
863  gsXmlTree & data )
864  {
865  const gsBasis<T> * ptr = & obj;
866 
867  if ( const gsBSplineBasis<T> * g =
868  dynamic_cast<const gsBSplineBasis<T> *>( ptr ) )
869  return gsXml< gsBSplineBasis<T> >::put(*g,data);
870 
871  if ( const gsNurbsBasis<T> * g =
872  dynamic_cast<const gsNurbsBasis<T> *>( ptr ) )
873  return gsXml< gsNurbsBasis<T> >::put(*g,data);
874 
875  // Tensor B-spline
876  if ( const gsTensorBSplineBasis<2, T> * g =
877  dynamic_cast<const gsTensorBSplineBasis<2, T> *>( ptr ) )
878  return gsXml< gsTensorBSplineBasis<2, T> >::put(*g,data);
879 
880  if ( const gsTensorBSplineBasis<3, T> * g =
881  dynamic_cast<const gsTensorBSplineBasis<3, T> *>( ptr ) )
882  return gsXml< gsTensorBSplineBasis<3, T> >::put(*g,data);
883 
884  if ( const gsTensorBSplineBasis<4, T> * g =
885  dynamic_cast<const gsTensorBSplineBasis<4, T> *>( ptr ) )
886  return gsXml< gsTensorBSplineBasis<4, T> >::put(*g,data);
887 
888  // Tensor Nurbs
889  if ( const gsTensorNurbsBasis<2, T> * g =
890  dynamic_cast<const gsTensorNurbsBasis<2, T> *>( ptr ) )
891  return gsXml< gsTensorNurbsBasis<2, T> >::put(*g,data);
892 
893  if ( const gsTensorNurbsBasis<3, T> * g =
894  dynamic_cast<const gsTensorNurbsBasis<3, T> *>( ptr ) )
895  return gsXml< gsTensorNurbsBasis<3, T> >::put(*g,data);
896 
897  if ( const gsTensorNurbsBasis<4, T> * g =
898  dynamic_cast<const gsTensorNurbsBasis<4, T> *>( ptr ) )
899  return gsXml< gsTensorNurbsBasis<4, T> >::put(*g,data);
900 
901 
902  // Tensor-Hier. B-splines
903  if ( const gsHTensorBasis<1,T> * g =
904  dynamic_cast<const gsHTensorBasis<1,T> *>( ptr ) )
905  return gsXml< gsHTensorBasis<1,T> >::put(*g,data);
906 
907  if ( const gsHTensorBasis<2,T> * g =
908  dynamic_cast<const gsHTensorBasis<2,T> *>( ptr ) )
909  return gsXml< gsHTensorBasis<2,T> >::put(*g,data);
910 
911  if ( const gsHTensorBasis<3,T> * g =
912  dynamic_cast<const gsHTensorBasis<3,T> *>( ptr ) )
913  return gsXml< gsHTensorBasis<3,T> >::put(*g,data);
914 
915  if ( const gsHTensorBasis<4,T> * g =
916  dynamic_cast<const gsHTensorBasis<4,T> *>( ptr ) )
917  return gsXml< gsHTensorBasis<4,T> >::put(*g,data);
918 
919  if ( const gsTHBSplineBasis<3,T> * g =
920  dynamic_cast<const gsTHBSplineBasis<3,T> *>( ptr ) )
921  return gsXml< gsTHBSplineBasis<3,T> >::put(*g,data);
922 
923  //if ( const gsTriangularBezierBasis<2,T> * g =
924  // dynamic_cast<const gsTriangularBezierBasis<2,T> *>( ptr ) )
925  // return gsXml< gsTriangularBezierBasis<2,T> >::put(*g,data);
926 
927  gsWarn<<"gsXmlUtils put: getBasis: No known basis \""<<obj<<"\". Error.\n";
928  return NULL;
929  }
930 };
931 
933 template<class T>
934 class gsXml< gsPde<T> >
935 {
936 private:
937  gsXml() { }
938 public:
939  GSXML_COMMON_FUNCTIONS(gsPde<T>);
940  static std::string tag () { return "Pde"; }
941  static std::string type () { return ""; }
942 
943  static gsPde<T> * get (gsXmlNode * node)
944  {
945  GISMO_ASSERT( !strcmp( node->name(),"Pde"),
946  "Something went wrong. Expected Pde tag." );
947 
948  std::string s = node->first_attribute("type")->value() ;
949  if ( s == "PoissonPde" )
950  return gsXml< gsPoissonPde<T> >::get(node);
951  if ( s == "SurfacePoissonPde" )
952  return gsXml< gsSurfacePoissonPde<T> >::get(node);
953 
954  gsWarn<<"gsXmlUtils: getPde: No known Pde \""<<s<<"\". Error.\n";
955  return NULL;
956  }
957 
958  static gsXmlNode * put (const gsPde<T> &,
959  gsXmlTree & )
960  {
961  return NULL;
962  }
963 };
964 
965 
966 // Get a Multipatch
967 template<class T>
968 class gsXml< gsMultiPatch<T> >
969 {
970 private:
971  gsXml() { }
972  typedef gsMultiPatch<T> Object;
973 
974 public:
975  GSXML_COMMON_FUNCTIONS(Object);
976  static std::string tag () { return "MultiPatch"; }
977  static std::string type () { return ""; }
978 
979  GSXML_GET_POINTER(Object);
980 
981  static void get_into (gsXmlNode * node, Object & obj)
982  {
983  GISMO_ASSERT( !strcmp( node->name(),"MultiPatch"),
984  "Something went wrong. Expected Multipatch tag." );
985 
986  // the geometry patches should be siblings of node
987  gsXmlNode * toplevel = node->parent();
988 
989  const int d = atoi( node->first_attribute("parDim")->value() );
990 
991  gsXmlNode * tmp = node->first_node("patches");
992  std::istringstream str ;
993  str.str( tmp->value() );
994 
995  std::vector< gsGeometry<T> *> patches;
996  std::map<int,int> ids;
997  if ( ! strcmp( tmp->first_attribute("type")->value(),"id_range") )
998  {
999  int first, last;
1000  gsGetInt(str, first);
1001  gsGetInt(str, last);
1002  for ( int i = first; i<=last; ++i )
1003  {
1004  GISMO_ASSERT( searchId(i, toplevel) != NULL,
1005  "No Geometry with Id "<<i<<" found in the XML data.");
1006  patches.push_back( getById< gsGeometry<T> >( toplevel, i ) );
1007  patches.back()->setId(i);
1008  ids[i] = i - first;
1009  }
1010  }
1011  else if ( ! strcmp( tmp->first_attribute("type")->value(),"id_index") )
1012  {
1013  int c = 0;
1014  for (int pindex; gsGetInt(str, pindex);)
1015  {
1016  GISMO_ASSERT( searchId(pindex, toplevel) != NULL,
1017  "No Geometry with Id "<<pindex<<" found in the XML data.");
1018  patches.push_back( getById< gsGeometry<T> >( toplevel, pindex ) );
1019  patches.back()->setId(pindex);
1020  ids[pindex] = c++;
1021  }
1022  }
1023  else
1024  {
1025  gsWarn<<"Unknown tag in XML multipatch object.\n";
1026  }
1027 
1028 
1029  //patches: 2 0 1
1030  // before offset range: 5 3 4
1031 
1032  // Boundaries and interfaces are also 3,4,5 so we need to translate them t0 0,1,2
1033 
1034  // Read boundary
1035  std::vector< patchSide > boundaries;
1036  for (gsXmlNode * child = node->first_node("boundary"); child;
1037  child = child->next_sibling("boundary"))
1038  {
1039  std::vector< patchSide > tmp_boundaries;
1040  if (child)
1041  {
1042  getBoundaries(child, ids, tmp_boundaries);
1043  boundaries.insert( boundaries.end(), tmp_boundaries.begin(), tmp_boundaries.end() );
1044  }
1045  }
1046  // Remove duplicates (keeps the first one)
1047  std::sort(boundaries.begin(), boundaries.end());
1048  boundaries.erase(std::unique(boundaries.begin(), boundaries.end()), boundaries.end());
1049 
1050  // Read interfaces
1051  std::vector< boundaryInterface > interfaces;
1052  for (gsXmlNode * child = node->first_node("interfaces"); child;
1053  child = child->next_sibling("interfaces"))
1054  {
1055  std::vector< boundaryInterface > tmp_interfaces;
1056  if (child)
1057  {
1058  getInterfaces(child, d, ids, tmp_interfaces);
1059  interfaces.insert( interfaces.end(), tmp_interfaces.begin(), tmp_interfaces.end() );
1060  }
1061  }
1062  // Remove duplicates (keeps the first one)
1063  std::sort(interfaces.begin(), interfaces.end());
1064  interfaces.erase(std::unique(interfaces.begin(), interfaces.end()), interfaces.end());
1065 
1066 
1067  obj = gsMultiPatch<T>(patches, boundaries, interfaces);
1068  }
1069 
1070  static gsXmlNode * put (const gsMultiPatch<T> & obj,
1071  gsXmlTree & data)
1072  {
1073  // First insert all geometries
1074  int max_id = data.maxId();
1075  gsXmlNode * tmp;
1076  for ( typename gsMultiPatch<T>::const_iterator it = obj.begin();
1077  it != obj.end(); ++it )
1078  {
1079  tmp = gsXml<gsGeometry<T> >::put(**it,data);
1080  data.appendToRoot(tmp);
1081  }
1082 
1083  std::ostringstream str;
1084  str<< max_id+1 <<" "<< data.maxId();
1085  tmp = internal::makeNode("patches" , str.str(), data);
1086  tmp->append_attribute( internal::makeAttribute("type", "id_range", data) );
1087  str.clear(); str.str("");
1088 
1089  // Make MultiPatch node
1090  gsXmlNode * mp_node = internal::makeNode("MultiPatch" , data);
1091  mp_node->append_attribute( internal::makeAttribute("parDim", obj.parDim() , data) );
1092  mp_node->append_node(tmp);
1093 
1094  appendBoxTopology(obj, mp_node, data);
1095 
1096  if (obj.numBoxProperties()!=0)
1097  gsWarn<<"Multi-patch object has box properties that are not written to XML\n";
1098 
1099  return mp_node;
1100  }
1101 
1102 };
1103 
1105 template <class T>
1106 class gsXml< gsMultiBasis<T> >
1107 {
1108 private:
1109  gsXml() { }
1110  typedef gsMultiBasis<T> Object;
1111 
1112 public:
1113  GSXML_COMMON_FUNCTIONS(Object);
1114  GSXML_GET_POINTER(Object);
1115  static std::string tag() { return "MultiBasis"; }
1116  static std::string type() { return ""; }
1117 
1118  static void get_into(gsXmlNode* node, Object & result)
1119  {
1120  GISMO_ASSERT( !strcmp( node->name(), "MultiBasis" ),
1121  "Something went wrong. Expected MultiBasis tag." );
1122 
1123  gsXmlNode* topLevel = node->parent();
1124 
1125  const int d = atoi( node->first_attribute("parDim")->value() );
1126 
1127  gsXmlNode* patchNode = node->first_node("patches");
1128  std::istringstream iss;
1129  iss.str( patchNode->value() );
1130 
1131  typename gsMultiBasis<T>::BasisContainer bases;
1132  std::map<int, int> ids;
1133  if ( !strcmp( patchNode->first_attribute("type")->value(), "id_range") )
1134  {
1135  int first, last;
1136  gsGetInt(iss, first);
1137  gsGetInt(iss, last);
1138  for (int i = first; i <= last; ++i)
1139  {
1140  bases.push_back( getById< gsBasis<T> >( topLevel, i ) );
1141  ids[i] = i - first;
1142  }
1143  }
1144  else if ( !strcmp( patchNode->first_attribute("type")->value(), "id_index") )
1145  {
1146  int c = 0;
1147  for ( int pindex; gsGetInt(iss, pindex); )
1148  {
1149  bases.push_back( getById< gsBasis<T> >( topLevel, pindex ) );
1150  ids[pindex] = c++;
1151  }
1152  }
1153  else
1154  {
1155  gsWarn << "unknown tag in XML multipatch object \n";
1156  }
1157 
1158  // Read boundary
1159  std::vector< patchSide > boundaries;
1160  gsXmlNode * tmp = node->first_node("boundary");
1161  if (tmp)
1162  getBoundaries(tmp, ids, boundaries);
1163 
1164  // Read interfaces
1165  std::vector< boundaryInterface > interfaces;
1166  tmp = node->first_node("interfaces");
1167  if (tmp)
1168  getInterfaces(tmp, d, ids, interfaces);
1169 
1170  gsBoxTopology topology( d, bases.size(), boundaries, interfaces);
1171 
1172  result = gsMultiBasis<T>(bases, topology);
1173  freeAll(bases);
1174  }
1175 
1176  static gsXmlNode* put(const gsMultiBasis<T>& obj,
1177  gsXmlTree& data)
1178  {
1179  // Insert all the basis
1180  int max_id = data.maxId();
1181  for ( typename gsMultiBasis<T>::const_iterator it = obj.begin();
1182  it != obj.end(); ++it )
1183  {
1184  gsXmlNode* basisXml = gsXml< gsBasis<T> >::put(**it, data);
1185  data.appendToRoot( basisXml );
1186  }
1187 
1188  std::ostringstream oss;
1189  oss<< max_id+1 <<" "<< data.maxId();
1190  gsXmlNode* node = internal::makeNode("patches", oss.str(), data);
1191  node->append_attribute( internal::makeAttribute("type", "id_range", data) );
1192  oss.clear();
1193  oss.str("");
1194 
1195  gsXmlNode* mbNode = internal::makeNode(tag(), data);
1196  mbNode->append_attribute( internal::makeAttribute("parDim", obj.dim(), data) );
1197  mbNode->append_node(node);
1198 
1199  appendBoxTopology(obj.topology(), mbNode, data);
1200 
1201  return mbNode;
1202  }
1203 
1204 };
1205 
1206 
1208 template<class T>
1209 class gsXml< gsPlanarDomain<T> >
1210 {
1211 private:
1212  gsXml() { }
1213 public:
1214  GSXML_COMMON_FUNCTIONS(gsPlanarDomain<T>);
1215  static std::string tag () { return "PlanarDomain"; }
1216  static std::string type () { return ""; }
1217 
1218  static gsPlanarDomain<T> * get (gsXmlNode * node)
1219  {
1220  GISMO_ASSERT( !strcmp( node->name(),"PlanarDomain"),
1221  "Something went wrong. Expected PlanarDomain tag." );
1222 
1223  std::vector<gsCurveLoop<T>*> loops;
1224  for (gsXmlNode * tmp = node->first_node("CurveLoop");
1225  tmp; tmp = tmp->next_sibling("CurveLoop"))
1226  loops.push_back( gsXml<gsCurveLoop<T> >::get(tmp) ) ;
1227 
1228  return new gsPlanarDomain<T>( loops );
1229  }
1230 
1231  static gsXmlNode * put (const gsPlanarDomain<T> & obj,
1232  gsXmlTree & data )
1233  {
1234  gsXmlNode * pl = internal::makeNode("PlanarDomain", data);
1235  gsXmlNode* tmp;
1236 
1237  // get number of loops
1238  int nl = obj.numLoops();
1239 
1240  for (int i=0; i!=nl; ++i)
1241  {
1242  tmp = internal::gsXml< gsCurveLoop<T> >::put(obj.loop(i), data );
1243  tmp->append_attribute( makeAttribute("index", i, data) );
1244  pl->append_node(tmp);
1245  }
1246  return pl;
1247  }
1248 };
1249 
1251 template<class T>
1252 class gsXml< gsCurveLoop<T> >
1253 {
1254 private:
1255  gsXml() { }
1256 public:
1257  GSXML_COMMON_FUNCTIONS(gsCurveLoop<T>);
1258  static std::string tag () { return "CurveLoop"; }
1259  static std::string type () { return ""; }
1260 
1261  static gsCurveLoop<T> * get (gsXmlNode * node)
1262  {
1263  GISMO_ASSERT( !strcmp( node->name(),"CurveLoop"),
1264  "Something went wrong. Expected CurveLoop tag." );
1265 
1266  std::vector<gsCurve<T>* > curves;
1267 
1268  for (gsXmlNode * tmp = node->first_node("Geometry");
1269  tmp; tmp = tmp->next_sibling("Geometry"))
1270  curves.push_back( gsXml<gsCurve<T> >::get(tmp) ) ;
1271 
1272  return new gsCurveLoop<T>( curves );
1273  }
1274 
1275  static gsXmlNode * put (const gsCurveLoop<T> & obj,
1276  gsXmlTree & data )
1277  {
1278  gsXmlNode * cl = internal::makeNode("CurveLoop", data);
1279  gsXmlNode* tmp;
1280 
1281  // get number of curves
1282  int nc = obj.numCurves();
1283 
1284  for (int i=0; i!=nc; ++i)
1285  {
1286  tmp = internal::gsXml< gsGeometry<T> >::put(obj.curve(i), data );
1287  tmp->append_attribute( makeAttribute("index", i, data) );
1288  cl->append_node(tmp);
1289  }
1290  return cl;
1291  }
1292 };
1293 
1294 
1296 template<class T>
1297 class gsXml< gsCurveFitting<T> >
1298 {
1299 private:
1300  gsXml() { }
1301 public:
1302  GSXML_COMMON_FUNCTIONS(gsCurveFitting<T>);
1303  static std::string tag () { return "CurveFitting"; }
1304  static std::string type() { return ""; }
1305 
1306  static gsCurveFitting<T> * get (gsXmlNode * node)
1307  {
1308  GISMO_ASSERT( !strcmp( node->name(),"CurveFitting"),
1309  "Something went wrong. Expected CurveFitting tag." );
1310 
1311  bool closed = (atoi(node->first_attribute("closed")->value() ) != 0);
1312 
1313  // Read knot-vector
1314  gsXmlNode * tmp = node->first_node("KnotVector");
1315  gsKnotVector<T> * kv = gsXml< gsKnotVector<T> >::get(tmp);
1316 
1317  // Read parameter values
1318  tmp = node->first_node("Matrix");
1319  gsMatrix<T> * parval = gsXml< gsMatrix<T> >::get(tmp);
1320 
1321  // Read points
1322  tmp = tmp->next_sibling("Matrix");
1323  gsMatrix<T> * pts = gsXml< gsMatrix<T> >::get(tmp);
1324 
1325  gsCurveFitting<T> * cf = new gsCurveFitting<T>(*parval,*pts,*kv,closed);
1326  delete parval;
1327  delete pts;
1328  delete kv;
1329  return cf ;
1330  }
1331 
1332  static gsXmlNode * put (const gsCurveFitting<T> &,
1333  gsXmlTree & )
1334  {
1335  return NULL;
1336  }
1337 };
1338 
1339 
1341 template<class T>
1342 class gsXml< gsPoissonPde<T> >
1343 {
1344 private:
1345  gsXml() { }
1346 public:
1347  GSXML_COMMON_FUNCTIONS(gsPoissonPde<T>);
1348  static std::string tag () { return "Pde"; }
1349  static std::string type () { return "PoissonPde"; }
1350 
1351  static gsPoissonPde<T> * get (gsXmlNode * node)
1352  {
1353  assert( ( !strcmp( node->name(),"Pde") ) &&
1354  ( !(
1355  strcmp( node->first_attribute("type")->value(),"PoissonPde")
1356  && strcmp( node->first_attribute("type")->value(),"SurfacePoissonPde")
1357  )) );
1358 
1359  // Read the dimension
1360  GISMO_ASSERT( node->first_attribute("dim"), "xml reader: No dim found" ) ;
1361  short_t d = atoi( node->first_attribute("dim")->value() );
1362 
1363 
1364  unsigned tDim = 0;
1365  gsXmlAttribute * targetDim = node->first_attribute("targetDim");
1366 
1367  if ( targetDim )
1368  tDim = atoi( targetDim->value() );
1369 
1370  if ( tDim >= 1 )
1371  {
1372  gsXmlNode * tmp = node->first_node("rhs");
1373  gsFunctionExpr<T> rhs_fnct;
1374  internal::gsXml<gsFunctionExpr<T> >::get_into(tmp, rhs_fnct);
1375 
1376  tmp = node->first_node("solution");
1377  if ( tmp )
1378  {
1379  gsFunctionExpr<T> msol;
1380  internal::gsXml<gsFunctionExpr<T> >::get_into(tmp, msol);
1381 
1382  return new gsPoissonPde<T>(rhs_fnct, d, msol );
1383  }
1384  else
1385  {
1386  return new gsPoissonPde<T>( rhs_fnct, d );
1387  }
1388  }
1389 
1390  // Read right hand side function
1391  gsXmlNode * tmp = node->first_node("rhs");
1392  gsFunctionExpr<T> rhs(tmp->value(), d);
1393 
1394  // Read exact solution, if one exists in the file
1395  tmp = node->first_node("solution");
1396  if ( tmp )
1397  {
1398  gsFunctionExpr<T> sol(tmp->value(), d);
1399  //gsDebugVar (*sol);
1400  return new gsPoissonPde<T>(rhs, d, sol );
1401  }
1402  else
1403  {
1404  return new gsPoissonPde<T>( rhs, d );
1405  }
1406  }
1407 
1408  static gsXmlNode * put (const gsPoissonPde<T> &,
1409  gsXmlTree & )
1410  {
1411  return NULL;
1412  }
1413 
1414 };
1415 
1416 /*
1418 template<class T>
1419 class gsXml< gsSurfacePoissonPde<T> >
1420 {
1421 private:
1422  gsXml() { }
1423 public:
1424  GSXML_COMMON_FUNCTIONS(gsSurfacePoissonPde<T>);
1425  static std::string tag () { return "Pde"; }
1426  static std::string type () { return "SurfacePoissonPde"; }
1427 
1428  static gsSurfacePoissonPde<T> * get (gsXmlNode * node)
1429  {
1430  assert( ( !strcmp( node->name(),"Pde") ) &&
1431  ( !strcmp( node->first_attribute("type")->value(),"SurfacePoissonPde") ) );
1432 
1433  // Read the dimension
1434  assert( node->first_attribute("dim") ) ;
1435  unsigned d = atoi( node->first_attribute("dim")->value() );
1436 
1437  // Read right hand side function
1438  gsXmlNode * tmp = node->first_node("rhs");
1439  gsFunctionExpr<T> * rhs = new gsFunctionExpr<T>(tmp->value());
1440 
1441  // Read exact solution, if one exists in the file
1442  tmp = node->first_node("solution");
1443  if ( tmp )
1444  {
1445  gsFunctionExpr<T> * sol = new gsFunctionExpr<T>(tmp->value());
1446  //gsDebugVar (*sol);
1447  return new gsSurfacePoissonPde<T>(rhs, d, sol );
1448  }
1449  else
1450  {
1451  return new gsSurfacePoissonPde<T>( rhs, d );
1452  }
1453  }
1454 
1455  static gsXmlNode * put (const gsSurfacePoissonPde<T> & obj,
1456  gsXmlTree & data )
1457  {
1458  return NULL;
1459  }
1460 
1461 };
1462 */
1463 
1464 /*
1466 template<class T>
1467 class gsXml< gsBVProblem<T> >
1468 {
1469 private:
1470  gsXml() { }
1471 public:
1472  GSXML_COMMON_FUNCTIONS(gsBVProblem<T>);
1473  static std::string tag () { return "BVProblem"; }
1474  static std::string type() { return ""; }
1475 
1476  static gsBVProblem<T> * get (gsXmlNode * node)
1477  {
1478  GISMO_ASSERT( !strcmp( node->name(),"BVProblem"),
1479  "Something went wrong. Expected BVProblem tag." );
1480 
1481  gsBVProblem<T> * bvp;
1482 
1483  // Read the Pde
1484  gsPde<T> * pde = gsXml< gsPde<T> >::get( node->first_node("Pde") );
1485 
1486  // Read domain
1487  int domain = atoi(node->first_attribute("domain")->value() );
1488  gsXmlNode * toplevel = node->parent();// the geometry patches should be siblings of node
1489  std::string dtag; // = getTag(toplevel, domain );
1490  for (gsXmlNode * child = node->first_node();
1491  child; child = child->next_sibling() )
1492  if ( atoi(child->first_attribute("id")->value() ) == domain )
1493  {
1494  dtag = child->name();
1495  break;
1496  }
1497 
1498  if ( dtag == "Geometry" )
1499  {
1500  gsGeometry<T> * geo = getById< gsGeometry<T> >(toplevel,domain);
1501  bvp = new gsBVProblem<T>(geo, pde);
1502  }
1503  else if ( dtag == "MultiPatch" )
1504  {
1505  // to do: memory to delete?
1506  gsMultiPatch<T> * mp = getById< gsMultiPatch<T> >(toplevel,domain);
1507  bvp = new gsBVProblem<T>(*mp, pde);
1508  }
1509  else
1510  {
1511  GISMO_ERROR("Invalid tag");
1512  }
1513 
1514  // Read in boundary conditions
1515  for (gsXmlNode * child = node->first_node("bc");
1516  child; child = child->next_sibling("bc") )
1517  {
1518  gsFunctionExpr<T> * ff =
1519  new gsFunctionExpr<T>(child->first_attribute("function")->value() );
1520  std::istringstream str;
1521  str.str( child->value() );
1522 
1523  if ( !strcmp(child->first_attribute("type")->value(), "dirichlet") )
1524  {
1525  for (int side; gsGetInt(str, side);)
1526  bvp->addCondition( static_cast<boxSide>(side),
1527  condition_type::dirichlet, ff);
1528  }
1529  else if ( !strcmp(child->first_attribute("type")->value(), "neumann") )
1530  {
1531  for (int side; gsGetInt(str, side);)
1532  bvp->addCondition( static_cast<boxSide>(side),
1533  condition_type::neumann, ff);
1534  }
1535  }
1536 
1537  return bvp ;
1538  }
1539 
1540  static gsXmlNode * put (const gsBVProblem<T> & obj,
1541  gsXmlTree & data )
1542  {
1543  return NULL;
1544  }
1545 };
1546 */
1547 
1548 }// end namespace internal
1549 
1550 }// end namespace gismo
1551 
1552 //#undef GSXML_COMMON_FUNCTIONS
1553 //#undef TMPLA2
1554 //#undef TMPLA3
Describes a Poisson PDE.
Represents a NURBS basis with one parameter.
Provides declaration of FunctionExpr class.
Represents a NURBS curve/function with one parameter.
#define short_t
Definition: gsConfig.h:35
Provides structs and classes related to interfaces and boundaries.
Object * getById(gsXmlNode *node, const int &id)
Definition: gsXml.h:291
Provides declaration of MultiBasis class.
Provides interface of gsTrimSurface class. Represents a trimmed surface (= spline &quot;master surface&quot; in...
Provides declaration of THBSplineBasis class.
Provides declaration of Basis abstract interface.
#define index_t
Definition: gsConfig.h:32
Represents a tensor-product NURBS patch.
gsXmlNode * searchId(const int id, gsXmlNode *root, const char *tag_name=NULL, const bool print_warning=true)
Definition: gsXml.h:254
#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
Provides implementation of generic XML functions.
Provides declaration of THBSplineBasis class.
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
Provides declaration of the MultiPatch class.
gsXmlAttribute * makeAttribute(const std::string &name, const std::string &value, gsXmlTree &data)
Helper to allocate XML attribute.
Definition: gsXml.cpp:37
void freeAll(It begin, It end)
Frees all pointers in the range [begin end)
Definition: gsMemory.h:312
Fits a (closed) B-spline curve to some given data.
gsXmlNode * makeNode(const std::string &name, gsXmlTree &data)
Helper to allocate XML node.
Definition: gsXml.cpp:54
Provides declaration of the Mesh class.
gsXmlNode * putMatrixToXml(gsMatrix< T > const &mat, gsXmlTree &data, std::string name="Matrix")
Helper to insert matrices into XML.
Definition: gsXml.hpp:103
Provides declaration of RationalBasis class.
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
This is the main header file that collects wrappers of Eigen for linear algebra.
void appendBoxTopology(const gsBoxTopology &topology, gsXmlNode *node, gsXmlTree &data)
Appends a box topology into node, used for gsMultiPatch and gsMultiBasis.
Definition: gsXml.cpp:186
Provides declaration of gsPlanarDomain class. The outer boundary (m_loops[0]) is a loop of curves...
Provides declaration of gsSolid class, a boundary-represented solid.