MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
geometryiotoml.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 "geometryiotoml.h"
8
9#include <cstring>
10#include "COMM/mpioverride.h"
11#include "IO/tomlutils.h"
12#include "MEMORY/scratch.h"
13#include "UTIL/debug.h"
14#include "UTIL/timer.h"
15
16using namespace std;
17using namespace maia::io::toml;
18
19
21
22
24 // TRACE();
25
26 switch(prop.type()) {
27 case MINT: {
28 DEBUG("GeometryIOToml::makeProperty found integer property :", MAIA_DEBUG_USER1);
29 p->propertyType = MINT;
30 p->elements = prop.size();
31 p->intField = new MInt[prop.size()];
32 copy(prop.asInt().begin(), prop.asInt().end(), p->intField);
33 break;
34 }
35
36 case MFLOAT: {
37 DEBUG("GeometryIOToml::makeProperty found float property :", MAIA_DEBUG_USER1);
38 p->propertyType = MFLOAT;
39 p->elements = prop.size();
40 p->floatField = new MFloat[prop.size()];
41 copy(prop.asFloat().begin(), prop.asFloat().end(), p->floatField);
42 break;
43 }
44
45 case MSTRING: {
46 DEBUG("GeometryIOToml::makeProperty found char property :", MAIA_DEBUG_USER1);
47 p->propertyType = MSTRING;
48 p->elements = prop.size();
49 p->stringField = new MString[prop.size()];
50 copy(prop.asString().begin(), prop.asString().end(), p->stringField);
51 break;
52 }
53 default: {
54 stringstream errorMessage;
55 errorMessage << "GeometryIOToml::makeProperty Error: Unsupported variable input type encountered!" << endl;
56 TERMM(1, errorMessage.str());
57 }
58 }
59
60 // Insert property into property map
61 const pair<const MString, GeometryProperty*> mp(p->name, p);
62 m_geometryPropertyMap->insert(mp);
63
64 DEBUG("GeometryIOToml::makeProperty created default property ", MAIA_DEBUG_USER1);
65 DEBUG("GeometryIOToml::makeProperty elements = " << p->elements, MAIA_DEBUG_USER1);
66 DEBUG("GeometryIOToml::makeProperty m_noProperties = " << m_geometryPropertyMap->size(), MAIA_DEBUG_USER1);
67}
68
69
70void GeometryIOToml::readBodiesNewIOMethod(const std::vector<Property>& properties) {
71 TRACE();
72 m_log << " * reading body information" << endl;
73
74 Property bodySegments, bodySegmentsNames, bodySegmentsNum;
75 for(auto&& prop : properties) {
76 if(prop.name() == "body_segments") {
77 bodySegments = prop;
78 } else if(prop.name() == "body_segments_names") {
79 bodySegmentsNames = prop;
80 } else if(prop.name() == "body_segments_num") {
81 bodySegmentsNum = prop;
82 }
83 }
84
85 if(bodySegments.valid() && bodySegmentsNames.valid() && bodySegmentsNum.valid()) {
86 MInt len_bsnum = bodySegmentsNum.size();
87 MInt len_bs = bodySegments.size();
88
89 MString bsallnames;
90 MIntScratchSpace bs(len_bs, AT_, "bs");
91 MStringScratchSpace bsname(len_bsnum, AT_, "bsname");
92 MIntScratchSpace bsnum(len_bsnum, AT_, "bsnum");
93
94 copy(bodySegments.asInt().begin(), bodySegments.asInt().end(), bs.data());
95 bsallnames = bodySegmentsNames.asString()[0];
96 copy(bodySegmentsNum.asInt().begin(), bodySegmentsNum.asInt().end(), bsnum.data());
97
98 for(MInt i = 0; i < len_bsnum; i++) {
99 MInt del_pos = bsallnames.find(",");
100 bsname[i] = bsallnames.substr(0, del_pos);
101 MString tmp = bsallnames.substr(del_pos + 1, bsallnames.length() - del_pos);
102 bsallnames = tmp;
103 }
104
105 for(MInt i = 0, j = 0; i < len_bsnum; i++) {
106 Body* body = new Body;
107 m_noBodies++;
108
109 body->name = bsname[i];
110 body->noSegments = bsnum[i];
111 body->segments = new MInt[body->noSegments];
112
113 for(MInt k = 0; k < body->noSegments; k++, j++)
114 body->segments[k] = bs[j];
115
116 if(m_bodyMap->find(body->name) == m_bodyMap->end()) m_bodyMap->insert(make_pair(body->name, body));
117 }
118 }
119
121}
122
123
124void GeometryIOToml::readBodiesOldIOMethod(const std::vector<Property>& properties) {
125 TRACE();
126
127 m_log << " * reading body information" << endl;
128
129 // Iterate over body_segments
130 for(auto&& prop : properties) {
131 // Skip if wrong variable name
132 if(!strstr(prop.name().c_str(), "body_segments.")) {
133 continue;
134 }
135
136 const auto pname = prop.name(); // This is necessary to prevent use-after-free errors
137 const char* du = strrchr(pname.c_str(), '.');
138
139 /* create body element */
140 Body* body;
141 body = new Body;
142 body->name.append(++du);
143 DEBUG("GeometryIOToml::readBodies Body found (name: " << body->name << ")", MAIA_DEBUG_USER2);
144 m_noBodies++;
145
146 /* get segments for the body */
147 MInt length = prop.size();
148 DEBUG("GeometryIOToml::readBodies The Body has " << length << " solvers.", MAIA_DEBUG_USER2);
149 body->noSegments = length;
150 body->segments = new MInt[length];
151 copy(prop.asInt().begin(), prop.asInt().end(), body->segments);
152
153 /* insert the body into the bodyMap*/
154 if(m_bodyMap->find(body->name) == m_bodyMap->end()) m_bodyMap->insert(make_pair(body->name, body));
155 }
156
158}
159
160
161//--------------------------------------------------------------------------
167 TRACE();
168 /* create a body named "default" */
169 Body* body;
170 body = new Body;
171 body->name.append("default");
172
173 /* search for all segments that are defined */
174 list<MInt> segmentList;
175 for(bodyMap::const_iterator it = m_bodyMap->begin(); it != m_bodyMap->end(); it++) {
176 for(MInt i = 0; i < it->second->noSegments; i++) {
177 segmentList.push_back(it->second->segments[i]);
178 }
179 }
180 segmentList.sort();
181
182 /* The number of undefined segments equals the number of total
183 segments minus the number of defined segments ... */
184 body->noSegments = (m_noSegments - segmentList.size());
185 body->segments = new MInt[body->noSegments];
186
187 /* this adds all segmentId's that aren't defined to the default body*/
188 MInt i = 0;
189 MInt simpleIterator = 0;
190 list<MInt>::const_iterator segmentIt = segmentList.begin();
191
192 if(!segmentList.empty()) {
193 while(i < m_noSegments) {
194 if(*segmentIt == i) {
195 i++;
196 segmentIt++;
197 } else {
198 body->segments[simpleIterator] = i;
199 DEBUG("GeometryIOToml::buildDefaultBody Added segment " << i << " to the default body. ", MAIA_DEBUG_USER1);
200 i++;
201 simpleIterator++;
202 }
203 }
204 }
205
206 /* insert the default body in the body map */
207 m_bodyMap->insert(make_pair(body->name, body));
208 DEBUG("GeometryIOToml::buildDefaultBody Default body has " << body->noSegments << " segments.", MAIA_DEBUG_USER1);
209 m_noBodies++;
210}
211
212
213//--------------------------------------------------------------------------
227 TRACE();
228
229 // init member variables
230 m_newIOMethod = false;
231 m_noSegments = 0;
232 m_noBodies = 0;
234 m_bodyMap = new bodyMap;
236
237 if(domainId() == 0) {
238 m_log << " - rank 0 reads data from disk" << endl;
239
240 // Read property file
241 ifstream ifs(fileName);
242 if(!ifs) {
243 TERMM(1, "could not open geometry file '" + fileName + "'");
244 }
245 stringstream ss;
246 ss << ifs.rdbuf();
247 if(ss.str() == "") {
248 TERMM(1, "geometry file '" + fileName + "' appears to be empty");
249 }
250
251 // Determine length of null-terminated character string
252 MInt length = ss.str().size() + 1;
253
254 // Convert to char array
255 vector<MChar> text(length);
256 strcpy(text.data(), ss.str().c_str());
257
258 // Broadcast string length and contents
259 MPI_Bcast(&length, 1, MPI_INT, 0, mpiComm(), AT_, "length");
260 MPI_Bcast(text.data(), length, MPI_CHAR, 0, mpiComm(), AT_, "text.data()");
261
262 // Store file content in string
263 m_rawText = ss.str();
264 } else {
265 // On all other domains, first receive string length
266 MInt length = -1;
267 MPI_Bcast(&length, 1, MPI_INT, 0, mpiComm(), AT_, "length");
268
269 // Then receive file contents
270 vector<MChar> text(length);
271 MPI_Bcast(text.data(), length, MPI_CHAR, 0, mpiComm(), AT_, "text.data()");
272
273 // Store file content in string
274 m_rawText = text.data();
275 }
276
277 // Create parser for TOML files and parse file contents
278 stringstream ss;
279 ss << m_rawText;
280 vector<maia::io::toml::Property> properties;
281 collectProperties(cpptoml::parser{ss}.parse(), properties);
282
283 // Read information on newIOMethod and number of segments
284 m_newIOMethod = false;
285 m_noSegments = -1;
286 for(auto&& prop : properties) {
287 if(prop.name() == "newIOMethod") {
288 m_newIOMethod = true;
289 continue;
290 }
291
292 if(prop.name() == "noSegments") {
293 m_noSegments = prop.asInt()[0];
294 continue;
295 }
296 }
297
298 // do the actual processing of the geometry properties
299 NEW_SUB_TIMER(t_readRest, "rest geometry property", g_t_readGeomFile);
300 NEW_SUB_TIMER(t_readBodies, "geometry bodies", g_t_readGeomFile);
301
302 if(m_newIOMethod) {
303 RECORD_TIMER_START(t_readBodies);
304 readBodiesNewIOMethod(properties);
305 RECORD_TIMER_STOP(t_readBodies);
306
307 RECORD_TIMER_START(t_readRest);
308 readPropertyFileNewIOMethod(properties);
309 RECORD_TIMER_STOP(t_readRest);
310 } else {
311 RECORD_TIMER_START(t_readBodies);
312 readBodiesOldIOMethod(properties);
313 RECORD_TIMER_STOP(t_readBodies);
314
315 RECORD_TIMER_START(t_readRest);
316 readPropertyFileOldIOMethod(properties);
317 RECORD_TIMER_STOP(t_readRest);
318 }
319
320 // fill the body and the property maps
323
324 m_log << endl;
325
326 return m_geometryAssembly;
327}
328
329
339void GeometryIOToml::readPropertyFileOldIOMethod(const std::vector<Property>& properties) {
340 TRACE();
341
343 m_log << " * reading rest of the properties" << endl;
344
345 // Check body consistency or die
346 if(!checkBodyConsistency()) {
347 TERMM(1, "Body consistency check failed");
348 }
349
350 for(auto&& prop : properties) {
351 // Store name for convenience
352 const MString varName = prop.name();
353
354 // if default property
355 if(!strstr(varName.c_str(), ".")) {
356 // if there's no dot in string (default prop)
357 // store default property in last solver,
358 // the others to their belonging id's
359
360 DEBUG("GeometryIOToml::readPropertyFile default property : " << varName, MAIA_DEBUG_USER1);
361 p = new GeometryProperty;
362 p->segmentId = m_noSegments; // Insert default segment as last segment
363 p->name.append(varName);
364 makeProperty(p, prop); // create new Property
365 }
366 // if a property defined for one or more bodies
367 else {
368 if(strstr(varName.c_str(), "_bodies.")) {
369 DEBUG("GeometryIOToml::readPropertyFile normal property: " << varName, MAIA_DEBUG_USER1);
370 MInt noBodies = prop.size();
371 MString* bodies = new MString[noBodies];
372 copy(prop.asString().begin(), prop.asString().end(), bodies);
373
374 // find all segments for the property
375 list<MInt> segmentList;
376 for(MInt i = 0; i != noBodies; i++) {
377 DEBUG("GeometryIOToml::readPropertyFile definition for body " << bodies[i], MAIA_DEBUG_USER1);
378 bodyIterator zI;
379 // look for the body in the bodyMap
380 zI = m_bodyMap->find(bodies[i]);
381 // append all segments of the body to the segmentlist
382 for(MInt j = 0; j < zI->second->noSegments; j++)
383 segmentList.push_back(zI->second->segments[j]);
384 }
385
386 char* du;
387 du = strrchr(const_cast<MChar*>(varName.c_str()), '.');
388 MString dummy(varName);
389 // strip the varname of "_bodies.1"
390 dummy.replace(dummy.find("_bodies."), dummy.size(), du);
391 DEBUG("GeometryIOToml::readPropertyFile found property : " << dummy, MAIA_DEBUG_USER1);
392 // find the property id
393
394 list<MInt>::const_iterator it = segmentList.begin();
395 dummy.erase(dummy.find(".")); // erase the dot and the id
396 // create the property for every segment
397 for(; it != segmentList.end(); it++) {
398 p = new GeometryProperty;
399 p->segmentId = *it;
400 p->name.append(dummy);
401 makeProperty(p, prop); // create new Property
402 DEBUG("GeometryIOToml::readPropertyFile created property for solver " << *it, MAIA_DEBUG_USER1);
403 }
404 } // end of if ( strstr ( varName,"_bodies." ) )
405 else {
406 // Determine the segmentId
407 char* du;
408 du = strrchr(const_cast<MChar*>(varName.c_str()), '.') + 1;
409 MInt singleSegmentId = atoi(du);
410
411 MString dummyName(varName);
412
413 if(singleSegmentId || *du == '0') {
414 DEBUG("Found single segment property definition for segment " << singleSegmentId, MAIA_DEBUG_IO);
415 p = new GeometryProperty;
416 p->segmentId = singleSegmentId;
417
418 MString dummy = dummyName;
419
420 dummyName.erase(dummyName.find(".")); // erase the dot and the id
421 p->name.append(dummyName);
422 makeProperty(p, prop); // create new Property
423 }
424 }
425 }
426 }
427 // Insert here the check for the geometry property consistency
429 DEBUG("GeometryIOToml::readPropertyFile ** Property check successful \n", MAIA_DEBUG_USER1);
430 }
431}
432
433
445void GeometryIOToml::readPropertyFileNewIOMethod(const std::vector<Property>& properties) {
446 TRACE();
447
448 m_log << " * reading rest of the properties" << endl;
449
450 // Check body consistency or die
451 if(!checkBodyConsistency()) {
452 TERMM(1, "Body consistency check failed");
453 }
454
455 for(auto&& prop : properties) {
456 // Store name for convenience
457 const MString varName = prop.name();
458
459 if(!strstr(varName.c_str(), ".")) {
461 p->segmentId = m_noSegments;
462 p->name.append(varName);
463 makeProperty(p, prop);
464 } else {
465 if(strstr(varName.c_str(), "BC.")) {
466 // create default
468 p_def->propertyType = MINT;
469 p_def->segmentId = m_noSegments;
470 p_def->name.append("BC");
471 p_def->elements = 1;
472 p_def->intField = new MInt[1];
473 p_def->intField[0] = 0;
474
475 const pair<const MString, GeometryProperty*> mp_def(p_def->name, p_def);
476 m_geometryPropertyMap->insert(mp_def);
477
478 // read all others
479 MInt len = prop.size();
480 MIntScratchSpace bcs(len, AT_, "bcs");
481 copy(prop.asInt().begin(), prop.asInt().end(), bcs.data());
482
483 // create a property for each element with increasing segmentId
484 for(MInt i = 0; i < len; i++) {
486 p->propertyType = MINT;
487 p->segmentId = i;
488 p->name.append("BC");
489 p->elements = 1;
490 p->intField = new MInt[1];
491 p->intField[0] = bcs[i];
492
493 const pair<const MString, GeometryProperty*> mp(p->name, p);
494 m_geometryPropertyMap->insert(mp);
495 }
496 } else if(strstr(varName.c_str(), "filename.")) {
497 // create default
499 p_def->propertyType = MSTRING;
500 p_def->segmentId = m_noSegments;
501 p_def->name.append("filename");
502 p_def->elements = 1;
503 p_def->stringField = new MString[1];
504 p_def->stringField[0] = "";
505
506 const pair<const MString, GeometryProperty*> mp_def(p_def->name, p_def);
507 m_geometryPropertyMap->insert(mp_def);
508
509 MString allnames = prop.asString()[0];
510
511 MInt num = count(allnames.begin(), allnames.end(), ',') + 1;
512 MStringScratchSpace name(num, AT_, "name");
513 for(MInt i = 0; i < num; i++) {
514 MInt del_pos = allnames.find(",");
515 name[i] = allnames.substr(0, del_pos);
516 MString tmp = allnames.substr(del_pos + 1, allnames.length() - del_pos);
517 allnames = tmp;
518 }
519
520 // create a property for each element with increasing segmentId
521 for(MInt i = 0; i < num; i++) {
523 p->propertyType = MSTRING;
524 p->segmentId = i;
525 p->name.append("filename");
526 p->elements = 1;
527 p->stringField = new MString[1];
528 p->stringField[0] = name[i];
529
530 const pair<const MString, GeometryProperty*> mp(p->name, p);
531 m_geometryPropertyMap->insert(mp);
532 }
533 }
534 }
535 }
536}
537
538
540 TRACE();
541
542 for(geometryPropertyIterator i = m_geometryPropertyMap->begin(); i != m_geometryPropertyMap->end(); i++) {
543 /* if default property exists, then take next property */
544
545 if(m_geometryPropertyMap->lower_bound(i->second->name)->second->segmentId == m_noSegments) {
546 DEBUG("GeometryIOToml::checkPropertyConsistency default property exists for :" << i->second->name,
547 MAIA_DEBUG_USER1);
548 } else {
549 return false;
550 }
551 }
552
553 return true;
554}
555
556
557//--------------------------------------------------------------------------
564 TRACE();
565 list<MInt> segmentList;
566 list<MInt> compareList;
567 MInt index = 0;
568 for(bodyMap::const_iterator it = m_bodyMap->begin(); it != m_bodyMap->end(); it++) {
569 for(MInt i = 0; i < it->second->noSegments; i++) {
570 // cerr << it->second->segments[i] << endl;
571 // cerr << index << endl;
572 segmentList.push_back(it->second->segments[i]);
573 compareList.push_back(index++);
574 }
575 }
576 segmentList.sort();
577 if(segmentList == compareList) {
578 return true;
579 } else {
580 return false;
581 }
582}
void readPropertyFileOldIOMethod(const std::vector< maia::io::toml::Property > &properties)
reads in the geomertry property file the old way
void readBodiesOldIOMethod(const std::vector< maia::io::toml::Property > &properties)
bodyMap * m_bodyMap
void readBodiesNewIOMethod(const std::vector< maia::io::toml::Property > &properties)
geometryPropertyMap * m_geometryPropertyMap
void readPropertyFileNewIOMethod(const std::vector< maia::io::toml::Property > &properties)
reads in the geomertry property file the old way
geometryAssembly * readPropertyFile(MString fileName)
check if the geometry property file is of new or old type and calls the according function
MPI_Comm mpiComm() const
MBool checkGeometryPropertyConsistency()
geometryAssembly * m_geometryAssembly
void makeProperty(GeometryProperty *, const maia::io::toml::Property &prop)
MBool checkBodyConsistency()
VariableType propertyType
This class is a ScratchSpace.
Definition: scratch.h:758
pointer data()
Definition: scratch.h:289
std::shared_ptr< table > parse()
Definition: cpptoml.h:1561
Class that represents a single key-value pair for TOML properties.
Definition: tomlutils.h:69
const std::vector< MInt > & asInt() const
Definition: tomlutils.h:96
const std::vector< MFloat > & asFloat() const
Definition: tomlutils.h:102
MBool valid() const
Definition: tomlutils.h:87
const std::vector< MString > & asString() const
Definition: tomlutils.h:90
VariableType type() const
Definition: tomlutils.h:84
MLong size() const
Definition: tomlutils.h:86
@ MINT
Definition: enums.h:269
@ MFLOAT
Definition: enums.h:269
@ MSTRING
Definition: enums.h:269
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
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
void collectProperties(const std::shared_ptr< cpptoml::table > &tab, std::vector< std::string > &names, std::vector< Property > &properties, std::map< std::string, int > &solverAliases)
Recursively traverse TOML table and collect all properties with name, type, and count.
Definition: tomlutils.h:256
bodyMap * bodies
geometryPropertyMap * geometryProperties
define array structures
MInt noSegments
MString name
MInt * segments