Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/meshing/meshfunc.cpp
3206 views
1
#include <mystdlib.h>
2
#include "meshing.hpp"
3
4
namespace netgen
5
{
6
extern const char * tetrules[];
7
// extern const char * tetrules2[];
8
extern const char * prismrules2[];
9
extern const char * pyramidrules[];
10
extern const char * pyramidrules2[];
11
12
13
extern double teterrpow;
14
MESHING3_RESULT MeshVolume (MeshingParameters & mp, Mesh& mesh3d)
15
{
16
int i, oldne;
17
PointIndex pi;
18
19
int meshed;
20
int cntsteps;
21
22
23
ARRAY<INDEX_2> connectednodes;
24
25
mesh3d.Compress();
26
27
// mesh3d.PrintMemInfo (cout);
28
29
if (mp.checkoverlappingboundary)
30
if (mesh3d.CheckOverlappingBoundary())
31
throw NgException ("Stop meshing since boundary mesh is overlapping");
32
33
int nonconsist = 0;
34
for (int k = 1; k <= mesh3d.GetNDomains(); k++)
35
{
36
PrintMessage (3, "Check subdomain ", k, " / ", mesh3d.GetNDomains());
37
38
mesh3d.FindOpenElements(k);
39
40
/*
41
bool res = mesh3d.CheckOverlappingBoundary();
42
if (res)
43
{
44
PrintError ("Surface is overlapping !!");
45
nonconsist = 1;
46
}
47
*/
48
49
bool res = (mesh3d.CheckConsistentBoundary() != 0);
50
if (res)
51
{
52
PrintError ("Surface mesh not consistent");
53
nonconsist = 1;
54
}
55
}
56
57
if (nonconsist)
58
{
59
PrintError ("Stop meshing since surface mesh not consistent");
60
throw NgException ("Stop meshing since surface mesh not consistent");
61
}
62
63
double globmaxh = mp.maxh;
64
65
for (int k = 1; k <= mesh3d.GetNDomains(); k++)
66
{
67
if (multithread.terminate)
68
break;
69
70
PrintMessage (2, "");
71
PrintMessage (1, "Meshing subdomain ", k, " of ", mesh3d.GetNDomains());
72
(*testout) << "Meshing subdomain " << k << endl;
73
74
mp.maxh = min2 (globmaxh, mesh3d.MaxHDomain(k));
75
76
mesh3d.CalcSurfacesOfNode();
77
mesh3d.FindOpenElements(k);
78
79
if (!mesh3d.GetNOpenElements())
80
continue;
81
82
83
84
Box<3> domain_bbox( Box<3>::EMPTY_BOX );
85
/*
86
Point<3> (1e10, 1e10, 1e10),
87
Point<3> (-1e10, -1e10, -1e10));
88
*/
89
90
for (SurfaceElementIndex sei = 0; sei < mesh3d.GetNSE(); sei++)
91
{
92
const Element2d & el = mesh3d[sei];
93
if (el.IsDeleted() ) continue;
94
95
if (mesh3d.GetFaceDescriptor(el.GetIndex()).DomainIn() == k ||
96
mesh3d.GetFaceDescriptor(el.GetIndex()).DomainOut() == k)
97
98
for (int j = 0; j < el.GetNP(); j++)
99
domain_bbox.Add (mesh3d[el[j]]);
100
}
101
domain_bbox.Increase (0.01 * domain_bbox.Diam());
102
103
104
for (int qstep = 1; qstep <= 3; qstep++)
105
{
106
if (mesh3d.HasOpenQuads())
107
{
108
string rulefile = ngdir;
109
110
const char ** rulep = NULL;
111
switch (qstep)
112
{
113
case 1:
114
rulefile += "/rules/prisms2.rls";
115
rulep = prismrules2;
116
break;
117
case 2: // connect pyramid to triangle
118
rulefile += "/rules/pyramids2.rls";
119
rulep = pyramidrules2;
120
break;
121
case 3: // connect to vis-a-vis point
122
rulefile += "/rules/pyramids.rls";
123
rulep = pyramidrules;
124
break;
125
}
126
127
// Meshing3 meshing(rulefile);
128
Meshing3 meshing(rulep);
129
130
MeshingParameters mpquad = mp;
131
132
mpquad.giveuptol = 15;
133
mpquad.baseelnp = 4;
134
mpquad.starshapeclass = 1000;
135
mpquad.check_impossible = qstep == 1; // for prisms only (air domain in trafo)
136
137
138
for (pi = PointIndex::BASE;
139
pi < mesh3d.GetNP()+PointIndex::BASE; pi++)
140
meshing.AddPoint (mesh3d[pi], pi);
141
142
mesh3d.GetIdentifications().GetPairs (0, connectednodes);
143
for (i = 1; i <= connectednodes.Size(); i++)
144
meshing.AddConnectedPair (connectednodes.Get(i));
145
146
for (i = 1; i <= mesh3d.GetNOpenElements(); i++)
147
{
148
Element2d hel = mesh3d.OpenElement(i);
149
meshing.AddBoundaryElement (hel);
150
}
151
152
oldne = mesh3d.GetNE();
153
154
meshing.GenerateMesh (mesh3d, mpquad);
155
156
for (i = oldne + 1; i <= mesh3d.GetNE(); i++)
157
mesh3d.VolumeElement(i).SetIndex (k);
158
159
(*testout)
160
<< "mesh has " << mesh3d.GetNE() << " prism/pyramid�elements" << endl;
161
162
mesh3d.FindOpenElements(k);
163
}
164
}
165
166
167
if (mesh3d.HasOpenQuads())
168
{
169
PrintSysError ("mesh has still open quads");
170
throw NgException ("Stop meshing since too many attempts");
171
// return MESHING3_GIVEUP;
172
}
173
174
175
if (mp.delaunay && mesh3d.GetNOpenElements())
176
{
177
Meshing3 meshing((const char**)NULL);
178
179
mesh3d.FindOpenElements(k);
180
181
182
for (pi = PointIndex::BASE;
183
pi < mesh3d.GetNP()+PointIndex::BASE; pi++)
184
meshing.AddPoint (mesh3d[pi], pi);
185
186
187
for (i = 1; i <= mesh3d.GetNOpenElements(); i++)
188
meshing.AddBoundaryElement (mesh3d.OpenElement(i));
189
190
oldne = mesh3d.GetNE();
191
192
meshing.Delaunay (mesh3d, k, mp);
193
194
for (i = oldne + 1; i <= mesh3d.GetNE(); i++)
195
mesh3d.VolumeElement(i).SetIndex (k);
196
197
PrintMessage (3, mesh3d.GetNP(), " points, ",
198
mesh3d.GetNE(), " elements");
199
}
200
201
202
cntsteps = 0;
203
if (mesh3d.GetNOpenElements())
204
do
205
{
206
if (multithread.terminate)
207
break;
208
209
mesh3d.FindOpenElements(k);
210
PrintMessage (5, mesh3d.GetNOpenElements(), " open faces");
211
cntsteps++;
212
213
if (cntsteps > mp.maxoutersteps)
214
throw NgException ("Stop meshing since too many attempts");
215
216
string rulefile = ngdir + "/tetra.rls";
217
PrintMessage (1, "start tetmeshing");
218
219
// Meshing3 meshing(rulefile);
220
Meshing3 meshing(tetrules);
221
222
ARRAY<int, PointIndex::BASE> glob2loc(mesh3d.GetNP());
223
glob2loc = -1;
224
225
for (pi = PointIndex::BASE;
226
pi < mesh3d.GetNP()+PointIndex::BASE; pi++)
227
228
if (domain_bbox.IsIn (mesh3d[pi]))
229
glob2loc[pi] =
230
meshing.AddPoint (mesh3d[pi], pi);
231
232
for (i = 1; i <= mesh3d.GetNOpenElements(); i++)
233
{
234
Element2d hel = mesh3d.OpenElement(i);
235
for (int j = 0; j < hel.GetNP(); j++)
236
hel[j] = glob2loc[hel[j]];
237
meshing.AddBoundaryElement (hel);
238
// meshing.AddBoundaryElement (mesh3d.OpenElement(i));
239
}
240
241
oldne = mesh3d.GetNE();
242
243
mp.giveuptol = 15 + 10 * cntsteps;
244
mp.sloppy = 5;
245
meshing.GenerateMesh (mesh3d, mp);
246
247
for (ElementIndex ei = oldne; ei < mesh3d.GetNE(); ei++)
248
mesh3d[ei].SetIndex (k);
249
250
251
mesh3d.CalcSurfacesOfNode();
252
mesh3d.FindOpenElements(k);
253
254
teterrpow = 2;
255
if (mesh3d.GetNOpenElements() != 0)
256
{
257
meshed = 0;
258
PrintMessage (5, mesh3d.GetNOpenElements(), " open faces found");
259
260
// mesh3d.Save ("tmp.vol");
261
262
263
MeshOptimize3d optmesh;
264
265
const char * optstr = "mcmstmcmstmcmstmcm";
266
size_t j;
267
for (j = 1; j <= strlen(optstr); j++)
268
{
269
mesh3d.CalcSurfacesOfNode();
270
mesh3d.FreeOpenElementsEnvironment(2);
271
mesh3d.CalcSurfacesOfNode();
272
273
switch (optstr[j-1])
274
{
275
case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break;
276
case 'd': optmesh.SplitImprove(mesh3d, OPT_REST); break;
277
case 's': optmesh.SwapImprove(mesh3d, OPT_REST); break;
278
case 't': optmesh.SwapImprove2(mesh3d, OPT_REST); break;
279
case 'm': mesh3d.ImproveMesh(OPT_REST); break;
280
}
281
282
}
283
284
mesh3d.FindOpenElements(k);
285
PrintMessage (3, "Call remove problem");
286
RemoveProblem (mesh3d, k);
287
mesh3d.FindOpenElements(k);
288
}
289
else
290
{
291
meshed = 1;
292
PrintMessage (1, "Success !");
293
}
294
}
295
while (!meshed);
296
297
PrintMessage (1, mesh3d.GetNP(), " points, ",
298
mesh3d.GetNE(), " elements");
299
}
300
301
mp.maxh = globmaxh;
302
303
MeshQuality3d (mesh3d);
304
305
return MESHING3_OK;
306
}
307
308
309
310
311
/*
312
313
314
MESHING3_RESULT MeshVolumeOld (MeshingParameters & mp, Mesh& mesh3d)
315
{
316
int i, k, oldne;
317
318
319
int meshed;
320
int cntsteps;
321
322
323
PlotStatistics3d * pstat;
324
if (globflags.GetNumFlag("silentflag", 1) <= 2)
325
pstat = new XPlotStatistics3d;
326
else
327
pstat = new TerminalPlotStatistics3d;
328
329
cntsteps = 0;
330
do
331
{
332
cntsteps++;
333
if (cntsteps > mp.maxoutersteps)
334
{
335
return MESHING3_OUTERSTEPSEXCEEDED;
336
}
337
338
339
int noldp = mesh3d.GetNP();
340
341
342
if ( (cntsteps == 1) && globflags.GetDefineFlag ("delaunay"))
343
{
344
cntsteps ++;
345
346
mesh3d.CalcSurfacesOfNode();
347
348
349
for (k = 1; k <= mesh3d.GetNDomains(); k++)
350
{
351
Meshing3 meshing(NULL, pstat);
352
353
mesh3d.FindOpenElements(k);
354
355
for (i = 1; i <= noldp; i++)
356
meshing.AddPoint (mesh3d.Point(i), i);
357
358
for (i = 1; i <= mesh3d.GetNOpenElements(); i++)
359
{
360
if (mesh3d.OpenElement(i).GetIndex() == k)
361
meshing.AddBoundaryElement (mesh3d.OpenElement(i));
362
}
363
364
oldne = mesh3d.GetNE();
365
if (globflags.GetDefineFlag ("blockfill"))
366
{
367
if (!globflags.GetDefineFlag ("localh"))
368
meshing.BlockFill
369
(mesh3d, mp.h * globflags.GetNumFlag ("relblockfillh", 1));
370
else
371
meshing.BlockFillLocalH (mesh3d);
372
}
373
374
MeshingParameters mpd;
375
meshing.Delaunay (mesh3d, mpd);
376
377
for (i = oldne + 1; i <= mesh3d.GetNE(); i++)
378
mesh3d.VolumeElement(i).SetIndex (k);
379
}
380
}
381
382
noldp = mesh3d.GetNP();
383
384
mesh3d.CalcSurfacesOfNode();
385
mesh3d.FindOpenElements();
386
for (k = 1; k <= mesh3d.GetNDomains(); k++)
387
{
388
Meshing3 meshing(globflags.GetStringFlag ("rules3d", NULL), pstat);
389
390
Point3d pmin, pmax;
391
mesh3d.GetBox (pmin, pmax, k);
392
393
rot.SetCenter (Center (pmin, pmax));
394
395
for (i = 1; i <= noldp; i++)
396
meshing.AddPoint (mesh3d.Point(i), i);
397
398
for (i = 1; i <= mesh3d.GetNOpenElements(); i++)
399
{
400
if (mesh3d.OpenElement(i).GetIndex() == k)
401
meshing.AddBoundaryElement (mesh3d.OpenElement(i));
402
}
403
404
oldne = mesh3d.GetNE();
405
406
407
if ( (cntsteps == 1) && globflags.GetDefineFlag ("blockfill"))
408
{
409
if (!globflags.GetDefineFlag ("localh"))
410
{
411
meshing.BlockFill
412
(mesh3d,
413
mp.h * globflags.GetNumFlag ("relblockfillh", 1));
414
}
415
else
416
{
417
meshing.BlockFillLocalH (mesh3d);
418
}
419
}
420
421
422
mp.giveuptol = int(globflags.GetNumFlag ("giveuptol", 15));
423
424
meshing.GenerateMesh (mesh3d, mp);
425
426
for (i = oldne + 1; i <= mesh3d.GetNE(); i++)
427
mesh3d.VolumeElement(i).SetIndex (k);
428
}
429
430
431
432
mesh3d.CalcSurfacesOfNode();
433
mesh3d.FindOpenElements();
434
435
teterrpow = 2;
436
if (mesh3d.GetNOpenElements() != 0)
437
{
438
meshed = 0;
439
(*mycout) << "Open elements found, old" << endl;
440
const char * optstr = "mcmcmcmcm";
441
int j;
442
for (j = 1; j <= strlen(optstr); j++)
443
switch (optstr[j-1])
444
{
445
case 'c': mesh3d.CombineImprove(); break;
446
case 'd': mesh3d.SplitImprove(); break;
447
case 's': mesh3d.SwapImprove(); break;
448
case 'm': mesh3d.ImproveMesh(2); break;
449
}
450
451
(*mycout) << "Call remove" << endl;
452
RemoveProblem (mesh3d);
453
(*mycout) << "Problem removed" << endl;
454
}
455
else
456
meshed = 1;
457
}
458
while (!meshed);
459
460
MeshQuality3d (mesh3d);
461
462
return MESHING3_OK;
463
}
464
465
*/
466
467
468
469
470
/*
471
MESHING3_RESULT MeshMixedVolume(MeshingParameters & mp, Mesh& mesh3d)
472
{
473
int i, j;
474
MESHING3_RESULT res;
475
Point3d pmin, pmax;
476
477
mp.giveuptol = 10;
478
mp.baseelnp = 4;
479
mp.starshapeclass = 100;
480
481
// TerminalPlotStatistics3d pstat;
482
483
Meshing3 meshing1("pyramids.rls");
484
for (i = 1; i <= mesh3d.GetNP(); i++)
485
meshing1.AddPoint (mesh3d.Point(i), i);
486
487
mesh3d.FindOpenElements();
488
for (i = 1; i <= mesh3d.GetNOpenElements(); i++)
489
if (mesh3d.OpenElement(i).GetIndex() == 1)
490
meshing1.AddBoundaryElement (mesh3d.OpenElement(i));
491
492
res = meshing1.GenerateMesh (mesh3d, mp);
493
494
mesh3d.GetBox (pmin, pmax);
495
PrintMessage (1, "Mesh pyramids, res = ", res);
496
if (res)
497
exit (1);
498
499
500
for (i = 1; i <= mesh3d.GetNE(); i++)
501
mesh3d.VolumeElement(i).SetIndex (1);
502
503
// do delaunay
504
505
mp.baseelnp = 0;
506
mp.starshapeclass = 5;
507
508
Meshing3 meshing2(NULL);
509
for (i = 1; i <= mesh3d.GetNP(); i++)
510
meshing2.AddPoint (mesh3d.Point(i), i);
511
512
mesh3d.FindOpenElements();
513
for (i = 1; i <= mesh3d.GetNOpenElements(); i++)
514
if (mesh3d.OpenElement(i).GetIndex() == 1)
515
meshing2.AddBoundaryElement (mesh3d.OpenElement(i));
516
517
MeshingParameters mpd;
518
meshing2.Delaunay (mesh3d, mpd);
519
520
for (i = 1; i <= mesh3d.GetNE(); i++)
521
mesh3d.VolumeElement(i).SetIndex (1);
522
523
524
mp.baseelnp = 0;
525
mp.giveuptol = 10;
526
527
for (int trials = 1; trials <= 50; trials++)
528
{
529
if (multithread.terminate)
530
return MESHING3_TERMINATE;
531
532
Meshing3 meshing3("tetra.rls");
533
for (i = 1; i <= mesh3d.GetNP(); i++)
534
meshing3.AddPoint (mesh3d.Point(i), i);
535
536
mesh3d.FindOpenElements();
537
for (i = 1; i <= mesh3d.GetNOpenElements(); i++)
538
if (mesh3d.OpenElement(i).GetIndex() == 1)
539
meshing3.AddBoundaryElement (mesh3d.OpenElement(i));
540
541
if (trials > 1)
542
CheckSurfaceMesh2 (mesh3d);
543
res = meshing3.GenerateMesh (mesh3d, mp);
544
545
for (i = 1; i <= mesh3d.GetNE(); i++)
546
mesh3d.VolumeElement(i).SetIndex (1);
547
548
if (res == 0) break;
549
550
551
552
for (i = 1; i <= mesh3d.GetNE(); i++)
553
{
554
const Element & el = mesh3d.VolumeElement(i);
555
if (el.GetNP() != 4)
556
{
557
for (j = 1; j <= el.GetNP(); j++)
558
mesh3d.AddLockedPoint (el.PNum(j));
559
}
560
}
561
562
mesh3d.CalcSurfacesOfNode();
563
mesh3d.FindOpenElements();
564
565
MeshOptimize3d optmesh;
566
567
teterrpow = 2;
568
const char * optstr = "mcmcmcmcm";
569
for (j = 1; j <= strlen(optstr); j++)
570
switch (optstr[j-1])
571
{
572
case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break;
573
case 'd': optmesh.SplitImprove(mesh3d); break;
574
case 's': optmesh.SwapImprove(mesh3d); break;
575
case 'm': mesh3d.ImproveMesh(); break;
576
}
577
578
RemoveProblem (mesh3d);
579
}
580
581
582
PrintMessage (1, "Meshing tets, res = ", res);
583
if (res)
584
{
585
mesh3d.FindOpenElements();
586
PrintSysError (1, "Open elemetns: ", mesh3d.GetNOpenElements());
587
exit (1);
588
}
589
590
591
592
for (i = 1; i <= mesh3d.GetNE(); i++)
593
{
594
const Element & el = mesh3d.VolumeElement(i);
595
if (el.GetNP() != 4)
596
{
597
for (j = 1; j <= el.GetNP(); j++)
598
mesh3d.AddLockedPoint (el.PNum(j));
599
}
600
}
601
602
mesh3d.CalcSurfacesOfNode();
603
mesh3d.FindOpenElements();
604
605
MeshOptimize3d optmesh;
606
607
teterrpow = 2;
608
const char * optstr = "mcmcmcmcm";
609
for (j = 1; j <= strlen(optstr); j++)
610
switch (optstr[j-1])
611
{
612
case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break;
613
case 'd': optmesh.SplitImprove(mesh3d); break;
614
case 's': optmesh.SwapImprove(mesh3d); break;
615
case 'm': mesh3d.ImproveMesh(); break;
616
}
617
618
619
return MESHING3_OK;
620
}
621
*/
622
623
624
625
626
627
628
MESHING3_RESULT OptimizeVolume (MeshingParameters & mp,
629
Mesh & mesh3d)
630
// const CSGeometry * geometry)
631
{
632
int i;
633
634
PrintMessage (1, "Volume Optimization");
635
636
/*
637
if (!mesh3d.PureTetMesh())
638
return MESHING3_OK;
639
*/
640
641
// (*mycout) << "optstring = " << mp.optimize3d << endl;
642
/*
643
const char * optstr = globflags.GetStringFlag ("optimize3d", "cmh");
644
int optsteps = int (globflags.GetNumFlag ("optsteps3d", 2));
645
*/
646
647
mesh3d.CalcSurfacesOfNode();
648
for (i = 1; i <= mp.optsteps3d; i++)
649
{
650
if (multithread.terminate)
651
break;
652
653
MeshOptimize3d optmesh;
654
655
teterrpow = mp.opterrpow;
656
for (size_t j = 1; j <= strlen(mp.optimize3d); j++)
657
{
658
if (multithread.terminate)
659
break;
660
661
switch (mp.optimize3d[j-1])
662
{
663
case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break;
664
case 'd': optmesh.SplitImprove(mesh3d); break;
665
case 's': optmesh.SwapImprove(mesh3d); break;
666
// case 'u': optmesh.SwapImproveSurface(mesh3d); break;
667
case 't': optmesh.SwapImprove2(mesh3d); break;
668
#ifdef SOLIDGEOM
669
case 'm': mesh3d.ImproveMesh(*geometry); break;
670
case 'M': mesh3d.ImproveMesh(*geometry); break;
671
#else
672
case 'm': mesh3d.ImproveMesh(); break;
673
case 'M': mesh3d.ImproveMesh(); break;
674
#endif
675
case 'j': mesh3d.ImproveMeshJacobian(); break;
676
}
677
}
678
mesh3d.mglevels = 1;
679
MeshQuality3d (mesh3d);
680
}
681
682
return MESHING3_OK;
683
}
684
685
686
687
688
void RemoveIllegalElements (Mesh & mesh3d)
689
{
690
int it = 10;
691
int nillegal, oldn;
692
693
PrintMessage (1, "Remove Illegal Elements");
694
// return, if non-pure tet-mesh
695
/*
696
if (!mesh3d.PureTetMesh())
697
return;
698
*/
699
mesh3d.CalcSurfacesOfNode();
700
701
nillegal = mesh3d.MarkIllegalElements();
702
703
MeshOptimize3d optmesh;
704
while (nillegal && (it--) > 0)
705
{
706
if (multithread.terminate)
707
break;
708
709
PrintMessage (5, nillegal, " illegal tets");
710
optmesh.SplitImprove (mesh3d, OPT_LEGAL);
711
712
mesh3d.MarkIllegalElements(); // test
713
optmesh.SwapImprove (mesh3d, OPT_LEGAL);
714
mesh3d.MarkIllegalElements(); // test
715
optmesh.SwapImprove2 (mesh3d, OPT_LEGAL);
716
717
oldn = nillegal;
718
nillegal = mesh3d.MarkIllegalElements();
719
720
if (oldn != nillegal)
721
it = 10;
722
}
723
PrintMessage (5, nillegal, " illegal tets");
724
}
725
}
726
727