Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/meshgen2d/src/Mesh.cpp
3196 views
1
#include "../config.h"
2
#include <stdio.h>
3
#ifdef WIN32
4
#include <direct.h>
5
#else
6
#include <unistd.h>
7
#endif
8
9
#include <iostream>
10
#include <math.h>
11
#include "Mesh.h"
12
#include "GeometryNode.h"
13
#include "GeometryEdge.h"
14
#include "Connect.h"
15
#include "BoundaryLayer.h"
16
#include "VoronoiVertex.h"
17
#include "VoronoiSegment.h"
18
#include "SSMFVoronoiSegment.h"
19
#include "SSSFVoronoiSegment.h"
20
#include "Border.h"
21
#include "Body.h"
22
#include "QuadLayer.h"
23
#include "TriangleNELayer.h"
24
25
#include "Node.h"
26
#include "Element.h"
27
28
#include <vector>
29
30
Mesh::Mesh()
31
{
32
}
33
34
void Mesh::
35
convertEdgeFormat( MeshParser& parser )
36
{
37
int i, len;
38
39
std::map<int, std::list<EdgeToken*> > nodeEdges;
40
std::map<int, std::list<LayerToken*> > nodeLayers;
41
std::map<int, int> edgeBody;
42
43
std::vector<Layer *> layers;
44
45
len = parser.nodes.size();
46
for( i = 0; i < len; ++i )
47
{
48
NodeToken *nt = parser.nodes[i];
49
GeometryNode *nd = new GeometryNode( nt->tag, nt->x, nt->y);
50
nd->boundaryTag = nt->boundaryTag;
51
// nd->setDelta( nt->delta );
52
geometryNodes[ nd->tag ] = nd;
53
}
54
55
len = parser.edges.size();
56
for( i = 0; i < len; ++i )
57
{
58
EdgeToken *et = parser.edges[i];
59
60
GeometryEdge *ed = new GeometryEdge( et->tag, et->segCount );
61
ed->setBoundaryTag(et->boundaryTag);
62
63
int sz = et->nodes.size();
64
for(int j = 0; j < sz; ++j)
65
{
66
nodeEdges[et->nodes[j]].push_back(et);
67
68
GeometryNodeMap::iterator it = geometryNodes.find(et->nodes[j]);
69
if (it == geometryNodes.end())
70
blm_error("Nonexisting node in edge", et->tag);
71
72
ed->addNode( it->second );
73
}
74
75
geometryEdges[ ed->tag ] = ed;
76
}
77
78
len = parser.bodies.size();
79
for( i = 0; i < len; ++i )
80
{
81
BodyToken *bt = parser.bodies[i];
82
83
Body *body = new Body( bt->tag, bt->parabolic );
84
int layerLen = bt->layers.size();
85
for( int m = 0; m < layerLen; ++m )
86
{
87
LayerToken *ly = bt->layers[m];
88
89
if (ly->delta <= 0.0)
90
ly->delta = bt->delta;
91
92
BGMesh *bgmesh = NULL;
93
Layer *layer;
94
95
// Here comes the selection depending on type
96
if( ly->type == QUAD_GRID )
97
layer = new QuadLayer( bt->tag );
98
else if( ly->type == TRIANGLE_NE_GRID )
99
layer = new TriangleNELayer( bt->tag );
100
else if( ly->type == TRIANGLE_NW_GRID )
101
layer = new TriangleNWLayer( bt->tag );
102
else if( ly->type == TRIANGLE_UJ_NE_GRID )
103
layer = new TriangleUJNELayer( bt->tag );
104
else if( ly->type == TRIANGLE_UJ_NW_GRID )
105
layer = new TriangleUJNWLayer( bt->tag );
106
else if( ly->type == TRIANGLE_FB_NE_GRID )
107
layer = new TriangleFBNELayer( bt->tag );
108
else if( ly->type == TRIANGLE_FB_NW_GRID )
109
layer = new TriangleFBNWLayer( bt->tag );
110
else
111
{
112
if( ly->type == CONNECT )
113
{
114
bgmesh = new BGTriangleMesh;
115
layer = new Connect( bt->tag, bgmesh );
116
}
117
else if ( ly->type == BOUNDARY_MESH )
118
{
119
bgmesh = new BGTriangleMesh;
120
layer = new BoundaryLayer( bt->tag, bgmesh );
121
}
122
else
123
{
124
if ( ly->bg->type == "Grid" )
125
bgmesh = new BGGridMesh(2.0);
126
else if ( ly->bg->type == "DenseGrid" )
127
bgmesh = new BGGridMesh(1.0);
128
else if ( ly->bg->type == "SparseGrid" )
129
bgmesh = new BGGridMesh(3.0);
130
else if ( ly->bg->type == "Delaunay" || ly->bg->type == "Explicit" )
131
bgmesh = new BGTriangleMesh;
132
else
133
blm_error("Unknown background mesh type:", ly->bg->type.c_str());
134
135
if( ly->bg->type == "Explicit" )
136
{
137
std::vector< GeometryNode * > bgnodes;
138
std::vector< GeometryEdge * > dummy;
139
140
for(int ind = 0; ind < ly->bg->nodes.size(); ++ind)
141
{
142
NodeToken nt = ly->bg->nodes[ind];
143
GeometryNode *nd = new GeometryNode( 0, nt.x, nt.y);
144
nd->setDelta( nt.delta * parser.scale );
145
bgnodes.push_back( nd );
146
}
147
148
bgmesh->initialize(bgnodes, dummy);
149
}
150
151
if( ly->type == VORONOI_VERTEX )
152
layer = new VoronoiVertex( bt->tag, bgmesh );
153
else if( ly->type == VORONOI_SEGMENT )
154
layer = new VoronoiSegment( bt->tag, bgmesh );
155
else if( ly->type == SSMF_VORONOI_SEGMENT )
156
layer = new SSMFVoronoiSegment( bt->tag, bgmesh );
157
else if( ly->type == SSSF_VORONOI_SEGMENT )
158
layer = new SSSFVoronoiSegment( bt->tag, bgmesh );
159
else
160
blm_error("Unknown layer type code!!!!");
161
}
162
163
// Insert the fixed nodes to the layer
164
for (int i = 0; i < ly->fixedNodes.size(); i++)
165
{
166
NodeToken *nt = ly->fixedNodes[i];
167
GeometryNode *nd = new GeometryNode( nt->tag, nt->x, nt->y);
168
169
if (nt->delta <= 0.0)
170
nt->delta = ly->delta > 0.0 ? ly->delta : parser.delta;
171
172
std::cout << "Node " << nt->tag << ": " << nt->delta * parser.scale << std::endl;
173
nd->setDelta( nt->delta * parser.scale );
174
175
layer->addFixedNode( nd );
176
}
177
}
178
179
int seedDirection = 1;
180
181
Border *bor = new Border( ly->loops.size() );
182
int loopLen = ly->loops.size();
183
for( int j = 0; j < loopLen; ++j )
184
{
185
int edgeLen = ly->loops[j]->edges.size();
186
187
for( int k = 0; k < edgeLen; k++ )
188
{
189
int edgeTag;
190
if (ly->loops[j]->direction > 0)
191
edgeTag = ly->loops[j]->edges[k];
192
else
193
edgeTag = -ly->loops[j]->edges[edgeLen-1-k];
194
195
int dir = edgeTag > 0 ? 1 : -1;
196
edgeTag = abs( edgeTag );
197
198
GeometryEdgeMap::iterator it = geometryEdges.find(edgeTag);
199
if (it == geometryEdges.end())
200
blm_error("Nonexisting edge in layer", ly->tag);
201
GeometryEdge *ed = it->second;
202
203
if (ly->gridh > 0 && ly->gridv > 0)
204
ed->setSegments(k & 1 ? ly->gridv : ly->gridh);
205
206
std::map<int,int>::iterator mi;
207
if ((mi = edgeBody.find(edgeTag)) == edgeBody.end())
208
edgeBody[edgeTag] = bt->tag;
209
else if (mi->second == bt->tag)
210
ed->makeVirtual();
211
else
212
ed->makeInner();
213
214
// Add background mesh to edge
215
if (bgmesh != NULL)
216
ed->addBGMesh(bgmesh);
217
218
// Push layer to node layer list, last node from next edge
219
std::vector<GeometryNode*> nds;
220
ed->exportGeometryNodes(nds, dir);
221
for (int n = 0; n < nds.size() - 1; n++)
222
nodeLayers[nds[n]->tag].push_back(ly);
223
224
bor->addLoopEdge( j, dir, ed );
225
226
if (ly->seed && ly->seed->edge == edgeTag)
227
seedDirection = dir;
228
}
229
}
230
231
// Set the seed
232
if (ly->type == SSMF_VORONOI_SEGMENT || ly->type == SSSF_VORONOI_SEGMENT)
233
{
234
SSVoronoiSegment *vs = static_cast<SSVoronoiSegment *>( layer );
235
if( ly->seed->type == "Explicit" )
236
{
237
vs->makeExplicitSeed( ly->seed->nodes[0],
238
ly->seed->nodes[1], ly->seed->nodes[2] );
239
}
240
else if( ly->seed->type == "Implicit" )
241
{
242
vs->makeImplicitSeed( geometryEdges[ ly->seed->edge ], seedDirection );
243
}
244
else
245
blm_error("Unknown seed type:", ly->seed->type.c_str());
246
}
247
248
layer->setBounds( bor );
249
body->addLayer( layer );
250
layers.push_back(layer);
251
}
252
253
bodies[ body->tag ] = body;
254
}
255
256
len = parser.nodes.size();
257
for (i = 0; i < len; i++)
258
{
259
NodeToken *nt = parser.nodes[i];
260
261
if (nt->delta <= 0.0)
262
{
263
double mean = 1.0;
264
int n = 0;
265
266
std::list<EdgeToken*> &edges = nodeEdges[nt->tag];
267
std::list<EdgeToken*>::iterator it;
268
for (it = edges.begin(); it != edges.end(); it++)
269
{
270
if ((*it)->delta > 0.0)
271
{
272
mean *= (*it)->delta;
273
n++;
274
}
275
}
276
277
if (n == 0)
278
{
279
std::list<LayerToken*> &layers = nodeLayers[nt->tag];
280
std::list<LayerToken*>::iterator it;
281
for (it = layers.begin(); it != layers.end(); it++)
282
{
283
if ((*it)->delta > 0.0)
284
{
285
mean *= (*it)->delta;
286
n++;
287
}
288
}
289
}
290
291
if (n > 0)
292
nt->delta = pow(mean, 1.0 / n);
293
else
294
nt->delta = parser.delta;
295
}
296
297
std::cout << "Node " << nt->tag << ": " << nt->delta * parser.scale << std::endl;
298
geometryNodes[nt->tag]->setDelta(nt->delta * parser.scale);
299
}
300
301
for (std::vector<Layer*>::iterator it = layers.begin(); it != layers.end(); it++)
302
{
303
(*it)->initialize();
304
}
305
306
std::cout << "Conversion completed." << std::endl;
307
}
308
309
void Mesh::
310
discretize()
311
{
312
GeometryNodeMapIt nit;
313
for( nit = geometryNodes.begin(); nit != geometryNodes.end(); ++nit )
314
{
315
MeshNode *mnd = new MeshNode( *((*nit).second) );
316
fixedNodes[ mnd->tag ] = mnd;
317
mnd->boundarynode = true;
318
}
319
320
GeometryEdgeMapIt eit;
321
for( eit = geometryEdges.begin(); eit != geometryEdges.end(); ++eit )
322
{
323
GeometryEdge *ed = (*eit).second;
324
if (ed->isConstant()) ed->discretize( fixedNodes );
325
}
326
327
for( eit = geometryEdges.begin(); eit != geometryEdges.end(); ++eit )
328
{
329
GeometryEdge *ed = (*eit).second;
330
if (!ed->isConstant()) ed->discretize( fixedNodes );
331
}
332
333
BodyMapIt bit;
334
for( bit = bodies.begin(); bit != bodies.end(); ++bit )
335
{
336
Body *bd = (*bit).second;
337
bd->discretize( fixedNodes, meshNodes, elements );
338
std::cout << "Body " << bd->tag << " completed!" << std::endl;
339
}
340
341
for( eit = geometryEdges.begin(); eit != geometryEdges.end(); ++eit )
342
{
343
GeometryEdge *ed = (*eit).second;
344
ed->elements(boundaryElements, 0);
345
}
346
347
createMiddleNodes();
348
349
std::cout << "Nodes: " << meshNodes.size() << std::endl;
350
std::cout << "Elements: " << elements.size() << std::endl;
351
}
352
353
void Mesh::
354
createMiddleNodes()
355
{
356
std::map<std::pair<int, int>, Node *> edgeNodeMap;
357
358
std::list<Element *>::iterator i;
359
for (i = elements.begin(); i != elements.end(); i++)
360
{
361
Element *e = *i;
362
if (bodies[e->partOfBody()]->isParabolic())
363
{
364
int size = e->size();
365
std::vector<Node *> newNodes;
366
for (int i = 0; i < size; i++)
367
{
368
Node *node;
369
370
Node *node0 = e->nodeAt(i), *node1 = e->nodeAt((i+1)%size);
371
std::pair<int, int> p(std::min(node0->tag, node1->tag), std::max(node0->tag, node1->tag));
372
std::map<std::pair<int, int>, Node *>::iterator ni;
373
if ((ni = edgeNodeMap.find(p)) == edgeNodeMap.end())
374
{
375
double x = (node0->x + node1->x) / 2;
376
double y = (node0->y + node1->y) / 2;
377
node = new MeshNode(x, y);
378
edgeNodeMap[p] = node;
379
meshNodes[node->tag] = node;
380
}
381
else
382
{
383
node = ni->second;
384
}
385
386
newNodes.push_back(node);
387
}
388
389
#if 0
390
if (e->elementType() > 400)
391
{
392
double x = (e->nodeAt(0)->x + e->nodeAt(1)->x + e->nodeAt(2)->x + e->nodeAt(3)->x) / 4.0;
393
double y = (e->nodeAt(0)->y + e->nodeAt(1)->y + e->nodeAt(2)->y + e->nodeAt(3)->y) / 4.0;
394
Node *node = new MeshNode(x, y);
395
meshNodes[node->tag] = node;
396
newNodes.push_back(node);
397
}
398
#endif
399
400
e->upgrade(newNodes);
401
}
402
}
403
404
std::vector<BoundaryElement *>::iterator bi;
405
for (bi = boundaryElements.begin(); bi != boundaryElements.end(); bi++)
406
{
407
BoundaryElement *e = *bi;
408
int t0 = e->from()->tag, t1 = e->to()->tag;
409
std::pair<int, int> p(std::min(t0, t1), std::max(t0, t1));
410
std::map<std::pair<int, int>, Node *>::iterator ni;
411
if ((ni = edgeNodeMap.find(p)) != edgeNodeMap.end())
412
e->addMiddleNode(ni->second);
413
}
414
}
415
416
void Mesh::output(std::ofstream& o)
417
{
418
NodeMapIt noit;
419
std::list< Element * >::iterator elit;
420
GeometryEdgeMapIt git;
421
422
int index = 1;
423
424
o << meshNodes.size() << ' ' << elements.size() << std::endl;
425
for( noit = meshNodes.begin(); noit != meshNodes.end(); ++noit)
426
{
427
Node *nd = (*noit).second;
428
nd->tag = index++;
429
o << *nd;
430
}
431
432
for( elit = elements.begin(); elit != elements.end(); ++elit)
433
{
434
o << **elit;
435
}
436
}
437
438
void Mesh::outputHeader(std::ofstream& o)
439
{
440
int ngnds = 0;
441
GeometryNodeMap::iterator it;
442
for (it = geometryNodes.begin(); it != geometryNodes.end(); it++)
443
if (it->second->boundaryTag > 0)
444
ngnds++;
445
446
o << meshNodes.size() << ' ' << elements.size() << ' ' << boundaryElements.size() + ngnds << '\n';
447
448
std::map<int, int> n;
449
450
std::list< Element* >::const_iterator e;
451
for (e = elements.begin(); e != elements.end(); e++)
452
n[(*e)->elementType()]++;
453
454
std::vector< BoundaryElement* >::const_iterator be;
455
for (be = boundaryElements.begin(); be != boundaryElements.end(); be++)
456
n[(*be)->middle() != NULL ? 203 : 202]++;
457
458
n[101] += ngnds;
459
460
o << n.size() << '\n';
461
462
std::map<int, int>::iterator i;
463
for (i = n.begin(); i != n.end(); i++)
464
o << i->first << ' ' << i->second << '\n';
465
}
466
467
void Mesh::outputNodes(std::ofstream &o)
468
{
469
int tag = 1;
470
NodeMapIt noit;
471
472
// o.setf(ios::scientific);
473
o.precision(16);
474
475
for( noit = meshNodes.begin(); noit != meshNodes.end(); ++noit)
476
{
477
Node *nd = (*noit).second;
478
nd->tag = tag++;
479
o << *nd;
480
}
481
}
482
483
void Mesh::outputElements(std::ofstream &o)
484
{
485
std::list< Element * >::iterator elit;
486
487
for( elit = elements.begin(); elit != elements.end(); ++elit)
488
{
489
o << **elit;
490
}
491
}
492
493
void Mesh::outputBoundary(std::ofstream &o)
494
{
495
std::vector< BoundaryElement* >::iterator bel;
496
for (bel = boundaryElements.begin(); bel != boundaryElements.end(); bel++)
497
{
498
o << **bel;
499
}
500
501
int id = boundaryElements.size() + 1;
502
GeometryNodeMapIt n;
503
for (n = geometryNodes.begin(); n != geometryNodes.end(); n++)
504
{
505
if (n->second->boundaryTag > 0)
506
o << id++ << ' ' << n->second->boundaryTag << " -1 -1 101 " << n->first << '\n';
507
}
508
}
509
510