Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/meshgen2d/src/MeshParser.cpp
3196 views
1
#include "MeshParser.h"
2
#include "MGError.h"
3
#include <string>
4
#include <iostream>
5
#include <ctype.h>
6
7
MeshParser::MeshParser( const char *path )
8
{
9
s.open( path );
10
if (s.fail())
11
blm_error( "Error opening file:", path );
12
13
bgmeshes = NULL;
14
}
15
16
MeshParser::MeshParser( const char *path, std::map<int, BGMeshToken *> *ebgs )
17
{
18
s.open( path );
19
if (s.fail())
20
blm_error( "Error opening file:", path );
21
22
bgmeshes = ebgs;
23
}
24
25
MeshParser::~MeshParser()
26
{
27
s.close();
28
}
29
30
void MeshParser::readInputFile()
31
{
32
if( !readHeader() )
33
{
34
blm_error( "Error reading header." );
35
}
36
37
if( !readNodes() )
38
{
39
blm_error( "Error reading nodes." );
40
}
41
42
if( !readEdges() )
43
{
44
blm_error( "Error reading edges." );
45
}
46
47
if( !readBodies() )
48
{
49
blm_error( "Error reading bodies." );
50
}
51
52
std::cout << "Parse OK" << std::endl;
53
}
54
55
int MeshParser::
56
readHeader()
57
{
58
if( !readWord( "Geometry2D:" ) ) return 0;
59
if( !readWord( "H:" ) ) return 0;
60
if( !readDouble( delta ) ) return 0;
61
if( !readWord( "MeshScalingFactor:" ) ) return 0;
62
if( !readDouble( scale ) ) return 0;
63
if( !readWord( "Nodes:" ) ) return 0;
64
if( !readInteger( nodeCount ) ) return 0;
65
if( !readWord( "Edges:" ) ) return 0;
66
if( !readInteger( edgeCount ) ) return 0;
67
if( !readWord( "Bodies:" ) ) return 0;
68
if( !readInteger( bodyCount ) ) return 0;
69
70
nodes.reserve( nodeCount );
71
edges.reserve( edgeCount );
72
bodies.reserve( bodyCount );
73
74
return 1;
75
}
76
77
int MeshParser::
78
readNodes()
79
{
80
int i;
81
for( i = 0; i < nodeCount; ++i )
82
{
83
NodeToken *nd = new NodeToken;
84
if( !readWord( "NodeId:" ) ) return 0;
85
if( !readInteger( nd->tag ) ) return 0;
86
if( !readInteger( nd->boundaryTag ) ) return 0;
87
88
while (ignoreComment());
89
char ch = s.peek();
90
if (ch == 'H')
91
{
92
if (!readWord( "H:" ) ) return 0;
93
if (!readDouble( nd->delta ) ) return 0;
94
}
95
else if (ch == 'R')
96
{
97
if (!readWord( "R:" ) ) return 0;
98
if (!readDouble( nd->delta ) ) return 0;
99
nd->delta *= delta;
100
}
101
else
102
{
103
nd->delta = -1.0;
104
}
105
106
if( !readDouble( nd->x ) ) return 0;
107
if( !readDouble( nd->y ) ) return 0;
108
nodes.push_back( nd );
109
}
110
return 1;
111
}
112
113
int MeshParser::
114
readEdges()
115
{
116
int i;
117
int edt;
118
int len;
119
120
for( i = 0; i < edgeCount; ++i )
121
{
122
EdgeToken *ed = new EdgeToken;
123
if( !readWord( "EdgeId:" ) ) return 0;
124
if( !readInteger( ed->tag ) ) return 0;
125
if( !readInteger( ed->boundaryTag ) ) return 0;
126
127
while (ignoreComment());
128
char ch = s.peek();
129
if (ch == 'H')
130
{
131
if (!readWord("H:")) return 0;
132
if (!readDouble(ed->delta)) return 0;
133
ed->segCount = 0;
134
}
135
else if (ch == 'R')
136
{
137
if (!readWord("R:")) return 0;
138
if (!readDouble(ed->delta)) return 0;
139
ed->delta *= delta;
140
ed->segCount = 0;
141
}
142
else if (ch == 'N')
143
{
144
if (!readWord("N:")) return 0;
145
if (!readInteger(ed->segCount)) return 0;
146
ed->delta = -1.0;
147
}
148
else
149
{
150
ed->delta = -1.0;
151
ed->segCount = 0;
152
}
153
154
if( !readInteger( len ) ) return 0;
155
for(int j = 0; j < len; ++j)
156
{
157
if( !readInteger( edt ) ) return 0;
158
ed->nodes.push_back( edt );
159
}
160
161
edges.push_back( ed );
162
}
163
return 1;
164
}
165
166
int MeshParser::
167
readBodies()
168
{
169
int i;
170
for( i = 0; i < bodyCount; ++i )
171
{
172
int layerCount;
173
currentBody = new BodyToken;
174
if( !readWord( "BodyId:" ) ) return 0;
175
if( !readInteger( currentBody->tag ) ) return 0;
176
177
while (ignoreComment());
178
char ch = s.peek();
179
if (ch == 'H')
180
{
181
if (!readWord( "H:" ) ) return 0;
182
if (!readDouble( currentBody->delta ) ) return 0;
183
}
184
else if (ch == 'R')
185
{
186
if (!readWord( "R:" ) ) return 0;
187
if (!readDouble( currentBody->delta ) ) return 0;
188
currentBody->delta *= delta;
189
}
190
else
191
{
192
currentBody->delta = -1.0;
193
}
194
195
if( !readWord( "ElementOrder:" ) ) return 0;
196
std::string order;
197
if( !readString( order ) ) return 0;
198
if (order == "Parabolic")
199
currentBody->parabolic = true;
200
else if (order == "Linear")
201
currentBody->parabolic = false;
202
else
203
return 0;
204
205
if( !readWord( "Layers:" ) ) return 0;
206
if( !readInteger( layerCount ) ) return 0;
207
if( !readLayers( layerCount ) ) return 0;
208
bodies.push_back( currentBody );
209
}
210
return 1;
211
}
212
213
int MeshParser::
214
readLayers( const int layerCount )
215
{
216
int i;
217
for( i = 0; i < layerCount; ++i )
218
{
219
int fixedNodeCount;
220
int loopCount;
221
currentLayer = new LayerToken;
222
if( !readWord( "LayerId:" ) ) return 0;
223
if( !readInteger( currentLayer->tag ) ) return 0;
224
225
while (ignoreComment());
226
char ch = s.peek();
227
if (ch == 'H')
228
{
229
if (!readWord( "H:" ) ) return 0;
230
if (!readDouble( currentLayer->delta ) ) return 0;
231
}
232
else if (ch == 'R')
233
{
234
if (!readWord( "R:" ) ) return 0;
235
if (!readDouble( currentLayer->delta ) ) return 0;
236
currentLayer->delta *= delta;
237
}
238
else
239
{
240
currentLayer->delta = -1.0;
241
}
242
243
if( !readWord( "LayerType:" ) ) return 0;
244
std::string type;
245
if( !readString( type ) ) return 0;
246
if (type == "Connect")
247
currentLayer->type = CONNECT;
248
else if (type == "BoundaryMesh")
249
currentLayer->type = BOUNDARY_MESH;
250
else if (type == "VoronoiVertex")
251
currentLayer->type = VORONOI_VERTEX;
252
else if (type == "MovingFront")
253
currentLayer->type = VORONOI_SEGMENT;
254
else if (type == "SSSFMovingFront")
255
currentLayer->type = SSSF_VORONOI_SEGMENT;
256
else if (type == "SSMFMovingFront")
257
currentLayer->type = SSMF_VORONOI_SEGMENT;
258
else if (type == "QuadGrid")
259
currentLayer->type = QUAD_GRID;
260
else if (type == "TriangleNEGrid")
261
currentLayer->type = TRIANGLE_NE_GRID;
262
else if (type == "TriangleNWGrid")
263
currentLayer->type = TRIANGLE_NW_GRID;
264
else if (type == "TriangleUJNEGrid")
265
currentLayer->type = TRIANGLE_UJ_NE_GRID;
266
else if (type == "TriangleUJNWGrid")
267
currentLayer->type = TRIANGLE_UJ_NW_GRID;
268
else if (type == "TriangleFBNEGrid")
269
currentLayer->type = TRIANGLE_FB_NE_GRID;
270
else if (type == "TriangleFBNWGrid")
271
currentLayer->type = TRIANGLE_FB_NW_GRID;
272
else
273
return 0;
274
275
if( currentLayer->type == QUAD_GRID ||
276
currentLayer->type == TRIANGLE_NE_GRID ||
277
currentLayer->type == TRIANGLE_NW_GRID ||
278
currentLayer->type == TRIANGLE_UJ_NE_GRID ||
279
currentLayer->type == TRIANGLE_UJ_NW_GRID ||
280
currentLayer->type == TRIANGLE_FB_NE_GRID ||
281
currentLayer->type == TRIANGLE_FB_NW_GRID)
282
{
283
std::string keyword;
284
if (!readString(keyword)) return 0;
285
if (keyword == "GridSize:")
286
{
287
if (!readInteger(currentLayer->gridh)) return 0;
288
if (!readInteger(currentLayer->gridv)) return 0;
289
if (!readString(keyword)) return 0;
290
}
291
292
if (keyword != "Loops:")
293
return 0;
294
295
if (!readInteger(loopCount)) return 0;
296
if (loopCount != 1) return 0;
297
if (!readLoops(loopCount)) return 0;
298
}
299
else
300
{
301
if( currentLayer->type == VORONOI_VERTEX ||
302
currentLayer->type == VORONOI_SEGMENT ||
303
currentLayer->type == SSMF_VORONOI_SEGMENT ||
304
currentLayer->type == SSSF_VORONOI_SEGMENT)
305
{
306
if( !readWord( "FixedNodes:" ) ) return 0;
307
if( !readInteger( fixedNodeCount ) ) return 0;
308
if( !readFixedNodes( fixedNodeCount ) ) return 0;
309
if( !readWord( "BGMesh:" ) ) return 0;
310
if( !readBGMesh() ) return 0;
311
}
312
313
if( currentLayer->type == SSMF_VORONOI_SEGMENT ||
314
currentLayer->type == SSSF_VORONOI_SEGMENT)
315
{
316
if( !readWord( "Seed:" ) ) return 0;
317
currentSeed = new SeedToken;
318
if( !readSeed() ) return 0;
319
currentLayer->seed = currentSeed;
320
}
321
322
if( !readWord( "Loops:" ) ) return 0;
323
if( !readInteger( loopCount ) ) return 0;
324
if( !readLoops( loopCount ) ) return 0;
325
}
326
327
currentBody->layers.push_back( currentLayer );
328
}
329
return 1;
330
}
331
332
int MeshParser::
333
readSeed()
334
{
335
if( !readString( currentSeed->type ) ) return 0;
336
if( currentSeed->type == "Explicit" )
337
{
338
int tag;
339
if( !readWord( "Nodes:" ) ) return 0;
340
if( !readInteger( tag ) ) return 0;
341
currentSeed->nodes.push_back( tag );
342
if( !readInteger( tag ) ) return 0;
343
currentSeed->nodes.push_back( tag );
344
if( !readInteger( tag ) ) return 0;
345
currentSeed->nodes.push_back( tag );
346
}
347
else if( currentSeed->type == "Implicit" )
348
{
349
if( !readWord( "Edge:" ) ) return 0;
350
if( !readInteger( currentSeed->edge ) ) return 0;
351
}
352
else return 0;
353
return 1;
354
}
355
356
int MeshParser::
357
readLoops( const int loopCount )
358
{
359
int i;
360
for( i = 0; i < loopCount; ++i )
361
{
362
int edCount;
363
LoopToken *loop = new LoopToken;
364
if( !readWord( "LoopId:" ) ) return 0;
365
if( !readInteger( loop->tag ) ) return 0;
366
if( !readWord( "Direction:" ) ) return 0;
367
if( !readInteger( loop->direction ) ||
368
loop->direction != 1 && loop->direction != -1 ) return 0;
369
if( !readWord( "Edges:" ) ) return 0;
370
if( !readInteger( edCount ) ) return 0;
371
for( int j = 0; j < edCount; ++j )
372
{
373
int ed;
374
if( !readInteger( ed ) ) return 0;
375
loop->edges.push_back( ed );
376
}
377
currentLayer->loops.push_back( loop );
378
}
379
return 1;
380
}
381
382
int MeshParser::
383
readFixedNodes( const int fixedNodeCount )
384
{
385
int i;
386
for( i = 0; i < fixedNodeCount; ++i )
387
{
388
NodeToken *nd = new NodeToken;
389
if( !readWord( "NodeId:" ) ) return 0;
390
if( !readInteger( nd->tag ) ) return 0;
391
if( !readInteger( nd->boundaryTag ) ) return 0;
392
393
while (ignoreComment());
394
char ch = s.peek();
395
if (ch == 'H')
396
{
397
if (!readWord( "H:" ) ) return 0;
398
if (!readDouble( nd->delta ) ) return 0;
399
}
400
else if (ch == 'R')
401
{
402
if (!readWord( "R:" ) ) return 0;
403
if (!readDouble( nd->delta ) ) return 0;
404
nd->delta *= delta;
405
}
406
else
407
{
408
nd->delta = -1.0;
409
}
410
411
if( !readDouble( nd->x ) ) return 0;
412
if( !readDouble( nd->y ) ) return 0;
413
414
currentLayer->fixedNodes.push_back( nd );
415
}
416
return 1;
417
}
418
419
int MeshParser::
420
readBGMesh()
421
{
422
currentLayer->bg = NULL;
423
if (bgmeshes != NULL)
424
{
425
std::map<int, BGMeshToken*>::iterator mesh = bgmeshes->find(currentLayer->tag);
426
if (mesh != bgmeshes->end())
427
currentLayer->bg = mesh->second;
428
else if ((mesh = bgmeshes->find(-1)) != bgmeshes->end())
429
currentLayer->bg = mesh->second;
430
}
431
432
BGMeshToken *bg = new BGMeshToken;
433
if( !readString( bg->type ) ) return 0;
434
if( bg->type == "Explicit" )
435
{
436
if (!readExplicitBGMesh(bg))
437
return 0;
438
}
439
else if ( bg->type == "External" )
440
{
441
std::string filename;
442
if (!readString( filename ) ) return 0;
443
444
if (currentLayer->bg == NULL)
445
{
446
MeshParser bgmeshparser(filename.c_str());
447
if (!bgmeshparser.readExplicitBGMesh(bg))
448
return 0;
449
}
450
bg->type = "Explicit";
451
}
452
453
if (currentLayer->bg == NULL)
454
currentLayer->bg = bg;
455
else
456
delete bg;
457
458
return 1;
459
}
460
461
int MeshParser::
462
readExplicitBGMesh(BGMeshToken *bg)
463
{
464
int len;
465
if( !readInteger( len ) ) return 0;
466
467
for(int i = 0; i < len; ++i)
468
{
469
NodeToken nd;
470
if( !readDouble( nd.x ) ) return 0;
471
if( !readDouble( nd.y ) ) return 0;
472
if( !readDouble( nd.delta ) ) return 0;
473
bg->nodes.push_back( nd );
474
}
475
476
return 1;
477
}
478
479
int MeshParser::
480
readBoundary()
481
{
482
int i, len, ed;
483
boundary = new BoundaryToken;
484
if( !readWord( "Boundaries:" ) ) return 0;
485
if( !readWord( "OuterBoundaries:" ) ) return 0;
486
if( !readInteger( len ) ) return 0;
487
for( i = 0; i < len; ++i )
488
{
489
if( !readInteger( ed ) ) return 0;
490
boundary->outerBoundaries.push_back( ed );
491
}
492
if( !readWord( "InnerBoundaries:" ) ) return 0;
493
if( !readInteger( len ) ) return 0;
494
for( i = 0; i < len; ++i )
495
{
496
if( !readInteger( ed ) ) return 0;
497
boundary->innerBoundaries.push_back( ed );
498
}
499
return 1;
500
}
501
502
// Read a whitespace-delimited word, with possible quoting for whitespace and comment characters
503
int MeshParser::
504
readString( std::string& ref )
505
{
506
ref.erase();
507
508
bool head = true, inquote = false, incomment = false;
509
510
while (!s.eof())
511
{
512
int ch = s.get();
513
514
if (incomment)
515
{
516
if (ch != '\n')
517
continue;
518
else
519
incomment = false;
520
}
521
522
// We are not in a comment
523
if (ch == '\"')
524
{
525
inquote = !inquote;
526
}
527
else if (!inquote && isspace(ch))
528
{
529
if (head)
530
continue;
531
else
532
break;
533
}
534
else if (!inquote && (ch == '!' || ch == '#'))
535
{
536
incomment = true;
537
}
538
else
539
{
540
head = false;
541
ref.insert(ref.end(), static_cast<char>(ch));
542
}
543
}
544
545
return !s.fail();
546
}
547
548
int MeshParser::
549
readInteger( int& ref )
550
{
551
while (ignoreComment());
552
s >> ref;
553
return !s.fail();
554
}
555
556
int MeshParser::
557
readDouble( double& ref )
558
{
559
while (ignoreComment());
560
s >> ref;
561
return !s.fail();
562
}
563
564
int MeshParser::
565
readWord( const char *ref )
566
{
567
while (ignoreComment());
568
std::string word;
569
s >> word;
570
if( word != ref ) return 0;
571
return !s.fail();
572
}
573
574
int MeshParser::
575
ignoreComment()
576
{
577
int ch = 0;
578
while (!s.eof() && isspace(ch = s.peek()))
579
s.ignore(1);
580
581
if( ch == '!' || ch == '#' )
582
{
583
s.ignore(0x7fffffff, '\n');
584
return 1;
585
}
586
return 0;
587
}
588
589