Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/meshing/improve2.cpp
3206 views
1
#include <mystdlib.h>
2
3
#include "meshing.hpp"
4
#include <opti.hpp>
5
6
#ifndef SMALLLIB
7
//#ifndef NOTCL
8
//#include <visual.hpp>
9
//#endif
10
#endif
11
12
namespace netgen
13
{
14
15
class Neighbour
16
{
17
int nr[3];
18
int orient[3];
19
20
public:
21
Neighbour () { nr[0] = nr[1] = nr[2] = -1; orient[0] = orient[1] = orient[2] = 0; }
22
23
void SetNr (int side, int anr) { nr[side-1] = anr; }
24
int GetNr (int side) { return nr[side-1]; }
25
26
void SetOrientation (int side, int aorient) { orient[side-1] = aorient; }
27
int GetOrientation (int side) { return orient[side-1]; }
28
};
29
30
31
32
33
class trionedge
34
{
35
public:
36
int tnr;
37
int sidenr;
38
39
trionedge () { tnr = 0; sidenr = 0; }
40
trionedge (int atnr, int asidenr)
41
{ tnr = atnr; sidenr = asidenr; }
42
};
43
44
45
46
47
void MeshOptimize2d :: EdgeSwapping (Mesh & mesh, int usemetric)
48
{
49
// return;
50
51
if (!faceindex)
52
{
53
if (usemetric)
54
PrintMessage (3, "Edgeswapping, metric");
55
else
56
PrintMessage (3, "Edgeswapping, topological");
57
58
for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++)
59
{
60
EdgeSwapping (mesh, usemetric);
61
62
if (multithread.terminate)
63
throw NgException ("Meshing stopped");
64
}
65
66
faceindex = 0;
67
mesh.CalcSurfacesOfNode();
68
return;
69
}
70
71
72
static int timer = NgProfiler::CreateTimer ("EdgeSwapping 2D");
73
NgProfiler::RegionTimer reg1 (timer);
74
75
76
int i, i2, j, j2;
77
bool should;
78
PointIndex pi;
79
80
ARRAY<SurfaceElementIndex> seia;
81
mesh.GetSurfaceElementsOfFace (faceindex, seia);
82
83
for (i = 0; i < seia.Size(); i++)
84
if (mesh[seia[i]].GetNP() != 3)
85
{
86
GenericImprove (mesh);
87
return;
88
}
89
90
int surfnr = mesh.GetFaceDescriptor (faceindex).SurfNr();
91
92
ARRAY<Neighbour> neighbors(mesh.GetNSE());
93
INDEX_2_HASHTABLE<trionedge> other(seia.Size() + 2);
94
95
96
ARRAY<char> swapped(mesh.GetNSE());
97
ARRAY<int,PointIndex::BASE> pdef(mesh.GetNP());
98
ARRAY<double,PointIndex::BASE> pangle(mesh.GetNP());
99
100
SurfaceElementIndex t1, t2;
101
int o1, o2;
102
103
PointIndex pi1, pi2, pi3, pi4;
104
PointGeomInfo gi1, gi2, gi3, gi4;
105
106
107
int nswaps = 0;
108
int e, done;
109
double d;
110
Vec3d nv1, nv2;
111
double horder;
112
double loch(-1);
113
static const double minangle[] = { 0, 1.481, 2.565, 3.627, 4.683, 5.736, 7, 9 };
114
115
pangle = 0;
116
117
for (i = 0; i < seia.Size(); i++)
118
{
119
const Element2d & sel = mesh[seia[i]];
120
for (j = 0; j < 3; j++)
121
{
122
POINTTYPE typ = mesh[sel[j]].Type();
123
if (typ == FIXEDPOINT || typ == EDGEPOINT)
124
{
125
pangle[sel[j]] +=
126
Angle (mesh[sel[(j+1)%3]] - mesh[sel[j]],
127
mesh[sel[(j+2)%3]] - mesh[sel[j]]);
128
}
129
}
130
}
131
132
for (pi = PointIndex::BASE;
133
pi < mesh.GetNP()+PointIndex::BASE; pi++)
134
{
135
if (mesh[pi].Type() == INNERPOINT || mesh[pi].Type() == SURFACEPOINT)
136
pdef[pi] = -6;
137
else
138
for (j = 0; j < 8; j++)
139
if (pangle[pi] >= minangle[j])
140
pdef[pi] = -1-j;
141
}
142
143
for (i = 0; i < seia.Size(); i++)
144
{
145
const Element2d & sel = mesh[seia[i]];
146
for (j = 0; j < 3; j++)
147
pdef[sel[j]]++;
148
}
149
150
for (i = 0; i < seia.Size(); i++)
151
{
152
//const Element2d & sel = mesh[seia[i]];
153
for (j = 0; j < 3; j++)
154
{
155
neighbors[seia[i]].SetNr (j+1, -1);
156
neighbors[seia[i]].SetOrientation (j+1, 0);
157
}
158
}
159
160
/*
161
ARRAY<Vec3d> normals(mesh.GetNP());
162
for (i = 1; i <= mesh.GetNSE(); i++)
163
{
164
Element2d & hel = mesh.SurfaceElement(i);
165
if (hel.GetIndex() == faceindex)
166
for (k = 1; k <= 3; k++)
167
{
168
int pi = hel.PNum(k);
169
SelectSurfaceOfPoint (mesh.Point(pi), hel.GeomInfoPi(k));
170
int surfi = mesh.GetFaceDescriptor(faceindex).SurfNr();
171
GetNormalVector (surfi, mesh.Point(pi), normals.Elem(pi));
172
normals.Elem(pi) /= normals.Elem(pi).Length();
173
}
174
}
175
*/
176
177
178
for (i = 0; i < seia.Size(); i++)
179
{
180
const Element2d & sel = mesh[seia[i]];
181
182
for (j = 1; j <= 3; j++)
183
{
184
pi1 = sel.PNumMod(j+1);
185
pi2 = sel.PNumMod(j+2);
186
187
loch = mesh.GetH(mesh[pi1]);
188
189
INDEX_2 edge(pi1, pi2);
190
edge.Sort();
191
192
if (mesh.IsSegment (pi1, pi2))
193
continue;
194
195
/*
196
if (segments.Used (edge))
197
continue;
198
*/
199
INDEX_2 ii2 (pi1, pi2);
200
if (other.Used (ii2))
201
{
202
// INDEX_2 i2s(ii2);
203
// i2s.Sort();
204
205
i2 = other.Get(ii2).tnr;
206
j2 = other.Get(ii2).sidenr;
207
208
neighbors[seia[i]].SetNr (j, i2);
209
neighbors[seia[i]].SetOrientation (j, j2);
210
neighbors[i2].SetNr (j2, seia[i]);
211
neighbors[i2].SetOrientation (j2, j);
212
}
213
else
214
{
215
other.Set (INDEX_2 (pi2, pi1), trionedge (seia[i], j));
216
}
217
}
218
}
219
220
for (i = 0; i < seia.Size(); i++)
221
swapped[seia[i]] = 0;
222
223
224
int t = 4;
225
done = 0;
226
while (!done && t >= 2)
227
{
228
for (i = 0; i < seia.Size(); i++)
229
{
230
t1 = seia[i];
231
232
if (mesh[t1].IsDeleted())
233
continue;
234
235
if (mesh[t1].GetIndex() != faceindex)
236
continue;
237
238
if (multithread.terminate)
239
throw NgException ("Meshing stopped");
240
241
for (o1 = 1; o1 <= 3; o1++)
242
{
243
t2 = neighbors[t1].GetNr (o1);
244
o2 = neighbors[t1].GetOrientation (o1);
245
246
if (t2 == -1) continue;
247
if (swapped[t1] || swapped[t2]) continue;
248
249
250
pi1 = mesh[t1].PNumMod(o1+1);
251
pi2 = mesh[t1].PNumMod(o1+2);
252
pi3 = mesh[t1].PNumMod(o1);
253
pi4 = mesh[t2].PNumMod(o2);
254
255
gi1 = mesh[t1].GeomInfoPiMod(o1+1);
256
gi2 = mesh[t1].GeomInfoPiMod(o1+2);
257
gi3 = mesh[t1].GeomInfoPiMod(o1);
258
gi4 = mesh[t2].GeomInfoPiMod(o2);
259
260
bool allowswap = true;
261
262
Vec3d auxvec1,auxvec2;
263
264
auxvec1 = mesh.Point(pi3)-mesh.Point(pi4);
265
auxvec2 = mesh.Point(pi1)-mesh.Point(pi4);
266
allowswap = allowswap && fabs(1.-(auxvec1*auxvec2)/(auxvec1.Length()*auxvec2.Length())) > 1e-4;
267
268
if(!allowswap)
269
continue;
270
271
// normal of new
272
nv1 = Cross (auxvec1,
273
auxvec2);
274
275
auxvec1 = mesh.Point(pi4)-mesh.Point(pi3);
276
auxvec2 = mesh.Point(pi2)-mesh.Point(pi3);
277
allowswap = allowswap && fabs(1.-(auxvec1*auxvec2)/(auxvec1.Length()*auxvec2.Length())) > 1e-4;
278
279
280
if(!allowswap)
281
continue;
282
283
nv2 = Cross (auxvec1,
284
auxvec2);
285
286
287
// normals of original
288
Vec3d nv3, nv4;
289
nv3 = Cross (mesh.Point(pi1)-mesh.Point(pi4),
290
mesh.Point(pi2)-mesh.Point(pi4));
291
nv4 = Cross (mesh.Point(pi2)-mesh.Point(pi3),
292
mesh.Point(pi1)-mesh.Point(pi3));
293
294
nv3 *= -1;
295
nv4 *= -1;
296
nv3.Normalize();
297
nv4.Normalize();
298
299
nv1.Normalize();
300
nv2.Normalize();
301
302
Vec<3> nvp3, nvp4;
303
SelectSurfaceOfPoint (mesh.Point(pi3), gi3);
304
GetNormalVector (surfnr, mesh.Point(pi3), gi3, nvp3);
305
306
nvp3.Normalize();
307
308
SelectSurfaceOfPoint (mesh.Point(pi4), gi4);
309
GetNormalVector (surfnr, mesh.Point(pi4), gi4, nvp4);
310
311
nvp4.Normalize();
312
313
314
315
double critval = cos (M_PI / 6); // 30 degree
316
allowswap = allowswap &&
317
(nv1 * nvp3 > critval) &&
318
(nv1 * nvp4 > critval) &&
319
(nv2 * nvp3 > critval) &&
320
(nv2 * nvp4 > critval) &&
321
(nvp3 * nv3 > critval) &&
322
(nvp4 * nv4 > critval);
323
324
325
horder = Dist (mesh.Point(pi1), mesh.Point(pi2));
326
327
if ( // nv1 * nv2 >= 0 &&
328
nv1.Length() > 1e-3 * horder * horder &&
329
nv2.Length() > 1e-3 * horder * horder &&
330
allowswap )
331
{
332
if (!usemetric)
333
{
334
e = pdef[pi1] + pdef[pi2] - pdef[pi3] - pdef[pi4];
335
d =
336
Dist2 (mesh.Point(pi1), mesh.Point(pi2)) -
337
Dist2 (mesh.Point(pi3), mesh.Point(pi4));
338
339
should = e >= t && (e > 2 || d > 0);
340
}
341
else
342
{
343
should =
344
CalcTriangleBadness (mesh.Point(pi4), mesh.Point(pi3), mesh.Point(pi1),
345
metricweight, loch) +
346
CalcTriangleBadness (mesh.Point(pi3), mesh.Point(pi4), mesh.Point(pi2),
347
metricweight, loch) <
348
CalcTriangleBadness (mesh.Point(pi1), mesh.Point(pi2), mesh.Point(pi3),
349
metricweight, loch) +
350
CalcTriangleBadness (mesh.Point(pi2), mesh.Point(pi1), mesh.Point(pi4),
351
metricweight, loch);
352
353
}
354
355
if (allowswap)
356
{
357
Element2d sw1 (pi4, pi3, pi1);
358
Element2d sw2 (pi3, pi4, pi2);
359
360
int legal1 =
361
mesh.LegalTrig (mesh.SurfaceElement (t1)) +
362
mesh.LegalTrig (mesh.SurfaceElement (t2));
363
int legal2 =
364
mesh.LegalTrig (sw1) + mesh.LegalTrig (sw2);
365
366
if (legal1 < legal2) should = 1;
367
if (legal2 < legal1) should = 0;
368
}
369
370
if (should)
371
{
372
// do swapping !
373
374
// cout << "swap " << endl;
375
376
nswaps ++;
377
378
// testout << "nv1 = " << nv1 << " nv2 = " << nv2 << endl;
379
380
381
done = 1;
382
383
mesh[t1].PNum(1) = pi1;
384
mesh[t1].PNum(2) = pi4;
385
mesh[t1].PNum(3) = pi3;
386
387
mesh[t2].PNum(1) = pi2;
388
mesh[t2].PNum(2) = pi3;
389
mesh[t2].PNum(3) = pi4;
390
391
mesh[t1].GeomInfoPi(1) = gi1;
392
mesh[t1].GeomInfoPi(2) = gi4;
393
mesh[t1].GeomInfoPi(3) = gi3;
394
395
mesh[t2].GeomInfoPi(1) = gi2;
396
mesh[t2].GeomInfoPi(2) = gi3;
397
mesh[t2].GeomInfoPi(3) = gi4;
398
399
pdef[pi1]--;
400
pdef[pi2]--;
401
pdef[pi3]++;
402
pdef[pi4]++;
403
404
swapped[t1] = 1;
405
swapped[t2] = 1;
406
}
407
}
408
}
409
}
410
t--;
411
}
412
413
mesh.SetNextTimeStamp();
414
}
415
416
417
418
419
420
421
422
423
void MeshOptimize2d :: CombineImprove (Mesh & mesh)
424
{
425
if (!faceindex)
426
{
427
PrintMessage (3, "Combine improve");
428
429
for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++)
430
{
431
CombineImprove (mesh);
432
433
if (multithread.terminate)
434
throw NgException ("Meshing stopped");
435
}
436
faceindex = 0;
437
return;
438
}
439
440
441
static int timer = NgProfiler::CreateTimer ("Combineimprove 2D");
442
NgProfiler::RegionTimer reg (timer);
443
444
445
446
int i, j, k, l;
447
PointIndex pi;
448
SurfaceElementIndex sei;
449
450
451
ARRAY<SurfaceElementIndex> seia;
452
mesh.GetSurfaceElementsOfFace (faceindex, seia);
453
454
455
for (i = 0; i < seia.Size(); i++)
456
if (mesh[seia[i]].GetNP() != 3)
457
return;
458
459
460
461
int surfnr = 0;
462
if (faceindex)
463
surfnr = mesh.GetFaceDescriptor (faceindex).SurfNr();
464
465
466
PointIndex pi1, pi2;
467
MeshPoint p1, p2, pnew;
468
double bad1, bad2;
469
Vec<3> nv;
470
471
int np = mesh.GetNP();
472
//int nse = mesh.GetNSE();
473
474
TABLE<SurfaceElementIndex,PointIndex::BASE> elementsonnode(np);
475
ARRAY<SurfaceElementIndex> hasonepi, hasbothpi;
476
477
for (i = 0; i < seia.Size(); i++)
478
{
479
Element2d & el = mesh[seia[i]];
480
for (j = 0; j < el.GetNP(); j++)
481
{
482
elementsonnode.Add (el[j], seia[i]);
483
}
484
}
485
486
487
ARRAY<bool,PointIndex::BASE> fixed(np);
488
fixed = false;
489
490
SegmentIndex si;
491
for (si = 0; si < mesh.GetNSeg(); si++)
492
{
493
INDEX_2 i2(mesh[si].p1, mesh[si].p2);
494
fixed[i2.I1()] = true;
495
fixed[i2.I2()] = true;
496
}
497
498
for(i = 0; i<mesh.LockedPoints().Size(); i++)
499
fixed[mesh.LockedPoints()[i]] = true;
500
501
502
ARRAY<Vec<3>,PointIndex::BASE> normals(np);
503
504
for (pi = PointIndex::BASE;
505
pi < np + PointIndex::BASE; pi++)
506
{
507
if (elementsonnode[pi].Size())
508
{
509
Element2d & hel = mesh[elementsonnode[pi][0]];
510
for (k = 0; k < 3; k++)
511
if (hel[k] == pi)
512
{
513
SelectSurfaceOfPoint (mesh[pi], hel.GeomInfoPi(k+1));
514
GetNormalVector (surfnr, mesh[pi], hel.GeomInfoPi(k+1), normals[pi]);
515
break;
516
}
517
if (k == 3)
518
{
519
cerr << "Neuer Fehler von Joachim, code 17121" << endl;
520
}
521
}
522
}
523
524
525
for (i = 0; i < seia.Size(); i++)
526
{
527
528
sei = seia[i];
529
Element2d & elem = mesh[sei];
530
if (elem.IsDeleted()) continue;
531
532
for (j = 0; j < 3; j++)
533
{
534
pi1 = elem[j];
535
pi2 = elem[(j+1) % 3];
536
537
if (pi1 < PointIndex::BASE ||
538
pi2 < PointIndex::BASE)
539
continue;
540
541
/*
542
INDEX_2 i2(pi1, pi2);
543
i2.Sort();
544
if (segmentht.Used(i2))
545
continue;
546
*/
547
548
bool debugflag = 0;
549
550
if (debugflag)
551
{
552
(*testout) << "Combineimprove, face = " << faceindex
553
<< "pi1 = " << pi1 << " pi2 = " << pi2 << endl;
554
}
555
556
/*
557
// save version:
558
if (fixed.Get(pi1) || fixed.Get(pi2))
559
continue;
560
if (pi2 < pi1) swap (pi1, pi2);
561
*/
562
563
// more general
564
if (fixed[pi2])
565
Swap (pi1, pi2);
566
567
if (fixed[pi2])
568
continue;
569
570
double loch = mesh.GetH (mesh[pi1]);
571
572
INDEX_2 si2 (pi1, pi2);
573
si2.Sort();
574
575
/*
576
if (edgetested.Used (si2))
577
continue;
578
edgetested.Set (si2, 1);
579
*/
580
581
hasonepi.SetSize(0);
582
hasbothpi.SetSize(0);
583
584
for (k = 0; k < elementsonnode[pi1].Size(); k++)
585
{
586
const Element2d & el2 = mesh[elementsonnode[pi1][k]];
587
588
if (el2.IsDeleted()) continue;
589
590
if (el2[0] == pi2 || el2[1] == pi2 || el2[2] == pi2)
591
{
592
hasbothpi.Append (elementsonnode[pi1][k]);
593
nv = Cross (Vec3d (mesh[el2[0]], mesh[el2[1]]),
594
Vec3d (mesh[el2[0]], mesh[el2[2]]));
595
}
596
else
597
{
598
hasonepi.Append (elementsonnode[pi1][k]);
599
}
600
}
601
602
603
Element2d & hel = mesh[hasbothpi[0]];
604
for (k = 0; k < 3; k++)
605
if (hel[k] == pi1)
606
{
607
SelectSurfaceOfPoint (mesh[pi1],
608
hel.GeomInfoPi(k+1));
609
GetNormalVector (surfnr, mesh[pi1], hel.GeomInfoPi(k+1), nv);
610
break;
611
}
612
if (k == 3)
613
{
614
cerr << "Neuer Fehler von Joachim, code 32434" << endl;
615
}
616
617
618
// nv = normals.Get(pi1);
619
620
621
622
for (k = 0; k < elementsonnode[pi2].Size(); k++)
623
{
624
const Element2d & el2 = mesh[elementsonnode[pi2][k]];
625
if (el2.IsDeleted()) continue;
626
627
if (el2[0] == pi1 || el2[1] == pi1 || el2[2] == pi1)
628
;
629
else
630
hasonepi.Append (elementsonnode[pi2][k]);
631
}
632
633
bad1 = 0;
634
int illegal1 = 0, illegal2 = 0;
635
for (k = 0; k < hasonepi.Size(); k++)
636
{
637
const Element2d & el = mesh[hasonepi[k]];
638
bad1 += CalcTriangleBadness (mesh[el[0]], mesh[el[1]], mesh[el[2]],
639
nv, -1, loch);
640
illegal1 += 1-mesh.LegalTrig(el);
641
}
642
643
for (k = 0; k < hasbothpi.Size(); k++)
644
{
645
const Element2d & el = mesh[hasbothpi[k]];
646
bad1 += CalcTriangleBadness (mesh[el[0]], mesh[el[1]], mesh[el[2]],
647
nv, -1, loch);
648
illegal1 += 1-mesh.LegalTrig(el);
649
}
650
bad1 /= (hasonepi.Size()+hasbothpi.Size());
651
652
p1 = mesh[pi1];
653
p2 = mesh[pi2];
654
655
pnew = p1;
656
mesh[pi1] = pnew;
657
mesh[pi2] = pnew;
658
659
bad2 = 0;
660
for (k = 0; k < hasonepi.Size(); k++)
661
{
662
Element2d & el = mesh[hasonepi[k]];
663
double err =
664
CalcTriangleBadness (mesh[el[0]], mesh[el[1]], mesh[el[2]],
665
nv, -1, loch);
666
bad2 += err;
667
668
Vec<3> hnv = Cross (Vec3d (mesh[el[0]],
669
mesh[el[1]]),
670
Vec3d (mesh[el[0]],
671
mesh[el[2]]));
672
if (hnv * nv < 0)
673
bad2 += 1e10;
674
675
for (l = 0; l < 3; l++)
676
if ( (normals[el[l]] * nv) < 0.5)
677
bad2 += 1e10;
678
679
illegal2 += 1-mesh.LegalTrig(el);
680
}
681
bad2 /= hasonepi.Size();
682
683
mesh[pi1] = p1;
684
mesh[pi2] = p2;
685
686
687
if (debugflag)
688
{
689
(*testout) << "bad1 = " << bad1 << ", bad2 = " << bad2 << endl;
690
}
691
692
693
bool should = (bad2 < bad1 && bad2 < 1e4);
694
if (bad2 < 1e4)
695
{
696
if (illegal1 > illegal2) should = 1;
697
if (illegal2 > illegal1) should = 0;
698
}
699
700
701
if (should)
702
{
703
// (*testout) << "combine !" << endl;
704
// (*testout) << "bad1 = " << bad1 << ", bad2 = " << bad2 << endl;
705
706
707
mesh[pi1] = pnew;
708
PointGeomInfo gi;
709
bool gi_set(false);
710
711
712
Element2d *el1p(NULL);
713
l=0;
714
while(mesh[elementsonnode[pi1][l]].IsDeleted() && l<elementsonnode.EntrySize(pi1)) l++;
715
if(l<elementsonnode.EntrySize(pi1))
716
el1p = &mesh[elementsonnode[pi1][l]];
717
else
718
cerr << "OOPS!" << endl;
719
720
for (l = 0; l < el1p->GetNP(); l++)
721
if ((*el1p)[l] == pi1)
722
{
723
gi = el1p->GeomInfoPi (l+1);
724
gi_set = true;
725
}
726
727
// (*testout) << "Connect point " << pi2 << " to " << pi1 << "\n";
728
for (k = 0; k < elementsonnode[pi2].Size(); k++)
729
{
730
Element2d & el = mesh[elementsonnode[pi2][k]];
731
if(el.IsDeleted()) continue;
732
elementsonnode.Add (pi1, elementsonnode[pi2][k]);
733
734
bool haspi1 = 0;
735
for (l = 0; l < el.GetNP(); l++)
736
if (el[l] == pi1)
737
haspi1 = 1;
738
if (haspi1) continue;
739
740
for (l = 0; l < el.GetNP(); l++)
741
{
742
if (el[l] == pi2)
743
{
744
el[l] = pi1;
745
el.GeomInfoPi (l+1) = gi;
746
}
747
748
fixed[el[l]] = true;
749
}
750
}
751
752
/*
753
for (k = 0; k < hasbothpi.Size(); k++)
754
{
755
cout << mesh[hasbothpi[k]] << endl;
756
for (l = 0; l < 3; l++)
757
cout << mesh[mesh[hasbothpi[k]][l]] << " ";
758
cout << endl;
759
}
760
*/
761
762
for (k = 0; k < hasbothpi.Size(); k++)
763
{
764
mesh[hasbothpi[k]].Delete();
765
/*
766
for (l = 0; l < 4; l++)
767
mesh[hasbothpi[k]][l] = PointIndex::BASE-1;
768
*/
769
}
770
771
}
772
}
773
}
774
775
// mesh.Compress();
776
mesh.SetNextTimeStamp();
777
}
778
779
780
void MeshOptimize2d :: CheckMeshApproximation (Mesh & mesh)
781
{
782
// Check angles between elements and normals at corners
783
/*
784
785
int i, j;
786
int ne = mesh.GetNSE();
787
int surfnr;
788
789
Vec3d n, ng;
790
ARRAY<Vec3d> ngs(3);
791
792
(*mycout) << "Check Surface Approxiamtion" << endl;
793
(*testout) << "Check Surface Approxiamtion" << endl;
794
795
for (i = 1; i <= ne; i++)
796
{
797
const Element2d & el = mesh.SurfaceElement(i);
798
surfnr = mesh.GetFaceDescriptor (el.GetIndex()).SurfNr();
799
Vec3d n = Cross (mesh.Point (el.PNum(1)) - mesh.Point (el.PNum(2)),
800
mesh.Point (el.PNum(1)) - mesh.Point (el.PNum(3)));
801
n /= n.Length();
802
803
for (j = 1; j <= el.GetNP(); j++)
804
{
805
SelectSurfaceOfPoint (mesh.Point(el.PNum(j)), el.GeomInfoPi(j));
806
GetNormalVector (surfnr, mesh.Point(el.PNum(j)), ng);
807
ng /= ng.Length();
808
ngs.Elem(j) = ng;
809
810
double angle = (180.0 / M_PI) * Angle (n, ng);
811
if (angle > 60)
812
{
813
(*testout) << "el " << i << " node " << el.PNum(j)
814
<< "has angle = " << angle << endl;
815
}
816
}
817
818
for (j = 1; j <= 3; j++)
819
{
820
double angle = (180.0 / M_PI) * Angle (ngs.Get(j), ngs.Get(j%3+1));
821
if (angle > 60)
822
{
823
(*testout) << "el " << i << " node-node "
824
<< ngs.Get(j) << " - " << ngs.Get(j%3+1)
825
<< " has angle = " << angle << endl;
826
}
827
}
828
}
829
*/
830
}
831
}
832
833