MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
geometryionetcdf.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
7#include "geometryionetcdf.h"
8
9#include <cstring>
10#include "COMM/mpioverride.h"
11#include "IO/parallelio.h"
12#include "UTIL/timer.h"
13#include "globals.h"
14using namespace std;
15
16//--------------------------------------------------------------------------
22
23//--------------------------------------------------------------------------
29 // TRACE();
30 using namespace maia::parallel_io;
32 maiabd_type type;
33 MInt noDims;
34 type = bdFile->getDatasetType(name);
35 if(bdFile->hasDataset(name, 0))
36 noDims = 0;
37 else
38 noDims = bdFile->getDatasetNoDims(name);
39 switch(type) {
40 case PIO_INT: {
41 DEBUG("GeometryIONetcdf::makeProperty found integer property :", MAIA_DEBUG_USER1);
42 p->propertyType = MINT;
43 if(noDims == 0) {
44 p->elements = 1;
45 p->intField = new MInt[1];
46 bdFile->readScalar(p->intField, name);
47 DEBUG("GeometryIONetcdf::makeProperty " << p->intField[0], MAIA_DEBUG_USER1);
48 }
49 if(noDims == 1) {
50 /* look up the length of the array */
51 length = bdFile->getArraySize(name);
52 p->elements = length;
53 p->intField = new MInt[length];
54 bdFile->setOffset(length, 0);
55 bdFile->readArray(p->intField, name);
56 // for (MInt i=0; i < length; i++) // delete this line!
57 // DEBUG("GeometryIONetcdf::makeProperty " << p->intField[i], MAIA_DEBUG_USER1);
58 }
59 if(noDims == 2) {
60 /*NOT YET IMPLEMENTED !*/
61 }
62 break;
63 }
64 case PIO_FLOAT: {
65 DEBUG("GeometryIONetcdf::makeProperty found float property :", MAIA_DEBUG_USER1);
66 p->propertyType = MFLOAT;
67 if(noDims == 0) {
68 p->elements = 1;
69 p->floatField = new MFloat[1];
70 bdFile->readScalar(p->floatField, name);
71 DEBUG("GeometryIONetcdf::makeProperty " << p->floatField[0], MAIA_DEBUG_USER1);
72 }
73 if(noDims == 1) {
74 /* look up the length of the array */
75 length = bdFile->getArraySize(name);
76 p->elements = length;
77 p->floatField = new MFloat[length];
78 bdFile->setOffset(length, 0);
79 bdFile->readArray(p->floatField, name);
80 // for (MInt i=0; i < length; i++) //delete this line!
81 // DEBUG("GeometryIONetcdf::makeProperty " << p->floatField[i], MAIA_DEBUG_USER1);
82 }
83 if(noDims == 2) {
84 /*NOT YET IMPLEMENTED !*/
85 }
86 break;
87 }
88 case PIO_STRING: {
89 DEBUG("GeometryIONetcdf::makeProperty found char property :", MAIA_DEBUG_USER1);
90 p->propertyType = MSTRING;
91 if(noDims == 0) {
92 p->elements = 1;
93 p->stringField = new MString[1];
94 MString buf;
95 bdFile->readScalar(&buf, name);
96 p->stringField->append(buf);
97 }
98 if(noDims == 1) {
99 p->elements = 1;
100 p->stringField = new MString[1];
101 /* look up the length of the string */
102 length = bdFile->getArraySize(name, 0);
103 MString buf;
104 bdFile->setOffset(length, 0);
105 bdFile->readArray(&buf, name);
106 p->stringField->append(buf);
107 DEBUG("GeometryIONetcdf::makeProperty " << p->stringField[0], MAIA_DEBUG_USER1);
108 }
109 if(noDims == 2) {
110 /* look up the number of strings */
111 ParallelIo::size_type noStrings = bdFile->getArraySize(name, 0);
112 length = bdFile->getArraySize(name, 1);
113 p->elements = length;
114 p->stringField = new MString[noStrings];
116 /* loop over number of strings */
117 for(MInt i = 0; i < p->elements; i++) {
118 start = i;
119 bdFile->setOffset(1, start, 2);
120 MString buf;
121 bdFile->readArray(&buf, name);
122 (p->stringField[i]).append(buf);
123 DEBUG("GeometryIONetcdf::makeProperty " << p->stringField[i], MAIA_DEBUG_USER1);
124 }
125 }
126 break;
127 }
128 default: {
129 // SX8 cannot compile with excepetion handling
130 // throw(IOError(" Error : Unsupported variable input type encountered! \n"));
131 }
132 }
133 const pair<const MString, GeometryProperty*> mp(p->name, p);
134 m_geometryPropertyMap->insert(mp);
135 DEBUG("GeometryIONetcdf::makeProperty created default property ", MAIA_DEBUG_USER1);
136 DEBUG("GeometryIONetcdf::makeProperty elements = " << p->elements, MAIA_DEBUG_USER1);
137 DEBUG("GeometryIONetcdf::makeProperty m_noProperties = " << m_geometryPropertyMap->size(), MAIA_DEBUG_USER1);
138}
139
140
142 TRACE();
143 m_log << " * reading body information" << endl;
144
145 if(bdFile->hasDataset("body_segments.") && bdFile->hasDataset("body_segments_names.")
146 && bdFile->hasDataset("body_segments_num.")) {
147 MInt len_bsnum = bdFile->getArraySize("body_segments_num.");
148 MInt len_bs = bdFile->getArraySize("body_segments.");
149 MInt len_bsname = bdFile->getArraySize("body_segments_names.");
150
151 MString bsallnames;
152 MIntScratchSpace bs(len_bs, AT_, "bs");
153 MStringScratchSpace bsname(len_bsnum, AT_, "bsname");
154 MIntScratchSpace bsnum(len_bsnum, AT_, "bsnum");
155
156 bdFile->setOffset(len_bs, 0);
157 bdFile->readArray(bs.getPointer(), "body_segments.");
158
159 bdFile->setOffset(len_bsname, 0);
160 bdFile->readArray(&bsallnames, "body_segments_names.");
161 bdFile->setOffset(len_bsnum, 0);
162 bdFile->readArray(bsnum.getPointer(), "body_segments_num.");
163
164 for(MInt i = 0; i < len_bsnum; i++) {
165 MInt del_pos = bsallnames.find(",");
166 bsname[i] = bsallnames.substr(0, del_pos);
167 MString tmp = bsallnames.substr(del_pos + 1, bsallnames.length() - del_pos);
168 bsallnames = tmp;
169 }
170
171 for(MInt i = 0, j = 0; i < len_bsnum; i++) {
172 Body* body = new Body;
173 m_noBodies++;
174
175 body->name = bsname[i];
176 body->noSegments = bsnum[i];
177 body->segments = new MInt[body->noSegments];
178
179 for(MInt k = 0; k < body->noSegments; k++, j++)
180 body->segments[k] = bs[j];
181
182 if(m_bodyMap->find(body->name) == m_bodyMap->end()) m_bodyMap->insert(make_pair(body->name, body));
183 }
184 }
185
187}
188
189//--------------------------------------------------------------------------
195 TRACE();
196
197 m_log << " * reading body information" << endl;
198 MInt noVariables = 0;
199 const char MPropertySeperator = '.'; // Seperator that defines different Properties
200
201 /* read and store the body information and the segment info*/
202 const char* du; // tmp variable
203
204 MString varName;
206
207 vector<MString> varNames = bdFile->getDatasetNames(1);
208 noVariables = varNames.size();
209
210 for(MInt n = 0; n < noVariables; n++) {
211 varName = varNames[n];
212 if(strstr(varName.c_str(), "body_segments.")) { // if a body has been identified
213 du = strrchr(varName.c_str(), MPropertySeperator); // get pointer to where the "." is
214
215 /* create body element */
216 Body* body;
217 body = new Body;
218 body->name.append(++du);
219 DEBUG("GeometryIONetcdf::readBodies Body found (name: " << body->name << ")", MAIA_DEBUG_USER2);
220 m_noBodies++;
221
222 /* get segments for the body */
223 length = bdFile->getArraySize(varName);
224 DEBUG("GeometryIONetcdf::readBodies The Body has " << length << " solvers.", MAIA_DEBUG_USER2);
225 body->noSegments = length;
226 body->segments = new MInt[length];
227 /* There is an implicit conversion from int to unsigned int between netcdf
228 and the body segments */
229 for(ParallelIo::size_type i = 0; i < length; i++) {
230 MInt dsegments;
231 bdFile->setOffset(1, i);
232 bdFile->readArray(&dsegments, varName);
233 body->segments[i] = dsegments;
234 }
235 /* insert the body into the bodyMap*/
236 if(m_bodyMap->find(body->name) == m_bodyMap->end()) {
237 m_bodyMap->insert(make_pair(body->name, body));
238 }
239 }
240 }
242}
243
244
245//--------------------------------------------------------------------------
251 TRACE();
252 /* create a body named "default" */
253 Body* body;
254 body = new Body;
255 body->name.append("default");
256
257 /* search for all segments that are defined */
258 list<MInt> segmentList;
259 for(bodyMap::const_iterator it = m_bodyMap->begin(); it != m_bodyMap->end(); it++) {
260 for(MInt i = 0; i < it->second->noSegments; i++) {
261 segmentList.push_back(it->second->segments[i]);
262 }
263 }
264 segmentList.sort();
265
266 /* The number of undefined segments equals the number of total
267 segments minus the number of defined segments ... */
268 body->noSegments = (m_noSegments - segmentList.size());
269 body->segments = new MInt[body->noSegments];
270
271 /* this adds all segmentId's that aren't defined to the default body*/
272 MInt i = 0;
273 MInt simpleIterator = 0;
274 list<MInt>::const_iterator segmentIt = segmentList.begin();
275
276 if(!segmentList.empty()) {
277 while(i < m_noSegments) {
278 if(*segmentIt == i) {
279 i++;
280 segmentIt++;
281 } else {
282 body->segments[simpleIterator] = i;
283 DEBUG("GeometryIONetcdf::buildDefaultBody Added segment " << i << " to the default body. ", MAIA_DEBUG_USER1);
284 i++;
285 simpleIterator++;
286 }
287 }
288 }
289
290 /* insert the default body in the body map */
291 m_bodyMap->insert(make_pair(body->name, body));
292 DEBUG("GeometryIONetcdf::buildDefaultBody Default body has " << body->noSegments << " segments.", MAIA_DEBUG_USER1);
293 m_noBodies++;
294}
295
296//--------------------------------------------------------------------------
309 TRACE();
310
311 // init member variables
312 m_newIOMethod = false;
313 m_noSegments = 0;
314 m_noBodies = 0;
316 m_bodyMap = new bodyMap;
318
319 // read initial variables required for further processing
320 if(domainId() == 0) {
321 ParallelIo parallelIo(name.c_str(), maia::parallel_io::PIO_READ, MPI_COMM_SELF);
322 m_newIOMethod = parallelIo.hasAttribute("newIOMethod");
323 parallelIo.readScalar(&m_noSegments, "noSegments");
324
325 MPI_Bcast(&m_newIOMethod, 1, MPI_INT, 0, mpiComm(), AT_, "m_newIOMethod");
326 MPI_Bcast(&m_noSegments, 1, MPI_INT, 0, mpiComm(), AT_, "m_noSegments");
327 } else {
328 MPI_Bcast(&m_newIOMethod, 1, MPI_INT, 0, mpiComm(), AT_, "m_newIOMethod");
329 MPI_Bcast(&m_noSegments, 1, MPI_INT, 0, mpiComm(), AT_, "m_noSegments");
330 }
331
332 // do the actual reading and distribute the geometry properties
333 if(domainId() == 0) {
334 m_log << " - rank 0 reads data from disk" << endl;
335
336 // open the property file
337 ParallelIo parallelIo(name.c_str(), maia::parallel_io::PIO_READ, MPI_COMM_SELF);
338
339 NEW_SUB_TIMER(t_readRest, "rest geometry property", g_t_readGeomFile);
340 NEW_SUB_TIMER(t_readBodies, "geometry bodies", g_t_readGeomFile);
341 NEW_SUB_TIMER(t_distBodies, "distribute bodies", g_t_readGeomFile);
342 NEW_SUB_TIMER(t_distRest, "distribute rest geometry property", g_t_readGeomFile);
343
344 if(m_newIOMethod) {
345 RECORD_TIMER_START(t_readBodies);
346 readBodiesNewIOMethod(&parallelIo);
347 RECORD_TIMER_STOP(t_readBodies);
348
349 RECORD_TIMER_START(t_readRest);
350 readPropertyFileNewIOMethod(&parallelIo);
351 RECORD_TIMER_STOP(t_readRest);
352 } else {
353 RECORD_TIMER_START(t_readBodies);
354 readBodiesOldIOMethod(&parallelIo);
355 RECORD_TIMER_STOP(t_readBodies);
356
357 RECORD_TIMER_START(t_readRest);
358 readPropertyFileOldIOMethod(&parallelIo);
359 RECORD_TIMER_STOP(t_readRest);
360 }
361
362 /*
363 for(bodyIterator it = m_bodyMap->begin(); it != m_bodyMap->end(); it++)
364{
365 Body* b = (*it).second;
366 cout << "body: " << b->name << " " << b->noSegments << " ";
367 for(MInt i = 0; i < b->noSegments; i++)
368 cout << b->segments[i] << " ";
369 cout << endl;
370}
371
372 cout << endl;
373 for(geometryPropertyIterator it = m_geometryPropertyMap->begin(); it != m_geometryPropertyMap->end(); it++)
374 {
375 GeometryProperty* b = (*it).second;
376 cout << "prop: " << b->name << " " << b->propertyType << " " << b->elements << " " << b->segmentId << " - ";
377 for(MInt i = 0; i < b->elements; i++)
378 {
379 if(b->propertyType == MINT)
380 cout << b->intField[i] << " ";
381 else if(b->propertyType == MFLOAT)
382 cout << b->floatField[i] << " ";
383 else if (b->propertyType == MSTRING)
384 cout << b->stringField[i] << " ";
385
386 }
387 cout << endl;
388}
389 */
390 if(noDomains() > 1) {
391 RECORD_TIMER_START(t_distBodies);
393 RECORD_TIMER_STOP(t_distBodies);
394
395 RECORD_TIMER_START(t_distRest);
397 RECORD_TIMER_STOP(t_distRest);
398 }
399 } else {
402
403 /*
404 for(bodyIterator it = m_bodyMap->begin(); it != m_bodyMap->end(); it++)
405{
406 Body* b = (*it).second;
407 cout << "body: " << b->name << " " << b->noSegments << " ";
408 for(MInt i = 0; i < b->noSegments; i++)
409 cout << b->segments[i] << " ";
410 cout << endl;
411}
412
413 cout << endl;
414 for(geometryPropertyIterator it = m_geometryPropertyMap->begin(); it != m_geometryPropertyMap->end(); it++)
415 {
416 GeometryProperty* b = (*it).second;
417 cout << "prop: " << b->name << " " << b->propertyType << " " << b->elements << " " << b->segmentId << " - ";
418 for(MInt i = 0; i < b->elements; i++)
419 {
420 if(b->propertyType == MINT)
421 cout << b->intField[i] << " ";
422 else if(b->propertyType == MFLOAT)
423 cout << b->floatField[i] << " ";
424 else if (b->propertyType == MSTRING)
425 cout << b->stringField[i] << " ";
426
427 }
428 cout << endl;
429}
430 */
431 }
432
433 // fill the body and the property maps
436
437 m_log << endl;
438
439 return m_geometryAssembly;
440}
441
454 TRACE();
455
456 MInt noVariables = 0;
457 const char MPropertySeperator = '.'; // Seperator that defines different Properties
458
459 MString varName;
460
462 m_log << " * reading rest of the properties" << endl;
463
464 // check the consistency of the body
466 vector<MString> varNames = parallelIo->getDatasetNames();
467 noVariables = varNames.size();
468
469 for(MInt id = 0; id < noVariables; id++) {
470 varName = varNames[id];
471 // if default property
472 if(!strstr(varName.c_str(), ".")) {
473 // if there's no dot in string (default prop)
474 // store default property in last solver,
475 // the others to their belonging id's
476
477 DEBUG("GeometryIONetcdf::readNCPropertyFile default property : " << varName, MAIA_DEBUG_USER1);
478 p = new GeometryProperty;
479 p->segmentId = m_noSegments; // Insert default segment as last segment
480 p->name.append(varName);
481 makeProperty(p, varName, parallelIo); // create new Property
482 }
483 // if a property defined for one or more bodies
484 else {
485 if(strstr(varName.c_str(), "_bodies.")) {
486 DEBUG("GeometryIONetcdf::readPropertyFile normal property: " << varName, MAIA_DEBUG_USER1);
488 noDims = parallelIo->getDatasetNoDims(varName);
489 MString* bodies = nullptr;
490 MInt noBodies = 1;
491 DEBUG("GeometryIONetcdf::readPropertyFile no of dimensions = " << noDims, MAIA_DEBUG_USER1);
492 switch(noDims) {
493 case 0: {
494 // if only one char (and one body)
495 MString buf;
496 parallelIo->readScalar(&buf, varName);
497 bodies = new MString(buf);
498 break;
499 }
500 case 1: {
501 // look up the length of the string
502 ParallelIo::size_type length = parallelIo->getArraySize(varName, 0);
503 MString buf;
504 parallelIo->setOffset(length, 0);
505 parallelIo->readArray(&buf, varName);
506 bodies = new MString(buf);
507 break;
508 }
509 case 2: {
510 // look up the number of bodies
511 ParallelIo::size_type dbodies;
512 dbodies = parallelIo->getArraySize(varName, 0);
513 noBodies = (MInt)dbodies;
514 bodies = new MString[noBodies];
516 // loop over number of bodies
517 for(MInt i = 0; i < noBodies; i++) {
518 start = i;
519 parallelIo->setOffset(1, start, 2);
520 MString buf;
521 parallelIo->readArray(&buf, varName);
522 (bodies[i]).append(buf);
523 DEBUG("GeometryIONetcdf::readPropertyFile " << bodies[i], MAIA_DEBUG_USER1);
524 }
525 break;
526 }
527 default: {
528 }
529 }
530 // find all segments for the property
531
532 list<MInt> segmentList;
533 for(MInt i = 0; i != noBodies; i++) {
534 DEBUG("GeometryIONetcdf::readPropertyFile definition for body " << bodies[i], MAIA_DEBUG_USER1);
535 bodyIterator zI;
536 // look for the body in the bodyMap
537 zI = m_bodyMap->find(bodies[i]);
538 // append all segments of the body to the segmentlist
539 for(MInt j = 0; j < zI->second->noSegments; j++)
540 segmentList.push_back(zI->second->segments[j]);
541 }
542
543 char* du;
544 du = strrchr(const_cast<MChar*>(varName.c_str()), MPropertySeperator);
545 MString dummy(varName);
546 // strip the varname of "_bodies.1"
547 dummy.replace(dummy.find("_bodies."), dummy.size(), du);
548 DEBUG("GeometryIONetcdf::readPropertyFile found property : " << dummy, MAIA_DEBUG_USER1);
549 // find the property id
550
551 list<MInt>::const_iterator it = segmentList.begin();
552 dummy.erase(dummy.find(".")); // erase the dot and the id
553 // create the property for every segment
554 for(; it != segmentList.end(); it++) {
555 p = new GeometryProperty;
556 p->segmentId = *it;
557 p->name.append(dummy);
558 makeProperty(p, dummy, parallelIo); // create new Property
559 DEBUG("GeometryIONetcdf::readPropertyFile created property for solver " << *it, MAIA_DEBUG_USER1);
560 }
561 } // end of if ( strstr ( varName,"_bodies." ) )
562 else {
563 // Determine the segmentId
564 char* du;
565 du = strrchr(const_cast<MChar*>(varName.c_str()), MPropertySeperator) + 1;
566 MInt singleSegmentId = atoi(du);
567
568 MString dummyName(varName);
569
570 if(singleSegmentId || *du == '0') {
571 DEBUG("Found single segment property definition for segment " << singleSegmentId, MAIA_DEBUG_IO);
572 p = new GeometryProperty;
573 p->segmentId = singleSegmentId;
574
575 MString dummy = dummyName;
576
577 dummyName.erase(dummyName.find(".")); // erase the dot and the id
578 p->name.append(dummyName);
579 makeProperty(p, dummy, parallelIo); // create new Property
580 }
581 }
582 }
583 }
584 // Insert here the check for the geometry property consistency
586 DEBUG("GeometryIONetcdf::readPropertyFile ** Property check successful \n", MAIA_DEBUG_USER1);
587 }
588 }
589}
590
603 TRACE();
604
605 m_log << " * reading rest of the properties" << endl;
606
608 vector<MString> varNames = parallelIo->getDatasetNames();
609 MInt noVariables = varNames.size();
610
611 for(MInt id = 0; id < noVariables; id++) {
612 MString varName = varNames[id];
613
614 if(!strstr(varName.c_str(), ".")) {
616 p->segmentId = m_noSegments;
617 p->name.append(varName);
618 makeProperty(p, varName, parallelIo);
619 } else {
620 if(strstr(varName.c_str(), "BC.")) {
621 // create default
623 p_def->propertyType = MINT;
624 p_def->segmentId = m_noSegments;
625 p_def->name.append("BC");
626 p_def->elements = 1;
627 p_def->intField = new MInt[1];
628 p_def->intField[0] = 0;
629
630 const pair<const MString, GeometryProperty*> mp_def(p_def->name, p_def);
631 m_geometryPropertyMap->insert(mp_def);
632
633 // read all others
634 MInt len = parallelIo->getArraySize(varName.c_str());
635 MIntScratchSpace bcs(len, AT_, "bcs");
636 parallelIo->setOffset(len, 0);
637 parallelIo->readArray(bcs.getPointer(), varName.c_str());
638
639 // create a property for each element with increasing segmentId
640 for(MInt i = 0; i < len; i++) {
642 p->propertyType = MINT;
643 p->segmentId = i;
644 p->name.append("BC");
645 p->elements = 1;
646 p->intField = new MInt[1];
647 p->intField[0] = bcs[i];
648
649 const pair<const MString, GeometryProperty*> mp(p->name, p);
650 m_geometryPropertyMap->insert(mp);
651 }
652 } else if(strstr(varName.c_str(), "filename.")) {
653 // create default
655 p_def->propertyType = MSTRING;
656 p_def->segmentId = m_noSegments;
657 p_def->name.append("filename");
658 p_def->elements = 1;
659 p_def->stringField = new MString[1];
660 p_def->stringField[0] = "";
661
662 const pair<const MString, GeometryProperty*> mp_def(p_def->name, p_def);
663 m_geometryPropertyMap->insert(mp_def);
664
665 MString allnames;
666 MInt lenAll = parallelIo->getArraySize("filename.");
667 parallelIo->setOffset(lenAll, 0);
668 parallelIo->readArray(&allnames, "filename.");
669
670 MInt num = count(allnames.begin(), allnames.end(), ',') + 1;
671 MStringScratchSpace name(num, AT_, "name");
672 for(MInt i = 0; i < num; i++) {
673 MInt del_pos = allnames.find(",");
674 name[i] = allnames.substr(0, del_pos);
675 MString tmp = allnames.substr(del_pos + 1, allnames.length() - del_pos);
676 allnames = tmp;
677 }
678
679 // create a property for each element with increasing segmentId
680 for(MInt i = 0; i < num; i++) {
682 p->propertyType = MSTRING;
683 p->segmentId = i;
684 p->name.append("filename");
685 p->elements = 1;
686 p->stringField = new MString[1];
687 p->stringField[0] = name[i];
688
689 const pair<const MString, GeometryProperty*> mp(p->name, p);
690 m_geometryPropertyMap->insert(mp);
691 }
692 }
693 }
694 }
695 }
696}
697
713 TRACE();
714
715 m_log << " - rank 0 distributes the geometry property information" << endl;
716 // 1. communicate the number of properties
717 MInt propsize = m_geometryPropertyMap->size();
718 MPI_Bcast(&propsize, 1, MPI_INT, 0, mpiComm(), AT_, "propsize");
719
720 // 2. run over all properties
721 for(geometryPropertyMap::iterator it = m_geometryPropertyMap->begin(); it != m_geometryPropertyMap->end(); ++it) {
722 GeometryProperty* prop = (*it).second;
723
724 // 2.1 communicate the name
725 MInt name_length = prop->name.length();
726 MCharScratchSpace c_name(name_length, AT_, "c_name");
727 strcpy(c_name.begin(), prop->name.c_str());
728
729 MPI_Bcast(&name_length, 1, MPI_INT, 0, mpiComm(), AT_, "name_length");
730 MPI_Bcast(c_name.begin(), name_length, MPI_CHAR, 0, mpiComm(), AT_, "c_name.begin()");
731
732 // 2.2 communicate the int data, i.e., propertyType, elements, segmentId
733 MIntScratchSpace int_data(3, AT_, "int_data");
734 int_data[0] = prop->propertyType;
735 int_data[1] = prop->elements;
736 int_data[2] = prop->segmentId;
737
738 MPI_Bcast(int_data.getPointer(), 3, MPI_INT, 0, mpiComm(), AT_, "int_data.getPointer()");
739
740 // 2.3 communicate the arrays
741 switch(prop->propertyType) {
742 case MINT: {
743 MPI_Bcast(prop->intField, prop->elements, MPI_INT, 0, mpiComm(), AT_, "prop->intField");
744 break;
745 }
746 case MFLOAT: {
747 MPI_Bcast(prop->floatField, prop->elements, MPI_DOUBLE, 0, mpiComm(), AT_, "prop->floatField");
748 break;
749 }
750 case MSTRING: {
751 MIntScratchSpace off(prop->elements + 1, AT_, "off");
752 MInt fld_len = 0;
753 for(MInt i = 0; i < prop->elements; i++) {
754 off[i] = fld_len;
755 fld_len += prop->stringField[i].length();
756 }
757 off[prop->elements] = fld_len;
758
759 char* buf = new char[fld_len];
760 for(MInt i = 0; i < prop->elements; i++)
761 strncpy(&buf[off[i]], prop->stringField[i].c_str(), prop->stringField[i].length());
762
763 MPI_Bcast(&fld_len, 1, MPI_INT, 0, mpiComm(), AT_, "fld_len");
764 MPI_Bcast(off.getPointer(), prop->elements + 1, MPI_INT, 0, mpiComm(), AT_, "off.getPointer()");
765 MPI_Bcast(buf, fld_len, MPI_CHAR, 0, mpiComm(), AT_, "buf");
766 delete[] buf;
767 break;
768 }
769 default: {
770 }
771 }
772 }
773}
774
775
792 TRACE();
793
794 // 1. receive the number of properties
795 MInt propsize = 0;
796 MPI_Bcast(&propsize, 1, MPI_INT, 0, mpiComm(), AT_, "propsize");
797
798 // 2. run over all properties
799 for(MInt p = 0; p < propsize; p++) {
801
802 // 2.1 receive the name
803 MInt name_length = 0;
804 MPI_Bcast(&name_length, 1, MPI_INT, 0, mpiComm(), AT_, "name_length");
805 char* name = new char[name_length + 1];
806 name[name_length] = '\0';
807 MPI_Bcast(name, name_length, MPI_CHAR, 0, mpiComm(), AT_, "name");
808 prop->name = name;
809
810 // 2.2 receive the int data, i.e., propertyType, elements, segmentId
811 MIntScratchSpace int_data(3, AT_, "int_data");
812 MPI_Bcast(int_data.getPointer(), 3, MPI_INT, 0, mpiComm(), AT_, "int_data.getPointer()");
813 prop->propertyType = (VariableType)int_data[0];
814 prop->elements = int_data[1];
815 prop->segmentId = int_data[2];
816
817 // 2.3 receive the arrays
818 switch(prop->propertyType) {
819 case MINT: {
820 prop->intField = new MInt[prop->elements];
821 MPI_Bcast(prop->intField, prop->elements, MPI_INT, 0, mpiComm(), AT_, "prop->intField");
822 break;
823 }
824 case MFLOAT: {
825 prop->floatField = new MFloat[prop->elements];
826 MPI_Bcast(prop->floatField, prop->elements, MPI_DOUBLE, 0, mpiComm(), AT_, "prop->floatField");
827 break;
828 }
829 case MSTRING: {
830 prop->stringField = new MString[prop->elements];
831
832 MIntScratchSpace off(prop->elements + 1, AT_, "off");
833 MInt fld_len = 0;
834 MPI_Bcast(&fld_len, 1, MPI_INT, 0, mpiComm(), AT_, "fld_len");
835 MPI_Bcast(off.getPointer(), prop->elements + 1, MPI_INT, 0, mpiComm(), AT_, "off.getPointer()");
836
837 char* buf = new char[fld_len];
838 MPI_Bcast(buf, fld_len, MPI_CHAR, 0, mpiComm(), AT_, "buf");
839
840 for(MInt i = 0; i < prop->elements; i++) {
841 MInt charsize = off[i + 1] - off[i];
842 char* tmp = new char[charsize + 1];
843 strncpy(tmp, &buf[off[i]], charsize);
844 tmp[charsize] = '\0';
845 MString st(tmp);
846 prop->stringField[i] = st;
847 delete[] tmp;
848 }
849 delete[] buf;
850 break;
851 }
852 default: {
853 }
854 }
855
856 // 2.4 insert the property into the property map
857 const pair<const MString, GeometryProperty*> mp(prop->name, prop);
858 m_geometryPropertyMap->insert(mp);
859 }
860}
861
876 TRACE();
877
878 m_log << " - rank 0 distributes the body information" << endl;
879
880 // 1. communicate the number of bodies
881 MInt bosize = m_bodyMap->size();
882 MPI_Bcast(&bosize, 1, MPI_INT, 0, mpiComm(), AT_, "bosize");
883
884 // 2. run over all bodies
885 for(bodyMap::iterator it = m_bodyMap->begin(); it != m_bodyMap->end(); ++it) {
886 Body* body = (*it).second;
887
888 // 2.1 communicate the name
889 MInt name_length = body->name.length();
890 MCharScratchSpace c_name(name_length, AT_, "c_name");
891 strcpy(c_name.begin(), body->name.c_str());
892
893 MPI_Bcast(&name_length, 1, MPI_INT, 0, mpiComm(), AT_, "name_length");
894 MPI_Bcast(c_name.begin(), name_length, MPI_CHAR, 0, mpiComm(), AT_, "c_name.begin()");
895
896 // 2.2 communicate the int data
897 MPI_Bcast(&body->noSegments, 1, MPI_INT, 0, mpiComm(), AT_, "body->noSegments");
898 MPI_Bcast(body->segments, body->noSegments, MPI_INT, 0, mpiComm(), AT_, "body->segments");
899 }
900}
901
917 TRACE();
918
919 // 1. receive the number of bodies
920 MInt bosize = 0;
921 MPI_Bcast(&bosize, 1, MPI_INT, 0, mpiComm(), AT_, "bosize");
922
923 // 2. run over all bodies
924 for(MInt p = 0; p < bosize; p++) {
925 Body* body = new Body;
926 m_noBodies++;
927
928 // 2.1 receive the name
929 MInt name_length = 0;
930 MPI_Bcast(&name_length, 1, MPI_INT, 0, mpiComm(), AT_, "name_length");
931 char* name = new char[name_length + 1];
932 name[name_length] = '\0';
933 MPI_Bcast(name, name_length, MPI_CHAR, 0, mpiComm(), AT_, "name");
934 body->name = name;
935
936 // 2.2 receive the int data
937 MPI_Bcast(&body->noSegments, 1, MPI_INT, 0, mpiComm(), AT_, "body->noSegments");
938 body->segments = new MInt[body->noSegments];
939 MPI_Bcast(body->segments, body->noSegments, MPI_INT, 0, mpiComm(), AT_, "body->segments");
940
941 // 2.3 insert body into body map
942 m_bodyMap->insert(make_pair(body->name, body));
943 }
944
946}
947
948//--------------------------------------------------------------------------------
954 TRACE();
955
956 for(geometryPropertyIterator i = m_geometryPropertyMap->begin(); i != m_geometryPropertyMap->end(); i++) {
957 /* if default property exists, then take next property */
958
959 if(m_geometryPropertyMap->lower_bound(i->second->name)->second->segmentId == m_noSegments) {
960 DEBUG("GeometryIONetcdf::checkPropertyConsistency default property exists for :" << i->second->name,
961 MAIA_DEBUG_USER1);
962 } else {
963 return false;
964 }
965 }
966
967 return true;
968}
969
970//--------------------------------------------------------------------------
977 TRACE();
978 list<MInt> segmentList;
979 list<MInt> compareList;
980 MInt index = 0;
981 for(bodyMap::const_iterator it = m_bodyMap->begin(); it != m_bodyMap->end(); it++) {
982 for(MInt i = 0; i < it->second->noSegments; i++) {
983 // cerr << it->second->segments[i] << endl;
984 // cerr << index << endl;
985 segmentList.push_back(it->second->segments[i]);
986 compareList.push_back(index++);
987 }
988 }
989 segmentList.sort();
990 if(segmentList == compareList) {
991 return true;
992 } else {
993 return false;
994 }
995}
996
997//---------------------------------------------------------------------------
1005 TRACE();
1006
1007 // WARNING: untested switch from NetCDF/Parallel netCDF to ParallelIo
1008 // The method previously used direct I/O calls, which were replaced by
1009 // ParallelIo methods in summer 2015. However, since the method was not
1010 // used by any of the testcases, this code is still *untested*. Thus,
1011 // if your code uses this part of the code, please make sure that the
1012 // I/O still works as expected and then remove this warning as well as
1013 // the subsequent TERMM().
1014 TERMM(1, "untested I/O method, please see comment for how to proceed");
1015 ParallelIo parallelIo(fileName, maia::parallel_io::PIO_REPLACE, MPI_COMM_SELF);
1016 /*
1017 *
1018 * ParallelIo define solver --->
1019 *
1020 */
1021 MString dimName;
1022 for(geometryPropertyMap::iterator i = pMap->begin(); i != pMap->end(); i++) {
1023 dimName = i->first;
1024 dimName.append("Dim");
1025 switch(i->second->type()) {
1026 case MINT: {
1027 parallelIo.defineArray(maia::parallel_io::PIO_INT, i->first, i->second->count());
1028 break;
1029 }
1030
1031 case MFLOAT: {
1032 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, i->first, i->second->count());
1033 break;
1034 }
1035
1036 case MSTRING: {
1037 ParallelIo::size_type totalCount[2];
1038 totalCount[0] = i->second->count();
1039 totalCount[1] = NC_MAX_NAME;
1040 parallelIo.defineArray(maia::parallel_io::PIO_STRING, i->first, 2, totalCount);
1041 break;
1042 }
1043
1044 default: {
1045 mTerm(1, AT_, "Uknown property type");
1046 }
1047 }
1048 }
1049
1050 /*
1051 *
1052 * <----- ParallelIo define solver
1053 *
1054 */
1055 for(geometryPropertyMap::iterator i = pMap->begin(); i != pMap->end(); i++) {
1056 switch(i->second->type()) {
1057 case MINT: {
1058 parallelIo.setOffset(i->second->count(), 0);
1059 parallelIo.writeArray(i->second->intField, i->first);
1060 break;
1061 }
1062
1063 case MFLOAT: {
1064 parallelIo.setOffset(i->second->count(), 0);
1065 parallelIo.writeArray(i->second->floatField, i->first);
1066 break;
1067 }
1068
1069 case MSTRING: {
1070 parallelIo.setOffset(i->second->count(), 0, 2);
1071 parallelIo.writeArray(i->second->asString(), i->first);
1072 break;
1073 }
1074
1075 default: {
1076 mTerm(1, AT_, "Unknown property type");
1077 }
1078 }
1079 }
1080}
void distributeBodyProperties()
distributes the body information under all processes
MPI_Comm mpiComm() const
void receiveBodyProperties()
receives the body information from rank 0
void readBodiesNewIOMethod(ParallelIo *)
geometryAssembly * m_geometryAssembly
void readPropertyFileNewIOMethod(ParallelIo *parallelIo)
reads in the geomertry property file the old way
MBool checkGeometryPropertyConsistency()
void receiveGeometryProperties()
receives the geometry properties from rank 0
geometryPropertyMap * m_geometryPropertyMap
void writeProperties(const MChar *fileName, geometryPropertyMap *pMap)
Write the properties into a netcdf file.
void readBodiesOldIOMethod(ParallelIo *)
geometryAssembly * readPropertyFile(MString fileName)
check if the geometry property file is of new or old type and calls the according function
void readPropertyFileOldIOMethod(ParallelIo *parallelIo)
reads in the geomertry property file the old way
void distributeGeometryProperties()
distributes the read geometry properties under all processes
void makeProperty(GeometryProperty *, MString, ParallelIo *)
VariableType propertyType
MInt getDatasetType(const MString &name)
Returns the data type of an array.
Definition: parallelio.h:530
void readScalar(T *scalar, const MString &name)
Read scalar data from file. [MPI]
Definition: parallelio.h:1758
void setOffset(const size_type localCount, const size_type offset, const size_type noDims, const size_type noChunks)
Set the local and global counts, as well the local offset for array operations.
Definition: parallelio.h:1840
void defineArray(maiabd_type type, const MString &name, size_type totalCount)
Create a new array in the file.
Definition: parallelio.h:783
void writeArray(const T *array, const MString &name, size_type memoryStride=-1, size_type diskStride=-1)
Write array data to file. [MPI]
Definition: parallelio.h:1046
MBool hasDataset(const MString &name, MInt dimension)
Check if the file contains an dataset with the given name and dimension.
Definition: parallelio.h:467
std::vector< MString > getDatasetNames(const size_type dimensions=-1)
Returns a vector with the names of all existing datasets with given dimensionality in the file.
Definition: parallelio.h:554
MBool hasAttribute(const MString &name, const MString &path="")
Check if a given attribute exists in the file.
Definition: parallelio.h:714
MLong size_type
Type used for all size- and offset-related values.
Definition: parallelio.h:123
size_type getArraySize(const MString &name, const size_type dimensionId=0)
Get the length of an array in the file.
Definition: parallelio.h:667
size_type getDatasetNoDims(const MString &name)
Get the number of dimensions of a dataset with given name.
Definition: parallelio.h:594
void readArray(T *array, const MString &name, size_type memoryStride=-1, size_type diskStride=-1)
Read array data from file. [MPI]
Definition: parallelio.h:1523
This class is a ScratchSpace.
Definition: scratch.h:758
T * getPointer() const
Deprecated: use begin() instead!
Definition: scratch.h:316
iterator begin()
Definition: scratch.h:273
VariableType
Definition: enums.h:269
@ MINT
Definition: enums.h:269
@ MFLOAT
Definition: enums.h:269
@ MSTRING
Definition: enums.h:269
void mTerm(const MInt errorCode, const MString &location, const MString &message)
Definition: functions.cpp:29
struct b geometryAssembly
std::multimap< MString, GeometryProperty * > geometryPropertyMap
geometryPropertyMap::const_iterator geometryPropertyIterator
std::map< MString, Body * > bodyMap
bodyMap::const_iterator bodyIterator
struct y Body
define array structures
MInt g_t_readGeomFile
InfoOutFile m_log
int32_t MInt
Definition: maiatypes.h:62
std::basic_string< char > MString
Definition: maiatypes.h:55
double MFloat
Definition: maiatypes.h:52
bool MBool
Definition: maiatypes.h:58
char MChar
Definition: maiatypes.h:56
MInt id
Definition: maiatypes.h:71
int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm, const MString &name, const MString &varname)
same as MPI_Bcast
const MInt PIO_REPLACE
Definition: parallelio.h:36
const MInt PIO_STRING
Definition: parallelio.h:52
const MInt PIO_INT
Definition: parallelio.h:48
const MInt PIO_FLOAT
Definition: parallelio.h:46
const MInt PIO_READ
Definition: parallelio.h:40
bodyMap * bodies
geometryPropertyMap * geometryProperties
define array structures
MInt noSegments
MString name
MInt * segments