Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/meshing/localh.cpp
3206 views
1
#include <mystdlib.h>
2
#include "meshing.hpp"
3
4
5
namespace netgen
6
{
7
8
GradingBox :: GradingBox (const double * ax1, const double * ax2)
9
{
10
h2 = 0.5 * (ax2[0] - ax1[0]);
11
for (int i = 0; i <= 2; i++)
12
{
13
/*
14
x1[i] = ax1[i];
15
x2[i] = ax2[i];
16
*/
17
xmid[i] = 0.5 * (ax1[i] + ax2[i]);
18
}
19
20
/*
21
(*testout) << "new box: " << xmid[0] << "-" << xmid[1] << "-" << xmid[2]
22
<< " h = " << (x2[0] - x1[0]) << endl;
23
*/
24
25
for (int i = 0; i < 8; i++)
26
childs[i] = NULL;
27
father = NULL;
28
29
flags.cutboundary = 0;
30
flags.isinner = 0;
31
flags.oldcell = 0;
32
flags.pinner = 0;
33
34
// hopt = x2[0] - x1[0];
35
hopt = 2 * h2;
36
}
37
38
39
40
BlockAllocator GradingBox :: ball(sizeof (GradingBox));
41
42
void * GradingBox :: operator new(size_t)
43
{
44
return ball.Alloc();
45
}
46
47
void GradingBox :: operator delete (void * p)
48
{
49
ball.Free (p);
50
}
51
52
53
54
55
56
57
58
void GradingBox :: DeleteChilds()
59
{
60
int i;
61
for (i = 0; i < 8; i++)
62
if (childs[i])
63
{
64
childs[i]->DeleteChilds();
65
delete childs[i];
66
childs[i] = NULL;
67
}
68
}
69
70
71
LocalH :: LocalH (const Point3d & pmin, const Point3d & pmax, double agrading)
72
{
73
double x1[3], x2[3];
74
double hmax;
75
int i;
76
77
boundingbox = Box3d (pmin, pmax);
78
grading = agrading;
79
80
// a small enlargement, non-regular points
81
double val = 0.0879;
82
for (i = 1; i <= 3; i++)
83
{
84
85
x1[i-1] = (1 + val * i) * pmin.X(i) - val * i * pmax.X(i);
86
x2[i-1] = 1.1 * pmax.X(i) - 0.1 * pmin.X(i);
87
}
88
89
hmax = x2[0] - x1[0];
90
for (i = 1; i <= 2; i++)
91
if (x2[i] - x1[i] > hmax)
92
hmax = x2[i] - x1[i];
93
94
for (i = 0; i <= 2; i++)
95
x2[i] = x1[i] + hmax;
96
97
root = new GradingBox (x1, x2);
98
boxes.Append (root);
99
}
100
101
LocalH :: ~LocalH ()
102
{
103
root->DeleteChilds();
104
delete root;
105
}
106
107
void LocalH :: Delete ()
108
{
109
root->DeleteChilds();
110
}
111
112
void LocalH :: SetH (const Point3d & p, double h)
113
{
114
/*
115
(*testout) << "Set h at " << p << " to " << h << endl;
116
if (h < 1e-8)
117
{
118
cout << "do not set h to " << h << endl;
119
return;
120
}
121
*/
122
123
if (fabs (p.X() - root->xmid[0]) > root->h2 ||
124
fabs (p.Y() - root->xmid[1]) > root->h2 ||
125
fabs (p.Z() - root->xmid[2]) > root->h2)
126
return;
127
128
/*
129
if (p.X() < root->x1[0] || p.X() > root->x2[0] ||
130
p.Y() < root->x1[1] || p.Y() > root->x2[1] ||
131
p.Z() < root->x1[2] || p.Z() > root->x2[2])
132
return;
133
*/
134
135
136
if (GetH(p) <= 1.2 * h) return;
137
138
139
GradingBox * box = root;
140
GradingBox * nbox = root;
141
GradingBox * ngb;
142
int childnr;
143
double x1[3], x2[3];
144
145
while (nbox)
146
{
147
box = nbox;
148
childnr = 0;
149
if (p.X() > box->xmid[0]) childnr += 1;
150
if (p.Y() > box->xmid[1]) childnr += 2;
151
if (p.Z() > box->xmid[2]) childnr += 4;
152
nbox = box->childs[childnr];
153
};
154
155
156
while (2 * box->h2 > h)
157
{
158
childnr = 0;
159
if (p.X() > box->xmid[0]) childnr += 1;
160
if (p.Y() > box->xmid[1]) childnr += 2;
161
if (p.Z() > box->xmid[2]) childnr += 4;
162
163
double h2 = box->h2;
164
if (childnr & 1)
165
{
166
x1[0] = box->xmid[0];
167
x2[0] = x1[0]+h2; // box->x2[0];
168
}
169
else
170
{
171
x2[0] = box->xmid[0];
172
x1[0] = x2[0]-h2; // box->x1[0];
173
}
174
175
if (childnr & 2)
176
{
177
x1[1] = box->xmid[1];
178
x2[1] = x1[1]+h2; // box->x2[1];
179
}
180
else
181
{
182
x2[1] = box->xmid[1];
183
x1[1] = x2[1]-h2; // box->x1[1];
184
}
185
186
if (childnr & 4)
187
{
188
x1[2] = box->xmid[2];
189
x2[2] = x1[2]+h2; // box->x2[2];
190
}
191
else
192
{
193
x2[2] = box->xmid[2];
194
x1[2] = x2[2]-h2; // box->x1[2];
195
}
196
197
ngb = new GradingBox (x1, x2);
198
box->childs[childnr] = ngb;
199
ngb->father = box;
200
201
boxes.Append (ngb);
202
box = box->childs[childnr];
203
}
204
205
box->hopt = h;
206
207
208
double hbox = 2 * box->h2; // box->x2[0] - box->x1[0];
209
double hnp = h + grading * hbox;
210
211
Point3d np;
212
int i;
213
for (i = 1; i <= 3; i++)
214
{
215
np = p;
216
np.X(i) = p.X(i) + hbox;
217
SetH (np, hnp);
218
219
np.X(i) = p.X(i) - hbox;
220
SetH (np, hnp);
221
}
222
/*
223
Point3d np;
224
int i1, i2, i3;
225
for (i1 = -1; i1 <= 1; i1++)
226
for (i2 = -1; i2 <= 1; i2++)
227
for (i3 = -1; i3 <= 1; i3++)
228
{
229
np.X() = p.X() + hbox * i1;
230
np.Y() = p.Y() + hbox * i2;
231
np.Z() = p.Z() + hbox * i3;
232
233
SetH (np, hnp);
234
}
235
*/
236
}
237
238
239
240
double LocalH :: GetH (const Point3d & x) const
241
{
242
const GradingBox * box = root;
243
const GradingBox * nbox;
244
int childnr;
245
246
while (1)
247
{
248
childnr = 0;
249
if (x.X() > box->xmid[0]) childnr += 1;
250
if (x.Y() > box->xmid[1]) childnr += 2;
251
if (x.Z() > box->xmid[2]) childnr += 4;
252
nbox = box->childs[childnr];
253
if (nbox)
254
box = nbox;
255
else
256
{
257
// (*testout) << "diam = " << (box->x2[0] - box->x1[0])
258
// << " h = " << box->hopt << endl;
259
return box->hopt;
260
}
261
}
262
}
263
264
265
/// minimal h in box (pmin, pmax)
266
double LocalH :: GetMinH (const Point3d & pmin, const Point3d & pmax) const
267
{
268
Point3d pmin2, pmax2;
269
for (int j = 1; j <= 3; j++)
270
if (pmin.X(j) < pmax.X(j))
271
{ pmin2.X(j) = pmin.X(j); pmax2.X(j) = pmax.X(j); }
272
else
273
{ pmin2.X(j) = pmax.X(j); pmax2.X(j) = pmin.X(j); }
274
275
return GetMinHRec (pmin2, pmax2, root);
276
}
277
278
279
double LocalH :: GetMinHRec (const Point3d & pmin, const Point3d & pmax,
280
const GradingBox * box) const
281
{
282
double h2 = box->h2;
283
if (pmax.X() < box->xmid[0]-h2 || pmin.X() > box->xmid[0]+h2 ||
284
pmax.Y() < box->xmid[1]-h2 || pmin.Y() > box->xmid[1]+h2 ||
285
pmax.Z() < box->xmid[2]-h2 || pmin.Z() > box->xmid[2]+h2)
286
return 1e8;
287
/*
288
if (pmax.X() < box->x1[0] || pmin.X() > box->x2[0] ||
289
pmax.Y() < box->x1[1] || pmin.Y() > box->x2[1] ||
290
pmax.Z() < box->x1[2] || pmin.Z() > box->x2[2])
291
return 1e8;
292
*/
293
294
295
double hmin = 2 * box->h2; // box->x2[0] - box->x1[0];
296
int i;
297
298
for (i = 0; i <= 7; i++)
299
{
300
if (box->childs[i])
301
{
302
double hi = GetMinHRec (pmin, pmax, box->childs[i]);
303
if (hi < hmin)
304
hmin = hi;
305
}
306
}
307
308
return hmin;
309
}
310
311
312
void LocalH :: CutBoundaryRec (const Point3d & pmin, const Point3d & pmax,
313
GradingBox * box)
314
{
315
double h2 = box->h2;
316
if (pmax.X() < box->xmid[0]-h2 || pmin.X() > box->xmid[0]+h2 ||
317
pmax.Y() < box->xmid[1]-h2 || pmin.Y() > box->xmid[1]+h2 ||
318
pmax.Z() < box->xmid[2]-h2 || pmin.Z() > box->xmid[2]+h2)
319
return;
320
/*
321
if (pmax.X() < box->x1[0] || pmin.X() > box->x2[0] ||
322
pmax.Y() < box->x1[1] || pmin.Y() > box->x2[1] ||
323
pmax.Z() < box->x1[2] || pmin.Z() > box->x2[2])
324
return;
325
*/
326
327
box->flags.cutboundary = 1;
328
for (int i = 0; i < 8; i++)
329
if (box->childs[i])
330
CutBoundaryRec (pmin, pmax, box->childs[i]);
331
}
332
333
334
335
336
void LocalH :: FindInnerBoxes ( // int (*sameside)(const Point3d & p1, const Point3d & p2),
337
AdFront3 * adfront,
338
int (*testinner)(const Point3d & p1))
339
{
340
int i;
341
342
int nf = adfront->GetNF();
343
344
for (i = 0; i < boxes.Size(); i++)
345
boxes[i] -> flags.isinner = 0;
346
347
root->flags.isinner = 0;
348
349
Point3d rpmid(root->xmid[0], root->xmid[1], root->xmid[2]);
350
Vec3d rv(root->h2, root->h2, root->h2);
351
Point3d rx2 = rpmid + rv;
352
Point3d rx1 = rpmid - rv;
353
354
355
root->flags.pinner = !adfront->SameSide (rpmid, rx2);
356
357
if (testinner)
358
(*testout) << "inner = " << root->flags.pinner << " =?= "
359
<< testinner(Point3d(root->xmid[0], root->xmid[1], root->xmid[2])) << endl;
360
361
ARRAY<int> faceinds(nf);
362
ARRAY<Box3d> faceboxes(nf);
363
364
for (i = 1; i <= nf; i++)
365
{
366
faceinds.Elem(i) = i;
367
adfront->GetFaceBoundingBox(i, faceboxes.Elem(i));
368
}
369
370
for (i = 0; i < 8; i++)
371
FindInnerBoxesRec2 (root->childs[i], adfront, faceboxes, faceinds, nf);
372
}
373
374
375
void LocalH ::
376
FindInnerBoxesRec2 (GradingBox * box,
377
class AdFront3 * adfront,
378
ARRAY<Box3d> & faceboxes,
379
ARRAY<int> & faceinds, int nfinbox)
380
{
381
if (!box) return;
382
383
int i, j;
384
385
GradingBox * father = box -> father;
386
387
Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]);
388
Vec3d v(box->h2, box->h2, box->h2);
389
Box3d boxc(c-v, c+v);
390
391
Point3d fc(father->xmid[0], father->xmid[1], father->xmid[2]);
392
Vec3d fv(father->h2, father->h2, father->h2);
393
Box3d fboxc(fc-fv, fc+fv);
394
395
Box3d boxcfc(c,fc);
396
397
398
static ARRAY<int> faceused;
399
static ARRAY<int> faceused2;
400
static ARRAY<int> facenotused;
401
402
faceused.SetSize(0);
403
facenotused.SetSize(0);
404
faceused2.SetSize(0);
405
406
for (j = 1; j <= nfinbox; j++)
407
{
408
// adfront->GetFaceBoundingBox (faceinds.Get(j), facebox);
409
const Box3d & facebox = faceboxes.Get(faceinds.Get(j));
410
411
if (boxc.Intersect (facebox))
412
faceused.Append(faceinds.Get(j));
413
else
414
facenotused.Append(faceinds.Get(j));
415
416
if (boxcfc.Intersect (facebox))
417
faceused2.Append (faceinds.Get(j));
418
}
419
420
for (j = 1; j <= faceused.Size(); j++)
421
faceinds.Elem(j) = faceused.Get(j);
422
for (j = 1; j <= facenotused.Size(); j++)
423
faceinds.Elem(j+faceused.Size()) = facenotused.Get(j);
424
425
426
if (!father->flags.cutboundary)
427
{
428
box->flags.isinner = father->flags.isinner;
429
box->flags.pinner = father->flags.pinner;
430
}
431
else
432
{
433
Point3d cf(father->xmid[0], father->xmid[1], father->xmid[2]);
434
435
if (father->flags.isinner)
436
box->flags.pinner = 1;
437
else
438
{
439
if (adfront->SameSide (c, cf, &faceused2))
440
box->flags.pinner = father->flags.pinner;
441
else
442
box->flags.pinner = 1 - father->flags.pinner;
443
}
444
445
if (box->flags.cutboundary)
446
box->flags.isinner = 0;
447
else
448
box->flags.isinner = box->flags.pinner;
449
}
450
451
int nf = faceused.Size();
452
for (i = 0; i < 8; i++)
453
FindInnerBoxesRec2 (box->childs[i], adfront, faceboxes, faceinds, nf);
454
}
455
456
457
458
459
460
461
462
463
464
465
466
467
/*
468
void LocalH :: FindInnerBoxes ( // int (*sameside)(const Point3d & p1, const Point3d & p2),
469
AdFront3 * adfront,
470
int (*testinner)(const Point3d & p1))
471
{
472
int i;
473
for (i = 1; i <= boxes.Size(); i++)
474
boxes.Elem(i)->flags.isinner = 0;
475
476
root->flags.isinner = 0;
477
478
Point3d rpmid(root->xmid[0], root->xmid[1], root->xmid[2]);
479
Point3d rx2 = rpmid + Vec3d (root->h2, root->h2, root->h2);
480
481
root->flags.pinner = !adfront->SameSide (rpmid, rx2);
482
483
if (testinner)
484
(*testout) << "inner = " << root->flags.pinner << " =?= "
485
<< testinner(Point3d(root->xmid[0], root->xmid[1], root->xmid[2])) << endl;
486
487
488
for (i = 2; i <= boxes.Size(); i++)
489
{
490
GradingBox * box = boxes.Elem(i);
491
GradingBox * father = box -> father;
492
493
Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]);
494
Vec3d v(box->h2, box->h2, box->h2);
495
Point3d x1 = c-v;
496
Point3d x2 = c+v;
497
498
499
if (!father->flags.cutboundary)
500
{
501
box->flags.isinner = father->flags.isinner;
502
box->flags.pinner = father->flags.pinner;
503
}
504
else
505
{
506
Point3d cf(father->xmid[0], father->xmid[1], father->xmid[2]);
507
508
if (father->flags.isinner)
509
box->flags.pinner = 1;
510
else
511
{
512
if (adfront->SameSide (c, cf))
513
box->flags.pinner = father->flags.pinner;
514
else
515
box->flags.pinner = 1 - father->flags.pinner;
516
}
517
518
if (box->flags.cutboundary)
519
box->flags.isinner = 0;
520
else
521
box->flags.isinner = box->flags.pinner;
522
}
523
}
524
// FindInnerBoxesRec (inner, root);
525
}
526
*/
527
528
529
void LocalH :: FindInnerBoxesRec ( int (*inner)(const Point3d & p),
530
GradingBox * box)
531
{
532
int i;
533
if (box->flags.cutboundary)
534
{
535
for (i = 0; i < 8; i++)
536
if (box->childs[i])
537
FindInnerBoxesRec (inner, box->childs[i]);
538
}
539
else
540
{
541
if (inner (Point3d (box->xmid[0], box->xmid[1], box->xmid[2])))
542
SetInnerBoxesRec (box);
543
}
544
}
545
546
547
void LocalH :: SetInnerBoxesRec (GradingBox * box)
548
{
549
box->flags.isinner = 1;
550
for (int i = 0; i < 8; i++)
551
if (box->childs[i])
552
ClearFlagsRec (box->childs[i]);
553
}
554
555
void LocalH :: ClearFlagsRec (GradingBox * box)
556
{
557
box->flags.cutboundary = 0;
558
box->flags.isinner = 0;
559
for (int i = 0; i < 8; i++)
560
if (box->childs[i])
561
ClearFlagsRec (box->childs[i]);
562
}
563
564
565
void LocalH :: WidenRefinement ()
566
{
567
int nb = boxes.Size();
568
int i;
569
// (*testout) << "old boxes: " << nb << endl;
570
for (i = 1; i <= nb; i++)
571
{
572
GradingBox * box = boxes.Get(i);
573
// double h = box->x2[0] - box->x1[0];
574
double h = box->hopt;
575
Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]);
576
// (*testout) << " i = " << i
577
// << " c = " << c << " h = " << h << endl;
578
579
for (int i1 = -1; i1 <= 1; i1++)
580
for (int i2 = -1; i2 <= 1; i2++)
581
for (int i3 = -1; i3 <= 1; i3++)
582
SetH (Point3d (c.X() + i1 * h,
583
c.Y() + i2 * h,
584
c.Z() + i3 * h), 1.001 * h);
585
}
586
}
587
588
void LocalH :: GetInnerPoints (ARRAY<Point3d> & points)
589
{
590
int i, nb = boxes.Size();
591
592
for (i = 1; i <= nb; i++)
593
{
594
GradingBox * box = boxes.Get(i);
595
/*
596
if (box->flags.pinner)
597
points.Append (box->randomip);
598
*/
599
// if (box->flags.pinner)
600
if (box->flags.isinner)
601
{
602
Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]);
603
points.Append (c);
604
/*
605
cout << "add point " << c << "; h = " << box->hopt
606
<< "; max-min = " << (box->x2[0]-box->x1[0]) << endl;
607
*/
608
}
609
}
610
}
611
612
613
614
void LocalH :: GetOuterPoints (ARRAY<Point3d> & points)
615
{
616
int i, nb = boxes.Size();
617
618
for (i = 1; i <= nb; i++)
619
{
620
GradingBox * box = boxes.Get(i);
621
if (!box->flags.isinner &&
622
!box->flags.cutboundary)
623
{
624
Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]);
625
points.Append (c);
626
}
627
}
628
}
629
630
631
632
void LocalH :: Convexify ()
633
{
634
ConvexifyRec (root);
635
}
636
637
void LocalH :: ConvexifyRec (GradingBox * box)
638
{
639
Point3d center(box->xmid[0], box->xmid[1], box->xmid[2]);
640
Point3d hp;
641
642
double size = 2 * box->h2; // box->x2[0] - box->x1[0];
643
double dx = 0.6 * size;
644
645
double maxh = box->hopt;
646
int i;
647
648
649
650
for (i = 1; i <= 6; i++)
651
{
652
hp = center;
653
switch (i)
654
{
655
case 1: hp.X() += dx; break;
656
case 2: hp.X() -= dx; break;
657
case 3: hp.Y() += dx; break;
658
case 4: hp.Y() -= dx; break;
659
case 5: hp.Z() += dx; break;
660
case 6: hp.Z() -= dx; break;
661
}
662
663
double hh = GetH (hp);
664
if (hh > maxh) maxh = hh;
665
}
666
667
if (maxh < 0.95 * box->hopt)
668
SetH (center, maxh);
669
670
for (i = 0; i < 8; i++)
671
if (box->childs[i])
672
ConvexifyRec (box->childs[i]);
673
}
674
675
void LocalH :: PrintMemInfo (ostream & ost) const
676
{
677
ost << "LocalH: " << boxes.Size() << " boxes of " << sizeof(GradingBox)
678
<< " bytes = " << boxes.Size()*sizeof(GradingBox) << " bytes" << endl;
679
}
680
}
681
682