Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/meshing/bisect.cpp
3206 views
1
#include <mystdlib.h>
2
#include "meshing.hpp"
3
4
#define noDEBUG
5
6
7
namespace netgen
8
{
9
//#include "../interface/writeuser.hpp"
10
class MarkedTet;
11
class MarkedPrism;
12
class MarkedIdentification;
13
class MarkedTri;
14
class MarkedQuad;
15
16
typedef MoveableArray<MarkedTet> T_MTETS;
17
typedef MoveableArray<MarkedPrism> T_MPRISMS;
18
typedef MoveableArray<MarkedIdentification> T_MIDS;
19
typedef MoveableArray<MarkedTri> T_MTRIS;
20
typedef MoveableArray<MarkedQuad> T_MQUADS;
21
22
23
24
class MarkedTet
25
{
26
public:
27
/// pnums of tet
28
PointIndex pnums[4];
29
/// material number
30
int matindex;
31
/// element marked for refinement
32
/// marked = 1: marked by element marker, marked = 2 due to closure
33
unsigned int marked:2;
34
/// flag of Arnold-Mukherjee algorithm
35
unsigned int flagged:1;
36
/// tetedge (local coordinates 0..3)
37
unsigned int tetedge1:3;
38
unsigned int tetedge2:3;
39
// marked edge of faces
40
// face_j : face without node j,
41
// mark_k : edge without node k
42
43
char faceedges[4];
44
// unsigned char faceedges[4];
45
bool incorder;
46
unsigned int order:6;
47
48
MarkedTet()
49
{
50
for (int i = 0; i < 4; i++) { faceedges[i] = 255; }
51
}
52
};
53
54
ostream & operator<< (ostream & ost, const MarkedTet & mt)
55
{
56
for(int i=0; i<4; i++)
57
ost << mt.pnums[i] << " ";
58
59
ost << mt.matindex << " " << int(mt.marked) << " " << int(mt.flagged) << " " << int(mt.tetedge1) << " " << int(mt.tetedge2) << " ";
60
61
ost << "faceedges = ";
62
for(int i=0; i<4; i++)
63
ost << int(mt.faceedges[i]) << " ";
64
65
ost << " order = ";
66
ost << mt.incorder << " " << int(mt.order) << "\n";
67
return ost;
68
}
69
istream & operator>> (istream & ost, MarkedTet & mt)
70
{
71
for(int i=0; i<4; i++)
72
ost >> mt.pnums[i];
73
74
ost >> mt.matindex;
75
76
int auxint;
77
ost >> auxint;
78
mt.marked = auxint;
79
ost >> auxint;
80
mt.flagged = auxint;
81
ost >> auxint;
82
mt.tetedge1 = auxint;
83
ost >> auxint;
84
mt.tetedge2 = auxint;
85
86
char auxchar;
87
88
for(int i=0; i<4; i++)
89
{
90
ost >> auxchar;
91
mt.faceedges[i] = auxchar;
92
}
93
94
ost >> mt.incorder;
95
ost >> auxint;
96
mt.order = auxint;
97
return ost;
98
}
99
100
class MarkedPrism
101
{
102
public:
103
/// 6 point numbers
104
PointIndex pnums[6];
105
/// material number
106
int matindex;
107
/// marked for refinement
108
int marked;
109
/// edge without node k (0,1,2)
110
int markededge;
111
112
bool incorder;
113
unsigned int order:6;
114
};
115
116
117
ostream & operator<< (ostream & ost, const MarkedPrism & mp)
118
{
119
for(int i=0; i<6; i++)
120
ost << mp.pnums[i] << " ";
121
122
ost << mp.matindex << " " << mp.marked << " " << mp.markededge << " " << mp.incorder << " " << int(mp.order) << "\n";
123
return ost;
124
}
125
istream & operator>> (istream & ist, MarkedPrism & mp)
126
{
127
for(int i=0; i<6; i++)
128
ist >> mp.pnums[i];
129
130
ist >> mp.matindex >> mp.marked >> mp.markededge >> mp.incorder;
131
int auxint;
132
ist >> auxint;
133
mp.order = auxint;
134
return ist;
135
}
136
137
138
class MarkedIdentification
139
{
140
public:
141
// number of points of one face (3 or 4)
142
int np;
143
/// 6 or 8 point numbers
144
PointIndex pnums[8];
145
/// marked for refinement
146
int marked;
147
/// edge starting with node k (0,1,2, or 3)
148
int markededge;
149
150
bool incorder;
151
unsigned int order:6;
152
};
153
154
155
ostream & operator<< (ostream & ost, const MarkedIdentification & mi)
156
{
157
ost << mi.np << " ";
158
for(int i=0; i<2*mi.np; i++)
159
ost << mi.pnums[i] << " ";
160
ost << mi.marked << " " << mi.markededge << " " << mi.incorder << " " << int(mi.order) << "\n";
161
return ost;
162
}
163
istream & operator>> (istream & ist, MarkedIdentification & mi)
164
{
165
ist >> mi.np;
166
for(int i=0; i<2*mi.np; i++)
167
ist >> mi.pnums[i];
168
ist >> mi.marked >> mi.markededge >> mi.incorder;
169
int auxint;
170
ist >> auxint;
171
mi.order = auxint;
172
return ist;
173
}
174
175
176
177
178
179
class MarkedTri
180
{
181
public:
182
/// three point numbers
183
PointIndex pnums[3];
184
/// three geominfos
185
PointGeomInfo pgeominfo[3];
186
/// marked for refinement
187
int marked;
188
/// edge without node k
189
int markededge;
190
/// surface id
191
int surfid;
192
193
bool incorder;
194
unsigned int order:6;
195
};
196
197
ostream & operator<< (ostream & ost, const MarkedTri & mt)
198
{
199
for(int i=0; i<3; i++)
200
ost << mt.pnums[i] << " ";
201
for(int i=0; i<3; i++)
202
ost << mt.pgeominfo[i] << " ";
203
ost << mt.marked << " " << mt.markededge << " " << mt.surfid << " " << mt.incorder << " " << int(mt.order) << "\n";
204
return ost;
205
}
206
istream & operator>> (istream & ist, MarkedTri & mt)
207
{
208
for(int i=0; i<3; i++)
209
ist >> mt.pnums[i];
210
for(int i=0; i<3; i++)
211
ist >> mt.pgeominfo[i];
212
ist >> mt.marked >> mt.markededge >> mt.surfid >> mt.incorder;
213
int auxint;
214
ist >> auxint;
215
mt.order = auxint;
216
return ist;
217
}
218
219
220
221
class MarkedQuad
222
{
223
public:
224
/// point numbers
225
PointIndex pnums[4];
226
///
227
PointGeomInfo pgeominfo[4];
228
/// marked for refinement
229
int marked;
230
/// marked edge: 0/2 = vertical, 1/3 = horizontal
231
int markededge;
232
/// surface id
233
int surfid;
234
235
bool incorder;
236
unsigned int order:6;
237
};
238
239
ostream & operator<< (ostream & ost, const MarkedQuad & mt)
240
{
241
for(int i=0; i<4; i++)
242
ost << mt.pnums[i] << " ";
243
for(int i=0; i<4; i++)
244
ost << mt.pgeominfo[i] << " ";
245
ost << mt.marked << " " << mt.markededge << " " << mt.surfid << " " << mt.incorder << " " << int(mt.order) << "\n";
246
return ost;
247
}
248
istream & operator>> (istream & ist, MarkedQuad & mt)
249
{
250
for(int i=0; i<4; i++)
251
ist >> mt.pnums[i];
252
for(int i=0; i<4; i++)
253
ist >> mt.pgeominfo[i];
254
ist >> mt.marked >> mt.markededge >> mt.surfid >> mt.incorder;
255
int auxint;
256
ist >> auxint;
257
mt.order = auxint;
258
return ist;
259
}
260
261
262
263
264
void PrettyPrint(ostream & ost, const MarkedTet & mt)
265
{
266
int te1 = mt.tetedge1;
267
int te2 = mt.tetedge2;
268
int order = mt.order;
269
270
ost << "MT: " << mt.pnums[0] << " - " << mt.pnums[1] << " - "
271
<< mt.pnums[2] << " - " << mt.pnums[3] << endl
272
<< "marked edge: " << te1 << " - " << te2
273
<< ", order = " << order << endl;
274
//for (int k = 0; k < 4; k++)
275
// ost << int(mt.faceedges[k]) << " ";
276
for (int k = 0; k < 4; k++)
277
{
278
ost << "face";
279
for (int j=0; j<4; j++)
280
if(j != k)
281
ost << " " << mt.pnums[j];
282
for(int i=0; i<3; i++)
283
for(int j=i+1; j<4; j++)
284
if(i != k && j != k && int(mt.faceedges[k]) == 6-k-i-j)
285
ost << " marked edge " << mt.pnums[i] << " " << mt.pnums[j] << endl;
286
}
287
ost << endl;
288
}
289
290
291
292
293
int BTSortEdges (const Mesh & mesh,
294
const ARRAY< ARRAY<int,PointIndex::BASE>* > & idmaps,
295
INDEX_2_CLOSED_HASHTABLE<int> & edgenumber)
296
{
297
PrintMessage(4,"sorting ... ");
298
299
// if (mesh.PureTetMesh())
300
if (1)
301
{
302
// new, fast version
303
304
ARRAY<INDEX_2> edges;
305
ARRAY<int> eclasses;
306
307
int i, j, k;
308
int cntedges = 0;
309
int go_on;
310
int ned(0);
311
312
// enumerate edges:
313
for (i = 1; i <= mesh.GetNE(); i++)
314
{
315
const Element & el = mesh.VolumeElement (i);
316
static int tetedges[6][2] =
317
{ { 1, 2 },
318
{ 1, 3 },
319
{ 1, 4 },
320
{ 2, 3 },
321
{ 2, 4 },
322
{ 3, 4 } } ;
323
static int prismedges[9][2] =
324
{ { 1, 2 },
325
{ 1, 3 },
326
{ 2, 3 },
327
{ 4, 5 },
328
{ 4, 6 },
329
{ 5, 6 },
330
{ 1, 4 },
331
{ 2, 5 },
332
{ 3, 6 } };
333
int pyramidedges[6][2] =
334
{ { 1, 2 },
335
{ 3, 4 },
336
{ 1, 5 },
337
{ 2, 5 },
338
{ 3, 5 },
339
{ 4, 5 } };
340
341
int (*tip)[2] = NULL;
342
343
switch (el.GetType())
344
{
345
case TET:
346
case TET10:
347
{
348
tip = tetedges;
349
ned = 6;
350
break;
351
}
352
case PRISM:
353
case PRISM12:
354
{
355
tip = prismedges;
356
ned = 6;
357
break;
358
}
359
case PYRAMID:
360
{
361
tip = pyramidedges;
362
ned = 6;
363
break;
364
}
365
}
366
367
for (j = 0; j < ned; j++)
368
{
369
INDEX_2 i2(el.PNum(tip[j][0]), el.PNum(tip[j][1]));
370
i2.Sort();
371
//(*testout) << "edge " << i2 << endl;
372
if (!edgenumber.Used(i2))
373
{
374
cntedges++;
375
edges.Append (i2);
376
edgenumber.Set(i2, cntedges);
377
}
378
}
379
}
380
381
// additional surface edges:
382
for (i = 1; i <= mesh.GetNSE(); i++)
383
{
384
const Element2d & el = mesh.SurfaceElement (i);
385
static int trigedges[3][2] =
386
{ { 1, 2 },
387
{ 2, 3 },
388
{ 3, 1 } };
389
390
static int quadedges[4][2] =
391
{ { 1, 2 },
392
{ 2, 3 },
393
{ 3, 4 },
394
{ 4, 1 } };
395
396
397
int (*tip)[2] = NULL;
398
399
switch (el.GetType())
400
{
401
case TRIG:
402
case TRIG6:
403
{
404
tip = trigedges;
405
ned = 3;
406
break;
407
}
408
case QUAD:
409
case QUAD6:
410
{
411
tip = quadedges;
412
ned = 4;
413
break;
414
}
415
default:
416
{
417
cerr << "Error: Sort for Bisect, SE has " << el.GetNP() << " points" << endl;
418
ned = 0;
419
}
420
}
421
422
for (j = 0; j < ned; j++)
423
{
424
INDEX_2 i2(el.PNum(tip[j][0]), el.PNum(tip[j][1]));
425
i2.Sort();
426
if (!edgenumber.Used(i2))
427
{
428
cntedges++;
429
edges.Append (i2);
430
edgenumber.Set(i2, cntedges);
431
}
432
}
433
}
434
435
436
437
438
439
eclasses.SetSize (cntedges);
440
for (i = 1; i <= cntedges; i++)
441
eclasses.Elem(i) = i;
442
443
// identify edges in element stack
444
do
445
{
446
go_on = 0;
447
for (i = 1; i <= mesh.GetNE(); i++)
448
{
449
const Element & el = mesh.VolumeElement (i);
450
451
if (el.GetType() != PRISM &&
452
el.GetType() != PRISM12 &&
453
el.GetType() != PYRAMID)
454
continue;
455
456
int prismpairs[3][4] =
457
{ { 1, 2, 4, 5 },
458
{ 2, 3, 5, 6 },
459
{ 1, 3, 4, 6 } };
460
461
int pyramidpairs[3][4] =
462
{ { 1, 2, 4, 3 },
463
{ 1, 5, 4, 5 },
464
{ 2, 5, 3, 5 } };
465
466
int (*pairs)[4] = NULL;
467
switch (el.GetType())
468
{
469
case PRISM:
470
case PRISM12:
471
{
472
pairs = prismpairs;
473
break;
474
}
475
case PYRAMID:
476
{
477
pairs = pyramidpairs;
478
break;
479
}
480
}
481
482
for (j = 0; j < 3; j++)
483
{
484
INDEX_2 e1 (el.PNum(pairs[j][0]),
485
el.PNum(pairs[j][1]));
486
INDEX_2 e2 (el.PNum(pairs[j][2]),
487
el.PNum(pairs[j][3]));
488
e1.Sort();
489
e2.Sort();
490
491
int eclass1 = edgenumber.Get (e1);
492
int eclass2 = edgenumber.Get (e2);
493
494
// (*testout) << "identify edges " << eclass1 << "-" << eclass2 << endl;
495
496
if (eclasses.Get(eclass1) >
497
eclasses.Get(eclass2))
498
{
499
eclasses.Elem(eclass1) =
500
eclasses.Get(eclass2);
501
go_on = 1;
502
}
503
else if (eclasses.Get(eclass2) >
504
eclasses.Get(eclass1))
505
{
506
eclasses.Elem(eclass2) =
507
eclasses.Get(eclass1);
508
go_on = 1;
509
}
510
}
511
}
512
513
for(SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++)
514
{
515
const Element2d & el2d = mesh[sei];
516
517
for(i = 0; i < el2d.GetNP(); i++)
518
{
519
INDEX_2 e1(el2d[i], el2d[(i+1) % el2d.GetNP()]);
520
e1.Sort();
521
INDEX_2 e2;
522
523
for(k = 0; k < idmaps.Size(); k++)
524
{
525
e2.I1() = (*idmaps[k])[e1.I1()];
526
e2.I2() = (*idmaps[k])[e1.I2()];
527
528
if(e2.I1() == 0 || e2.I2() == 0 ||
529
e1.I1() == e2.I1() || e1.I2() == e2.I2())
530
continue;
531
532
e2.Sort();
533
if(!edgenumber.Used(e2))
534
continue;
535
536
537
int eclass1 = edgenumber.Get (e1);
538
int eclass2 = edgenumber.Get (e2);
539
540
if (eclasses.Get(eclass1) >
541
eclasses.Get(eclass2))
542
{
543
eclasses.Elem(eclass1) =
544
eclasses.Get(eclass2);
545
546
547
go_on = 1;
548
}
549
else if (eclasses.Get(eclass2) >
550
eclasses.Get(eclass1))
551
{
552
eclasses.Elem(eclass2) =
553
eclasses.Get(eclass1);
554
go_on = 1;
555
}
556
}
557
}
558
559
}
560
561
}
562
while (go_on);
563
564
// for (i = 1; i <= cntedges; i++)
565
// {
566
// (*testout) << "edge " << i << ": "
567
// << edges.Get(i).I1() << "-" << edges.Get(i).I2()
568
// << ", class = " << eclasses.Get(i) << endl;
569
// }
570
571
// compute classlength:
572
ARRAY<double> edgelength(cntedges);
573
574
/*
575
for (i = 1; i <= cntedges; i++)
576
edgelength.Elem(i) = 1e20;
577
*/
578
579
for (i = 1; i <= cntedges; i++)
580
{
581
INDEX_2 edge = edges.Get(i);
582
double elen = Dist (mesh.Point(edge.I1()),
583
mesh.Point(edge.I2()));
584
edgelength.Elem (i) = elen;
585
}
586
587
/*
588
for (i = 1; i <= mesh.GetNE(); i++)
589
{
590
const Element & el = mesh.VolumeElement (i);
591
592
if (el.GetType() == TET)
593
{
594
for (j = 1; j <= 3; j++)
595
for (k = j+1; k <= 4; k++)
596
{
597
INDEX_2 i2(el.PNum(j), el.PNum(k));
598
i2.Sort();
599
600
int enr = edgenumber.Get(i2);
601
double elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2()));
602
if (elen < edgelength.Get(enr))
603
edgelength.Set (enr, elen);
604
}
605
}
606
else if (el.GetType() == PRISM)
607
{
608
for (j = 1; j <= 3; j++)
609
{
610
k = (j % 3) + 1;
611
612
INDEX_2 i2(el.PNum(j), el.PNum(k));
613
i2.Sort();
614
615
int enr = edgenumber.Get(i2);
616
double elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2()));
617
if (elen < edgelength.Get(enr))
618
edgelength.Set (enr, elen);
619
620
i2 = INDEX_2(el.PNum(j+3), el.PNum(k+3));
621
i2.Sort();
622
623
enr = edgenumber.Get(i2);
624
elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2()));
625
if (elen < edgelength.Get(enr))
626
edgelength.Set (enr, elen);
627
628
if (!edgenumber.Used(i2))
629
{
630
cntedges++;
631
edgenumber.Set(i2, cntedges);
632
}
633
i2 = INDEX_2(el.PNum(j), el.PNum(j+3));
634
i2.Sort();
635
636
enr = edgenumber.Get(i2);
637
elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2()));
638
if (elen < edgelength.Get(enr))
639
edgelength.Set (enr, elen);
640
}
641
}
642
}
643
*/
644
645
646
for (i = 1; i <= cntedges; i++)
647
{
648
if (eclasses.Get(i) != i)
649
{
650
if (edgelength.Get(i) < edgelength.Get(eclasses.Get(i)))
651
edgelength.Elem(eclasses.Get(i)) = edgelength.Get(i);
652
edgelength.Elem(i) = 1e20;
653
}
654
}
655
656
657
TABLE<int> eclasstab(cntedges);
658
for (i = 1; i <= cntedges; i++)
659
eclasstab.Add1 (eclasses.Get(i), i);
660
661
662
// sort edges:
663
ARRAY<int> sorted(cntedges);
664
665
QickSort (edgelength, sorted);
666
667
int cnt = 0;
668
for (i = 1; i <= cntedges; i++)
669
{
670
int ii = sorted.Get(i);
671
for (j = 1; j <= eclasstab.EntrySize(ii); j++)
672
{
673
cnt++;
674
edgenumber.Set (edges.Get(eclasstab.Get(ii, j)), cnt);
675
}
676
}
677
return cnt;
678
}
679
680
else
681
682
{
683
// old version
684
685
int i, j;
686
int cnt = 0;
687
int found;
688
double len2, maxlen2;
689
INDEX_2 ep;
690
691
// sort edges by length, parallel edges (on prisms)
692
// are added in blocks
693
694
do
695
{
696
found = 0;
697
maxlen2 = 1e30;
698
699
for (i = 1; i <= mesh.GetNE(); i++)
700
{
701
const Element & el = mesh.VolumeElement (i);
702
int ned;
703
int tetedges[6][2] =
704
{ { 1, 2 },
705
{ 1, 3 },
706
{ 1, 4 },
707
{ 2, 3 },
708
{ 2, 4 },
709
{ 3, 4 } };
710
int prismedges[6][2] =
711
{ { 1, 2 },
712
{ 1, 3 },
713
{ 2, 4 },
714
{ 4, 5 },
715
{ 4, 6 },
716
{ 5, 6 } };
717
int pyramidedges[6][2] =
718
{ { 1, 2 },
719
{ 3, 4 },
720
{ 1, 5 },
721
{ 2, 5 },
722
{ 3, 5 },
723
{ 4, 5 } };
724
725
int (*tip)[2];
726
727
switch (el.GetType())
728
{
729
case TET:
730
{
731
tip = tetedges;
732
ned = 6;
733
break;
734
}
735
case PRISM:
736
{
737
tip = prismedges;
738
ned = 6;
739
break;
740
}
741
case PYRAMID:
742
{
743
tip = pyramidedges;
744
ned = 6;
745
break;
746
}
747
}
748
749
for (j = 0; j < ned; j++)
750
{
751
INDEX_2 i2(el.PNum(tip[j][0]), el.PNum(tip[j][1]));
752
i2.Sort();
753
if (!edgenumber.Used(i2))
754
{
755
len2 = Dist (mesh.Point (i2.I1()),
756
mesh.Point (i2.I2()));
757
if (len2 < maxlen2)
758
{
759
maxlen2 = len2;
760
ep = i2;
761
found = 1;
762
}
763
}
764
}
765
}
766
if (found)
767
{
768
cnt++;
769
edgenumber.Set (ep, cnt);
770
771
772
// find connected edges:
773
int go_on = 0;
774
do
775
{
776
go_on = 0;
777
for (i = 1; i <= mesh.GetNE(); i++)
778
{
779
const Element & el = mesh.VolumeElement (i);
780
if (el.GetNP() != 6) continue;
781
782
int prismpairs[3][4] =
783
{ { 1, 2, 4, 5 },
784
{ 2, 3, 5, 6 },
785
{ 1, 3, 4, 6 } };
786
787
int pyramidpairs[3][4] =
788
{ { 1, 2, 4, 3 },
789
{ 1, 5, 4, 5 },
790
{ 2, 5, 3, 5 } };
791
792
int (*pairs)[4];
793
switch (el.GetType())
794
{
795
case PRISM:
796
{
797
pairs = prismpairs;
798
break;
799
}
800
case PYRAMID:
801
{
802
pairs = pyramidpairs;
803
break;
804
}
805
}
806
807
for (j = 0; j < 3; j++)
808
{
809
INDEX_2 e1 (el.PNum(pairs[j][0]),
810
el.PNum(pairs[j][1]));
811
INDEX_2 e2 (el.PNum(pairs[j][2]),
812
el.PNum(pairs[j][3]));
813
e1.Sort();
814
e2.Sort();
815
816
int used1 = edgenumber.Used (e1);
817
int used2 = edgenumber.Used (e2);
818
819
if (used1 && !used2)
820
{
821
cnt++;
822
edgenumber.Set (e2, cnt);
823
go_on = 1;
824
}
825
if (used2 && !used1)
826
{
827
cnt++;
828
edgenumber.Set (e1, cnt);
829
go_on = 1;
830
}
831
}
832
}
833
}
834
while (go_on);
835
}
836
}
837
while (found);
838
839
return cnt;
840
}
841
}
842
843
844
845
846
void BTDefineMarkedTet (const Element & el,
847
INDEX_2_CLOSED_HASHTABLE<int> & edgenumber,
848
MarkedTet & mt)
849
{
850
int i, j, k;
851
for (i = 0; i < 4; i++)
852
mt.pnums[i] = el[i];
853
854
mt.marked = 0;
855
mt.flagged = 0;
856
857
mt.incorder = 0;
858
mt.order = 1;
859
860
int val = 0;
861
// find marked edge of tet:
862
for (i = 0; i < 3; i++)
863
for (j = i+1; j < 4; j++)
864
{
865
INDEX_2 i2(mt.pnums[i], mt.pnums[j]);
866
i2.Sort();
867
int hval = edgenumber.Get(i2);
868
if (hval > val)
869
{
870
val = hval;
871
mt.tetedge1 = i;
872
mt.tetedge2 = j;
873
}
874
}
875
876
877
// find marked edges of faces:
878
for (k = 0; k < 4; k++)
879
{
880
val = 0;
881
for (i = 0; i < 3; i++)
882
for (j = i+1; j < 4; j++)
883
if (i != k && j != k)
884
{
885
INDEX_2 i2(mt.pnums[i], mt.pnums[j]);
886
i2.Sort();
887
int hval = edgenumber.Get(i2);
888
if (hval > val)
889
{
890
val = hval;
891
int hi = 6 - k - i - j;
892
mt.faceedges[k] = char(hi);
893
}
894
}
895
}
896
}
897
898
899
900
901
void BTDefineMarkedPrism (const Element & el,
902
INDEX_2_CLOSED_HASHTABLE<int> & edgenumber,
903
MarkedPrism & mp)
904
{
905
int i, j;
906
907
if (el.GetType() == PRISM ||
908
el.GetType() == PRISM12)
909
{
910
for (i = 0; i < 6; i++)
911
mp.pnums[i] = el[i];
912
}
913
else if (el.GetType() == PYRAMID)
914
{
915
static int map[6] =
916
{ 1, 2, 5, 4, 3, 5 };
917
for (i = 0; i < 6; i++)
918
mp.pnums[i] = el.PNum(map[i]);
919
}
920
else if (el.GetType() == TET ||
921
el.GetType() == TET10)
922
{
923
static int map[6] =
924
{ 1, 4, 3, 2, 4, 3 };
925
for (i = 0; i < 6; i++)
926
mp.pnums[i] = el.PNum(map[i]);
927
928
}
929
else
930
{
931
PrintSysError ("Define marked prism called for non-prism and non-pyramid");
932
}
933
934
935
936
mp.marked = 0;
937
938
mp.incorder = 0;
939
mp.order = 1;
940
941
int val = 0;
942
for (i = 0; i < 2; i++)
943
for (j = i+1; j < 3; j++)
944
{
945
INDEX_2 i2(mp.pnums[i], mp.pnums[j]);
946
i2.Sort();
947
int hval = edgenumber.Get(i2);
948
if (hval > val)
949
{
950
val = hval;
951
mp.markededge = 3 - i - j;
952
}
953
}
954
}
955
956
957
958
bool BTDefineMarkedId(const Element2d & el,
959
INDEX_2_CLOSED_HASHTABLE<int> & edgenumber,
960
const ARRAY<int,PointIndex::BASE> & idmap,
961
MarkedIdentification & mi)
962
{
963
964
bool identified = true;
965
mi.np = el.GetNP();
966
int min1(0),min2(0);
967
for(int j = 0; identified && j < mi.np; j++)
968
{
969
mi.pnums[j] = el[j];
970
mi.pnums[j+mi.np] = idmap[el[j]];
971
972
if(j == 0 || el[j] < min1)
973
min1 = el[j];
974
if(j == 0 || mi.pnums[j+mi.np] < min2)
975
min2 = mi.pnums[j+mi.np];
976
977
identified = (mi.pnums[j+mi.np] != 0 && mi.pnums[j+mi.np] != mi.pnums[j]);
978
}
979
980
identified = identified && (min1 < min2);
981
982
if(identified)
983
{
984
mi.marked = 0;
985
986
mi.incorder = 0;
987
mi.order = 1;
988
989
int val = 0;
990
for (int i = 0; i < mi.np; i++)
991
{
992
INDEX_2 i2(mi.pnums[i], mi.pnums[(i+1)%mi.np]);
993
i2.Sort();
994
int hval = edgenumber.Get(i2);
995
if (hval > val)
996
{
997
val = hval;
998
mi.markededge = i;
999
}
1000
}
1001
}
1002
1003
return identified;
1004
}
1005
1006
1007
void BTDefineMarkedTri (const Element2d & el,
1008
INDEX_2_CLOSED_HASHTABLE<int> & edgenumber,
1009
MarkedTri & mt)
1010
{
1011
int i, j;
1012
for (i = 0; i < 3; i++)
1013
{
1014
mt.pnums[i] = el[i];
1015
mt.pgeominfo[i] = el.GeomInfoPi (i+1);
1016
}
1017
1018
mt.marked = 0;
1019
mt.surfid = el.GetIndex();
1020
1021
mt.incorder = 0;
1022
mt.order = 1;
1023
1024
int val = 0;
1025
for (i = 0; i < 2; i++)
1026
for (j = i+1; j < 3; j++)
1027
{
1028
INDEX_2 i2(mt.pnums[i], mt.pnums[j]);
1029
i2.Sort();
1030
int hval = edgenumber.Get(i2);
1031
if (hval > val)
1032
{
1033
val = hval;
1034
mt.markededge = 3 - i - j;
1035
}
1036
}
1037
}
1038
1039
1040
1041
void PrettyPrint(ostream & ost, const MarkedTri & mt)
1042
{
1043
ost << "MarkedTrig: " << endl;
1044
ost << " pnums = "; for (int i=0; i<3; i++) ost << mt.pnums[i] << " "; ost << endl;
1045
ost << " marked = " << mt.marked << ", markededge=" << mt.markededge << endl;
1046
for(int i=0; i<2; i++)
1047
for(int j=i+1; j<3; j++)
1048
if(mt.markededge == 3-i-j)
1049
ost << " marked edge pnums = " << mt.pnums[i] << " " << mt.pnums[j] << endl;
1050
}
1051
1052
1053
void PrettyPrint(ostream & ost, const MarkedQuad & mq)
1054
{
1055
ost << "MarkedQuad: " << endl;
1056
ost << " pnums = "; for (int i=0; i<4; i++) ost << mq.pnums[i] << " "; ost << endl;
1057
ost << " marked = " << mq.marked << ", markededge=" << mq.markededge << endl;
1058
}
1059
1060
1061
1062
1063
1064
void BTDefineMarkedQuad (const Element2d & el,
1065
INDEX_2_CLOSED_HASHTABLE<int> & edgenumber,
1066
MarkedQuad & mq)
1067
{
1068
int i;
1069
for (i = 0; i < 4; i++)
1070
mq.pnums[i] = el[i];
1071
Swap (mq.pnums[2], mq.pnums[3]);
1072
1073
mq.marked = 0;
1074
mq.markededge = 0;
1075
mq.surfid = el.GetIndex();
1076
}
1077
1078
1079
1080
1081
// mark elements due to local h
1082
int BTMarkTets (T_MTETS & mtets,
1083
T_MPRISMS & mprisms,
1084
const Mesh & mesh)
1085
{
1086
int i, j, k;
1087
int step;
1088
1089
int marked = 0;
1090
1091
int np = mesh.GetNP();
1092
Vector hv(np);
1093
for (i = 1; i <= np; i++)
1094
hv.Elem(i) = mesh.GetH (mesh.Point(i));
1095
1096
double hfac = 1;
1097
1098
for (step = 1; step <= 2; step++)
1099
{
1100
for (i = 1; i <= mtets.Size(); i++)
1101
{
1102
double h = 0;
1103
1104
for (j = 0; j < 3; j++)
1105
for (k = j+1; k < 4; k++)
1106
{
1107
const Point<3> & p1 = mesh.Point (mtets.Get(i).pnums[j]);
1108
const Point<3> & p2 = mesh.Point (mtets.Get(i).pnums[k]);
1109
double hh = Dist2 (p1, p2);
1110
if (hh > h) h = hh;
1111
}
1112
h = sqrt (h);
1113
1114
double hshould = 1e10;
1115
for (j = 0; j < 4; j++)
1116
{
1117
double hi = hv.Get (mtets.Get(i).pnums[j]);
1118
if (hi < hshould)
1119
hshould = hi;
1120
}
1121
1122
1123
if (step == 1)
1124
{
1125
if (h / hshould > hfac)
1126
hfac = h / hshould;
1127
}
1128
else
1129
{
1130
if (h > hshould * hfac)
1131
{
1132
mtets.Elem(i).marked = 1;
1133
marked = 1;
1134
}
1135
else
1136
mtets.Elem(i).marked = 0;
1137
}
1138
1139
}
1140
for (i = 1; i <= mprisms.Size(); i++)
1141
{
1142
double h = 0;
1143
1144
for (j = 0; j < 2; j++)
1145
for (k = j+1; k < 3; k++)
1146
{
1147
const Point<3> & p1 = mesh.Point (mprisms.Get(i).pnums[j]);
1148
const Point<3> & p2 = mesh.Point (mprisms.Get(i).pnums[k]);
1149
double hh = Dist2 (p1, p2);
1150
if (hh > h) h = hh;
1151
}
1152
h = sqrt (h);
1153
1154
double hshould = 1e10;
1155
for (j = 0; j < 6; j++)
1156
{
1157
double hi = hv.Get (mprisms.Get(i).pnums[j]);
1158
if (hi < hshould)
1159
hshould = hi;
1160
}
1161
1162
1163
if (step == 1)
1164
{
1165
if (h / hshould > hfac)
1166
hfac = h / hshould;
1167
}
1168
else
1169
{
1170
if (h > hshould * hfac)
1171
{
1172
mprisms.Elem(i).marked = 1;
1173
marked = 1;
1174
}
1175
else
1176
mprisms.Elem(i).marked = 0;
1177
}
1178
1179
}
1180
1181
1182
1183
if (step == 1)
1184
{
1185
if (hfac > 2)
1186
hfac /= 2;
1187
else
1188
hfac = 1;
1189
}
1190
1191
}
1192
return marked;
1193
}
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
void BTBisectTet (const MarkedTet & oldtet, int newp,
1209
MarkedTet & newtet1, MarkedTet & newtet2)
1210
{
1211
#ifdef DEBUG
1212
*testout << "bisect tet " << oldtet << endl;
1213
#endif
1214
1215
int i, j, k;
1216
1217
1218
// points vis a vis from tet-edge
1219
int vis1, vis2;
1220
vis1 = 0;
1221
while (vis1 == oldtet.tetedge1 || vis1 == oldtet.tetedge2)
1222
vis1++;
1223
vis2 = 6 - vis1 - oldtet.tetedge1 - oldtet.tetedge2;
1224
1225
1226
1227
1228
1229
// is tet of type P ?
1230
int istypep = 0;
1231
for (i = 0; i < 4; i++)
1232
{
1233
int cnt = 0;
1234
for (j = 0; j < 4; j++)
1235
if (oldtet.faceedges[j] == i)
1236
cnt++;
1237
if (cnt == 3)
1238
istypep = 1;
1239
}
1240
1241
1242
1243
for (i = 0; i < 4; i++)
1244
{
1245
newtet1.pnums[i] = oldtet.pnums[i];
1246
newtet2.pnums[i] = oldtet.pnums[i];
1247
}
1248
newtet1.flagged = istypep && !oldtet.flagged;
1249
newtet2.flagged = istypep && !oldtet.flagged;
1250
1251
int nm = oldtet.marked - 1;
1252
if (nm < 0) nm = 0;
1253
newtet1.marked = nm;
1254
newtet2.marked = nm;
1255
1256
#ifdef DEBUG
1257
*testout << "newtet1,before = " << newtet1 << endl;
1258
*testout << "newtet2,before = " << newtet2 << endl;
1259
#endif
1260
1261
for (i = 0; i < 4; i++)
1262
{
1263
if (i == oldtet.tetedge1)
1264
{
1265
newtet2.pnums[i] = newp;
1266
newtet2.faceedges[i] = oldtet.faceedges[i]; // inherited face
1267
newtet2.faceedges[vis1] = i; // cut faces
1268
newtet2.faceedges[vis2] = i;
1269
1270
j = 0;
1271
while (j == i || j == oldtet.faceedges[i])
1272
j++;
1273
k = 6 - i - oldtet.faceedges[i] - j;
1274
newtet2.tetedge1 = j; // tet-edge
1275
newtet2.tetedge2 = k;
1276
1277
// new face:
1278
if (istypep && oldtet.flagged)
1279
{
1280
int hi = 6 - oldtet.tetedge1 - j - k;
1281
newtet2.faceedges[oldtet.tetedge2] = char(hi);
1282
}
1283
else
1284
newtet2.faceedges[oldtet.tetedge2] = oldtet.tetedge1;
1285
1286
1287
*testout << "i = " << i << ", j = " << j << " k = " << k
1288
<< " oldtet.tetedge1 = " << oldtet.tetedge1
1289
<< " oldtet.tetedge2 = " << oldtet.tetedge2
1290
<< " 6-oldtet.tetedge1-j-k = " << 6 - oldtet.tetedge1 - j - k
1291
<< " 6-oldtet.tetedge1-j-k = " << short(6 - oldtet.tetedge1 - j - k)
1292
<< endl;
1293
*testout << "vis1 = " << vis1 << ", vis2 = " << vis2 << endl;
1294
for (int j = 0; j < 4; j++)
1295
if (newtet2.faceedges[j] > 3)
1296
{
1297
*testout << "ERROR1" << endl;
1298
}
1299
}
1300
1301
if (i == oldtet.tetedge2)
1302
{
1303
newtet1.pnums[i] = newp;
1304
newtet1.faceedges[i] = oldtet.faceedges[i]; // inherited face
1305
newtet1.faceedges[vis1] = i;
1306
newtet1.faceedges[vis2] = i;
1307
j = 0;
1308
while (j == i || j == oldtet.faceedges[i])
1309
j++;
1310
k = 6 - i - oldtet.faceedges[i] - j;
1311
newtet1.tetedge1 = j;
1312
newtet1.tetedge2 = k;
1313
1314
// new face:
1315
if (istypep && oldtet.flagged)
1316
{
1317
int hi = 6 - oldtet.tetedge2 - j - k;
1318
newtet1.faceedges[oldtet.tetedge1] = char(hi);
1319
}
1320
else
1321
newtet1.faceedges[oldtet.tetedge1] = oldtet.tetedge2;
1322
1323
for (int j = 0; j < 4; j++)
1324
if (newtet2.faceedges[j] > 3)
1325
{
1326
*testout << "ERROR2" << endl;
1327
}
1328
1329
}
1330
}
1331
1332
newtet1.matindex = oldtet.matindex;
1333
newtet2.matindex = oldtet.matindex;
1334
newtet1.incorder = 0;
1335
newtet1.order = oldtet.order;
1336
newtet2.incorder = 0;
1337
newtet2.order = oldtet.order;
1338
1339
*testout << "newtet1 = " << newtet1 << endl;
1340
*testout << "newtet2 = " << newtet2 << endl;
1341
}
1342
1343
1344
1345
1346
void BTBisectPrism (const MarkedPrism & oldprism, int newp1, int newp2,
1347
MarkedPrism & newprism1, MarkedPrism & newprism2)
1348
{
1349
int i;
1350
1351
for (i = 0; i < 6; i++)
1352
{
1353
newprism1.pnums[i] = oldprism.pnums[i];
1354
newprism2.pnums[i] = oldprism.pnums[i];
1355
}
1356
1357
int pe1, pe2;
1358
pe1 = 0;
1359
if (pe1 == oldprism.markededge)
1360
pe1++;
1361
pe2 = 3 - oldprism.markededge - pe1;
1362
1363
newprism1.pnums[pe2] = newp1;
1364
newprism1.pnums[pe2+3] = newp2;
1365
newprism1.markededge = pe2;
1366
newprism2.pnums[pe1] = newp1;
1367
newprism2.pnums[pe1+3] = newp2;
1368
newprism2.markededge = pe1;
1369
1370
newprism1.matindex = oldprism.matindex;
1371
newprism2.matindex = oldprism.matindex;
1372
1373
int nm = oldprism.marked - 1;
1374
if (nm < 0) nm = 0;
1375
newprism1.marked = nm;
1376
newprism2.marked = nm;
1377
1378
newprism1.incorder = 0;
1379
newprism1.order = oldprism.order;
1380
newprism2.incorder = 0;
1381
newprism2.order = oldprism.order;
1382
}
1383
1384
1385
void BTBisectIdentification (const MarkedIdentification & oldid,
1386
ARRAY<int> & newp,
1387
MarkedIdentification & newid1,
1388
MarkedIdentification & newid2)
1389
{
1390
for(int i=0; i<2*oldid.np; i++)
1391
{
1392
newid1.pnums[i] = oldid.pnums[i];
1393
newid2.pnums[i] = oldid.pnums[i];
1394
}
1395
newid1.np = newid2.np = oldid.np;
1396
1397
if(oldid.np == 3)
1398
{
1399
newid1.pnums[(oldid.markededge+1)%3] = newp[0];
1400
newid1.pnums[(oldid.markededge+1)%3+3] = newp[1];
1401
newid1.markededge = (oldid.markededge+2)%3;
1402
1403
newid2.pnums[oldid.markededge] = newp[0];
1404
newid2.pnums[oldid.markededge+3] = newp[1];
1405
newid2.markededge = (oldid.markededge+1)%3;
1406
}
1407
else if(oldid.np == 4)
1408
{
1409
newid1.pnums[(oldid.markededge+1)%4] = newp[0];
1410
newid1.pnums[(oldid.markededge+2)%4] = newp[2];
1411
newid1.pnums[(oldid.markededge+1)%4+4] = newp[1];
1412
newid1.pnums[(oldid.markededge+2)%4+4] = newp[3];
1413
newid1.markededge = (oldid.markededge+3)%4;
1414
1415
newid2.pnums[oldid.markededge] = newp[0];
1416
newid2.pnums[(oldid.markededge+3)%4] = newp[2];
1417
newid2.pnums[oldid.markededge+4] = newp[1];
1418
newid2.pnums[(oldid.markededge+3)%4+4] = newp[3];
1419
newid2.markededge = (oldid.markededge+1)%4;
1420
}
1421
1422
1423
int nm = oldid.marked - 1;
1424
if (nm < 0) nm = 0;
1425
newid1.marked = newid2.marked = nm;
1426
1427
newid1.incorder = newid2.incorder = 0;
1428
newid1.order = newid2.order = oldid.order;
1429
}
1430
1431
1432
1433
void BTBisectTri (const MarkedTri & oldtri, int newp, const PointGeomInfo & newpgi,
1434
MarkedTri & newtri1, MarkedTri & newtri2)
1435
{
1436
int i;
1437
1438
for (i = 0; i < 3; i++)
1439
{
1440
newtri1.pnums[i] = oldtri.pnums[i];
1441
newtri1.pgeominfo[i] = oldtri.pgeominfo[i];
1442
newtri2.pnums[i] = oldtri.pnums[i];
1443
newtri2.pgeominfo[i] = oldtri.pgeominfo[i];
1444
}
1445
1446
int pe1, pe2;
1447
pe1 = 0;
1448
if (pe1 == oldtri.markededge)
1449
pe1++;
1450
pe2 = 3 - oldtri.markededge - pe1;
1451
1452
newtri1.pnums[pe2] = newp;
1453
newtri1.pgeominfo[pe2] = newpgi;
1454
newtri1.markededge = pe2;
1455
1456
newtri2.pnums[pe1] = newp;
1457
newtri2.pgeominfo[pe1] = newpgi;
1458
newtri2.markededge = pe1;
1459
1460
1461
newtri1.surfid = oldtri.surfid;
1462
newtri2.surfid = oldtri.surfid;
1463
1464
int nm = oldtri.marked - 1;
1465
if (nm < 0) nm = 0;
1466
newtri1.marked = nm;
1467
newtri2.marked = nm;
1468
1469
newtri1.incorder = 0;
1470
newtri1.order = oldtri.order;
1471
newtri2.incorder = 0;
1472
newtri2.order = oldtri.order;
1473
1474
1475
}
1476
1477
1478
void BTBisectQuad (const MarkedQuad & oldquad,
1479
int newp1, const PointGeomInfo & npgi1,
1480
int newp2, const PointGeomInfo & npgi2,
1481
MarkedQuad & newquad1, MarkedQuad & newquad2)
1482
{
1483
int i;
1484
1485
for (i = 0; i < 4; i++)
1486
{
1487
newquad1.pnums[i] = oldquad.pnums[i];
1488
newquad1.pgeominfo[i] = oldquad.pgeominfo[i];
1489
newquad2.pnums[i] = oldquad.pnums[i];
1490
newquad2.pgeominfo[i] = oldquad.pgeominfo[i];
1491
}
1492
1493
/* if (oldquad.marked==1) // he/sz: 2d quads or 3d prism
1494
{
1495
newquad1.pnums[1] = newp1;
1496
newquad1.pgeominfo[1] = npgi1;
1497
newquad1.pnums[3] = newp2;
1498
newquad1.pgeominfo[3] = npgi2;
1499
1500
newquad2.pnums[0] = newp1;
1501
newquad2.pgeominfo[0] = npgi1;
1502
newquad2.pnums[2] = newp2;
1503
newquad2.pgeominfo[2] = npgi2;
1504
}
1505
1506
else if (oldquad.marked==2) // he/sz: 2d quads only
1507
{
1508
newquad1.pnums[0] = newp1;
1509
newquad1.pnums[1] = newp2;
1510
newquad1.pnums[3] = oldquad.pnums[2];
1511
newquad1.pnums[2] = oldquad.pnums[0];
1512
newquad1.pgeominfo[0] = npgi1;
1513
newquad1.pgeominfo[1] = npgi2;
1514
newquad1.pgeominfo[3] = oldquad.pgeominfo[2];
1515
newquad1.pgeominfo[2] = oldquad.pgeominfo[0];
1516
1517
newquad2.pnums[0] = newp2;
1518
newquad2.pnums[1] = newp1;
1519
newquad2.pnums[3] = oldquad.pnums[1];
1520
newquad2.pnums[2] = oldquad.pnums[3];
1521
newquad2.pgeominfo[0] = npgi2;
1522
newquad2.pgeominfo[1] = npgi1;
1523
newquad2.pgeominfo[3] = oldquad.pgeominfo[1];
1524
newquad2.pgeominfo[2] = oldquad.pgeominfo[3];
1525
}
1526
1527
*/
1528
1529
if (oldquad.markededge==0 || oldquad.markededge==2)
1530
{
1531
newquad1.pnums[1] = newp1;
1532
newquad1.pgeominfo[1] = npgi1;
1533
newquad1.pnums[3] = newp2;
1534
newquad1.pgeominfo[3] = npgi2;
1535
1536
newquad2.pnums[0] = newp1;
1537
newquad2.pgeominfo[0] = npgi1;
1538
newquad2.pnums[2] = newp2;
1539
newquad2.pgeominfo[2] = npgi2;
1540
}
1541
else // 1 || 3
1542
{
1543
newquad1.pnums[2] = newp1;
1544
newquad1.pgeominfo[2] = npgi1;
1545
newquad1.pnums[3] = newp2;
1546
newquad1.pgeominfo[3] = npgi2;
1547
1548
newquad2.pnums[0] = newp1;
1549
newquad2.pgeominfo[0] = npgi1;
1550
newquad2.pnums[1] = newp2;
1551
newquad2.pgeominfo[1] = npgi2;
1552
}
1553
newquad1.surfid = oldquad.surfid;
1554
newquad2.surfid = oldquad.surfid;
1555
1556
int nm = oldquad.marked - 1;
1557
if (nm < 0) nm = 0;
1558
1559
newquad1.marked = nm;
1560
newquad2.marked = nm;
1561
1562
if (nm==1)
1563
{
1564
newquad1.markededge=1;
1565
newquad2.markededge=1;
1566
}
1567
else
1568
{
1569
newquad1.markededge=0;
1570
newquad2.markededge=0;
1571
}
1572
1573
}
1574
1575
1576
int MarkHangingIdentifications(T_MIDS & mids,
1577
const INDEX_2_CLOSED_HASHTABLE<int> & cutedges)
1578
{
1579
int i, j;
1580
1581
int hanging = 0;
1582
for (i = 1; i <= mids.Size(); i++)
1583
{
1584
if (mids.Elem(i).marked)
1585
{
1586
hanging = 1;
1587
continue;
1588
}
1589
1590
const int np = mids.Get(i).np;
1591
1592
for(j = 0; j < np; j++)
1593
{
1594
INDEX_2 edge1(mids.Get(i).pnums[j],
1595
mids.Get(i).pnums[(j+1) % np]);
1596
INDEX_2 edge2(mids.Get(i).pnums[j+np],
1597
mids.Get(i).pnums[((j+1) % np) + np]);
1598
1599
edge1.Sort();
1600
edge2.Sort();
1601
if (cutedges.Used (edge1) ||
1602
cutedges.Used (edge2))
1603
{
1604
mids.Elem(i).marked = 1;
1605
hanging = 1;
1606
}
1607
}
1608
}
1609
1610
return hanging;
1611
}
1612
1613
1614
/*
1615
void IdentifyCutEdges(Mesh & mesh,
1616
INDEX_2_CLOSED_HASHTABLE<int> & cutedges)
1617
{
1618
int i,j,k;
1619
1620
ARRAY< ARRAY<int,PointIndex::BASE>* > idmaps;
1621
for(i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++)
1622
{
1623
idmaps.Append(new ARRAY<int,PointIndex::BASE>);
1624
mesh.GetIdentifications().GetMap(i,*idmaps.Last());
1625
}
1626
1627
1628
1629
for(SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++)
1630
{
1631
const Element2d & el2d = mesh[sei];
1632
1633
for(i = 0; i < el2d.GetNP(); i++)
1634
{
1635
INDEX_2 e1(el2d[i], el2d[(i+1) % el2d.GetNP()]);
1636
e1.Sort();
1637
1638
if(!cutedges.Used(e1))
1639
continue;
1640
1641
1642
for(k = 0; k < idmaps.Size(); k++)
1643
{
1644
INDEX_2 e2((*idmaps[k])[e1.I1()],
1645
(*idmaps[k])[e1.I2()]);
1646
1647
if(e2.I1() == 0 || e2.I2() == 0 ||
1648
e1.I1() == e2.I1() || e1.I2() == e2.I2())
1649
continue;
1650
1651
e2.Sort();
1652
1653
if(cutedges.Used(e2))
1654
continue;
1655
1656
Point3d np = Center(mesh.Point(e2.I1()),
1657
mesh.Point(e2.I2()));
1658
int newp = mesh.AddPoint(np);
1659
cutedges.Set(e2,newp);
1660
(*testout) << "DAAA" << endl;
1661
}
1662
}
1663
}
1664
1665
1666
for(i=0; i<idmaps.Size(); i++)
1667
delete idmaps[i];
1668
idmaps.DeleteAll();
1669
}
1670
*/
1671
1672
1673
int MarkHangingTets (T_MTETS & mtets,
1674
const INDEX_2_CLOSED_HASHTABLE<int> & cutedges)
1675
{
1676
int i, j, k;
1677
1678
int hanging = 0;
1679
for (i = 1; i <= mtets.Size(); i++)
1680
{
1681
MarkedTet & teti = mtets.Elem(i);
1682
1683
if (teti.marked)
1684
{
1685
hanging = 1;
1686
continue;
1687
}
1688
1689
for (j = 0; j < 3; j++)
1690
for (k = j+1; k < 4; k++)
1691
{
1692
INDEX_2 edge(teti.pnums[j],
1693
teti.pnums[k]);
1694
edge.Sort();
1695
if (cutedges.Used (edge))
1696
{
1697
teti.marked = 1;
1698
hanging = 1;
1699
}
1700
}
1701
}
1702
1703
return hanging;
1704
}
1705
1706
1707
1708
int MarkHangingPrisms (T_MPRISMS & mprisms,
1709
const INDEX_2_CLOSED_HASHTABLE<int> & cutedges)
1710
{
1711
int i, j, k;
1712
1713
int hanging = 0;
1714
for (i = 1; i <= mprisms.Size(); i++)
1715
{
1716
if (mprisms.Elem(i).marked)
1717
{
1718
hanging = 1;
1719
continue;
1720
}
1721
1722
for (j = 0; j < 2; j++)
1723
for (k = j+1; k < 3; k++)
1724
{
1725
INDEX_2 edge1(mprisms.Get(i).pnums[j],
1726
mprisms.Get(i).pnums[k]);
1727
INDEX_2 edge2(mprisms.Get(i).pnums[j+3],
1728
mprisms.Get(i).pnums[k+3]);
1729
edge1.Sort();
1730
edge2.Sort();
1731
if (cutedges.Used (edge1) ||
1732
cutedges.Used (edge2))
1733
{
1734
mprisms.Elem(i).marked = 1;
1735
hanging = 1;
1736
}
1737
}
1738
}
1739
return hanging;
1740
}
1741
1742
1743
1744
int MarkHangingTris (T_MTRIS & mtris,
1745
const INDEX_2_CLOSED_HASHTABLE<int> & cutedges)
1746
{
1747
int i, j, k;
1748
1749
int hanging = 0;
1750
for (i = 1; i <= mtris.Size(); i++)
1751
{
1752
if (mtris.Get(i).marked)
1753
{
1754
hanging = 1;
1755
continue;
1756
}
1757
for (j = 0; j < 2; j++)
1758
for (k = j+1; k < 3; k++)
1759
{
1760
INDEX_2 edge(mtris.Get(i).pnums[j],
1761
mtris.Get(i).pnums[k]);
1762
edge.Sort();
1763
if (cutedges.Used (edge))
1764
{
1765
mtris.Elem(i).marked = 1;
1766
hanging = 1;
1767
}
1768
}
1769
}
1770
return hanging;
1771
}
1772
1773
1774
1775
int MarkHangingQuads (T_MQUADS & mquads,
1776
const INDEX_2_CLOSED_HASHTABLE<int> & cutedges)
1777
{
1778
int i;
1779
1780
int hanging = 0;
1781
for (i = 1; i <= mquads.Size(); i++)
1782
{
1783
if (mquads.Elem(i).marked)
1784
{
1785
hanging = 1;
1786
continue;
1787
}
1788
1789
INDEX_2 edge1(mquads.Get(i).pnums[0],
1790
mquads.Get(i).pnums[1]);
1791
INDEX_2 edge2(mquads.Get(i).pnums[2],
1792
mquads.Get(i).pnums[3]);
1793
edge1.Sort();
1794
edge2.Sort();
1795
if (cutedges.Used (edge1) ||
1796
cutedges.Used (edge2))
1797
{
1798
mquads.Elem(i).marked = 1;
1799
mquads.Elem(i).markededge = 0;
1800
hanging = 1;
1801
continue;
1802
}
1803
1804
// he/sz: second case: split horizontally
1805
INDEX_2 edge3(mquads.Get(i).pnums[1],
1806
mquads.Get(i).pnums[3]);
1807
INDEX_2 edge4(mquads.Get(i).pnums[2],
1808
mquads.Get(i).pnums[0]);
1809
1810
edge3.Sort();
1811
edge4.Sort();
1812
if (cutedges.Used (edge3) ||
1813
cutedges.Used (edge4))
1814
{
1815
mquads.Elem(i).marked = 1;
1816
mquads.Elem(i).markededge = 1;
1817
hanging = 1;
1818
continue;
1819
}
1820
1821
}
1822
return hanging;
1823
}
1824
1825
1826
1827
void ConnectToNodeRec (int node, int tonode,
1828
const TABLE<int> & conto, ARRAY<int> & connecttonode)
1829
{
1830
int i, n2;
1831
// (*testout) << "connect " << node << " to " << tonode << endl;
1832
for (i = 1; i <= conto.EntrySize(node); i++)
1833
{
1834
n2 = conto.Get(node, i);
1835
if (!connecttonode.Get(n2))
1836
{
1837
connecttonode.Elem(n2) = tonode;
1838
ConnectToNodeRec (n2, tonode, conto, connecttonode);
1839
}
1840
}
1841
}
1842
1843
1844
1845
1846
T_MTETS mtets;
1847
T_MPRISMS mprisms;
1848
T_MIDS mids;
1849
T_MTRIS mtris;
1850
T_MQUADS mquads;
1851
1852
1853
void WriteMarkedElements(ostream & ost)
1854
{
1855
ost << "Marked Elements\n";
1856
1857
ost << mtets.Size() << "\n";
1858
for(int i=0; i<mtets.Size(); i++)
1859
ost << mtets[i];
1860
1861
ost << mprisms.Size() << "\n";
1862
for(int i=0; i<mprisms.Size(); i++)
1863
ost << mprisms[i];
1864
1865
ost << mids.Size() << "\n";
1866
for(int i=0; i<mids.Size(); i++)
1867
ost << mids[i];
1868
1869
ost << mtris.Size() << "\n";
1870
for(int i=0; i<mtris.Size(); i++)
1871
ost << mtris[i];
1872
1873
ost << mquads.Size() << "\n";
1874
for(int i=0; i<mquads.Size(); i++)
1875
ost << mquads[i];
1876
ost << endl;
1877
}
1878
1879
bool ReadMarkedElements(istream & ist, const Mesh & mesh)
1880
{
1881
string auxstring("");
1882
if(ist)
1883
ist >> auxstring;
1884
1885
if(auxstring != "Marked")
1886
return false;
1887
1888
if(ist)
1889
ist >> auxstring;
1890
1891
if(auxstring != "Elements")
1892
return false;
1893
1894
int size;
1895
1896
ist >> size;
1897
mtets.SetSize(size);
1898
for(int i=0; i<size; i++)
1899
{
1900
ist >> mtets[i];
1901
if(mtets[i].pnums[0] > mesh.GetNV() ||
1902
mtets[i].pnums[1] > mesh.GetNV() ||
1903
mtets[i].pnums[2] > mesh.GetNV() ||
1904
mtets[i].pnums[3] > mesh.GetNV())
1905
return false;
1906
}
1907
1908
ist >> size;
1909
mprisms.SetSize(size);
1910
for(int i=0; i<size; i++)
1911
ist >> mprisms[i];
1912
1913
ist >> size;
1914
mids.SetSize(size);
1915
for(int i=0; i<size; i++)
1916
ist >> mids[i];
1917
1918
ist >> size;
1919
mtris.SetSize(size);
1920
for(int i=0; i<size; i++)
1921
ist >> mtris[i];
1922
1923
ist >> size;
1924
mquads.SetSize(size);
1925
for(int i=0; i<size; i++)
1926
ist >> mquads[i];
1927
1928
return true;
1929
}
1930
1931
1932
1933
1934
1935
void BisectTetsCopyMesh (Mesh & mesh, const class CSGeometry *,
1936
BisectionOptions & opt,
1937
const ARRAY< ARRAY<int,PointIndex::BASE>* > & idmaps,
1938
const string & refinfofile)
1939
{
1940
mtets.SetName ("bisection, tets");
1941
mprisms.SetName ("bisection, prisms");
1942
mtris.SetName ("bisection, trigs");
1943
mquads.SetName ("bisection, quads");
1944
mids.SetName ("bisection, identifications");
1945
1946
//int np = mesh.GetNP();
1947
int ne = mesh.GetNE();
1948
int nse = mesh.GetNSE();
1949
int i, j, k, l, m;
1950
1951
/*
1952
if (mtets.Size() + mprisms.Size() == mesh.GetNE())
1953
return;
1954
*/
1955
1956
bool readok = false;
1957
1958
if(refinfofile != "")
1959
{
1960
PrintMessage(3,"Reading marked-element information from \"",refinfofile,"\"");
1961
ifstream ist(refinfofile.c_str());
1962
1963
readok = ReadMarkedElements(ist,mesh);
1964
1965
ist.close();
1966
}
1967
1968
if(!readok)
1969
{
1970
PrintMessage(3,"resetting marked-element information");
1971
mtets.SetSize(0);
1972
mprisms.SetSize(0);
1973
mids.SetSize(0);
1974
mtris.SetSize(0);
1975
mquads.SetSize(0);
1976
1977
1978
INDEX_2_HASHTABLE<int> shortedges(100);
1979
for (i = 1; i <= ne; i++)
1980
{
1981
const Element & el = mesh.VolumeElement(i);
1982
if (el.GetType() == PRISM ||
1983
el.GetType() == PRISM12)
1984
{
1985
for (j = 1; j <= 3; j++)
1986
{
1987
INDEX_2 se(el.PNum(j), el.PNum(j+3));
1988
se.Sort();
1989
shortedges.Set (se, 1);
1990
}
1991
}
1992
}
1993
1994
1995
1996
// INDEX_2_HASHTABLE<int> edgenumber(np);
1997
INDEX_2_CLOSED_HASHTABLE<int> edgenumber(9*ne+4*nse);
1998
1999
BTSortEdges (mesh, idmaps, edgenumber);
2000
2001
2002
for (i = 1; i <= ne; i++)
2003
{
2004
const Element & el = mesh.VolumeElement(i);
2005
2006
switch (el.GetType())
2007
{
2008
case TET:
2009
case TET10:
2010
{
2011
// if tet has short edge, it is handled as degenerated prism
2012
2013
int foundse = 0;
2014
for (j = 1; j <= 3; j++)
2015
for (k = j+1; k <= 4; k++)
2016
{
2017
INDEX_2 se(el.PNum(j), el.PNum(k));
2018
se.Sort();
2019
if (shortedges.Used (se))
2020
{
2021
// cout << "tet converted to prism" << endl;
2022
2023
foundse = 1;
2024
int p3 = 1;
2025
while (p3 == j || p3 == k)
2026
p3++;
2027
int p4 = 10 - j - k - p3;
2028
2029
// even permutation ?
2030
int pi[4];
2031
pi[0] = j;
2032
pi[1] = k;
2033
pi[2] = p3;
2034
pi[3] = p4;
2035
int cnt = 0;
2036
for (l = 1; l <= 4; l++)
2037
for (m = 0; m < 3; m++)
2038
if (pi[m] > pi[m+1])
2039
{
2040
Swap (pi[m], pi[m+1]);
2041
cnt++;
2042
}
2043
if (cnt % 2)
2044
Swap (p3, p4);
2045
2046
Element hel = el;
2047
hel.PNum(1) = el.PNum(j);
2048
hel.PNum(2) = el.PNum(k);
2049
hel.PNum(3) = el.PNum(p3);
2050
hel.PNum(4) = el.PNum(p4);
2051
2052
MarkedPrism mp;
2053
BTDefineMarkedPrism (hel, edgenumber, mp);
2054
mp.matindex = el.GetIndex();
2055
mprisms.Append (mp);
2056
}
2057
}
2058
if (!foundse)
2059
{
2060
MarkedTet mt;
2061
BTDefineMarkedTet (el, edgenumber, mt);
2062
mt.matindex = el.GetIndex();
2063
mtets.Append (mt);
2064
}
2065
break;
2066
}
2067
case PYRAMID:
2068
{
2069
// eventually rotate
2070
MarkedPrism mp;
2071
2072
INDEX_2 se(el.PNum(1), el.PNum(2));
2073
se.Sort();
2074
if (shortedges.Used (se))
2075
{
2076
Element hel = el;
2077
hel.PNum(1) = el.PNum(2);
2078
hel.PNum(2) = el.PNum(3);
2079
hel.PNum(3) = el.PNum(4);
2080
hel.PNum(4) = el.PNum(1);
2081
BTDefineMarkedPrism (hel, edgenumber, mp);
2082
}
2083
else
2084
{
2085
BTDefineMarkedPrism (el, edgenumber, mp);
2086
}
2087
2088
mp.matindex = el.GetIndex();
2089
mprisms.Append (mp);
2090
break;
2091
}
2092
case PRISM:
2093
case PRISM12:
2094
{
2095
MarkedPrism mp;
2096
BTDefineMarkedPrism (el, edgenumber, mp);
2097
mp.matindex = el.GetIndex();
2098
mprisms.Append (mp);
2099
break;
2100
}
2101
}
2102
}
2103
2104
for (i = 1; i <= nse; i++)
2105
{
2106
const Element2d & el = mesh.SurfaceElement(i);
2107
if (el.GetType() == TRIG ||
2108
el.GetType() == TRIG6)
2109
{
2110
MarkedTri mt;
2111
BTDefineMarkedTri (el, edgenumber, mt);
2112
mtris.Append (mt);
2113
}
2114
else
2115
{
2116
MarkedQuad mq;
2117
BTDefineMarkedQuad (el, edgenumber, mq);
2118
mquads.Append (mq);
2119
}
2120
2121
MarkedIdentification mi;
2122
for(j=0; j<idmaps.Size(); j++)
2123
if(BTDefineMarkedId(el, edgenumber, *idmaps[j], mi))
2124
mids.Append(mi);
2125
}
2126
}
2127
2128
2129
2130
2131
mesh.mlparentelement.SetSize(ne);
2132
for (i = 1; i <= ne; i++)
2133
mesh.mlparentelement.Elem(i) = 0;
2134
mesh.mlparentsurfaceelement.SetSize(nse);
2135
for (i = 1; i <= nse; i++)
2136
mesh.mlparentsurfaceelement.Elem(i) = 0;
2137
2138
if (printmessage_importance>0)
2139
{
2140
ostringstream str1,str2;
2141
str1 << "copied " << mtets.Size() << " tets, " << mprisms.Size() << " prisms";
2142
str2 << " " << mtris.Size() << " trigs, " << mquads.Size() << " quads";
2143
2144
PrintMessage(4,str1.str());
2145
PrintMessage(4,str2.str());
2146
}
2147
}
2148
2149
2150
/*
2151
void UpdateEdgeMarks2(Mesh & mesh,
2152
const ARRAY< ARRAY<int,PointIndex::BASE>* > & idmaps)
2153
{
2154
ARRAY< ARRAY<MarkedTet>*,PointIndex::BASE > mtets_old(mesh.GetNP());
2155
ARRAY< ARRAY<MarkedPrism>*,PointIndex::BASE > mprisms_old(mesh.GetNP());
2156
ARRAY< ARRAY<MarkedIdentification>*,PointIndex::BASE > mids_old(mesh.GetNP());
2157
ARRAY< ARRAY<MarkedTri>*,PointIndex::BASE > mtris_old(mesh.GetNP());
2158
ARRAY< ARRAY<MarkedQuad>*,PointIndex::BASE > mquads_old(mesh.GetNP());
2159
2160
for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
2161
mtets_old[i] = new ARRAY<MarkedTet>;
2162
for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
2163
mprisms_old[i] = new ARRAY<MarkedPrism>;
2164
for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
2165
mids_old[i] = new ARRAY<MarkedIdentification>;
2166
for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
2167
mtris_old[i] = new ARRAY<MarkedTri>;
2168
for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
2169
mquads_old[i] = new ARRAY<MarkedQuad>;
2170
2171
for(int i=0; i<mtets.Size(); i++)
2172
mtets_old[mtets[i].pnums[0]]->Append(mtets[i]);
2173
for(int i=0; i<mprisms.Size(); i++)
2174
mprisms_old[mprisms[i].pnums[0]]->Append(mprisms[i]);
2175
for(int i=0; i<mids.Size(); i++)
2176
mids_old[mids[i].pnums[0]]->Append(mids[i]);
2177
for(int i=0; i<mtris.Size(); i++)
2178
{
2179
(*testout) << "i " << i << endl;
2180
(*testout) << "mtris[i] " << mtris[i].pnums[0] << " " << mtris[i].pnums[1] << " " << mtris[i].pnums[2] << endl;
2181
mtris_old[mtris[i].pnums[0]]->Append(mtris[i]);
2182
}
2183
for(int i=0; i<mquads.Size(); i++)
2184
mquads_old[mquads[i].pnums[0]]->Append(mquads[i]);
2185
2186
2187
2188
int np = mesh.GetNP();
2189
int ne = mesh.GetNE();
2190
int nse = mesh.GetNSE();
2191
int i, j, k, l, m;
2192
2193
2194
// if (mtets.Size() + mprisms.Size() == mesh.GetNE())
2195
// return;
2196
2197
2198
2199
mtets.SetSize(0);
2200
mprisms.SetSize(0);
2201
mids.SetSize(0);
2202
mtris.SetSize(0);
2203
mquads.SetSize(0);
2204
2205
2206
INDEX_2_HASHTABLE<int> shortedges(100);
2207
for (i = 1; i <= ne; i++)
2208
{
2209
const Element & el = mesh.VolumeElement(i);
2210
if (el.GetType() == PRISM ||
2211
el.GetType() == PRISM12)
2212
{
2213
for (j = 1; j <= 3; j++)
2214
{
2215
INDEX_2 se(el.PNum(j), el.PNum(j+3));
2216
se.Sort();
2217
shortedges.Set (se, 1);
2218
}
2219
}
2220
}
2221
2222
2223
2224
// INDEX_2_HASHTABLE<int> edgenumber(np);
2225
INDEX_2_CLOSED_HASHTABLE<int> edgenumber(9*ne+4*nse);
2226
2227
BTSortEdges (mesh, idmaps, edgenumber);
2228
2229
2230
for (i = 1; i <= ne; i++)
2231
{
2232
const Element & el = mesh.VolumeElement(i);
2233
2234
switch (el.GetType())
2235
{
2236
case TET:
2237
case TET10:
2238
{
2239
// if tet has short edge, it is handled as degenerated prism
2240
2241
int foundse = 0;
2242
for (j = 1; j <= 3; j++)
2243
for (k = j+1; k <= 4; k++)
2244
{
2245
INDEX_2 se(el.PNum(j), el.PNum(k));
2246
se.Sort();
2247
if (shortedges.Used (se))
2248
{
2249
// cout << "tet converted to prism" << endl;
2250
2251
foundse = 1;
2252
int p3 = 1;
2253
while (p3 == j || p3 == k)
2254
p3++;
2255
int p4 = 10 - j - k - p3;
2256
2257
// even permutation ?
2258
int pi[4];
2259
pi[0] = j;
2260
pi[1] = k;
2261
pi[2] = p3;
2262
pi[3] = p4;
2263
int cnt = 0;
2264
for (l = 1; l <= 4; l++)
2265
for (m = 0; m < 3; m++)
2266
if (pi[m] > pi[m+1])
2267
{
2268
Swap (pi[m], pi[m+1]);
2269
cnt++;
2270
}
2271
if (cnt % 2)
2272
Swap (p3, p4);
2273
2274
Element hel = el;
2275
hel.PNum(1) = el.PNum(j);
2276
hel.PNum(2) = el.PNum(k);
2277
hel.PNum(3) = el.PNum(p3);
2278
hel.PNum(4) = el.PNum(p4);
2279
2280
MarkedPrism mp;
2281
2282
BTDefineMarkedPrism (hel, edgenumber, mp);
2283
mp.matindex = el.GetIndex();
2284
mprisms.Append (mp);
2285
}
2286
}
2287
if (!foundse)
2288
{
2289
MarkedTet mt;
2290
2291
int oldind = -1;
2292
for(l = 0; oldind < 0 && l<mtets_old[el[0]]->Size(); l++)
2293
if(el[1] == (*mtets_old[el[0]])[l].pnums[1] &&
2294
el[2] == (*mtets_old[el[0]])[l].pnums[2] &&
2295
el[3] == (*mtets_old[el[0]])[l].pnums[3])
2296
oldind = l;
2297
2298
if(oldind >= 0)
2299
mtets.Append((*mtets_old[el[0]])[oldind]);
2300
else
2301
{
2302
BTDefineMarkedTet (el, edgenumber, mt);
2303
mt.matindex = el.GetIndex();
2304
mtets.Append (mt);
2305
}
2306
}
2307
break;
2308
}
2309
case PYRAMID:
2310
{
2311
// eventually rotate
2312
MarkedPrism mp;
2313
2314
INDEX_2 se(el.PNum(1), el.PNum(2));
2315
se.Sort();
2316
if (shortedges.Used (se))
2317
{
2318
Element hel = el;
2319
hel.PNum(1) = el.PNum(2);
2320
hel.PNum(2) = el.PNum(3);
2321
hel.PNum(3) = el.PNum(4);
2322
hel.PNum(4) = el.PNum(1);
2323
BTDefineMarkedPrism (hel, edgenumber, mp);
2324
}
2325
else
2326
{
2327
BTDefineMarkedPrism (el, edgenumber, mp);
2328
}
2329
2330
mp.matindex = el.GetIndex();
2331
mprisms.Append (mp);
2332
break;
2333
}
2334
case PRISM:
2335
case PRISM12:
2336
{
2337
MarkedPrism mp;
2338
BTDefineMarkedPrism (el, edgenumber, mp);
2339
mp.matindex = el.GetIndex();
2340
mprisms.Append (mp);
2341
break;
2342
}
2343
}
2344
}
2345
2346
for (i = 1; i <= nse; i++)
2347
{
2348
const Element2d & el = mesh.SurfaceElement(i);
2349
if (el.GetType() == TRIG ||
2350
el.GetType() == TRIG6)
2351
{
2352
MarkedTri mt;
2353
BTDefineMarkedTri (el, edgenumber, mt);
2354
mtris.Append (mt);
2355
}
2356
else
2357
{
2358
MarkedQuad mq;
2359
BTDefineMarkedQuad (el, edgenumber, mq);
2360
mquads.Append (mq);
2361
}
2362
2363
MarkedIdentification mi;
2364
2365
2366
2367
for(j=0; j<idmaps.Size(); j++)
2368
if(BTDefineMarkedId(el, edgenumber, *idmaps[j], mi))
2369
{
2370
mids.Append(mi);
2371
2372
int oldind = -1;
2373
for(l = 0; oldind < 0 && l<mids_old[mi.pnums[0]]->Size(); l++)
2374
{
2375
bool equal = true;
2376
for(int m = 1; equal && m < mi.np; m++)
2377
equal = (mi.pnums[m] == (*mids_old[el[0]])[l].pnums[m]);
2378
if(equal)
2379
oldind = l;
2380
}
2381
2382
if(oldind >= 0)
2383
mids.Last() = (*mids_old[mi.pnums[0]])[oldind];
2384
}
2385
2386
}
2387
2388
2389
2390
for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
2391
delete mtets_old[i];
2392
for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
2393
delete mprisms_old[i];
2394
for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
2395
delete mids_old[i];
2396
for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
2397
delete mtris_old[i];
2398
for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
2399
delete mquads_old[i];
2400
}
2401
*/
2402
2403
2404
void UpdateEdgeMarks (Mesh & mesh,
2405
const ARRAY< ARRAY<int,PointIndex::BASE>* > & idmaps)
2406
//const ARRAY < ARRAY<Element>* > & elements_before,
2407
//const ARRAY < ARRAY<int>* > & markedelts_num,
2408
// const ARRAY < ARRAY<Element2d>* > & surfelements_before,
2409
// const ARRAY < ARRAY<int>* > & markedsurfelts_num)
2410
{
2411
T_MTETS mtets_old; mtets_old.Copy(mtets);
2412
T_MPRISMS mprisms_old; mprisms_old.Copy(mprisms);
2413
T_MIDS mids_old; mids_old.Copy(mids);
2414
T_MTRIS mtris_old; mtris_old.Copy(mtris);
2415
T_MQUADS mquads_old; mquads_old.Copy(mquads);
2416
2417
2418
2419
2420
mtets.SetSize(0);
2421
mprisms.SetSize(0);
2422
mids.SetSize(0);
2423
mtris.SetSize(0);
2424
mquads.SetSize(0);
2425
2426
//int nv = mesh.GetNV();
2427
2428
2429
INDEX_2_CLOSED_HASHTABLE<int> edgenumber(9*mesh.GetNE()+4*mesh.GetNSE());
2430
2431
int maxnum = BTSortEdges (mesh, idmaps, edgenumber);
2432
2433
for(int m = 0; m < mtets_old.Size(); m++)
2434
{
2435
MarkedTet & mt = mtets_old[m];
2436
2437
//(*testout) << "old mt " << mt;
2438
2439
INDEX_2 edge (mt.pnums[mt.tetedge1],mt.pnums[mt.tetedge2]);
2440
edge.Sort();
2441
if(edgenumber.Used(edge))
2442
{
2443
int val = edgenumber.Get(edge);
2444
//(*testout) << "set voledge " << edge << " from " << val;
2445
if(val <= maxnum)
2446
{
2447
val += 2*maxnum;
2448
edgenumber.Set(edge,val);
2449
}
2450
else if(val <= 2*maxnum)
2451
{
2452
val += maxnum;
2453
edgenumber.Set(edge,val);
2454
}
2455
//(*testout) << " to " << val << endl;
2456
}
2457
2458
for(int k=0; k<4; k++)
2459
for(int i=0; i<3; i++)
2460
for(int j=i+1; i != k && j<4; j++)
2461
if(j != k && int(mt.faceedges[k]) == 6-k-i-j)
2462
{
2463
edge[0] = mt.pnums[i];
2464
edge[1] = mt.pnums[j];
2465
edge.Sort();
2466
if(edgenumber.Used(edge))
2467
{
2468
int val = edgenumber.Get(edge);
2469
//(*testout) << "set faceedge " << edge << " from " << val;
2470
if(val <= maxnum)
2471
{
2472
val += maxnum;
2473
edgenumber.Set(edge,val);
2474
}
2475
//(*testout) << " to " << val << endl;
2476
}
2477
}
2478
}
2479
2480
2481
2482
2483
for(ElementIndex ei = 0; ei < mesh.GetNE(); ei++)
2484
{
2485
const Element & el = mesh[ei];
2486
2487
//int pos = elements_before[el[0]]->Pos(el);
2488
//int elnum = (pos >= 0) ? (*markedelts_num[el[0]])[pos] : -1;
2489
2490
switch (el.GetType())
2491
{
2492
case TET:
2493
case TET10:
2494
{
2495
//if(elnum >= 0)
2496
// {
2497
// mtets.Append(mtets_old[elnum]);
2498
// }
2499
//else
2500
// {
2501
MarkedTet mt;
2502
BTDefineMarkedTet (el, edgenumber, mt);
2503
mt.matindex = el.GetIndex();
2504
2505
mtets.Append (mt);
2506
2507
//(*testout) << "mtet " << mtets.Last() << endl;
2508
break;
2509
}
2510
case PYRAMID:
2511
{
2512
cerr << "Refinement :: UpdateEdgeMarks not yet implemented for pyramids"
2513
<< endl;
2514
break;
2515
}
2516
2517
case PRISM:
2518
case PRISM12:
2519
{
2520
cerr << "Refinement :: UpdateEdgeMarks not yet implemented for prisms"
2521
<< endl;
2522
break;
2523
}
2524
}
2525
2526
}
2527
2528
2529
2530
for(SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++)
2531
{
2532
const Element2d & el = mesh[sei];
2533
2534
/*
2535
for(int k=0; k<3; k++)
2536
auxind3[k] = el[k];
2537
2538
auxind3.Sort();
2539
2540
int pos = oldfaces[auxind3[0]]->Pos(auxind3);
2541
if(pos < 0)
2542
cout << "UIUIUI" << endl;
2543
*/
2544
2545
switch (el.GetType())
2546
{
2547
case TRIG:
2548
case TRIG6:
2549
{
2550
MarkedTri mt;
2551
BTDefineMarkedTri (el, edgenumber, mt);
2552
mtris.Append (mt);
2553
break;
2554
}
2555
2556
case QUAD:
2557
case QUAD6:
2558
{
2559
MarkedQuad mt;
2560
BTDefineMarkedQuad (el, edgenumber, mt);
2561
mquads.Append (mt);
2562
break;
2563
}
2564
}
2565
2566
2567
MarkedIdentification mi;
2568
for(int j=0; j<idmaps.Size(); j++)
2569
if(BTDefineMarkedId(el, edgenumber, *idmaps[j], mi))
2570
mids.Append(mi);
2571
2572
2573
/*
2574
int pos = surfelements_before[el[0]]->Pos(el);
2575
int elnum = (pos >= 0) ? (*markedsurfelts_num[el[0]])[pos] : -1;
2576
2577
2578
switch (el.GetType())
2579
{
2580
case TRIG:
2581
case TRIG6:
2582
{
2583
if(elnum >= 0)
2584
mtris.Append(mtris_old[elnum]);
2585
else
2586
{
2587
MarkedTri mt;
2588
BTDefineMarkedTri (el, edgenumber, mt);
2589
mtris.Append (mt);
2590
(*testout) << "(new) ";
2591
}
2592
(*testout) << "mtri " << mtris.Last();
2593
break;
2594
}
2595
2596
case QUAD:
2597
case QUAD6:
2598
{
2599
if(elnum >= 0)
2600
mquads.Append(mquads_old[elnum]);
2601
else
2602
{
2603
MarkedQuad mt;
2604
BTDefineMarkedQuad (el, edgenumber, mt);
2605
mquads.Append (mt);
2606
}
2607
break;
2608
}
2609
}
2610
*/
2611
}
2612
2613
/*
2614
for(int i=0; i<oldfaces.Size(); i++)
2615
{
2616
delete oldfaces[i];
2617
delete oldmarkededges[i];
2618
}
2619
*/
2620
2621
}
2622
2623
2624
2625
2626
void Refinement :: Bisect (Mesh & mesh,
2627
BisectionOptions & opt,
2628
ARRAY<double> * quality_loss)
2629
{
2630
PrintMessage(1,"Mesh bisection");
2631
PushStatus("Mesh bisection");
2632
2633
static int localizetimer = NgProfiler::CreateTimer("localize edgepoints");
2634
NgProfiler::RegionTimer * loct = new NgProfiler::RegionTimer(localizetimer);
2635
LocalizeEdgePoints(mesh);
2636
delete loct;
2637
2638
ARRAY< ARRAY<int,PointIndex::BASE>* > idmaps;
2639
for(int i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++)
2640
{
2641
if(mesh.GetIdentifications().GetType(i) == Identifications::PERIODIC)
2642
{
2643
idmaps.Append(new ARRAY<int,PointIndex::BASE>);
2644
mesh.GetIdentifications().GetMap(i,*idmaps.Last(),true);
2645
}
2646
}
2647
2648
2649
string refelementinfofileread = "";
2650
string refelementinfofilewrite = "";
2651
2652
if(opt.refinementfilename)
2653
{
2654
ifstream inf(opt.refinementfilename);
2655
string st;
2656
inf >> st;
2657
if(st == "refinementinfo")
2658
{
2659
while(inf)
2660
{
2661
while(inf && st != "markedelementsfile")
2662
inf >> st;
2663
2664
if(inf)
2665
inf >> st;
2666
2667
if(st == "read" && inf)
2668
ReadEnclString(inf,refelementinfofileread,'\"');
2669
else if(st == "write" && inf)
2670
ReadEnclString(inf,refelementinfofilewrite,'\"');
2671
}
2672
}
2673
inf.close();
2674
}
2675
2676
2677
2678
if (mesh.mglevels == 1 || idmaps.Size() > 0)
2679
BisectTetsCopyMesh(mesh, NULL, opt, idmaps, refelementinfofileread);
2680
2681
2682
mesh.ComputeNVertices();
2683
2684
int np = mesh.GetNV();
2685
mesh.SetNP(np);
2686
2687
// int ne = mesh.GetNE();
2688
// int nse = mesh.GetNSE();
2689
int i, j, l;
2690
2691
// int initnp = np;
2692
// int maxsteps = 3;
2693
2694
mesh.mglevels++;
2695
2696
/*
2697
if (opt.refinementfilename || opt.usemarkedelements)
2698
maxsteps = 3;
2699
*/
2700
2701
2702
2703
if (opt.refine_p)
2704
{
2705
int ne = mesh.GetNE();
2706
int nse = mesh.GetNSE();
2707
int ox,oy,oz;
2708
for (ElementIndex ei = 0; ei < ne; ei++)
2709
if (mesh[ei].TestRefinementFlag())
2710
{
2711
mesh[ei].GetOrder(ox,oy,oz);
2712
mesh[ei].SetOrder (ox+1,oy+1,oz+1);
2713
if (mesh[ei].TestStrongRefinementFlag())
2714
mesh[ei].SetOrder (ox+2,oy+2,oz+2);
2715
}
2716
for (SurfaceElementIndex sei = 0; sei < nse; sei++)
2717
if (mesh[sei].TestRefinementFlag())
2718
{
2719
mesh[sei].GetOrder(ox,oy);
2720
mesh[sei].SetOrder(ox+1,oy+1);
2721
if (mesh[sei].TestStrongRefinementFlag())
2722
mesh[sei].SetOrder(ox+2,oy+2);
2723
}
2724
2725
/*
2726
#ifndef SABINE //Nachbarelemente mit ordx,ordy,ordz
2727
2728
ARRAY<int,PointIndex::BASE> v_order (mesh.GetNP());
2729
v_order = 0;
2730
2731
for (ElementIndex ei = 0; ei < ne; ei++)
2732
for (j = 0; j < mesh[ei].GetNP(); j++)
2733
if (mesh[ei].GetOrder() > v_order[mesh[ei][j]])
2734
v_order[mesh[ei][j]] = mesh[ei].GetOrder();
2735
2736
for (SurfaceElementIndex sei = 0; sei < nse; sei++)
2737
for (j = 0; j < mesh[sei].GetNP(); j++)
2738
if (mesh[sei].GetOrder() > v_order[mesh[sei][j]])
2739
v_order[mesh[sei][j]] = mesh[sei].GetOrder();
2740
2741
for (ElementIndex ei = 0; ei < ne; ei++)
2742
for (j = 0; j < mesh[ei].GetNP(); j++)
2743
if (mesh[ei].GetOrder() < v_order[mesh[ei][j]]-1)
2744
mesh[ei].SetOrder(v_order[mesh[ei][j]]-1);
2745
2746
for (SurfaceElementIndex sei = 0; sei < nse; sei++)
2747
for (j = 0; j < mesh[sei].GetNP(); j++)
2748
if (mesh[sei].GetOrder() < v_order[mesh[sei][j]]-1)
2749
mesh[sei].SetOrder(v_order[mesh[sei][j]]-1);
2750
2751
#endif
2752
*/
2753
2754
PopStatus();
2755
return;
2756
}
2757
2758
2759
2760
// INDEX_2_HASHTABLE<int> cutedges(10 + 5 * (mtets.Size()+mprisms.Size()+mtris.Size()+mquads.Size()));
2761
INDEX_2_CLOSED_HASHTABLE<int> cutedges(10 + 9 * (mtets.Size()+mprisms.Size()+mtris.Size()+mquads.Size()));
2762
2763
bool noprojection = false;
2764
2765
for (l = 1; l <= 1; l++)
2766
{
2767
int marked = 0;
2768
if (opt.refinementfilename)
2769
{
2770
ifstream inf(opt.refinementfilename);
2771
PrintMessage(3,"load refinementinfo from file ",opt.refinementfilename);
2772
2773
string st;
2774
inf >> st;
2775
if(st == "refinementinfo")
2776
// new version
2777
{
2778
for(i=1; i<=mtets.Size(); i++)
2779
mtets.Elem(i).marked = 0;
2780
for(i=1; i<=mprisms.Size(); i++)
2781
mprisms.Elem(i).marked = 0;
2782
for(i=1; i<=mtris.Size(); i++)
2783
mtris.Elem(i).marked = 0;
2784
for(i=1; i<=mquads.Size(); i++)
2785
mquads.Elem(i).marked = 0;
2786
for(i=1; i<=mprisms.Size(); i++)
2787
mids.Elem(i).marked = 0;
2788
2789
inf >> st;
2790
while(inf)
2791
{
2792
if(st[0] == '#')
2793
{
2794
inf.ignore(10000,'\n');
2795
inf >> st;
2796
}
2797
else if(st == "markedelementsfile")
2798
{
2799
inf >> st;
2800
ReadEnclString(inf,st,'\"');
2801
inf >> st;
2802
}
2803
else if(st == "noprojection")
2804
{
2805
noprojection = true;
2806
inf >> st;
2807
}
2808
else if(st == "refine")
2809
{
2810
inf >> st;
2811
if(st == "elements")
2812
{
2813
inf >> st;
2814
bool isint = true;
2815
for(string::size_type ii=0; isint && ii<st.size(); ii++)
2816
isint = (isdigit(st[ii]) != 0);
2817
2818
while(inf && isint)
2819
{
2820
mtets.Elem(atoi(st.c_str())).marked = 3;
2821
marked = 1;
2822
2823
inf >> st;
2824
isint = true;
2825
for(string::size_type ii=0; isint && ii<st.size(); ii++)
2826
isint = (isdigit(st[ii]) != 0);
2827
}
2828
}
2829
else if(st == "orthobrick")
2830
{
2831
double bounds[6];
2832
for(i=0; i<6; i++)
2833
inf >> bounds[i];
2834
2835
int cnt = 0;
2836
2837
for(ElementIndex ei = 0; ei < mesh.GetNE(); ei++)
2838
{
2839
const Element & el = mesh[ei];
2840
2841
//
2842
Point<3> center(0,0,0);
2843
for(i=0; i<el.GetNP(); i++)
2844
{
2845
const MeshPoint & point = mesh[el[i]];
2846
center(0) += point(0);
2847
center(1) += point(1);
2848
center(2) += point(2);
2849
}
2850
for(i=0; i<3; i++)
2851
center(i) *= 1./double(el.GetNP());
2852
if(bounds[0] <= center(0) && center(0) <= bounds[3] &&
2853
bounds[1] <= center(1) && center(1) <= bounds[4] &&
2854
bounds[2] <= center(2) && center(2) <= bounds[5])
2855
{
2856
mtets[ei].marked = 3;
2857
cnt++;
2858
}
2859
2860
2861
// bool contained = false;
2862
// for(int i=0; !contained && i<el.GetNP(); i++)
2863
// {
2864
// const MeshPoint & point = mesh[el[i]];
2865
// contained = (bounds[0] <= point.X() && point.X() <= bounds[3] &&
2866
// bounds[1] <= point.Y() && point.Y() <= bounds[4] &&
2867
// bounds[2] <= point.Z() && point.Z() <= bounds[5]);
2868
// }
2869
// if(contained)
2870
// {
2871
// mtets[ei].marked = 3;
2872
// cnt++;
2873
// }
2874
}
2875
2876
2877
ostringstream strstr;
2878
strstr.precision(2);
2879
strstr << "marked " << float(cnt)/float(mesh.GetNE())*100.
2880
#ifdef WIN32
2881
<< "%%"
2882
#else
2883
<< "%"
2884
#endif
2885
<<" of the elements";
2886
PrintMessage(4,strstr.str());
2887
2888
if(cnt > 0)
2889
marked = 1;
2890
2891
2892
inf >> st;
2893
}
2894
else
2895
{
2896
throw NgException("something wrong with refinementinfo file");
2897
}
2898
}
2899
}
2900
}
2901
else
2902
{
2903
inf.close();
2904
inf.open(opt.refinementfilename);
2905
2906
char ch;
2907
for (i = 1; i <= mtets.Size(); i++)
2908
{
2909
inf >> ch;
2910
if(!inf)
2911
throw NgException("something wrong with refinementinfo file (old format)");
2912
mtets.Elem(i).marked = (ch == '1');
2913
}
2914
marked = 1;
2915
}
2916
inf.close();
2917
}
2918
2919
else if (opt.usemarkedelements)
2920
{
2921
int cntm = 0;
2922
2923
// all in one !
2924
if (mprisms.Size())
2925
{
2926
int cnttet = 0;
2927
int cntprism = 0;
2928
for (i = 1; i <= mesh.GetNE(); i++)
2929
{
2930
if (mesh.VolumeElement(i).GetType() == TET ||
2931
mesh.VolumeElement(i).GetType() == TET10)
2932
{
2933
cnttet++;
2934
mtets.Elem(cnttet).marked =
2935
3 * mesh.VolumeElement(i).TestRefinementFlag();
2936
if (mtets.Elem(cnttet).marked)
2937
cntm++;
2938
}
2939
else
2940
{
2941
cntprism++;
2942
mprisms.Elem(cntprism).marked =
2943
2 * mesh.VolumeElement(i).TestRefinementFlag();
2944
if (mprisms.Elem(cntprism).marked)
2945
cntm++;
2946
}
2947
2948
}
2949
}
2950
else
2951
for (i = 1; i <= mtets.Size(); i++)
2952
{
2953
mtets.Elem(i).marked =
2954
3 * mesh.VolumeElement(i).TestRefinementFlag();
2955
if (mtets.Elem(i).marked)
2956
cntm++;
2957
}
2958
2959
// (*testout) << "mtets = " << mtets << endl;
2960
2961
/*
2962
for (i = 1; i <= mtris.Size(); i++)
2963
mtris.Elem(i).marked = 0;
2964
for (i = 1; i <= mquads.Size(); i++)
2965
mquads.Elem(i).marked = 0;
2966
*/
2967
2968
if (printmessage_importance>0)
2969
{
2970
ostringstream str;
2971
str << "marked elements: " << cntm;
2972
PrintMessage(4,str.str());
2973
}
2974
2975
int cnttrig = 0;
2976
int cntquad = 0;
2977
for (i = 1; i <= mesh.GetNSE(); i++)
2978
{
2979
if (mesh.SurfaceElement(i).GetType() == TRIG ||
2980
mesh.SurfaceElement(i).GetType() == TRIG6)
2981
{
2982
cnttrig++;
2983
mtris.Elem(cnttrig).marked =
2984
mesh.SurfaceElement(i).TestRefinementFlag() ? 2 : 0;
2985
// mtris.Elem(cnttrig).marked = 0;
2986
if (mtris.Elem(cnttrig).marked)
2987
cntm++;
2988
}
2989
else
2990
{
2991
cntquad++;
2992
// 2d: marked=2, 3d prisms: marked=1
2993
mquads.Elem(cntquad).marked =
2994
mesh.SurfaceElement(i).TestRefinementFlag() ? 4-mesh.GetDimension() : 0 ;
2995
// mquads.Elem(cntquad).marked = 0;
2996
if (mquads.Elem(cntquad).marked)
2997
cntm++;
2998
}
2999
}
3000
3001
if (printmessage_importance>0)
3002
{
3003
ostringstream str;
3004
str << "with surface-elements: " << cntm;
3005
PrintMessage(4,str.str());
3006
}
3007
3008
// he/sz: das wird oben schon richtig gemacht.
3009
// hier sind die quads vergessen!
3010
/*
3011
if (mesh.GetDimension() == 2)
3012
{
3013
cntm = 0;
3014
for (i = 1; i <= mtris.Size(); i++)
3015
{
3016
mtris.Elem(i).marked =
3017
2 * mesh.SurfaceElement(i).TestRefinementFlag();
3018
// mtris.Elem(i).marked = 2;
3019
if (mtris.Elem(i).marked)
3020
cntm++;
3021
}
3022
3023
if (!cntm)
3024
{
3025
for (i = 1; i <= mtris.Size(); i++)
3026
{
3027
mtris.Elem(i).marked = 2;
3028
cntm++;
3029
}
3030
}
3031
cout << "trigs: " << mtris.Size() << " ";
3032
cout << "marked: " << cntm << endl;
3033
}
3034
*/
3035
3036
marked = (cntm > 0);
3037
}
3038
else
3039
{
3040
marked = BTMarkTets (mtets, mprisms, mesh);
3041
}
3042
3043
if (!marked) break;
3044
3045
3046
//(*testout) << "mtets " << mtets << endl;
3047
3048
if (opt.refine_p)
3049
{
3050
PrintMessage(3,"refine p");
3051
3052
for (i = 1; i <= mtets.Size(); i++)
3053
mtets.Elem(i).incorder = mtets.Elem(i).marked ? 1 : 0;
3054
3055
for (i = 1; i <= mtets.Size(); i++)
3056
if (mtets.Elem(i).incorder)
3057
mtets.Elem(i).marked = 0;
3058
3059
3060
for (i = 1; i <= mprisms.Size(); i++)
3061
mprisms.Elem(i).incorder = mprisms.Elem(i).marked ? 1 : 0;
3062
3063
for (i = 1; i <= mprisms.Size(); i++)
3064
if (mprisms.Elem(i).incorder)
3065
mprisms.Elem(i).marked = 0;
3066
3067
3068
for (i = 1; i <= mtris.Size(); i++)
3069
mtris.Elem(i).incorder = mtris.Elem(i).marked ? 1 : 0;
3070
3071
for (i = 1; i <= mtris.Size(); i++)
3072
{
3073
if (mtris.Elem(i).incorder)
3074
mtris.Elem(i).marked = 0;
3075
}
3076
}
3077
3078
if (opt.refine_hp)
3079
{
3080
PrintMessage(3,"refine hp");
3081
BitArray singv(np);
3082
singv.Clear();
3083
3084
if (mesh.GetDimension() == 3)
3085
{
3086
for (i = 1; i <= mesh.GetNSeg(); i++)
3087
{
3088
const Segment & seg = mesh.LineSegment(i);
3089
singv.Set (seg.p1);
3090
singv.Set (seg.p2);
3091
}
3092
/*
3093
for ( i=1; i<= mesh.GetNSE(); i++)
3094
{
3095
const Element2d & sel = mesh.SurfaceElement(i);
3096
for(int j=1; j<=sel.GetNP(); j++)
3097
singv.Set(sel.PNum(j));
3098
}
3099
*/
3100
}
3101
else
3102
{
3103
// vertices with 2 different bnds
3104
ARRAY<int> bndind(np);
3105
bndind = 0;
3106
for (i = 1; i <= mesh.GetNSeg(); i++)
3107
{
3108
const Segment & seg = mesh.LineSegment(i);
3109
for (j = 0; j < 2; j++)
3110
{
3111
int pi = (j == 0) ? seg.p1 : seg.p2;
3112
if (bndind.Elem(pi) == 0)
3113
bndind.Elem(pi) = seg.edgenr;
3114
else if (bndind.Elem(pi) != seg.edgenr)
3115
singv.Set (pi);
3116
}
3117
}
3118
}
3119
3120
3121
3122
for (i = 1; i <= mtets.Size(); i++)
3123
mtets.Elem(i).incorder = 1;
3124
for (i = 1; i <= mtets.Size(); i++)
3125
{
3126
if (!mtets.Elem(i).marked)
3127
mtets.Elem(i).incorder = 0;
3128
for (j = 0; j < 4; j++)
3129
if (singv.Test (mtets.Elem(i).pnums[j]))
3130
mtets.Elem(i).incorder = 0;
3131
}
3132
for (i = 1; i <= mtets.Size(); i++)
3133
if (mtets.Elem(i).incorder)
3134
mtets.Elem(i).marked = 0;
3135
3136
3137
for (i = 1; i <= mprisms.Size(); i++)
3138
mprisms.Elem(i).incorder = 1;
3139
for (i = 1; i <= mprisms.Size(); i++)
3140
{
3141
if (!mprisms.Elem(i).marked)
3142
mprisms.Elem(i).incorder = 0;
3143
for (j = 0; j < 6; j++)
3144
if (singv.Test (mprisms.Elem(i).pnums[j]))
3145
mprisms.Elem(i).incorder = 0;
3146
}
3147
for (i = 1; i <= mprisms.Size(); i++)
3148
if (mprisms.Elem(i).incorder)
3149
mprisms.Elem(i).marked = 0;
3150
3151
3152
for (i = 1; i <= mtris.Size(); i++)
3153
mtris.Elem(i).incorder = 1;
3154
for (i = 1; i <= mtris.Size(); i++)
3155
{
3156
if (!mtris.Elem(i).marked)
3157
mtris.Elem(i).incorder = 0;
3158
for (j = 0; j < 3; j++)
3159
if (singv.Test (mtris.Elem(i).pnums[j]))
3160
mtris.Elem(i).incorder = 0;
3161
}
3162
for (i = 1; i <= mtris.Size(); i++)
3163
{
3164
if (mtris.Elem(i).incorder)
3165
mtris.Elem(i).marked = 0;
3166
}
3167
}
3168
3169
3170
3171
3172
3173
int hangingvol, hangingsurf, hangingedge;
3174
3175
//cout << "write?" << endl;
3176
//string yn;
3177
//cin >> yn;
3178
3179
(*testout) << "refine volume elements" << endl;
3180
do
3181
{
3182
// refine volume elements
3183
3184
int nel = mtets.Size();
3185
for (i = 1; i <= nel; i++)
3186
if (mtets.Elem(i).marked)
3187
{
3188
MarkedTet oldtet;
3189
MarkedTet newtet1, newtet2;
3190
int newp;
3191
3192
3193
oldtet = mtets.Get(i);
3194
//if(yn == "y")
3195
// (*testout) << "bisected tet " << oldtet;
3196
INDEX_2 edge(oldtet.pnums[oldtet.tetedge1],
3197
oldtet.pnums[oldtet.tetedge2]);
3198
edge.Sort();
3199
if (cutedges.Used (edge))
3200
{
3201
newp = cutedges.Get(edge);
3202
}
3203
else
3204
{
3205
Point<3> npt = Center (mesh.Point (edge.I1()),
3206
mesh.Point (edge.I2()));
3207
newp = mesh.AddPoint (npt);
3208
cutedges.Set (edge, newp);
3209
}
3210
3211
BTBisectTet (oldtet, newp, newtet1, newtet2);
3212
3213
mtets.Elem(i) = newtet1;
3214
mtets.Append (newtet2);
3215
3216
#ifdef DEBUG
3217
*testout << "tet1 has elnr = " << i << ", tet2 has elnr = " << mtets.Size() << endl;
3218
#endif
3219
//if(yn == "y")
3220
// (*testout) << "and got " << newtet1 << "and " << newtet2 << endl;
3221
3222
mesh.mlparentelement.Append (i);
3223
}
3224
3225
int npr = mprisms.Size();
3226
for (i = 1; i <= npr; i++)
3227
if (mprisms.Elem(i).marked)
3228
{
3229
MarkedPrism oldprism;
3230
MarkedPrism newprism1, newprism2;
3231
int newp1, newp2;
3232
3233
oldprism = mprisms.Get(i);
3234
int pi1 = 0;
3235
if (pi1 == oldprism.markededge)
3236
pi1++;
3237
int pi2 = 3-pi1-oldprism.markededge;
3238
3239
INDEX_2 edge1(oldprism.pnums[pi1],
3240
oldprism.pnums[pi2]);
3241
INDEX_2 edge2(oldprism.pnums[pi1+3],
3242
oldprism.pnums[pi2+3]);
3243
edge1.Sort();
3244
edge2.Sort();
3245
3246
if (cutedges.Used (edge1))
3247
newp1 = cutedges.Get(edge1);
3248
else
3249
{
3250
Point<3> npt = Center (mesh.Point (edge1.I1()),
3251
mesh.Point (edge1.I2()));
3252
newp1 = mesh.AddPoint (npt);
3253
cutedges.Set (edge1, newp1);
3254
}
3255
if (cutedges.Used (edge2))
3256
newp2 = cutedges.Get(edge2);
3257
else
3258
{
3259
Point<3> npt = Center (mesh.Point (edge2.I1()),
3260
mesh.Point (edge2.I2()));
3261
newp2 = mesh.AddPoint (npt);
3262
cutedges.Set (edge2, newp2);
3263
}
3264
3265
3266
BTBisectPrism (oldprism, newp1, newp2, newprism1, newprism2);
3267
//if(yn == "y")
3268
// (*testout) << "bisected prism " << oldprism << "and got " << newprism1 << "and " << newprism2 << endl;
3269
mprisms.Elem(i) = newprism1;
3270
mprisms.Append (newprism2);
3271
}
3272
3273
int nid = mids.Size();
3274
for (i = 1; i <= nid; i++)
3275
if (mids.Elem(i).marked)
3276
{
3277
MarkedIdentification oldid,newid1,newid2;
3278
ARRAY<int> newp;
3279
3280
oldid = mids.Get(i);
3281
3282
ARRAY<INDEX_2> edges;
3283
edges.Append(INDEX_2(oldid.pnums[oldid.markededge],
3284
oldid.pnums[(oldid.markededge+1)%oldid.np]));
3285
edges.Append(INDEX_2(oldid.pnums[oldid.markededge + oldid.np],
3286
oldid.pnums[(oldid.markededge+1)%oldid.np + oldid.np]));
3287
3288
if(oldid.np == 4)
3289
{
3290
edges.Append(INDEX_2(oldid.pnums[(oldid.markededge+2)%oldid.np],
3291
oldid.pnums[(oldid.markededge+3)%oldid.np]));
3292
edges.Append(INDEX_2(oldid.pnums[(oldid.markededge+2)%oldid.np + oldid.np],
3293
oldid.pnums[(oldid.markededge+3)%oldid.np + oldid.np]));
3294
}
3295
for (j = 0; j < edges.Size(); j++)
3296
{
3297
edges[j].Sort();
3298
3299
if(cutedges.Used(edges[j]))
3300
newp.Append(cutedges.Get(edges[j]));
3301
else
3302
{
3303
Point<3> npt = Center (mesh.Point (edges[j].I1()),
3304
mesh.Point (edges[j].I2()));
3305
newp.Append(mesh.AddPoint(npt));
3306
cutedges.Set(edges[j],newp[j]);
3307
}
3308
}
3309
3310
BTBisectIdentification(oldid,newp,newid1,newid2);
3311
mids.Elem(i) = newid1;
3312
mids.Append(newid2);
3313
}
3314
3315
3316
//IdentifyCutEdges(mesh, cutedges);
3317
3318
3319
hangingvol =
3320
MarkHangingTets (mtets, cutedges) +
3321
MarkHangingPrisms (mprisms, cutedges) +
3322
MarkHangingIdentifications (mids, cutedges);
3323
3324
3325
int nsel = mtris.Size();
3326
3327
for (i = 1; i <= nsel; i++)
3328
if (mtris.Elem(i).marked)
3329
{
3330
MarkedTri oldtri;
3331
MarkedTri newtri1, newtri2;
3332
PointIndex newp;
3333
3334
oldtri = mtris.Get(i);
3335
int oldpi1 = oldtri.pnums[(oldtri.markededge+1)%3];
3336
int oldpi2 = oldtri.pnums[(oldtri.markededge+2)%3];
3337
INDEX_2 edge(oldpi1, oldpi2);
3338
edge.Sort();
3339
3340
// cerr << "edge = " << edge.I1() << "-" << edge.I2() << endl;
3341
3342
if (cutedges.Used (edge))
3343
{
3344
newp = cutedges.Get(edge);
3345
}
3346
else
3347
{
3348
Point<3> npt = Center (mesh.Point (edge.I1()),
3349
mesh.Point (edge.I2()));
3350
newp = mesh.AddPoint (npt);
3351
cutedges.Set (edge, newp);
3352
}
3353
// newp = cutedges.Get(edge);
3354
3355
int si = mesh.GetFaceDescriptor (oldtri.surfid).SurfNr();
3356
// geom->GetSurface(si)->Project (mesh.Point(newp));
3357
PointGeomInfo npgi;
3358
3359
// cerr << "project point " << newp << " old: " << mesh.Point(newp);
3360
if (mesh[newp].Type() != EDGEPOINT)
3361
PointBetween (mesh.Point (oldpi1), mesh.Point (oldpi2),
3362
0.5, si,
3363
oldtri.pgeominfo[(oldtri.markededge+1)%3],
3364
oldtri.pgeominfo[(oldtri.markededge+2)%3],
3365
mesh.Point (newp), npgi);
3366
// cerr << " new: " << mesh.Point(newp) << endl;
3367
3368
BTBisectTri (oldtri, newp, npgi, newtri1, newtri2);
3369
//if(yn == "y")
3370
// (*testout) << "bisected tri " << oldtri << "and got " << newtri1 << "and " << newtri2 << endl;
3371
3372
3373
mtris.Elem(i) = newtri1;
3374
mtris.Append (newtri2);
3375
mesh.mlparentsurfaceelement.Append (i);
3376
}
3377
3378
int nquad = mquads.Size();
3379
for (i = 1; i <= nquad; i++)
3380
if (mquads.Elem(i).marked)
3381
{
3382
MarkedQuad oldquad;
3383
MarkedQuad newquad1, newquad2;
3384
int newp1, newp2;
3385
3386
oldquad = mquads.Get(i);
3387
/*
3388
INDEX_2 edge1(oldquad.pnums[0],
3389
oldquad.pnums[1]);
3390
INDEX_2 edge2(oldquad.pnums[2],
3391
oldquad.pnums[3]);
3392
*/
3393
INDEX_2 edge1, edge2;
3394
PointGeomInfo pgi11, pgi12, pgi21, pgi22;
3395
if (oldquad.markededge==0 || oldquad.markededge==2)
3396
{
3397
edge1.I1()=oldquad.pnums[0]; pgi11=oldquad.pgeominfo[0];
3398
edge1.I2()=oldquad.pnums[1]; pgi12=oldquad.pgeominfo[1];
3399
edge2.I1()=oldquad.pnums[2]; pgi21=oldquad.pgeominfo[2];
3400
edge2.I2()=oldquad.pnums[3]; pgi22=oldquad.pgeominfo[3];
3401
}
3402
else // 3 || 1
3403
{
3404
edge1.I1()=oldquad.pnums[0]; pgi11=oldquad.pgeominfo[0];
3405
edge1.I2()=oldquad.pnums[2]; pgi12=oldquad.pgeominfo[2];
3406
edge2.I1()=oldquad.pnums[1]; pgi21=oldquad.pgeominfo[1];
3407
edge2.I2()=oldquad.pnums[3]; pgi22=oldquad.pgeominfo[3];
3408
}
3409
3410
edge1.Sort();
3411
edge2.Sort();
3412
3413
if (cutedges.Used (edge1))
3414
{
3415
newp1 = cutedges.Get(edge1);
3416
}
3417
else
3418
{
3419
Point<3> np1 = Center (mesh.Point (edge1.I1()),
3420
mesh.Point (edge1.I2()));
3421
newp1 = mesh.AddPoint (np1);
3422
cutedges.Set (edge1, newp1);
3423
}
3424
3425
if (cutedges.Used (edge2))
3426
{
3427
newp2 = cutedges.Get(edge2);
3428
}
3429
else
3430
{
3431
Point<3> np2 = Center (mesh.Point (edge2.I1()),
3432
mesh.Point (edge2.I2()));
3433
newp2 = mesh.AddPoint (np2);
3434
cutedges.Set (edge2, newp2);
3435
}
3436
3437
PointGeomInfo npgi1, npgi2;
3438
3439
int si = mesh.GetFaceDescriptor (oldquad.surfid).SurfNr();
3440
// geom->GetSurface(si)->Project (mesh.Point(newp1));
3441
// geom->GetSurface(si)->Project (mesh.Point(newp2));
3442
3443
// (*testout)
3444
// cerr << "project point 1 " << newp1 << " old: " << mesh.Point(newp1);
3445
PointBetween (mesh.Point (edge1.I1()), mesh.Point (edge1.I2()),
3446
0.5, si,
3447
pgi11,
3448
pgi12,
3449
mesh.Point (newp1), npgi1);
3450
// (*testout)
3451
// cerr << " new: " << mesh.Point(newp1) << endl;
3452
3453
3454
// cerr << "project point 2 " << newp2 << " old: " << mesh.Point(newp2);
3455
PointBetween (mesh.Point (edge2.I1()), mesh.Point (edge2.I2()),
3456
0.5, si,
3457
pgi21,
3458
pgi22,
3459
mesh.Point (newp2), npgi2);
3460
// cerr << " new: " << mesh.Point(newp2) << endl;
3461
3462
3463
BTBisectQuad (oldquad, newp1, npgi1, newp2, npgi2,
3464
newquad1, newquad2);
3465
3466
mquads.Elem(i) = newquad1;
3467
mquads.Append (newquad2);
3468
}
3469
3470
3471
hangingsurf =
3472
MarkHangingTris (mtris, cutedges) +
3473
MarkHangingQuads (mquads, cutedges);
3474
3475
hangingedge = 0;
3476
3477
int nseg = mesh.GetNSeg ();
3478
for (i = 1; i <= nseg; i++)
3479
{
3480
Segment & seg = mesh.LineSegment (i);
3481
INDEX_2 edge(seg.p1, seg.p2);
3482
edge.Sort();
3483
if (cutedges.Used (edge))
3484
{
3485
hangingedge = 1;
3486
Segment nseg1 = seg;
3487
Segment nseg2 = seg;
3488
3489
int newpi = cutedges.Get(edge);
3490
3491
nseg1.p2 = newpi;
3492
nseg2.p1 = newpi;
3493
3494
EdgePointGeomInfo newepgi;
3495
3496
3497
//
3498
// cerr << "move edgepoint " << newpi << " from " << mesh.Point(newpi);
3499
PointBetween (mesh.Point (seg.p1), mesh.Point (seg.p2),
3500
0.5, seg.surfnr1, seg.surfnr2,
3501
seg.epgeominfo[0], seg.epgeominfo[1],
3502
mesh.Point (newpi), newepgi);
3503
// cerr << " to " << mesh.Point (newpi) << endl;
3504
3505
3506
nseg1.epgeominfo[1] = newepgi;
3507
nseg2.epgeominfo[0] = newepgi;
3508
3509
mesh.LineSegment (i) = nseg1;
3510
mesh.AddSegment (nseg2);
3511
}
3512
}
3513
}
3514
while (hangingvol || hangingsurf || hangingedge);
3515
3516
if (printmessage_importance>0)
3517
{
3518
ostringstream strstr;
3519
strstr << mtets.Size() << " tets" << endl
3520
<< mtris.Size() << " trigs" << endl;
3521
if (mprisms.Size())
3522
{
3523
strstr << mprisms.Size() << " prisms" << endl
3524
<< mquads.Size() << " quads" << endl;
3525
}
3526
strstr << mesh.GetNP() << " points";
3527
PrintMessage(4,strstr.str());
3528
3529
}
3530
}
3531
3532
3533
// (*testout) << "mtets = " << mtets << endl;
3534
3535
if (opt.refine_hp)
3536
{
3537
//
3538
ARRAY<int> v_order (mesh.GetNP());
3539
v_order = 0;
3540
if (mesh.GetDimension() == 3)
3541
{
3542
for (i = 1; i <= mtets.Size(); i++)
3543
if (mtets.Elem(i).incorder)
3544
mtets.Elem(i).order++;
3545
3546
for (i = 0; i < mtets.Size(); i++)
3547
for (j = 0; j < 4; j++)
3548
if (int(mtets[i].order) > v_order.Elem(mtets[i].pnums[j]))
3549
v_order.Elem(mtets[i].pnums[j]) = mtets[i].order;
3550
for (i = 0; i < mtets.Size(); i++)
3551
for (j = 0; j < 4; j++)
3552
if (int(mtets[i].order) < v_order.Elem(mtets[i].pnums[j])-1)
3553
mtets[i].order = v_order.Elem(mtets[i].pnums[j])-1;
3554
}
3555
else
3556
{
3557
for (i = 1; i <= mtris.Size(); i++)
3558
if (mtris.Elem(i).incorder)
3559
{
3560
mtris.Elem(i).order++;
3561
}
3562
3563
for (i = 0; i < mtris.Size(); i++)
3564
for (j = 0; j < 3; j++)
3565
if (int(mtris[i].order) > v_order.Elem(mtris[i].pnums[j]))
3566
v_order.Elem(mtris[i].pnums[j]) = mtris[i].order;
3567
for (i = 0; i < mtris.Size(); i++)
3568
{
3569
for (j = 0; j < 3; j++)
3570
if (int(mtris[i].order) < v_order.Elem(mtris[i].pnums[j])-1)
3571
mtris[i].order = v_order.Elem(mtris[i].pnums[j])-1;
3572
}
3573
}
3574
}
3575
3576
mtets.SetAllocSize (mtets.Size());
3577
mprisms.SetAllocSize (mprisms.Size());
3578
mids.SetAllocSize (mids.Size());
3579
mtris.SetAllocSize (mtris.Size());
3580
mquads.SetAllocSize (mquads.Size());
3581
3582
3583
mesh.ClearVolumeElements();
3584
mesh.VolumeElements().SetAllocSize (mtets.Size()+mprisms.Size());
3585
for (i = 1; i <= mtets.Size(); i++)
3586
{
3587
Element el(TET);
3588
el.SetIndex (mtets.Get(i).matindex);
3589
for (j = 1; j <= 4; j++)
3590
el.PNum(j) = mtets.Get(i).pnums[j-1];
3591
el.SetOrder (mtets.Get(i).order);
3592
mesh.AddVolumeElement (el);
3593
}
3594
for (i = 1; i <= mprisms.Size(); i++)
3595
{
3596
Element el(PRISM);
3597
el.SetIndex (mprisms.Get(i).matindex);
3598
for (j = 1; j <= 6; j++)
3599
el.PNum(j) = mprisms.Get(i).pnums[j-1];
3600
el.SetOrder (mprisms.Get(i).order);
3601
3602
// degenerated prism ?
3603
static const int map1[] = { 3, 2, 5, 6, 1 };
3604
static const int map2[] = { 1, 3, 6, 4, 2 };
3605
static const int map3[] = { 2, 1, 4, 5, 3 };
3606
3607
3608
const int * map = NULL;
3609
int deg1 = 0, deg2 = 0, deg3 = 0;
3610
// int deg = 0;
3611
if (el.PNum(1) == el.PNum(4)) { map = map1; deg1 = 1; }
3612
if (el.PNum(2) == el.PNum(5)) { map = map2; deg2 = 1; }
3613
if (el.PNum(3) == el.PNum(6)) { map = map3; deg3 = 1; }
3614
3615
switch (deg1+deg2+deg3)
3616
{
3617
case 1:
3618
{
3619
for (j = 1; j <= 5; j++)
3620
el.PNum(j) = mprisms.Get(i).pnums[map[j-1]-1];
3621
3622
el.SetType (PYRAMID);
3623
break;
3624
}
3625
case 2:
3626
{
3627
static const int tetmap1[] = { 1, 2, 3, 4 };
3628
static const int tetmap2[] = { 2, 3, 1, 5 };
3629
static const int tetmap3[] = { 3, 1, 2, 6 };
3630
if (!deg1) map = tetmap1;
3631
if (!deg2) map = tetmap2;
3632
if (!deg3) map = tetmap3;
3633
for (j = 1; j <= 4; j++)
3634
el.PNum(j) = mprisms.Get(i).pnums[map[j-1]-1];
3635
/*
3636
if (!deg1) el.PNum(4) = el.PNum(4);
3637
if (!deg2) el.PNum(4) = el.PNum(5);
3638
if (!deg3) el.PNum(4) = el.PNum(6);
3639
*/
3640
el.SetType(TET);
3641
break;
3642
}
3643
default:
3644
;
3645
}
3646
mesh.AddVolumeElement (el);
3647
}
3648
3649
mesh.ClearSurfaceElements();
3650
for (i = 1; i <= mtris.Size(); i++)
3651
{
3652
Element2d el(TRIG);
3653
el.SetIndex (mtris.Get(i).surfid);
3654
el.SetOrder (mtris.Get(i).order);
3655
for (j = 1; j <= 3; j++)
3656
{
3657
el.PNum(j) = mtris.Get(i).pnums[j-1];
3658
el.GeomInfoPi(j) = mtris.Get(i).pgeominfo[j-1];
3659
}
3660
mesh.AddSurfaceElement (el);
3661
}
3662
for (i = 1; i <= mquads.Size(); i++)
3663
{
3664
Element2d el(QUAD);
3665
el.SetIndex (mquads.Get(i).surfid);
3666
for (j = 1; j <= 4; j++)
3667
el.PNum(j) = mquads.Get(i).pnums[j-1];
3668
Swap (el.PNum(3), el.PNum(4));
3669
mesh.AddSurfaceElement (el);
3670
}
3671
3672
3673
3674
// write multilevel hierarchy to mesh:
3675
np = mesh.GetNP();
3676
mesh.mlbetweennodes.SetSize(np);
3677
if (mesh.mglevels <= 2)
3678
{
3679
PrintMessage(4,"RESETTING mlbetweennodes");
3680
for (i = 1; i <= np; i++)
3681
{
3682
mesh.mlbetweennodes.Elem(i).I1() = 0;
3683
mesh.mlbetweennodes.Elem(i).I2() = 0;
3684
}
3685
}
3686
3687
/*
3688
for (i = 1; i <= cutedges.GetNBags(); i++)
3689
for (j = 1; j <= cutedges.GetBagSize(i); j++)
3690
{
3691
INDEX_2 edge;
3692
int newpi;
3693
cutedges.GetData (i, j, edge, newpi);
3694
mesh.mlbetweennodes.Elem(newpi) = edge;
3695
}
3696
*/
3697
3698
BitArray isnewpoint(np);
3699
isnewpoint.Clear();
3700
3701
for (i = 1; i <= cutedges.Size(); i++)
3702
if (cutedges.UsedPos(i))
3703
{
3704
INDEX_2 edge;
3705
int newpi;
3706
cutedges.GetData (i, edge, newpi);
3707
isnewpoint.Set(newpi);
3708
mesh.mlbetweennodes.Elem(newpi) = edge;
3709
}
3710
3711
3712
/*
3713
mesh.PrintMemInfo (cout);
3714
cout << "tets ";
3715
mtets.PrintMemInfo (cout);
3716
cout << "prims ";
3717
mprisms.PrintMemInfo (cout);
3718
cout << "tris ";
3719
mtris.PrintMemInfo (cout);
3720
cout << "quads ";
3721
mquads.PrintMemInfo (cout);
3722
cout << "cutedges ";
3723
cutedges.PrintMemInfo (cout);
3724
*/
3725
3726
3727
/*
3728
3729
// find connected nodes (close nodes)
3730
TABLE<int> conto(np);
3731
for (i = 1; i <= mprisms.Size(); i++)
3732
for (j = 1; j <= 6; j++)
3733
{
3734
int n1 = mprisms.Get(i).pnums[j-1];
3735
int n2 = mprisms.Get(i).pnums[(j+2)%6];
3736
// if (n1 != n2)
3737
{
3738
int found = 0;
3739
for (k = 1; k <= conto.EntrySize(n1); k++)
3740
if (conto.Get(n1, k) == n2)
3741
{
3742
found = 1;
3743
break;
3744
}
3745
if (!found)
3746
conto.Add (n1, n2);
3747
}
3748
}
3749
mesh.connectedtonode.SetSize(np);
3750
for (i = 1; i <= np; i++)
3751
mesh.connectedtonode.Elem(i) = 0;
3752
3753
3754
// (*testout) << "connection table: " << endl;
3755
// for (i = 1; i <= np; i++)
3756
// {
3757
// (*testout) << "node " << i << ": ";
3758
// for (j = 1; j <= conto.EntrySize(i); j++)
3759
// (*testout) << conto.Get(i, j) << " ";
3760
// (*testout) << endl;
3761
// }
3762
3763
3764
for (i = 1; i <= np; i++)
3765
if (mesh.connectedtonode.Elem(i) == 0)
3766
{
3767
mesh.connectedtonode.Elem(i) = i;
3768
ConnectToNodeRec (i, i, conto, mesh.connectedtonode);
3769
}
3770
*/
3771
3772
// mesh.BuildConnectedNodes();
3773
3774
3775
3776
3777
mesh.ComputeNVertices();
3778
3779
3780
3781
// update identification tables
3782
for (i = 1; i <= mesh.GetIdentifications().GetMaxNr(); i++)
3783
{
3784
ARRAY<int,PointIndex::BASE> identmap;
3785
3786
mesh.GetIdentifications().GetMap (i, identmap);
3787
3788
3789
/*
3790
for (j = 1; j <= cutedges.GetNBags(); j++)
3791
for (k = 1; k <= cutedges.GetBagSize(j); k++)
3792
{
3793
INDEX_2 i2;
3794
int newpi;
3795
cutedges.GetData (j, k, i2, newpi);
3796
INDEX_2 oi2(identmap.Get(i2.I1()),
3797
identmap.Get(i2.I2()));
3798
oi2.Sort();
3799
if (cutedges.Used (oi2))
3800
{
3801
int onewpi = cutedges.Get(oi2);
3802
mesh.GetIdentifications().Add (newpi, onewpi, i);
3803
}
3804
}
3805
*/
3806
3807
for (j = 1; j <= cutedges.Size(); j++)
3808
if (cutedges.UsedPos(j))
3809
{
3810
INDEX_2 i2;
3811
int newpi;
3812
cutedges.GetData (j, i2, newpi);
3813
INDEX_2 oi2(identmap.Get(i2.I1()),
3814
identmap.Get(i2.I2()));
3815
oi2.Sort();
3816
if (cutedges.Used (oi2))
3817
{
3818
int onewpi = cutedges.Get(oi2);
3819
mesh.GetIdentifications().Add (newpi, onewpi, i);
3820
}
3821
}
3822
}
3823
3824
3825
3826
3827
// Repair works only for tets!
3828
bool do_repair = mesh.PureTetMesh ();
3829
3830
//if(mesh.mglevels == 3)
3831
// noprojection = true;
3832
3833
//noprojection = true;
3834
3835
if(noprojection)
3836
{
3837
do_repair = false;
3838
for(int ii=1; ii<=mesh.GetNP(); ii++)
3839
{
3840
if(isnewpoint.Test(ii) && mesh.mlbetweennodes[ii][0] > 0)
3841
{
3842
mesh.Point(ii) = Center(mesh.Point(mesh.mlbetweennodes[ii][0]),mesh.Point(mesh.mlbetweennodes[ii][1]));
3843
}
3844
}
3845
}
3846
3847
3848
// Check/Repair
3849
3850
//cout << "Hallo Welt" << endl;
3851
//getchar();
3852
3853
static bool repaired_once;
3854
if(mesh.mglevels == 1)
3855
repaired_once = false;
3856
3857
//mesh.Save("before.vol");
3858
3859
static int reptimer = NgProfiler::CreateTimer("check/repair");
3860
NgProfiler::RegionTimer * regt(NULL);
3861
regt = new NgProfiler::RegionTimer(reptimer);
3862
3863
ARRAY<ElementIndex> bad_elts;
3864
ARRAY<double> pure_badness;
3865
3866
if(do_repair || quality_loss != NULL)
3867
{
3868
pure_badness.SetSize(mesh.GetNP()+2);
3869
GetPureBadness(mesh,pure_badness,isnewpoint);
3870
}
3871
3872
3873
if(do_repair)
3874
{
3875
const double max_worsening = 1;
3876
3877
const bool uselocalworsening = false;
3878
3879
bool repaired = false;
3880
3881
Validate(mesh,bad_elts,pure_badness,max_worsening,uselocalworsening);
3882
3883
if (printmessage_importance>0)
3884
{
3885
ostringstream strstr;
3886
for(int ii=0; ii<bad_elts.Size(); ii++)
3887
strstr << "bad element " << bad_elts[ii] << "\n";
3888
PrintMessage(1,strstr.str());
3889
}
3890
if(repaired_once || bad_elts.Size() > 0)
3891
{
3892
clock_t t1(clock());
3893
3894
3895
// update id-maps
3896
j=0;
3897
for(i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++)
3898
{
3899
if(mesh.GetIdentifications().GetType(i) == Identifications::PERIODIC)
3900
{
3901
mesh.GetIdentifications().GetMap(i,*idmaps[j],true);
3902
j++;
3903
}
3904
}
3905
3906
3907
// do the repair
3908
try
3909
{
3910
RepairBisection(mesh,bad_elts,isnewpoint,*this,
3911
pure_badness,
3912
max_worsening,uselocalworsening,
3913
idmaps);
3914
repaired = true;
3915
repaired_once = true;
3916
}
3917
catch(NgException & ex)
3918
{
3919
PrintMessage(1,string("Problem: ") + ex.What());
3920
}
3921
3922
3923
if (printmessage_importance>0)
3924
{
3925
ostringstream strstr;
3926
strstr << "Time for Repair: " << double(clock() - t1)/double(CLOCKS_PER_SEC) << endl
3927
<< "bad elements after repair: " << bad_elts << endl;
3928
PrintMessage(1,strstr.str());
3929
}
3930
3931
if(quality_loss != NULL)
3932
Validate(mesh,bad_elts,pure_badness,1e100,uselocalworsening,quality_loss);
3933
3934
if(idmaps.Size() == 0)
3935
UpdateEdgeMarks(mesh,idmaps);
3936
3937
/*
3938
if(1==1)
3939
UpdateEdgeMarks(mesh,idmaps);
3940
else
3941
mesh.mglevels = 1;
3942
*/
3943
3944
//mesh.ImproveMesh();
3945
3946
}
3947
}
3948
delete regt;
3949
3950
3951
3952
3953
3954
3955
3956
for(i=0; i<idmaps.Size(); i++)
3957
delete idmaps[i];
3958
idmaps.DeleteAll();
3959
3960
mesh.UpdateTopology();
3961
3962
if(refelementinfofilewrite != "")
3963
{
3964
PrintMessage(3,"writing marked-elements information to \"",refelementinfofilewrite,"\"");
3965
ofstream ofst(refelementinfofilewrite.c_str());
3966
3967
WriteMarkedElements(ofst);
3968
3969
ofst.close();
3970
}
3971
3972
3973
PrintMessage (1, "Bisection done");
3974
3975
PopStatus();
3976
}
3977
3978
3979
3980
3981
BisectionOptions :: BisectionOptions ()
3982
{
3983
outfilename = NULL;
3984
mlfilename = NULL;
3985
refinementfilename = NULL;
3986
femcode = NULL;
3987
maxlevel = 50;
3988
usemarkedelements = 0;
3989
refine_hp = 0;
3990
refine_p = 0;
3991
}
3992
3993
3994
Refinement :: Refinement ()
3995
{
3996
optimizer2d = NULL;
3997
}
3998
3999
Refinement :: ~Refinement ()
4000
{
4001
;
4002
}
4003
4004
4005
void Refinement :: PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint,
4006
int surfi,
4007
const PointGeomInfo & gi1,
4008
const PointGeomInfo & gi2,
4009
Point<3> & newp, PointGeomInfo & newgi)
4010
{
4011
newp = p1+secpoint*(p2-p1);
4012
}
4013
4014
void Refinement :: PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint,
4015
int surfi1, int surfi2,
4016
const EdgePointGeomInfo & ap1,
4017
const EdgePointGeomInfo & ap2,
4018
Point<3> & newp, EdgePointGeomInfo & newgi)
4019
{
4020
newp = p1+secpoint*(p2-p1);
4021
}
4022
4023
4024
Vec<3> Refinement :: GetTangent (const Point<3> & p, int surfi1, int surfi2,
4025
const EdgePointGeomInfo & ap1) const
4026
{
4027
cerr << "Refinement::GetTangent not overloaded" << endl;
4028
return Vec<3> (0,0,0);
4029
}
4030
4031
Vec<3> Refinement :: GetNormal (const Point<3> & p, int surfi1,
4032
const PointGeomInfo & gi) const
4033
{
4034
cerr << "Refinement::GetNormal not overloaded" << endl;
4035
return Vec<3> (0,0,0);
4036
}
4037
4038
4039
void Refinement :: ProjectToSurface (Point<3> & p, int surfi)
4040
{
4041
if (printmessage_importance>0)
4042
cerr << "Refinement :: ProjectToSurface ERROR: no geometry set" << endl;
4043
};
4044
4045
void Refinement :: ProjectToEdge (Point<3> & p, int surfi1, int surfi2, const EdgePointGeomInfo & egi) const
4046
{
4047
cerr << "Refinement::ProjectToEdge not overloaded" << endl;
4048
}
4049
}
4050
4051