1 /*****************************************************************************/
2 /* XDMF */
3 /* eXtensible Data Model and Format */
4 /* */
5 /* Id : XdmfTemplate.cpp */
6 /* */
7 /* Author: */
8 /* Andrew Burns */
9 /* andrew.j.burns2@us.army.mil */
10 /* US Army Research Laboratory */
11 /* Aberdeen Proving Ground, MD */
12 /* */
13 /* Copyright @ 2013 US Army Research Laboratory */
14 /* All Rights Reserved */
15 /* See Copyright.txt for details */
16 /* */
17 /* This software is distributed WITHOUT ANY WARRANTY; without */
18 /* even the implied warranty of MERCHANTABILITY or FITNESS */
19 /* FOR A PARTICULAR PURPOSE. See the above copyright notice */
20 /* for more information. */
21 /* */
22 /*****************************************************************************/
23
24 #include <sstream>
25 #include <utility>
26 #include "XdmfArray.hpp"
27 #include "XdmfCurvilinearGrid.hpp"
28 #include "XdmfItem.hpp"
29 #include "XdmfItemFactory.hpp"
30 #include "XdmfReader.hpp"
31 #include "XdmfGridCollection.hpp"
32 #include "XdmfGridCollectionType.hpp"
33 #include "XdmfGridTemplate.hpp"
34 #include "XdmfRectilinearGrid.hpp"
35 #include "XdmfRegularGrid.hpp"
36 #include "XdmfTemplate.hpp"
37 #include "XdmfTopology.hpp"
38 #include "XdmfError.hpp"
39 #include "XdmfUnstructuredGrid.hpp"
40 #include "XdmfVisitor.hpp"
41 #include "XdmfWriter.hpp"
42
43 #include "XdmfSystemUtils.hpp"
44
45 #include <boost/tokenizer.hpp>
46
47 #include <stdio.h>
48
49 shared_ptr<XdmfGridTemplate>
New()50 XdmfGridTemplate::New()
51 {
52 shared_ptr<XdmfGridTemplate> p(new XdmfGridTemplate());
53 return p;
54 }
55
56
XdmfGridTemplate()57 XdmfGridTemplate::XdmfGridTemplate() :
58 XdmfTemplate(),
59 XdmfGridCollection(),
60 mTimeCollection(XdmfArray::New())
61 {
62 mTimeCollection->setName("Time Collection");
63 }
64
XdmfGridTemplate(XdmfGridTemplate & refTemplate)65 XdmfGridTemplate::XdmfGridTemplate(XdmfGridTemplate & refTemplate) :
66 XdmfTemplate(refTemplate),
67 XdmfGridCollection(refTemplate),
68 mTimeCollection(refTemplate.mTimeCollection)
69 {
70 }
71
~XdmfGridTemplate()72 XdmfGridTemplate::~XdmfGridTemplate()
73 {
74 }
75
76 const std::string XdmfGridTemplate::ItemTag = "Template";
77
78 unsigned int
addStep()79 XdmfGridTemplate::addStep()
80 {
81 XdmfTemplate::addStep();
82 if (shared_dynamic_cast<XdmfGrid>(mBase)->getTime()) {
83 if (!mTimeCollection->isInitialized()) {
84 mTimeCollection->read();
85 }
86 mTimeCollection->pushBack(shared_dynamic_cast<XdmfGrid>(mBase)->getTime()->getValue());
87 }
88 return mCurrentStep;
89 }
90
91 std::map<std::string, std::string>
getItemProperties() const92 XdmfGridTemplate::getItemProperties() const
93 {
94 std::map<std::string, std::string> templateProperties = XdmfGridCollection::getItemProperties();
95
96 templateProperties["BaseType"] = "Grid";
97 return templateProperties;
98 }
99
100 std::string
getItemTag() const101 XdmfGridTemplate::getItemTag() const
102 {
103 return ItemTag;
104 }
105
106 shared_ptr<XdmfArray>
getTimes()107 XdmfGridTemplate::getTimes()
108 {
109 return mTimeCollection;
110 }
111
112 shared_ptr<XdmfGridCollection>
getGridCollection(const unsigned int index)113 XdmfGridTemplate::getGridCollection(const unsigned int index)
114 {
115 if (mBase) {
116 if (index < getNumberSteps()) {
117 this->clearStep();
118 this->setStep(index);
119 if (shared_ptr<XdmfGridCollection> grid =
120 shared_dynamic_cast<XdmfGridCollection>(mBase)) {
121 return grid;
122 }
123 else {
124 return shared_ptr<XdmfGridCollection>();
125 }
126 }
127 else {
128 return shared_ptr<XdmfGridCollection>();
129 }
130 }
131 else {
132 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get GridCollection from template without a base");
133 return shared_ptr<XdmfGridCollection>();
134 }
135 }
136
137 shared_ptr<const XdmfGridCollection>
getGridCollection(const unsigned int index) const138 XdmfGridTemplate::getGridCollection(const unsigned int index) const
139 {
140 if (shared_ptr<XdmfGridCollection> grid =
141 shared_dynamic_cast<XdmfGridCollection>(mBase)) {
142 if (index != mCurrentStep)
143 {
144 XdmfError::message(XdmfError::FATAL, "Error: GridTemplates can not return a constant reference to its base on an index other than the currently loaded one.");
145 return shared_ptr<XdmfGridCollection>();
146 }
147 else
148 {
149 return grid;
150 }
151 }
152 else {
153 return shared_ptr<XdmfGridCollection>();
154 }
155 }
156
157 shared_ptr<XdmfGridCollection>
getGridCollection(const std::string & Name)158 XdmfGridTemplate::getGridCollection(const std::string & Name)
159 {
160 if (mBase) {
161 if (shared_ptr<XdmfGridCollection> grid =
162 shared_dynamic_cast<XdmfGridCollection>(mBase)) {
163 if (grid->getName().compare(Name) == 0) {
164 return grid;
165 }
166 else {
167 return shared_ptr<XdmfGridCollection>();
168 }
169 }
170 else {
171 return shared_ptr<XdmfGridCollection>();
172 }
173 }
174 else {
175 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get GridCollection from template without a base");
176 return shared_ptr<XdmfGridCollection>();
177 }
178 }
179
180 shared_ptr<const XdmfGridCollection>
getGridCollection(const std::string & Name) const181 XdmfGridTemplate::getGridCollection(const std::string & Name) const
182 {
183 if (mBase) {
184 if (shared_ptr<XdmfGridCollection> grid =
185 shared_dynamic_cast<XdmfGridCollection>(mBase)) {
186 if (grid->getName().compare(Name) == 0) {
187 return grid;
188 }
189 else {
190 return shared_ptr<XdmfGridCollection>();
191 }
192 }
193 else {
194 return shared_ptr<XdmfGridCollection>();
195 }
196 }
197 else {
198 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get GridCollection from template without a base");
199 return shared_ptr<XdmfGridCollection>();
200 }
201 }
202
203 unsigned int
getNumberGridCollections() const204 XdmfGridTemplate::getNumberGridCollections() const
205 {
206 if (shared_ptr<XdmfGridCollection> grid =
207 shared_dynamic_cast<XdmfGridCollection>(mBase)) {
208 return this->getNumberSteps();
209 }
210 else {
211 return 0;
212 }
213 }
214
215 void
insert(const shared_ptr<XdmfGridCollection>)216 XdmfGridTemplate::insert(const shared_ptr<XdmfGridCollection> /*GridCollection*/)
217 {
218 XdmfError::message(XdmfError::FATAL, "Error: Attempting to use insert to add an XdmfGridCollection to an XdmfGridTemplate. "
219 "Use addStep instead of insert to add to an XdmfGridTemplate");
220 }
221
222 void
removeGridCollection(const unsigned int index)223 XdmfGridTemplate::removeGridCollection(const unsigned int index)
224 {
225 if (mBase) {
226 if (index < getNumberSteps()) {
227 if (shared_ptr<XdmfGridCollection> grid =
228 shared_dynamic_cast<XdmfGridCollection>(mBase)) {
229 this->removeStep(index);
230 }
231 }
232 }
233 else {
234 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get GridCollection from template without a base");
235 }
236 }
237
238 void
removeGridCollection(const std::string &)239 XdmfGridTemplate::removeGridCollection(const std::string & /*Name*/)
240 {
241 XdmfError::message(XdmfError::FATAL, "Error: Removing Grids by name from XdmfGridTemplate is not supported");
242 }
243
244 shared_ptr<XdmfCurvilinearGrid>
getCurvilinearGrid(const unsigned int index)245 XdmfGridTemplate::getCurvilinearGrid(const unsigned int index)
246 {
247 if (mBase) {
248 if (index < getNumberSteps()) {
249 this->clearStep();
250 this->setStep(index);
251 if (shared_ptr<XdmfCurvilinearGrid> grid =
252 shared_dynamic_cast<XdmfCurvilinearGrid>(mBase)) {
253 return grid;
254 }
255 else {
256 return shared_ptr<XdmfCurvilinearGrid>();
257 }
258 }
259 else {
260 return shared_ptr<XdmfCurvilinearGrid>();
261 }
262 }
263 else {
264 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get CurvilinearGrid from template without a base");
265 return shared_ptr<XdmfCurvilinearGrid>();
266 }
267 }
268
269 shared_ptr<const XdmfCurvilinearGrid>
getCurvilinearGrid(const unsigned int index) const270 XdmfGridTemplate::getCurvilinearGrid(const unsigned int index) const
271 {
272 if (shared_ptr<XdmfCurvilinearGrid> grid =
273 shared_dynamic_cast<XdmfCurvilinearGrid>(mBase)) {
274 if (index != mCurrentStep)
275 {
276 XdmfError::message(XdmfError::FATAL, "Error: GridTemplates can not return a constant reference to its base on an index other than the currently loaded one.");
277 return shared_ptr<XdmfCurvilinearGrid>();
278 }
279 else
280 {
281 return grid;
282 }
283 }
284 else {
285 return shared_ptr<XdmfCurvilinearGrid>();
286 }
287 }
288
289 shared_ptr<XdmfCurvilinearGrid>
getCurvilinearGrid(const std::string & Name)290 XdmfGridTemplate::getCurvilinearGrid(const std::string & Name)
291 {
292 if (mBase) {
293 if (shared_ptr<XdmfCurvilinearGrid> grid =
294 shared_dynamic_cast<XdmfCurvilinearGrid>(mBase)) {
295 if (grid->getName().compare(Name) == 0) {
296 return grid;
297 }
298 else {
299 return shared_ptr<XdmfCurvilinearGrid>();
300 }
301 }
302 else {
303 return shared_ptr<XdmfCurvilinearGrid>();
304 }
305 }
306 else {
307 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get CurvilinearGrid from template without a base");
308 return shared_ptr<XdmfCurvilinearGrid>();
309 }
310 }
311
312 shared_ptr<const XdmfCurvilinearGrid>
getCurvilinearGrid(const std::string & Name) const313 XdmfGridTemplate::getCurvilinearGrid(const std::string & Name) const
314 {
315 if (mBase) {
316 if (shared_ptr<XdmfCurvilinearGrid> grid =
317 shared_dynamic_cast<XdmfCurvilinearGrid>(mBase)) {
318 if (grid->getName().compare(Name) == 0) {
319 return grid;
320 }
321 else {
322 return shared_ptr<XdmfCurvilinearGrid>();
323 }
324 }
325 else {
326 return shared_ptr<XdmfCurvilinearGrid>();
327 }
328 }
329 else {
330 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get CurvilinearGrid from template without a base");
331 return shared_ptr<XdmfCurvilinearGrid>();
332 }
333 }
334
335 unsigned int
getNumberCurvilinearGrids() const336 XdmfGridTemplate::getNumberCurvilinearGrids() const
337 {
338 if (shared_ptr<XdmfCurvilinearGrid> grid =
339 shared_dynamic_cast<XdmfCurvilinearGrid>(mBase)) {
340 return this->getNumberSteps();
341 }
342 else {
343 return 0;
344 }
345 }
346
347 void
insert(const shared_ptr<XdmfCurvilinearGrid>)348 XdmfGridTemplate::insert(const shared_ptr<XdmfCurvilinearGrid> /*CurvilinearGrid*/)
349 {
350 XdmfError::message(XdmfError::FATAL, "Error: Attempting to use insert to add an XdmfCurvilinearGrid to an XdmfGridTemplate. "
351 "Use addStep instead of insert to add to an XdmfGridTemplate");
352 }
353
354 void
removeCurvilinearGrid(const unsigned int index)355 XdmfGridTemplate::removeCurvilinearGrid(const unsigned int index)
356 {
357 if (mBase) {
358 if (index < getNumberSteps()) {
359 if (shared_ptr<XdmfCurvilinearGrid> grid =
360 shared_dynamic_cast<XdmfCurvilinearGrid>(mBase)) {
361 this->removeStep(index);
362 }
363 }
364 }
365 else {
366 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get CurvilinearGrid from template without a base");
367 }
368 }
369
370 void
removeCurvilinearGrid(const std::string &)371 XdmfGridTemplate::removeCurvilinearGrid(const std::string & /*Name*/)
372 {
373 XdmfError::message(XdmfError::FATAL, "Error: Removing Grids by name from XdmfGridTemplate is not supported");
374 }
375
376 shared_ptr<XdmfRectilinearGrid>
getRectilinearGrid(const unsigned int index)377 XdmfGridTemplate::getRectilinearGrid(const unsigned int index)
378 {
379 if (mBase) {
380 if (index < getNumberSteps()) {
381 this->clearStep();
382 this->setStep(index);
383 if (shared_ptr<XdmfRectilinearGrid> grid =
384 shared_dynamic_cast<XdmfRectilinearGrid>(mBase)) {
385 return grid;
386 }
387 else {
388 return shared_ptr<XdmfRectilinearGrid>();
389 }
390 }
391 else {
392 return shared_ptr<XdmfRectilinearGrid>();
393 }
394 }
395 else {
396 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get RectilinearGrid from template without a base");
397 return shared_ptr<XdmfRectilinearGrid>();
398 }
399 }
400
401 shared_ptr<const XdmfRectilinearGrid>
getRectilinearGrid(const unsigned int index) const402 XdmfGridTemplate::getRectilinearGrid(const unsigned int index) const
403 {
404 if (shared_ptr<XdmfRectilinearGrid> grid =
405 shared_dynamic_cast<XdmfRectilinearGrid>(mBase)) {
406 if (index != mCurrentStep)
407 {
408 XdmfError::message(XdmfError::FATAL, "Error: GridTemplates can not return a constant reference to its base on an index other than the currently loaded one.");
409 return shared_ptr<XdmfRectilinearGrid>();
410 }
411 else
412 {
413 return grid;
414 }
415 }
416 else {
417 return shared_ptr<XdmfRectilinearGrid>();
418 }
419 }
420
421 shared_ptr<XdmfRectilinearGrid>
getRectilinearGrid(const std::string & Name)422 XdmfGridTemplate::getRectilinearGrid(const std::string & Name)
423 {
424 if (mBase) {
425 if (shared_ptr<XdmfRectilinearGrid> grid =
426 shared_dynamic_cast<XdmfRectilinearGrid>(mBase)) {
427 if (grid->getName().compare(Name) == 0) {
428 return grid;
429 }
430 else {
431 return shared_ptr<XdmfRectilinearGrid>();
432 }
433 }
434 else {
435 return shared_ptr<XdmfRectilinearGrid>();
436 }
437 }
438 else {
439 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get RectilinearGrid from template without a base");
440 return shared_ptr<XdmfRectilinearGrid>();
441 }
442 }
443
444 shared_ptr<const XdmfRectilinearGrid>
getRectilinearGrid(const std::string & Name) const445 XdmfGridTemplate::getRectilinearGrid(const std::string & Name) const
446 {
447 if (mBase) {
448 if (shared_ptr<XdmfRectilinearGrid> grid =
449 shared_dynamic_cast<XdmfRectilinearGrid>(mBase)) {
450 if (grid->getName().compare(Name) == 0) {
451 return grid;
452 }
453 else {
454 return shared_ptr<XdmfRectilinearGrid>();
455 }
456 }
457 else {
458 return shared_ptr<XdmfRectilinearGrid>();
459 }
460 }
461 else {
462 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get RectilinearGrid from template without a base");
463 return shared_ptr<XdmfRectilinearGrid>();
464 }
465 }
466
467 unsigned int
getNumberRectilinearGrids() const468 XdmfGridTemplate::getNumberRectilinearGrids() const
469 {
470 if (shared_ptr<XdmfRectilinearGrid> grid =
471 shared_dynamic_cast<XdmfRectilinearGrid>(mBase)) {
472 return this->getNumberSteps();
473 }
474 else {
475 return 0;
476 }
477 }
478
479 void
insert(const shared_ptr<XdmfRectilinearGrid>)480 XdmfGridTemplate::insert(const shared_ptr<XdmfRectilinearGrid> /*RectilinearGrid*/)
481 {
482 XdmfError::message(XdmfError::FATAL, "Error: Attempting to use insert to add a XdmfRectilinearGrid to an XdmfGridTemplate."
483 "Use addStep instead of insert to add to an XdmfGridTemplate");
484 }
485
486 void
removeRectilinearGrid(const unsigned int index)487 XdmfGridTemplate::removeRectilinearGrid(const unsigned int index)
488 {
489 if (mBase) {
490 if (index < getNumberSteps()) {
491 if (shared_ptr<XdmfRectilinearGrid> grid =
492 shared_dynamic_cast<XdmfRectilinearGrid>(mBase)) {
493 this->removeStep(index);
494 }
495 }
496 }
497 else {
498 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get RectilinearGrid from template without a base");
499 }
500 }
501
502 void
removeRectilinearGrid(const std::string &)503 XdmfGridTemplate::removeRectilinearGrid(const std::string & /*Name*/)
504 {
505 XdmfError::message(XdmfError::FATAL, "Error: Removing Grids by name from XdmfGridTemplate is not supported");
506 }
507
508 shared_ptr<XdmfRegularGrid>
getRegularGrid(const unsigned int index)509 XdmfGridTemplate::getRegularGrid(const unsigned int index)
510 {
511 if (mBase) {
512 if (index < getNumberSteps()) {
513 this->clearStep();
514 this->setStep(index);
515 if (shared_ptr<XdmfRegularGrid> grid =
516 shared_dynamic_cast<XdmfRegularGrid>(mBase)) {
517 return grid;
518 }
519 else {
520 return shared_ptr<XdmfRegularGrid>();
521 }
522 }
523 else {
524 return shared_ptr<XdmfRegularGrid>();
525 }
526 }
527 else {
528 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get RegularGrid from template without a base");
529 return shared_ptr<XdmfRegularGrid>();
530 }
531 }
532
533 shared_ptr<const XdmfRegularGrid>
getRegularGrid(const unsigned int index) const534 XdmfGridTemplate::getRegularGrid(const unsigned int index) const
535 {
536 if (shared_ptr<XdmfRegularGrid> grid =
537 shared_dynamic_cast<XdmfRegularGrid>(mBase)) {
538 if (index != mCurrentStep)
539 {
540 XdmfError::message(XdmfError::FATAL, "Error: GridTemplates can not return a constant reference to its base on an index other than the currently loaded one.");
541 return shared_ptr<XdmfRegularGrid>();
542 }
543 else
544 {
545 return grid;
546 }
547 }
548 else {
549 return shared_ptr<XdmfRegularGrid>();
550 }
551 }
552
553 shared_ptr<XdmfRegularGrid>
getRegularGrid(const std::string & Name)554 XdmfGridTemplate::getRegularGrid(const std::string & Name)
555 {
556 if (mBase) {
557 if (shared_ptr<XdmfRegularGrid> grid =
558 shared_dynamic_cast<XdmfRegularGrid>(mBase)) {
559 if (grid->getName().compare(Name) == 0) {
560 return grid;
561 }
562 else {
563 return shared_ptr<XdmfRegularGrid>();
564 }
565 }
566 else {
567 return shared_ptr<XdmfRegularGrid>();
568 }
569 }
570 else {
571 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get RegularGrid from template without a base");
572 return shared_ptr<XdmfRegularGrid>();
573 }
574 }
575
576 shared_ptr<const XdmfRegularGrid>
getRegularGrid(const std::string & Name) const577 XdmfGridTemplate::getRegularGrid(const std::string & Name) const
578 {
579 if (mBase) {
580 if (shared_ptr<XdmfRegularGrid> grid =
581 shared_dynamic_cast<XdmfRegularGrid>(mBase)) {
582 if (grid->getName().compare(Name) == 0) {
583 return grid;
584 }
585 else {
586 return shared_ptr<XdmfRegularGrid>();
587 }
588 }
589 else {
590 return shared_ptr<XdmfRegularGrid>();
591 }
592 }
593 else {
594 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get RegularGrid from template without a base");
595 return shared_ptr<XdmfRegularGrid>();
596 }
597 }
598
599 unsigned int
getNumberRegularGrids() const600 XdmfGridTemplate::getNumberRegularGrids() const
601 {
602 if (shared_ptr<XdmfRegularGrid> grid =
603 shared_dynamic_cast<XdmfRegularGrid>(mBase)) {
604 return this->getNumberSteps();
605 }
606 else {
607 return 0;
608 }
609 }
610
611 void
insert(const shared_ptr<XdmfRegularGrid>)612 XdmfGridTemplate::insert(const shared_ptr<XdmfRegularGrid> /*RegularGrid*/)
613 {
614 XdmfError::message(XdmfError::FATAL, "Error: Attempting to use insert to add an XdmfRegularGrid to an XdmfGridTemplate."
615 "Use addStep instead of insert to add to an XdmfGridTemplate");
616 }
617
618 void
removeRegularGrid(const unsigned int index)619 XdmfGridTemplate::removeRegularGrid(const unsigned int index)
620 {
621 if (mBase) {
622 if (index < getNumberSteps()) {
623 if (shared_ptr<XdmfRegularGrid> grid =
624 shared_dynamic_cast<XdmfRegularGrid>(mBase)) {
625 this->removeStep(index);
626 }
627 }
628 }
629 else {
630 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get RegularGrid from template without a base");
631 }
632 }
633
634 void
removeRegularGrid(const std::string & Name)635 XdmfGridTemplate::removeRegularGrid(const std::string & Name)
636 {
637 XdmfError::message(XdmfError::FATAL, "Error: Removing Grids by name from XdmfGridTemplate is not supported");
638 }
639
640 shared_ptr<XdmfUnstructuredGrid>
getUnstructuredGrid(const unsigned int index)641 XdmfGridTemplate::getUnstructuredGrid(const unsigned int index)
642 {
643 if (mBase) {
644 if (index < getNumberSteps()) {
645 this->clearStep();
646 this->setStep(index);
647 if (shared_ptr<XdmfUnstructuredGrid> grid =
648 shared_dynamic_cast<XdmfUnstructuredGrid>(mBase)) {
649 return grid;
650 }
651 else {
652 return shared_ptr<XdmfUnstructuredGrid>();
653 }
654 }
655 else {
656 return shared_ptr<XdmfUnstructuredGrid>();
657 }
658 }
659 else {
660 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get UnstructuredGrid from template without a base");
661 return shared_ptr<XdmfUnstructuredGrid>();
662 }
663 }
664
665 shared_ptr<const XdmfUnstructuredGrid>
getUnstructuredGrid(const unsigned int index) const666 XdmfGridTemplate::getUnstructuredGrid(const unsigned int index) const
667 {
668 if (shared_ptr<XdmfUnstructuredGrid> grid =
669 shared_dynamic_cast<XdmfUnstructuredGrid>(mBase)) {
670 if (index != mCurrentStep)
671 {
672 XdmfError::message(XdmfError::FATAL, "Error: GridTemplates can not return a constant reference to its base on an index other than the currently loaded one.");
673 return shared_ptr<XdmfUnstructuredGrid>();
674 }
675 else
676 {
677 return grid;
678 }
679 }
680 else {
681 return shared_ptr<XdmfUnstructuredGrid>();
682 }
683 }
684
685 shared_ptr<XdmfUnstructuredGrid>
getUnstructuredGrid(const std::string & Name)686 XdmfGridTemplate::getUnstructuredGrid(const std::string & Name)
687 {
688 if (mBase) {
689 if (shared_ptr<XdmfUnstructuredGrid> grid =
690 shared_dynamic_cast<XdmfUnstructuredGrid>(mBase)) {
691 if (grid->getName().compare(Name) == 0) {
692 return grid;
693 }
694 else {
695 return shared_ptr<XdmfUnstructuredGrid>();
696 }
697 }
698 else {
699 return shared_ptr<XdmfUnstructuredGrid>();
700 }
701 }
702 else {
703 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get UnstructuredGrid from template without a base");
704 return shared_ptr<XdmfUnstructuredGrid>();
705 }
706 }
707
708 shared_ptr<const XdmfUnstructuredGrid>
getUnstructuredGrid(const std::string & Name) const709 XdmfGridTemplate::getUnstructuredGrid(const std::string & Name) const
710 {
711 if (mBase) {
712 if (shared_ptr<XdmfUnstructuredGrid> grid =
713 shared_dynamic_cast<XdmfUnstructuredGrid>(mBase)) {
714 if (grid->getName().compare(Name) == 0) {
715 return grid;
716 }
717 else {
718 return shared_ptr<XdmfUnstructuredGrid>();
719 }
720 }
721 else {
722 return shared_ptr<XdmfUnstructuredGrid>();
723 }
724 }
725 else {
726 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get UnstructuredGrid from template without a base");
727 return shared_ptr<XdmfUnstructuredGrid>();
728 }
729 }
730
731 unsigned int
getNumberUnstructuredGrids() const732 XdmfGridTemplate::getNumberUnstructuredGrids() const
733 {
734 if (shared_ptr<XdmfUnstructuredGrid> grid =
735 shared_dynamic_cast<XdmfUnstructuredGrid>(mBase)) {
736 return this->getNumberSteps();
737 }
738 else {
739 return 0;
740 }
741 }
742
743
744 void
insert(const shared_ptr<XdmfUnstructuredGrid> UnstructuredGrid)745 XdmfGridTemplate::insert(const shared_ptr<XdmfUnstructuredGrid> UnstructuredGrid)
746 {
747 XdmfError::message(XdmfError::FATAL, "Error: Attempting to use insert to add an XdmfUnstructuredGrid to an XdmfGridTemplate."
748 "Use addStep instead of insert to add to an XdmfGridTemplate");
749 }
750
751 void
removeUnstructuredGrid(const unsigned int index)752 XdmfGridTemplate::removeUnstructuredGrid(const unsigned int index)
753 {
754 if (mBase) {
755 if (index < getNumberSteps()) {
756 if (shared_ptr<XdmfUnstructuredGrid> grid =
757 shared_dynamic_cast<XdmfUnstructuredGrid>(mBase)) {
758 this->removeStep(index);
759 }
760 }
761 }
762 else {
763 XdmfError::message(XdmfError::FATAL, "Error: Attempting to get UnstructuredGrid from template without a base");
764 }
765 }
766
767
768 void
removeUnstructuredGrid(const std::string & Name)769 XdmfGridTemplate::removeUnstructuredGrid(const std::string & Name)
770 {
771 XdmfError::message(XdmfError::FATAL, "Error: Removing Grids by name from XdmfGridTemplate is not supported");
772 }
773
774 void
populateItem(const std::map<std::string,std::string> & itemProperties,const std::vector<shared_ptr<XdmfItem>> & childItems,const XdmfCoreReader * const reader)775 XdmfGridTemplate::populateItem(const std::map<std::string, std::string> & itemProperties,
776 const std::vector<shared_ptr<XdmfItem> > & childItems,
777 const XdmfCoreReader * const reader)
778 {
779 // We are overrriding the populate item of the template and grid collection here
780 // The template functions internally different from either.
781
782 this->setType(XdmfGridCollectionType::New(itemProperties));
783
784 // The first child item is the base
785 mBase = childItems[0];
786 mCurrentStep = 0;
787
788 if (childItems.size() > 1) {
789 for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
790 childItems.begin() + 1;
791 iter != childItems.end();
792 ++iter) {
793 if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
794 if (array->getName().compare("Data Description") == 0) {
795 // Split description into substrings based on the " character
796
797 if (array->getNumberHeavyDataControllers() > 0 && !mHeavyWriter) {
798 mHeavyWriter = reader->generateHeavyDataWriter(array->getHeavyDataController(0)->getName(), array->getHeavyDataController(0)->getFilePath());
799 }
800
801 array->read();
802
803 // If a character array, create std::string version? TODO
804 std::string descriptionString;
805 if (array->getArrayType() == XdmfArrayType::Int8())
806 {
807 descriptionString = std::string((char *)array->getValuesInternal());
808 }
809 else if (array->getArrayType() == XdmfArrayType::String())
810 {
811 descriptionString = array->getValue<std::string>(0);
812 }
813
814 size_t index = descriptionString.find_first_of("\"");
815 size_t previousIndex = 0;
816
817 if (index != std::string::npos) {
818 // Removing the prepended "
819 previousIndex = index + 1;
820 index = descriptionString.find_first_of("\"", previousIndex);
821 }
822
823 while (index != std::string::npos) {
824 std::string type = descriptionString.substr(previousIndex, index - previousIndex);
825 mDataTypes.push_back(type);
826 previousIndex = index + 1;
827 index = descriptionString.find_first_of("\"", previousIndex);
828 if (index - previousIndex > 0) {
829 std::string description;
830 description = descriptionString.substr(previousIndex, index - previousIndex);
831 mDataDescriptions.push_back(description);
832 // create controllers here based on the type/description?
833 // Is array type already filled?
834 // Potentially call "fillControllers" after populating?
835 if (index != std::string::npos) {
836 previousIndex = index + 1;
837 index = descriptionString.find_first_of("\"", previousIndex);
838 }
839 }
840 else {
841 XdmfError::message(XdmfError::FATAL, "Error: Type without a description in XdmfTemplate::populateItem");
842 }
843 }
844 }
845 else if (array->getName().compare("Time Collection") == 0) {
846 mTimeCollection = array;
847 }
848 else {
849 mTrackedArrays.push_back(array.get());
850 mTrackedArrayDims.push_back(array->getDimensions());
851 mTrackedArrayTypes.push_back(array->getArrayType());
852 }
853 }
854 }
855 }
856 mDataControllers.resize(mDataTypes.size());
857 if (!mItemFactory) {
858 mItemFactory = XdmfItemFactory::New();
859 }
860 std::map<std::string, std::string> populateProperties;
861 if (mHeavyWriter) {
862 // The heavy writer provides the XMLDir, which is used to get full paths for the controllers
863 // It is assumed that the files that the controllers reference are in the same directory
864 // as the file that the writer references
865 std::string filepath = XdmfSystemUtils::getRealPath(mHeavyWriter->getFilePath());
866 size_t index = filepath.find_last_of("/\\");
867 filepath = filepath.substr(0, index + 1);
868 populateProperties["XMLDir"] = filepath;
869 }
870 for (unsigned int i = 0; i < mDataDescriptions.size(); ++i) {
871 populateProperties["Content"] = mDataDescriptions[i];
872 std::vector<shared_ptr<XdmfHeavyDataController> > readControllers =
873 reader->generateHeavyDataControllers(populateProperties, mTrackedArrayDims[i % mTrackedArrays.size()], mTrackedArrayTypes[i % mTrackedArrays.size()], mDataTypes[i]);
874 if (readControllers.size() > 0) {
875 // Heavy data controllers reference the data
876 for (unsigned int j = 0; j < readControllers.size(); ++j) {
877 mDataControllers[i].push_back(readControllers[j]);
878 }
879 }
880 }
881 // Compare the first set of controllers to the size of the first array
882 unsigned int controllerTotal = 0;
883 for (unsigned int i = 0; i < mDataControllers[0].size(); ++i)
884 {
885 controllerTotal += mDataControllers[0][i]->getSize();
886 }
887 // If the array is smaller, set the writer to append.
888 if (controllerTotal > mTrackedArrays[0]->getSize())
889 {
890 mHeavyWriter->setMode(XdmfHeavyDataWriter::Append);
891 mNumSteps = controllerTotal / mTrackedArrays[0]->getSize();
892 }
893 else {
894 mNumSteps = mDataControllers.size() / mTrackedArrays.size();
895 }
896 }
897
898 void
removeStep(unsigned int stepId)899 XdmfGridTemplate::removeStep(unsigned int stepId)
900 {
901 if (stepId < this->getNumberSteps()) {
902 XdmfTemplate::removeStep(stepId);
903 mTimeCollection->erase(stepId);
904 }
905 this->setIsChanged(true);
906 }
907
908 void
setBase(shared_ptr<XdmfItem> newBase)909 XdmfGridTemplate::setBase(shared_ptr<XdmfItem> newBase)
910 {
911 if (shared_ptr<XdmfGrid> grid = shared_dynamic_cast<XdmfGrid>(newBase)) {
912 XdmfTemplate::setBase(newBase);
913 }
914 else {
915 XdmfError::message(XdmfError::FATAL, "Error: XdmfGridTemplate::setBase,"
916 " attempting to set a Base that is not grid type.");
917 }
918 }
919
920 void
setStep(unsigned int stepId)921 XdmfGridTemplate::setStep(unsigned int stepId)
922 {
923 XdmfTemplate::setStep(stepId);
924 if (mTimeCollection->getSize() >= stepId) {
925 if (!mTimeCollection->isInitialized()) {
926 mTimeCollection->read();
927 }
928 if (shared_dynamic_cast<XdmfGrid>(mBase)->getTime()) {
929 shared_dynamic_cast<XdmfGrid>(mBase)->getTime()->setValue(mTimeCollection->getValue<double>(stepId));
930 }
931 else {
932 shared_dynamic_cast<XdmfGrid>(mBase)->setTime(XdmfTime::New(mTimeCollection->getValue<double>(stepId)));
933 }
934 }
935 }
936
937 void
setStep(shared_ptr<XdmfTime> time)938 XdmfGridTemplate::setStep(shared_ptr<XdmfTime> time)
939 {
940 if (mTimeCollection->getSize() > 0)
941 {
942 if (!mTimeCollection->isInitialized()) {
943 mTimeCollection->read();
944 }
945 unsigned int index = 0;
946 while (index < mTimeCollection->getSize() &&
947 time->getValue() != mTimeCollection->getValue<double>(index))
948 {
949 ++index;
950 }
951 if (index < mTimeCollection->getSize())
952 {
953 this->setStep(index);
954 }
955 }
956 }
957
958 void
traverse(const shared_ptr<XdmfBaseVisitor> visitor)959 XdmfGridTemplate::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
960 {
961 // We are only using the template traverse
962 // since the grid data is only held in the Base
963 if (mTimeCollection->getSize() > 0)
964 {
965 this->setType(XdmfGridCollectionType::Temporal());
966 }
967 else
968 {
969 this->setType(XdmfGridCollectionType::Spatial());
970 }
971 XdmfTemplate::traverse(visitor);
972 mTimeCollection->accept(visitor);
973 }
974
975 XDMF_ITEM_C_CHILD_WRAPPER(XdmfGridTemplate, XDMFGRIDTEMPLATE)
976