Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
file_io_ugx_impl.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3 * Author: Sebastian Reiter
4 *
5 * This file is part of UG4.
6 *
7 * UG4 is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License version 3 (as published by the
9 * Free Software Foundation) with the following additional attribution
10 * requirements (according to LGPL/GPL v3 §7):
11 *
12 * (1) The following notice must be displayed in the Appropriate Legal Notices
13 * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 *
15 * (2) The following notice must be displayed at a prominent place in the
16 * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 *
18 * (3) The following bibliography is recommended for citation and must be
19 * preserved in all covered files:
20 * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 * parallel geometric multigrid solver on hierarchically distributed grids.
22 * Computing and visualization in science 16, 4 (2013), 151-164"
23 * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 * flexible software system for simulating pde based models on high performance
25 * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU Lesser General Public License for more details.
31 */
32
33#ifndef __H__LIB_GRID__FILE_IO_UGX_IMPL__
34#define __H__LIB_GRID__FILE_IO_UGX_IMPL__
35
36#include <sstream>
37#include <cstring>
41
42namespace ug
43{
44
46template <class TAPosition>
47bool SaveGridToUGX(Grid& grid, ISubsetHandler& sh, const char* filename,
48 TAPosition& aPos)
49{
50 GridWriterUGX ugxWriter;
51 ugxWriter.add_grid(grid, "defGrid", aPos);
52 ugxWriter.add_subset_handler(sh, "defSH", 0);
53
54 return ugxWriter.write_to_file(filename);
55};
56
58template <class TAPosition>
59bool LoadGridFromUGX(Grid& grid, SPProjectionHandler& ph, size_t& num_ph, ISubsetHandler& sh, std::vector<std::string> additionalSHNames,
60 std::vector<SmartPtr<ISubsetHandler>> ash, const char* filename, TAPosition& aPos)
61{
62 GridReaderUGX ugxReader;
63 if(!ugxReader.parse_file(filename)){
64 UG_LOG("ERROR in LoadGridFromUGX: File not found: " << filename << std::endl);
65 return false;
66 }
67
68 if(ugxReader.num_grids() < 1){
69 UG_LOG("ERROR in LoadGridFromUGX: File contains no grid.\n");
70 return false;
71 }
72
73 ugxReader.grid(grid, 0, aPos);
74
75 if(ugxReader.num_subset_handlers(0) > 0)
76 ugxReader.subset_handler(sh, 0, 0);
77
78 for(size_t i_name = 0; i_name < additionalSHNames.size(); ++i_name){
79 std::string shName = additionalSHNames[i_name];
80 for(size_t i_sh = 0; i_sh < ugxReader.num_subset_handlers(0); ++i_sh){
81 if(shName == ugxReader.get_subset_handler_name(0, i_sh)){
82 ugxReader.subset_handler(*ash[i_name], i_sh, 0);
83 }
84 }
85 }
86
87 if((num_ph = ugxReader.num_projection_handlers(0)) != 0){
88 ugxReader.projection_handler(*ph, 0, 0);
89 size_t shIndex = ugxReader.get_projection_handler_subset_handler_index(0, 0);
90 std::string shName2;
91 shName2 = std::string(ugxReader.get_subset_handler_name(0, shIndex));
92
93 if (shIndex > 0)
94 {
95 for(size_t i_name = 0; i_name < additionalSHNames.size(); ++i_name)
96 if(shName2==additionalSHNames[i_name])
97 {
98 try {ph->set_subset_handler(ash[i_name]);}
99 UG_CATCH_THROW("Additional subset handler '"<< shName2 << "' has not been added to the domain.\n"
100 "Do so by using Domain::create_additional_subset_handler(std::string name).");
101 }
102 }
103 }
104
105 return true;
106}
107
108template <class TAPosition>
109bool LoadGridFromUGX(Grid& grid, ISubsetHandler& sh, const char* filename,
110 TAPosition& aPos)
111{
112 GridReaderUGX ugxReader;
113 if(!ugxReader.parse_file(filename)){
114 UG_LOG("ERROR in LoadGridFromUGX: File not found: " << filename << std::endl);
115 return false;
116 }
117
118 if(ugxReader.num_grids() < 1){
119 UG_LOG("ERROR in LoadGridFromUGX: File contains no grid.\n");
120 return false;
121 }
122
123 ugxReader.grid(grid, 0, aPos);
124
125 if(ugxReader.num_subset_handlers(0) > 0)
126 ugxReader.subset_handler(sh, 0, 0);
127
128 return true;
129}
130
131
133template <class TPositionAttachment>
135add_grid(Grid& grid, const char* name,
136 TPositionAttachment& aPos)
137{
138 using namespace rapidxml;
139 using namespace std;
140// access node data
141 if(!grid.has_vertex_attachment(aPos)){
142 UG_LOG(" position attachment missing in grid " << name << endl);
143 return false;
144 }
145
147
148// create a new grid-node
149 xml_node<>* gridNode = m_doc.allocate_node(node_element, "grid");
150 gridNode->append_attribute(m_doc.allocate_attribute("name", name));
151
152// store the grid and the node in an entry
153 m_vEntries.push_back(Entry(&grid, gridNode));
154
155// append it to the document
156 m_doc.append_node(gridNode);
157
158// initialize the grids attachments
160
161// access indices
164
165// write vertices
166 if(grid.num<RegularVertex>() > 0)
167 gridNode->append_node(create_vertex_node(grid.begin<RegularVertex>(),
168 grid.end<RegularVertex>(), aaPos));
169
170// write constrained vertices
171 if(grid.num<ConstrainedVertex>() > 0)
172 gridNode->append_node(create_constrained_vertex_node(
173 grid.begin<ConstrainedVertex>(),
174 grid.end<ConstrainedVertex>(),
175 aaPos, aaIndEDGE, aaIndFACE));
176
177// add the remaining grid elements to the nodes
178 add_elements_to_node(gridNode, grid);
179
180 process_global_attachments<Vertex>(grid, gridNode);
181 process_global_attachments<Edge>(grid, gridNode);
182 process_global_attachments<Face>(grid, gridNode);
183 process_global_attachments<Volume>(grid, gridNode);
184
185 return true;
186}
187
188//template <class TPositionAttachment>
189//void GridWriterUGX::
190//add_grid(MultiGrid& mg, const char* name,
191// TPositionAttachment& aPos)
192//{
193//}
194
195template <class TElem>
198{
199 static const char* attachmentNodeNames[4] = {"vertex_attachment",
200 "edge_attachment",
201 "face_attachment",
202 "volume_attachment"};
203 return attachmentNodeNames[TElem::BASE_OBJECT_ID];
204}
205
206
207template <class TElem, class TAttachment>
209add_attachment(TAttachment attachment,
210 const char* name,
211 size_t refGridIndex)
212{
213 using namespace rapidxml;
214 using namespace std;
215
216 UG_COND_THROW(refGridIndex >= m_vEntries.size(),
217 "Invalid refGridIndex: " << refGridIndex
218 << ", but only " << m_vEntries.size() << " grids available.");
219
220 Grid& grid = *m_vEntries[refGridIndex].grid;
221 stringstream ss;
222
223 if(!grid.has_attachment<TElem>(attachment))
224 return;
225
226 Grid::AttachmentAccessor<TElem, TAttachment> aaVal(grid, attachment);
227
228 const typename Grid::traits<TElem>::iterator iterEnd = grid.end<TElem>();
229 for(typename Grid::traits<TElem>::iterator iter = grid.begin<TElem>();
230 iter != iterEnd;)
231 {
233 UG_COND_THROW(!ss, "Failed to write attachment entry.\n");
234 ++iter;
235 if(iter != iterEnd)
236 ss << " ";
237 }
238
239// create the node
240 xml_node<>* node = m_doc.allocate_node(
241 node_element,
242 attachment_node_name<TElem>(),
243 m_doc.allocate_string(ss.str().c_str()));
244
245// attributes
246 node->append_attribute(
247 m_doc.allocate_attribute(
248 "name",
249 m_doc.allocate_string(name)));
250
251 node->append_attribute(
252 m_doc.allocate_attribute(
253 "type",
254 m_doc.allocate_string(
256
257//todo: only default pass-on is stored, not the actual used one!
258 node->append_attribute(
259 m_doc.allocate_attribute(
260 "passOn",
261 m_doc.allocate_string(mkstr(int(attachment.default_pass_on_behaviour())).c_str())));
262
263 m_vEntries[refGridIndex].node->append_node(node);
264}
265
266
267template <class TAAPos>
268rapidxml::xml_node<>*
271 RegularVertexIterator vrtsEnd,
272 TAAPos& aaPos)
273{
274 using namespace rapidxml;
275 using namespace std;
276// the number of coordinates
277 const int numCoords = (int)TAAPos::ValueType::Size;
278
279// write the vertices to a temporary stream
280 stringstream ss;
281 ss.precision(18);
282 for(RegularVertexIterator iter = vrtsBegin; iter != vrtsEnd; ++iter)
283 {
284 for(int i = 0; i < numCoords; ++i)
285 ss << aaPos[*iter][i] << " ";
286 }
287
288// create the node
289 xml_node<>* node = NULL;
290
291 if(ss.str().size() > 0){
292 // allocate a string and erase last character(' ')
293 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
294 nodeData[ss.str().size()-1] = 0;
295 // create a node with some data
296 node = m_doc.allocate_node(node_element, "vertices", nodeData);
297 }
298 else{
299 // create an emtpy node
300 node = m_doc.allocate_node(node_element, "vertices");
301 }
302
303 char* buff = m_doc.allocate_string(NULL, 10);
304 snprintf(buff, 10, "%d", numCoords);
305 node->append_attribute(m_doc.allocate_attribute("coords", buff));
306
307// return the node
308 return node;
309}
310
311template <class TAAPos>
312rapidxml::xml_node<>*
316 TAAPos& aaPos,
317 AAEdgeIndex aaIndEDGE,
318 AAFaceIndex aaIndFACE)
319{
320 using namespace rapidxml;
321 using namespace std;
322// the number of coordinates
323 const int numCoords = (int)TAAPos::ValueType::Size;
324
325// write the vertices to a temporary stream
326 stringstream ss;
327 ss.precision(18);
328 for(ConstrainedVertexIterator iter = vrtsBegin; iter != vrtsEnd; ++iter)
329 {
330 for(int i = 0; i < numCoords; ++i)
331 ss << aaPos[*iter][i] << " ";
332
333 // write index and local coordinate of associated constraining element
334 // codes: -1: no constraining element
335 // 0: vertex. index follows (not yet supported)
336 // 1: edge. index and 1 local coordinate follow.
337 // 2: face. index and 2 local coordinates follow.
338 // 3: volume. index and 3 local coordinates follow. (not yet supported)
339 Edge* ce = dynamic_cast<Edge*>((*iter)->get_constraining_object());
340 Face* cf = dynamic_cast<Face*>((*iter)->get_constraining_object());
341 if(ce)
342 ss << "1 " << aaIndEDGE[ce] << " " << (*iter)->get_local_coordinate_1() << " ";
343 else if(cf)
344 ss << "2 " << aaIndFACE[cf] << " " << (*iter)->get_local_coordinate_1()
345 << " " << (*iter)->get_local_coordinate_2() << " ";
346 else
347 ss << "-1 ";
348 }
349
350// create the node
351 xml_node<>* node = NULL;
352
353 if(ss.str().size() > 0){
354 // allocate a string and erase last character(' ')
355 char* nodeData = m_doc.allocate_string(ss.str().c_str(), ss.str().size());
356 nodeData[ss.str().size()-1] = 0;
357 // create a node with some data
358 node = m_doc.allocate_node(node_element, "constrained_vertices", nodeData);
359 }
360 else{
361 // create an emtpy node
362 node = m_doc.allocate_node(node_element, "constrained_vertices");
363 }
364
365 char* buff = m_doc.allocate_string(NULL, 10);
366 snprintf(buff, 10, "%d", numCoords);
367 node->append_attribute(m_doc.allocate_attribute("coords", buff));
368
369// return the node
370 return node;
371}
372
373
374template <class TElem>
376process_global_attachments(Grid& grid, rapidxml::xml_node<>* gridNode)
377{
378 using namespace std;
379 using namespace rapidxml;
380 const vector<string>& attachmentNames = GlobalAttachments::declared_attachment_names();
381
382 for(size_t ia = 0; ia < attachmentNames.size(); ++ia){
383 const std::string& name = attachmentNames[ia];
384 if(!GlobalAttachments::is_attached<TElem>(grid, name))
385 continue;
386
387 stringstream ss;
388 GlobalAttachments::write_attachment_values<TElem>(ss, grid, name);
389
390 // create the node
391 xml_node<>* node = m_doc.allocate_node(
392 node_element,
393 attachment_node_name<TElem>(),
394 m_doc.allocate_string(ss.str().c_str()));
395
396 // attributes
397 node->append_attribute(
398 m_doc.allocate_attribute(
399 "name",
400 m_doc.allocate_string(name.c_str())));
401
402 node->append_attribute(
403 m_doc.allocate_attribute(
404 "type",
405 m_doc.allocate_string(
407
408 node->append_attribute(
409 m_doc.allocate_attribute(
410 "passOn",
411 m_doc.allocate_string(mkstr(int(
413
414 node->append_attribute(
415 m_doc.allocate_attribute(
416 "global",
417 m_doc.allocate_string("1")));
418
419 gridNode->append_node(node);
420 }
421}
422
423
426// implementation of GridReaderUGX
427template <class TPositionAttachment>
429grid(Grid& gridOut, size_t index,
430 TPositionAttachment& aPos)
431{
432 using namespace rapidxml;
433 using namespace std;
434
435// make sure that a node at the given index exists
436 if(num_grids() <= index){
437 UG_LOG(" GridReaderUGX::read: bad grid index!\n");
438 return false;
439 }
440
441 Grid& grid = gridOut;
442
443// Since we have to create all elements in the correct order and
444// since we have to make sure that no elements are created in between,
445// we'll first disable all grid-options and reenable them later on
446 uint gridopts = grid.get_options();
447 grid.set_options(GRIDOPT_NONE);
448
449// access node data
450 if(!grid.has_vertex_attachment(aPos)){
451 grid.attach_to_vertices(aPos);
452 }
453
455
456// store the grid in the grid-vector and assign indices to the vertices
457 m_entries[index].grid = &grid;
458
459// get the grid-node and the vertex-vector
460 xml_node<>* gridNode = m_entries[index].node;
461 vector<Vertex*>& vertices = m_entries[index].vertices;
462 vector<Edge*>& edges = m_entries[index].edges;
463 vector<Face*>& faces = m_entries[index].faces;
464 vector<Volume*>& volumes = m_entries[index].volumes;
465
466// we'll record constraining objects for constrained-vertices and constrained-edges
467 std::vector<std::pair<int, int> > constrainingObjsVRT;
468 std::vector<std::pair<int, int> > constrainingObjsEDGE;
469 std::vector<std::pair<int, int> > constrainingObjsTRI;
470 std::vector<std::pair<int, int> > constrainingObjsQUAD;
471
472// iterate through the nodes in the grid and create the entries
473 xml_node<>* curNode = gridNode->first_node();
474 for(;curNode; curNode = curNode->next_sibling()){
475 bool bSuccess = true;
476 const char* name = curNode->name();
477 if(strcmp(name, "vertices") == 0)
478 bSuccess = create_vertices(vertices, grid, curNode, aaPos);
479 else if(strcmp(name, "constrained_vertices") == 0)
480 bSuccess = create_constrained_vertices(vertices, constrainingObjsVRT,
481 grid, curNode, aaPos);
482 else if(strcmp(name, "edges") == 0)
483 bSuccess = create_edges(edges, grid, curNode, vertices);
484 else if(strcmp(name, "constraining_edges") == 0)
485 bSuccess = create_constraining_edges(edges, grid, curNode, vertices);
486 else if(strcmp(name, "constrained_edges") == 0)
487 bSuccess = create_constrained_edges(edges, constrainingObjsEDGE,
488 grid, curNode, vertices);
489 else if(strcmp(name, "triangles") == 0)
490 bSuccess = create_triangles(faces, grid, curNode, vertices);
491 else if(strcmp(name, "constraining_triangles") == 0)
492 bSuccess = create_constraining_triangles(faces, grid, curNode, vertices);
493 else if(strcmp(name, "constrained_triangles") == 0)
494 bSuccess = create_constrained_triangles(faces, constrainingObjsTRI,
495 grid, curNode, vertices);
496 else if(strcmp(name, "quadrilaterals") == 0)
497 bSuccess = create_quadrilaterals(faces, grid, curNode, vertices);
498 else if(strcmp(name, "constraining_quadrilaterals") == 0)
499 bSuccess = create_constraining_quadrilaterals(faces, grid, curNode, vertices);
500 else if(strcmp(name, "constrained_quadrilaterals") == 0)
501 bSuccess = create_constrained_quadrilaterals(faces, constrainingObjsQUAD,
502 grid, curNode, vertices);
503 else if(strcmp(name, "tetrahedrons") == 0)
504 bSuccess = create_tetrahedrons(volumes, grid, curNode, vertices);
505 else if(strcmp(name, "hexahedrons") == 0)
506 bSuccess = create_hexahedrons(volumes, grid, curNode, vertices);
507 else if(strcmp(name, "prisms") == 0)
508 bSuccess = create_prisms(volumes, grid, curNode, vertices);
509 else if(strcmp(name, "pyramids") == 0)
510 bSuccess = create_pyramids(volumes, grid, curNode, vertices);
511 else if(strcmp(name, "octahedrons") == 0)
512 bSuccess = create_octahedrons(volumes, grid, curNode, vertices);
513
514 else if(strcmp(name, "vertex_attachment") == 0)
515 bSuccess = read_attachment<Vertex>(grid, curNode);
516 else if(strcmp(name, "edge_attachment") == 0)
517 bSuccess = read_attachment<Edge>(grid, curNode);
518 else if(strcmp(name, "face_attachment") == 0)
519 bSuccess = read_attachment<Face>(grid, curNode);
520 else if(strcmp(name, "volume_attachment") == 0)
521 bSuccess = read_attachment<Volume>(grid, curNode);
522
523
524 if(!bSuccess){
525 grid.set_options(gridopts);
526 return false;
527 }
528 }
529
530// resolve constrained object relations
531 if(!constrainingObjsVRT.empty()){
532 //UG_LOG("num-edges: " << edges.size() << std::endl);
533 // iterate over the pairs.
534 // at the same time we'll iterate over the constrained vertices since
535 // they are synchronized.
537 for(std::vector<std::pair<int, int> >::iterator iter = constrainingObjsVRT.begin();
538 iter != constrainingObjsVRT.end(); ++iter, ++hvIter)
539 {
540 ConstrainedVertex* hv = *hvIter;
541
542 switch(iter->first){
543 case 1: // constraining object is an edge
544 {
545 // make sure that the index is valid
546 if(iter->second >= 0 && iter->second < (int)edges.size()){
547 // get the edge
548 ConstrainingEdge* edge = dynamic_cast<ConstrainingEdge*>(edges[iter->second]);
549 if(edge){
550 hv->set_constraining_object(edge);
551 edge->add_constrained_object(hv);
552 }
553 else{
554 UG_LOG("WARNING: Type-ID / type mismatch. Ignoring edge " << iter->second << ".\n");
555 }
556 }
557 else{
558 UG_LOG("ERROR in GridReaderUGX: Bad edge index in constrained vertex: " << iter->second << "\n");
559 }
560 }break;
561
562 case 2: // constraining object is an face
563 {
564 // make sure that the index is valid
565 if(iter->second >= 0 && iter->second < (int)faces.size()){
566 // get the edge
567 ConstrainingFace* face = dynamic_cast<ConstrainingFace*>(faces[iter->second]);
568 if(face){
569 hv->set_constraining_object(face);
570 face->add_constrained_object(hv);
571 }
572 else{
573 UG_LOG("WARNING in GridReaderUGX: Type-ID / type mismatch. Ignoring face " << iter->second << ".\n");
574 }
575 }
576 else{
577 UG_LOG("ERROR in GridReaderUGX: Bad face index in constrained vertex: " << iter->second << "\n");
578 }
579 }break;
580
581 default:
582 {
583// UG_LOG("WARNING in GridReaderUGX: unsupported type-id of constraining vertex"
584// << " at " << GetGridObjectCenter(grid, hv) << "\n");
585 break;
586 }
587 }
588 }
589 }
590
591 if(!constrainingObjsEDGE.empty()){
592 // iterate over the pairs.
593 // at the same time we'll iterate over the constrained vertices since
594 // they are synchronized.
596 for(std::vector<std::pair<int, int> >::iterator iter = constrainingObjsEDGE.begin();
597 iter != constrainingObjsEDGE.end(); ++iter, ++ceIter)
598 {
599 ConstrainedEdge* ce = *ceIter;
600
601 switch(iter->first){
602 case 1: // constraining object is an edge
603 {
604 // make sure that the index is valid
605 if(iter->second >= 0 && iter->second < (int)edges.size()){
606 // get the edge
607 ConstrainingEdge* edge = dynamic_cast<ConstrainingEdge*>(edges[iter->second]);
608 if(edge){
609 ce->set_constraining_object(edge);
610 edge->add_constrained_object(ce);
611 }
612 else{
613 UG_LOG("WARNING in GridReaderUGX: Type-ID / type mismatch. Ignoring edge " << iter->second << ".\n");
614 }
615 }
616 else{
617 UG_LOG("ERROR in GridReaderUGX: Bad edge index in constrained edge.\n");
618 }
619 }break;
620 case 2: // constraining object is an face
621 {
622 // make sure that the index is valid
623 if(iter->second >= 0 && iter->second < (int)faces.size()){
624 // get the edge
625 ConstrainingFace* face = dynamic_cast<ConstrainingFace*>(faces[iter->second]);
626 if(face){
627 ce->set_constraining_object(face);
628 face->add_constrained_object(ce);
629 }
630 else{
631 UG_LOG("WARNING in GridReaderUGX: Type-ID / type mismatch. Ignoring face " << iter->second << ".\n");
632 }
633 }
634 else{
635 UG_LOG("ERROR in GridReaderUGX: Bad face index in constrained edge: " << iter->second << "\n");
636 }
637 }break;
638
639 default:
640 {
641// UG_LOG("WARNING in GridReaderUGX: unsupported type-id of constraining edge"
642// << " at " << GetGridObjectCenter(grid, ce) << "\n");
643 break;
644 }
645 }
646 }
647 }
648
649 if(!constrainingObjsTRI.empty()){
650 // iterate over the pairs.
651 // at the same time we'll iterate over the constrained vertices since
652 // they are synchronized.
654 for(std::vector<std::pair<int, int> >::iterator iter = constrainingObjsTRI.begin();
655 iter != constrainingObjsTRI.end(); ++iter, ++cfIter)
656 {
657 ConstrainedFace* cdf = *cfIter;
658
659 switch(iter->first){
660 case 2: // constraining object is an face
661 {
662 // make sure that the index is valid
663 if(iter->second >= 0 && iter->second < (int)faces.size()){
664 // get the edge
665 ConstrainingFace* face = dynamic_cast<ConstrainingFace*>(faces[iter->second]);
666 if(face){
667 cdf->set_constraining_object(face);
668 face->add_constrained_object(cdf);
669 }
670 else{
671 UG_LOG("WARNING in GridReaderUGX: Type-ID / type mismatch. Ignoring face " << iter->second << ".\n");
672 }
673 }
674 else{
675 UG_LOG("ERROR in GridReaderUGX: Bad face index in constrained face: " << iter->second << "\n");
676 }
677 }break;
678
679 default:
680 {
681// UG_LOG("WARNING in GridReaderUGX: unsupported type-id of constraining triangle"
682// << " at " << GetGridObjectCenter(grid, cdf) << "\n");
683 break;
684 }
685 }
686 }
687 }
688
689 if(!constrainingObjsQUAD.empty()){
690 // iterate over the pairs.
691 // at the same time we'll iterate over the constrained vertices since
692 // they are synchronized.
694 for(std::vector<std::pair<int, int> >::iterator iter = constrainingObjsQUAD.begin();
695 iter != constrainingObjsQUAD.end(); ++iter, ++cfIter)
696 {
697 ConstrainedFace* cdf = *cfIter;
698
699 switch(iter->first){
700 case 2: // constraining object is an face
701 {
702 // make sure that the index is valid
703 if(iter->second >= 0 && iter->second < (int)faces.size()){
704 // get the edge
705 ConstrainingFace* face = dynamic_cast<ConstrainingFace*>(faces[iter->second]);
706 if(face){
707 cdf->set_constraining_object(face);
708 face->add_constrained_object(cdf);
709 }
710 else{
711 UG_LOG("WARNING in GridReaderUGX: Type-ID / type mismatch. Ignoring face " << iter->second << ".\n");
712 }
713 }
714 else{
715 UG_LOG("ERROR in GridReaderUGX: Bad face index in constrained face: " << iter->second << "\n");
716 }
717 }break;
718
719 default:
720 {
721// UG_LOG("WARNING in GridReaderUGX: unsupported type-id of constraining quadrilateral"
722// << " at " << GetGridObjectCenter(grid, cdf) << "\n");
723 break;
724 }
725 }
726 }
727 }
728
729// reenable the grids options.
730 grid.set_options(gridopts);
731
732 return true;
733}
734
735template <class TAAPos>
737create_vertices(std::vector<Vertex*>& vrtsOut, Grid& grid,
738 rapidxml::xml_node<>* vrtNode, TAAPos aaPos)
739{
740 using namespace rapidxml;
741 using namespace std;
742
743 int numSrcCoords = -1;
744 xml_attribute<>* attrib = vrtNode->first_attribute("coords");
745 if(attrib)
746 numSrcCoords = atoi(attrib->value());
747
748 int numDestCoords = (int)TAAPos::ValueType::Size;
749
750 assert(numDestCoords > 0 && "bad position attachment type");
751
752 if(numSrcCoords < 1 || numDestCoords < 1)
753 return false;
754
755// create a buffer with which we can access the data
756 string str(vrtNode->value(), vrtNode->value_size());
757 stringstream ss(str, ios_base::in);
758
759// if numDestCoords == numSrcCoords parsing will be faster
760 if(numSrcCoords == numDestCoords){
761 while(!ss.eof()){
762 // read the data
763 typename TAAPos::ValueType v;
764
765 for(int i = 0; i < numSrcCoords; ++i)
766 ss >> v[i];
767
768 // make sure that everything went right
769 if(ss.fail())
770 break;
771
772 // create a new vertex
773 RegularVertex* vrt = *grid.create<RegularVertex>();
774 vrtsOut.push_back(vrt);
775
776 // set the coordinates
777 aaPos[vrt] = v;
778 }
779 }
780 else{
781 // we have to be careful with reading.
782 // if numDestCoords < numSrcCoords we'll ignore some coords,
783 // in the other case we'll add some 0's.
784 int minNumCoords = min(numSrcCoords, numDestCoords);
785 typename TAAPos::ValueType::value_type dummy = 0;
786
787 while(!ss.eof()){
788 // read the data
789 typename TAAPos::ValueType v;
790
791 int iMin;
792 for(iMin = 0; iMin < minNumCoords; ++iMin)
793 ss >> v[iMin];
794
795 // ignore unused entries in the input buffer
796 for(int i = iMin; i < numSrcCoords; ++i)
797 ss >> dummy;
798
799 // add 0's to the vector
800 for(int i = iMin; i < numDestCoords; ++i)
801 v[i] = 0;
802
803 // make sure that everything went right
804 if(ss.fail())
805 break;
806
807 // create a new vertex
808 RegularVertex* vrt = *grid.create<RegularVertex>();
809 vrtsOut.push_back(vrt);
810
811 // set the coordinates
812 aaPos[vrt] = v;
813 }
814 }
815
816 return true;
817}
818
819template <class TAAPos>
821create_constrained_vertices(std::vector<Vertex*>& vrtsOut,
822 std::vector<std::pair<int, int> >& constrainingObjsOut,
823 Grid& grid, rapidxml::xml_node<>* vrtNode, TAAPos aaPos)
824{
825 using namespace rapidxml;
826 using namespace std;
827
828 int numSrcCoords = -1;
829 xml_attribute<>* attrib = vrtNode->first_attribute("coords");
830 if(attrib)
831 numSrcCoords = atoi(attrib->value());
832
833 int numDestCoords = (int)TAAPos::ValueType::Size;
834
835 assert(numDestCoords > 0 && "bad position attachment type");
836
837 if(numSrcCoords < 1 || numDestCoords < 1)
838 return false;
839
840// create a buffer with which we can access the data
841 string str(vrtNode->value(), vrtNode->value_size());
842 stringstream ss(str, ios_base::in);
843
844// we have to be careful with reading.
845// if numDestCoords < numSrcCoords we'll ignore some coords,
846// in the other case we'll add some 0's.
847 int minNumCoords = min(numSrcCoords, numDestCoords);
848 typename TAAPos::ValueType::value_type dummy = 0;
849
850//todo: speed could be improved, if dest and src position types have the same dimension
851 while(!ss.eof()){
852 // read the data
853 typename TAAPos::ValueType v;
854
855 int iMin;
856 for(iMin = 0; iMin < minNumCoords; ++iMin)
857 ss >> v[iMin];
858
859 // ignore unused entries in the input buffer
860 for(int i = iMin; i < numSrcCoords; ++i)
861 ss >> dummy;
862
863 // add 0's to the vector
864 for(int i = iMin; i < numDestCoords; ++i)
865 v[i] = 0;
866
867 // now read the type of the constraining object and its index
868 int conObjType = -1;
869 int conObjIndex = -1;
870 ss >> conObjType;
871
872 if(conObjType != -1)
873 ss >> conObjIndex;
874
875 // depending on the constrainings object type, we'll read local coordinates
876 vector3 localCoords(0, 0, 0);
877 switch(conObjType){
878 case 1: // an edge. read one local coord
879 ss >> localCoords.x();
880 break;
881 case 2: // a face. read two local coords
882 ss >> localCoords.x() >> localCoords.y();
883 break;
884 default:
885 break;
886 }
887
888 // make sure that everything went right
889 if(ss.fail())
890 break;
891
892 // create a new vertex
893 ConstrainedVertex* vrt = *grid.create<ConstrainedVertex>();
894 vrtsOut.push_back(vrt);
895
896 // set the coordinates
897 aaPos[vrt] = v;
898
899 // set local coordinates
900 vrt->set_local_coordinates(localCoords.x(), localCoords.y());
901
902 // add the constraining object id and index to the list
903 constrainingObjsOut.push_back(std::make_pair(conObjType, conObjIndex));
904 }
905
906 return true;
907}
908
909
910template <class TElem>
912read_attachment(Grid& grid, rapidxml::xml_node<>* node)
913{
914 using namespace rapidxml;
915 using namespace std;
916
917 xml_attribute<>* attribName = node->first_attribute("name");
918 UG_COND_THROW(!attribName, "Invalid attachment entry: No 'name' attribute was supplied!");
919 string name = attribName->value();
920
921 xml_attribute<>* attribType = node->first_attribute("type");
922 UG_COND_THROW(!attribType, "Invalid attachment entry: No 'type' attribute was supplied!");
923 string type = attribType->value();
924
925 bool global = false;
926 if (xml_attribute<>* attrib = node->first_attribute("global")){
927 global = bool(atoi(attrib->value()));
928 }
929
930 bool passOn = false;
931 if (xml_attribute<>* attrib = node->first_attribute("passOn")){
932 passOn = bool(atoi(attrib->value()));
933 }
934
935 if(global && !GlobalAttachments::is_declared(name)){
938 // GlobalAttachments::mark_attachment_as_locally_declared(name);
939 }
940 else
941 return true;
942 }
943
945 "Attachment type mismatch. Expecting type: " <<
947 << ", but given type is: " << type);
948
949 string str(node->value(), node->value_size());
950 stringstream ss(str, ios_base::in);
951 GlobalAttachments::read_attachment_values<TElem>(ss, grid, name);
952
953 return true;
954}
955
956}// end of namespace
957
958#endif
location name
Definition checkpoint_util.lua:128
Definition smart_pointer.h:108
This edge is a sub-edge of a.
Definition grid_objects_1d.h:146
void set_constraining_object(GridObject *pObj)
Definition grid_objects_1d.h:218
This class stores the constraining object.
Definition grid_objects_2d.h:383
void set_constraining_object(GridObject *pObj)
Definition grid_objects_2d.h:395
a quadrilateral constrained by another object.
Definition grid_objects_2d.h:501
a triangle constrained by another object.
Definition grid_objects_2d.h:440
A vertex appearing on edges or faces.
Definition grid_objects_0d.h:110
void set_constraining_object(GridObject *constrObj)
Definition grid_objects_0d.h:143
void set_local_coordinates(number x, number y)
Definition grid_objects_0d.h:167
contains elements of type
Definition grid_objects_1d.h:279
void add_constrained_object(Vertex *pObj)
Definition grid_objects_1d.h:353
This class is used to store constrained geometric objects.
Definition grid_objects_2d.h:562
void add_constrained_object(Vertex *pObj)
Definition grid_objects_2d.h:584
Base-class for edges.
Definition grid_base_objects.h:397
Faces are 2-dimensional objects.
Definition grid_base_objects.h:510
static const char * type_name(const std::string &name)
Definition global_attachments.h:213
static bool type_is_registered(const std::string &typeName)
Definition global_attachments.h:124
static bool attachment_pass_on_behaviour(const std::string &name)
Definition global_attachments.h:117
static void declare_attachment(const std::string &name, bool passOnBehaviour=false)
Definition global_attachments.h:47
static bool is_declared(const std::string &name)
Definition global_attachments.h:111
static const std::vector< std::string > & declared_attachment_names()
Definition global_attachments.h:105
the generic attachment-accessor for access to grids attachment pipes.
Definition grid.h:182
Manages the elements of a grid and their interconnection.
Definition grid.h:132
size_t num() const
Definition grid_impl.hpp:230
bool has_attachment(IAttachment &attachment)
Definition grid.h:796
geometry_traits< TGeomObj >::iterator begin()
Definition grid_impl.hpp:164
bool has_vertex_attachment(IAttachment &attachment)
Definition grid.h:798
geometry_traits< TGeomObj >::iterator end()
Definition grid_impl.hpp:175
uint get_options() const
Definition grid.cpp:706
Grants read access to ugx files.
Definition file_io_ugx.h:301
bool create_hexahedrons(std::vector< Volume * > &volsOut, Grid &grid, rapidxml::xml_node<> *node, std::vector< Vertex * > &vrts)
Definition file_io_ugx.cpp:1782
bool parse_file(const char *filename)
parses an xml file
Definition file_io_ugx.cpp:1304
bool projection_handler(ProjectionHandler &phOut, size_t phIndex, size_t refGridIndex)
fills the given projection-handler
Definition file_io_ugx.cpp:1266
size_t num_projection_handlers(size_t refGridIndex) const
returns the number of projection-handlers for the given grid
Definition file_io_ugx.cpp:1196
bool create_vertices(std::vector< Vertex * > &vrtsOut, Grid &grid, rapidxml::xml_node<> *vrtNode, TAAPos aaPos)
creates vertices from a vertex-node.
Definition file_io_ugx_impl.hpp:737
bool create_constrained_vertices(std::vector< Vertex * > &vrtsOut, std::vector< std::pair< int, int > > &constrainingObjsOut, Grid &grid, rapidxml::xml_node<> *vrtNode, TAAPos aaPos)
Definition file_io_ugx_impl.hpp:821
size_t num_grids() const
returns the number of grids
Definition file_io_ugx.h:310
bool create_constraining_edges(std::vector< Edge * > &edgesOut, Grid &grid, rapidxml::xml_node<> *node, std::vector< Vertex * > &vrts)
Definition file_io_ugx.cpp:1408
bool read_attachment(Grid &grid, rapidxml::xml_node<> *node)
Definition file_io_ugx_impl.hpp:912
bool create_constrained_edges(std::vector< Edge * > &edgesOut, std::vector< std::pair< int, int > > &constrainingObjsOut, Grid &grid, rapidxml::xml_node<> *node, std::vector< Vertex * > &vrts)
Definition file_io_ugx.cpp:1443
bool create_tetrahedrons(std::vector< Volume * > &volsOut, Grid &grid, rapidxml::xml_node<> *node, std::vector< Vertex * > &vrts)
Definition file_io_ugx.cpp:1743
bool create_constrained_quadrilaterals(std::vector< Face * > &facesOut, std::vector< std::pair< int, int > > &constrainingObjsOut, Grid &grid, rapidxml::xml_node<> *node, std::vector< Vertex * > &vrts)
Definition file_io_ugx.cpp:1691
bool create_octahedrons(std::vector< Volume * > &volsOut, Grid &grid, rapidxml::xml_node<> *node, std::vector< Vertex * > &vrts)
Definition file_io_ugx.cpp:1906
bool create_edges(std::vector< Edge * > &edgesOut, Grid &grid, rapidxml::xml_node<> *node, std::vector< Vertex * > &vrts)
Definition file_io_ugx.cpp:1372
bool create_constraining_triangles(std::vector< Face * > &facesOut, Grid &grid, rapidxml::xml_node<> *node, std::vector< Vertex * > &vrts)
Definition file_io_ugx.cpp:1527
size_t get_projection_handler_subset_handler_index(size_t phIndex, size_t refGridIndex)
returns the subset handler index for a projection handler
Definition file_io_ugx.cpp:1221
bool create_constrained_triangles(std::vector< Face * > &facesOut, std::vector< std::pair< int, int > > &constrainingObjsOut, Grid &grid, rapidxml::xml_node<> *node, std::vector< Vertex * > &vrts)
Definition file_io_ugx.cpp:1564
bool create_pyramids(std::vector< Volume * > &volsOut, Grid &grid, rapidxml::xml_node<> *node, std::vector< Vertex * > &vrts)
Definition file_io_ugx.cpp:1866
const char * get_subset_handler_name(size_t refGridIndex, size_t subsetHandlerIndex) const
returns the name of the given subset handler
Definition file_io_ugx.cpp:957
bool subset_handler(ISubsetHandler &shOut, size_t subsetHandlerIndex, size_t refGridIndex)
fills the given subset-handler
Definition file_io_ugx.cpp:970
bool create_constraining_quadrilaterals(std::vector< Face * > &facesOut, Grid &grid, rapidxml::xml_node<> *node, std::vector< Vertex * > &vrts)
Definition file_io_ugx.cpp:1651
bool create_prisms(std::vector< Volume * > &volsOut, Grid &grid, rapidxml::xml_node<> *node, std::vector< Vertex * > &vrts)
Definition file_io_ugx.cpp:1825
bool create_quadrilaterals(std::vector< Face * > &facesOut, Grid &grid, rapidxml::xml_node<> *node, std::vector< Vertex * > &vrts)
Definition file_io_ugx.cpp:1612
size_t num_subset_handlers(size_t refGridIndex) const
returns the number of subset handlers for the given grid
Definition file_io_ugx.cpp:945
bool grid(Grid &gridOut, size_t index, TPositionAttachment &aPos)
returns the i-th grid.
Definition file_io_ugx_impl.hpp:429
bool create_triangles(std::vector< Face * > &facesOut, Grid &grid, rapidxml::xml_node<> *node, std::vector< Vertex * > &vrts)
Definition file_io_ugx.cpp:1490
std::vector< GridEntry > m_entries
holds grids which already have been created
Definition file_io_ugx.h:493
Grants write access to ugx files.
Definition file_io_ugx.h:108
rapidxml::xml_document m_doc
the xml_document which stores the data
Definition file_io_ugx.h:283
void add_elements_to_node(rapidxml::xml_node<> *node, Grid &grid)
adds grid elements (edges, faces, volumes) to the given node.
Definition file_io_ugx.cpp:424
void add_attachment(TAttachment attachment, const char *name, size_t refGridIndex)
Definition file_io_ugx_impl.hpp:209
void process_global_attachments(Grid &grid, rapidxml::xml_node<> *gridNode)
Definition file_io_ugx_impl.hpp:376
std::vector< Entry > m_vEntries
List of accessible grids.
Definition file_io_ugx.h:286
rapidxml::xml_node * create_constrained_vertex_node(ConstrainedVertexIterator vrtsBegin, ConstrainedVertexIterator vrtsEnd, TAAPos &aaPos, AAEdgeIndex aaIndEDGE, AAFaceIndex aaIndFACE)
Definition file_io_ugx_impl.hpp:314
const char * attachment_node_name()
Definition file_io_ugx_impl.hpp:197
AInt m_aInt
attached to vertices of each grid during add_grid.
Definition file_io_ugx.h:289
rapidxml::xml_node * create_vertex_node(RegularVertexIterator vrtsBegin, RegularVertexIterator vrtsEnd, TAAPos &aaPos)
Definition file_io_ugx_impl.hpp:270
bool write_to_file(const char *filename)
Definition file_io_ugx.cpp:111
void init_grid_attachments(Grid &grid)
Definition file_io_ugx.cpp:376
bool add_grid(Grid &grid, const char *name, TPositionAttachment &aPos)
Definition file_io_ugx_impl.hpp:135
void add_subset_handler(ISubsetHandler &sh, const char *name, size_t refGridIndex)
Definition file_io_ugx.cpp:152
Definition subset_handler_interface.h:223
A basic vertex-type.
Definition grid_objects_0d.h:62
@ GRIDOPT_NONE
Definition grid_constants.h:91
#define UG_CATCH_THROW(msg)
Definition error.h:64
#define UG_LOG(msg)
Definition log.h:367
unsigned int uint
Definition types.h:114
#define UG_COND_THROW(cond, msg)
UG_COND_THROW(cond, msg) : performs a UG_THROW(msg) if cond == true.
Definition error.h:61
Definition smart_pointer.h:814
the ug namespace
geometry_traits< ConstrainedTriangle >::iterator ConstrainedTriangleIterator
Definition grid_objects_2d.h:487
geometry_traits< ConstrainedQuadrilateral >::iterator ConstrainedQuadrilateralIterator
Definition grid_objects_2d.h:545
bool LoadGridFromUGX(Grid &grid, ISubsetHandler &sh, const char *filename)
Reads a grid to an ugx file.
Definition file_io_ugx.cpp:69
bool SaveGridToUGX(Grid &grid, ISubsetHandler &sh, const char *filename)
Writes a grid to a ugx file.
Definition file_io_ugx.cpp:55
geometry_traits< RegularVertex >::iterator RegularVertexIterator
Definition grid_objects_0d.h:94
geometry_traits< ConstrainedVertex >::iterator ConstrainedVertexIterator
Definition grid_objects_0d.h:196
geometry_traits< ConstrainedEdge >::iterator ConstrainedEdgeIterator
Definition grid_objects_1d.h:264
#define mkstr(s)
Comfortable (but not necessarily efficient) string building.
Definition stringify.h:100
geometry_traits< TElem >::iterator iterator
Definition grid.h:143
entries are stored for each grid.
Definition file_io_ugx.h:272
Definition attachment_info_traits.h:46
static void write_value(std::ostream &out, const_reference_type v)
Definition attachment_io_traits.h:45