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