Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/interface/writetet.cpp
3206 views
1
2
#include <mystdlib.h>
3
4
#include <myadt.hpp>
5
#include <linalg.hpp>
6
#include <csg.hpp>
7
#include <acisgeom.hpp>
8
#include <meshing.hpp>
9
10
namespace netgen
11
{
12
13
#include "writeuser.hpp"
14
15
16
void WriteTETFormat (const Mesh & mesh,
17
const string & filename)//, const string& problemType )
18
{
19
string problemType = "";
20
if(!mesh.PureTetMesh())
21
throw NgException("Can only export pure tet mesh in this format");
22
23
cout << "starting .tet export to file " << filename << endl;
24
25
26
ARRAY<int> point_ids,edge_ids,face_ids;
27
ARRAY<int> elnum(mesh.GetNE());
28
elnum = -1;
29
30
31
ARRAY<int> userdata_int;
32
ARRAY<double> userdata_double;
33
ARRAY<int> ports;
34
35
ARRAY<int> uid_to_group_3D, uid_to_group_2D, uid_to_group_1D, uid_to_group_0D;
36
37
int pos_int = 0;
38
int pos_double = 0;
39
40
bool haveuserdata =
41
(mesh.GetUserData("TETmesh:double",userdata_double) &&
42
mesh.GetUserData("TETmesh:int",userdata_int) &&
43
mesh.GetUserData("TETmesh:ports",ports) &&
44
mesh.GetUserData("TETmesh:point_id",point_ids,PointIndex::BASE) &&
45
mesh.GetUserData("TETmesh:uid_to_group_3D",uid_to_group_3D) &&
46
mesh.GetUserData("TETmesh:uid_to_group_2D",uid_to_group_2D) &&
47
mesh.GetUserData("TETmesh:uid_to_group_1D",uid_to_group_1D) &&
48
mesh.GetUserData("TETmesh:uid_to_group_0D",uid_to_group_0D));
49
50
51
int version,subversion;
52
53
if(haveuserdata)
54
{
55
version = int(userdata_double[0]);
56
subversion = int(10*(userdata_double[0] - version));
57
pos_double++;
58
}
59
else
60
{
61
version = 2;
62
subversion = 0;
63
}
64
65
66
if(version >= 2)
67
{
68
// test if ids are disjunct, if not version 2.0 not possible
69
int maxbc(-1),mindomain(-1);
70
71
for(ElementIndex i=0; i<mesh.GetNE(); i++)
72
if(i==0 || mesh[i].GetIndex() < mindomain)
73
mindomain = mesh[i].GetIndex();
74
for(int i=1; i<=mesh.GetNFD(); i++)
75
if(i==1 || mesh.GetFaceDescriptor(i).BCProperty() > maxbc)
76
maxbc = mesh.GetFaceDescriptor(i).BCProperty();
77
78
if(maxbc >= mindomain)
79
{
80
cout << "WARNING: writing version " << version << "." << subversion << " tetfile not possible, ";
81
version = 1; subversion = 1;
82
cout << "using version " << version << "." << subversion << endl;
83
}
84
}
85
86
87
88
int startsize = point_ids.Size();
89
point_ids.SetSize(mesh.GetNP()+1);
90
for(int i=startsize; i<point_ids.Size(); i++)
91
point_ids[i] = -1;
92
93
94
for(int i=0; i<PointIndex::BASE; i++)
95
point_ids[i] = -1;
96
97
98
INDEX_2_CLOSED_HASHTABLE<int> edgenumbers(6*mesh.GetNE()+3*mesh.GetNSE());;
99
INDEX_3_CLOSED_HASHTABLE<int> facenumbers(4*mesh.GetNE()+mesh.GetNSE());
100
101
ARRAY<INDEX_2> edge2node;
102
ARRAY<INDEX_3> face2edge;
103
ARRAY<INDEX_4> element2face;
104
105
int numelems(0),numfaces(0),numedges(0),numnodes(0);
106
107
for(SegmentIndex si = 0; si < mesh.GetNSeg(); si++)
108
{
109
const Segment & seg = mesh[si];
110
INDEX_2 i2(seg.p1,seg.p2);
111
i2.Sort();
112
if(edgenumbers.Used(i2))
113
continue;
114
115
numedges++;
116
edgenumbers.Set(i2,numedges);
117
edge2node.Append(i2);
118
119
edge_ids.Append(seg.edgenr);
120
121
if(point_ids[seg.p1] == -1)
122
point_ids[seg.p1] = (version >= 2) ? seg.edgenr : 0;
123
if(point_ids[seg.p2] == -1)
124
point_ids[seg.p2] = (version >= 2) ? seg.edgenr : 0;
125
}
126
127
for(SurfaceElementIndex si = 0; si < mesh.GetNSE(); si++)
128
{
129
if(mesh[si].IsDeleted())
130
continue;
131
132
const Element2d & elem = mesh[si];
133
134
numfaces++;
135
INDEX_3 i3(elem[0], elem[1], elem[2]);
136
137
int min = i3[0];
138
int minpos = 0;
139
for(int j=1; j<3; j++)
140
if(i3[j] < min)
141
{
142
min = i3[j]; minpos = j;
143
}
144
if(minpos == 1)
145
{
146
int aux = i3[0]; i3[0] = i3[1]; i3[1] = i3[2]; i3[2] = aux;
147
}
148
else if(minpos == 2)
149
{
150
int aux = i3[0]; i3[0] = i3[2]; i3[2] = i3[1]; i3[1] = aux;
151
}
152
facenumbers.Set(i3,numfaces);
153
154
int bc = mesh.GetFaceDescriptor(elem.GetIndex()).BCProperty();
155
face_ids.Append(bc);
156
157
for(int j=0; j<3; j++)
158
if(point_ids[elem[j]] == -1)
159
point_ids[elem[j]] = (version >= 2) ? bc : 0;
160
161
INDEX_2 i2a,i2b;
162
INDEX_3 f_to_n;
163
for(int j=0; j<3; j++)
164
{
165
i2a = INDEX_2(i3[j],i3[(j+1)%3]);
166
i2b[0] = i2a[1]; i2b[1] = i2a[0];
167
if(edgenumbers.Used(i2a))
168
f_to_n[j] = edgenumbers.Get(i2a);
169
else if(edgenumbers.Used(i2b))
170
f_to_n[j] = -edgenumbers.Get(i2b);
171
else
172
{
173
numedges++;
174
edgenumbers.Set(i2a,numedges);
175
edge2node.Append(i2a);
176
f_to_n[j] = numedges;
177
if(version >= 2)
178
edge_ids.Append(bc);
179
else
180
edge_ids.Append(0);
181
}
182
}
183
face2edge.Append(f_to_n);
184
}
185
186
for(ElementIndex ei = 0; ei < mesh.GetNE(); ei++)
187
{
188
const Element & el = mesh[ei];
189
190
if(el.IsDeleted())
191
continue;
192
193
numelems++;
194
elnum[ei] = numelems;
195
196
static int tetfaces[4][3] =
197
{ { 0, 2, 1 },
198
{ 0, 1, 3 },
199
{ 1, 2, 3 },
200
{ 2, 0, 3 } };
201
202
for(int j=0; j<4; j++)
203
if(point_ids[el[j]] == -1)
204
point_ids[el[j]] = (version >= 2) ? el.GetIndex() : 0;
205
206
INDEX_4 e_to_f;
207
208
for(int i = 0; i < 4; i++)
209
{
210
INDEX_3 i3a(el[tetfaces[i][0]],el[tetfaces[i][1]],el[tetfaces[i][2]]);
211
212
int min = i3a[0];
213
int minpos = 0;
214
for(int j=1; j<3; j++)
215
if(i3a[j] < min)
216
{
217
min = i3a[j]; minpos = j;
218
}
219
if(minpos == 1)
220
{
221
int aux = i3a[0]; i3a[0] = i3a[1]; i3a[1] = i3a[2]; i3a[2] = aux;
222
}
223
else if(minpos == 2)
224
{
225
int aux = i3a[0]; i3a[0] = i3a[2]; i3a[2] = i3a[1]; i3a[1] = aux;
226
}
227
INDEX_3 i3b(i3a[0],i3a[2],i3a[1]);
228
229
230
if(facenumbers.Used(i3a))
231
e_to_f[i] = facenumbers.Get(i3a);
232
else if(facenumbers.Used(i3b))
233
e_to_f[i] = -facenumbers.Get(i3b);
234
else
235
{
236
numfaces++;
237
facenumbers.Set(i3a,numfaces);
238
e_to_f[i] = numfaces;
239
if(version >= 2)
240
face_ids.Append(el.GetIndex());
241
else
242
face_ids.Append(0);
243
244
INDEX_2 i2a,i2b;
245
INDEX_3 f_to_n;
246
for(int j=0; j<3; j++)
247
{
248
i2a = INDEX_2(i3a[j],i3a[(j+1)%3]);
249
i2b[0] = i2a[1]; i2b[1] = i2a[0];
250
if(edgenumbers.Used(i2a))
251
f_to_n[j] = edgenumbers.Get(i2a);
252
else if(edgenumbers.Used(i2b))
253
f_to_n[j] = -edgenumbers.Get(i2b);
254
else
255
{
256
numedges++;
257
edgenumbers.Set(i2a,numedges);
258
edge2node.Append(i2a);
259
f_to_n[j] = numedges;
260
if(version >= 2)
261
edge_ids.Append(el.GetIndex());
262
else
263
edge_ids.Append(0);
264
}
265
}
266
face2edge.Append(f_to_n);
267
}
268
}
269
element2face.Append(e_to_f);
270
}
271
272
273
274
275
ofstream outfile(filename.c_str());
276
277
outfile.precision(16);
278
279
int unitcode;
280
double tolerance;
281
double dS1,dS2, alphaDeg;
282
double x3D,y3D,z3D;
283
int modelverts(0), modeledges(0), modelfaces(0), modelcells(0);
284
285
int numObj0D,numObj1D,numObj2D,numObj3D;
286
int numports = ports.Size();
287
288
ARRAY<int> nodenum(point_ids.Size()+1);
289
290
nodenum = -1;
291
292
293
294
numnodes = 0;
295
for(int i=0; i<point_ids.Size(); i++)
296
{
297
if(point_ids[i] != -1)
298
{
299
numnodes++;
300
nodenum[i] = numnodes;
301
}
302
}
303
304
305
if(haveuserdata)
306
{
307
unitcode = userdata_int[pos_int];
308
pos_int++;
309
310
tolerance = userdata_double[pos_double];
311
pos_double++;
312
313
dS1 = userdata_double[pos_double];
314
pos_double++;
315
dS2 = userdata_double[pos_double];
316
pos_double++;
317
alphaDeg = userdata_double[pos_double];
318
pos_double++;
319
320
x3D = userdata_double[pos_double];
321
pos_double++;
322
y3D = userdata_double[pos_double];
323
pos_double++;
324
z3D = userdata_double[pos_double];
325
pos_double++;
326
327
if(version == 2)
328
{
329
modelverts = userdata_int[pos_int];
330
pos_int++;
331
modeledges = userdata_int[pos_int];
332
pos_int++;
333
modelfaces = userdata_int[pos_int];
334
pos_int++;
335
modelcells = userdata_int[pos_int];
336
pos_int++;
337
}
338
339
numObj3D = userdata_int[pos_int];
340
pos_int++;
341
numObj2D = userdata_int[pos_int];
342
pos_int++;
343
numObj1D = userdata_int[pos_int];
344
pos_int++;
345
numObj0D = userdata_int[pos_int];
346
pos_int++;
347
}
348
else
349
{
350
unitcode = 3;
351
352
tolerance = 1e-5;
353
354
dS1 = dS2 = alphaDeg = 0;
355
356
x3D = y3D = z3D = 0;
357
358
modelverts = modeledges = modelfaces = modelcells = 0;
359
360
numObj3D = numObj2D = numObj1D = numObj0D = 0;
361
}
362
363
string uidpid;
364
if(version == 1)
365
uidpid = "PID";
366
else if (version == 2)
367
uidpid = "UID";
368
369
370
ARRAY< ARRAY<int,PointIndex::BASE>* > idmaps;
371
for(int i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++)
372
{
373
if(mesh.GetIdentifications().GetType(i) == Identifications::PERIODIC)
374
{
375
idmaps.Append(new ARRAY<int,PointIndex::BASE>);
376
mesh.GetIdentifications().GetMap(i,*idmaps.Last(),true);
377
}
378
}
379
380
ARRAY<int> id_num,id_type;
381
ARRAY< ARRAY<int> *> id_groups;
382
383
384
// sst 2008-03-12: Write problem class...
385
{
386
std::string block;
387
block = "// CST Tetrahedral ";
388
block += !problemType.empty() ? problemType : "High Frequency";
389
block += " Mesh, Version no.:\n";
390
391
size_t size = block.size()-3;
392
block += "// ";
393
block.append( size, '^' );
394
block += "\n";
395
396
outfile
397
<< block
398
<< version << "." << subversion << "\n\n";
399
}
400
401
outfile
402
<< "// User Units Code (1=CM 2=MM 3=M 4=MIC 5=NM 6=FT 7=IN 8=MIL):\n" \
403
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \
404
<< unitcode << "\n\n" \
405
<< "// Geometric coord \"zero\" tolerance threshold:\n" \
406
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \
407
<< tolerance << "\n\n" \
408
<< "// Periodic UnitCell dS1 , dS2 , alphaDeg:\n" \
409
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \
410
<< dS1 << " " << dS2 << " " << alphaDeg <<"\n\n" \
411
<< "// Periodic UnitCell origin in global coords (x3D,y3D,z3D):\n" \
412
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \
413
<< x3D << " " << y3D << " " << z3D << "\n" << endl;
414
415
if(version == 2)
416
{
417
outfile << "// Model entity count: Vertices, Edges, Faces, Cells:\n" \
418
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \
419
<< modelverts << " " << modeledges << " " << modelfaces << " " << modelcells << endl << endl;
420
}
421
422
423
outfile << "// Topological mesh-entity counts (#elements,#faces,#edges,#nodes):\n" \
424
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
425
outfile << numelems << " "
426
<< numfaces << " "
427
<< numedges << " "
428
<< numnodes << endl << endl;
429
430
outfile << "// NodeID, X, Y, Z, Type (0=Reg 1=PMaster 2=PSlave 3=CPMaster 4=CPSlave), "<< uidpid <<":\n" \
431
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
432
433
434
435
id_num.SetSize(mesh.GetNP()+1);
436
id_type.SetSize(mesh.GetNP()+1);
437
id_num = 0;
438
id_type = 0;
439
440
int n2,n4,n8;
441
n2 = n4 = n8 = 0;
442
443
444
for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
445
{
446
if(id_num[i] != 0)
447
continue;
448
449
if(nodenum[i] == -1)
450
continue;
451
452
ARRAY<int> group;
453
group.Append(i);
454
for(int j=0; j<idmaps.Size(); j++)
455
{
456
startsize = group.Size();
457
for(int k=0; k<startsize; k++)
458
{
459
int id = (*idmaps[j])[group[k]];
460
if(id != 0 && !group.Contains(id) && nodenum[id] != -1)
461
{
462
group.Append(id);
463
id_num[id] = j+1+id_num[group[k]];
464
}
465
}
466
}
467
if(group.Size() > 1)
468
{
469
id_groups.Append(new ARRAY<int>(group));
470
if(group.Size() == 2)
471
{
472
id_type[i] = 1;
473
id_type[group[1]] = 2;
474
n2++;
475
}
476
else if(group.Size() == 4)
477
{
478
id_type[i] = 3;
479
for(int j=1; j<group.Size(); j++)
480
id_type[group[j]] = 4;
481
n4++;
482
}
483
else if(group.Size() == 8)
484
{
485
id_type[i] = 5;
486
for(int j=1; j<group.Size(); j++)
487
id_type[group[j]] = 6;
488
n8++;
489
}
490
else
491
cerr << "ERROR: Identification group size = " << group.Size() << endl;
492
}
493
494
}
495
496
497
for(PointIndex i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
498
{
499
if(nodenum[i] == -1)
500
continue;
501
outfile << nodenum[i] << " "
502
<< mesh[i](0) << " "
503
<< mesh[i](1) << " "
504
<< mesh[i](2) << " " << id_type[i] << " ";
505
if(i-PointIndex::BASE < point_ids.Size())
506
outfile << point_ids[i];
507
else
508
outfile << "0";
509
outfile << "\n";
510
}
511
outfile << endl;
512
513
outfile << "\n// Number of Periodic Master Nodes:\n" \
514
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \
515
<< n2 << "\n" \
516
<< "\n" \
517
<< "// MasterNodeID, SlaveNodeID, TranslCode (1=dS1 2=dS2 3=dS1+dS2):\n" \
518
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
519
for(int i=0; i<id_groups.Size(); i++)
520
{
521
if(id_groups[i]->Size() != 2)
522
continue;
523
524
for(int j=0; j<id_groups[i]->Size(); j++)
525
outfile << nodenum[(*id_groups[i])[j]] << " ";
526
for(int j=1; j<id_groups[i]->Size(); j++)
527
outfile << id_num[(*id_groups[i])[j]] << " ";
528
outfile << "\n";
529
530
delete id_groups[i];
531
id_groups[i] = NULL;
532
}
533
outfile << endl;
534
535
536
outfile << "// Number of Corner Periodic Master Nodes:\n" \
537
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \
538
<< n4 << "\n" \
539
<< "\n" \
540
<< "// MasterNodeID, 3-SlaveNodeID's, 3-TranslCodes (1=dS1 2=dS2 3=dS1+dS2):\n" \
541
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
542
543
544
for(int i=0; i<id_groups.Size(); i++)
545
{
546
if(!id_groups[i] || id_groups[i]->Size() != 4)
547
continue;
548
549
for(int j=0; j<id_groups[i]->Size(); j++)
550
outfile << nodenum[(*id_groups[i])[j]] << " ";
551
for(int j=1; j<id_groups[i]->Size(); j++)
552
{
553
outfile << id_num[(*id_groups[i])[j]] << " ";
554
}
555
outfile << "\n";
556
557
delete id_groups[i];
558
id_groups[i] = NULL;
559
}
560
outfile << endl;
561
562
563
outfile << "// Number of Cubic Periodic Master Nodes:\n" \
564
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \
565
<< n8 << "\n" \
566
<< "\n" \
567
<< "// MasterNodeID, 7-SlaveNodeID's, TranslCodes:\n" \
568
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
569
for(int i=0; i<id_groups.Size(); i++)
570
{
571
if(!id_groups[i] || id_groups[i]->Size() != 8)
572
continue;
573
574
for(int j=0; j<id_groups[i]->Size(); j++)
575
outfile << nodenum[(*id_groups[i])[j]] << " ";
576
for(int j=1; j<id_groups[i]->Size(); j++)
577
outfile << id_num[(*id_groups[i])[j]] << " ";
578
outfile << "\n";
579
580
delete id_groups[i];
581
id_groups[i] = NULL;
582
}
583
outfile << endl;
584
585
586
587
588
outfile << "// EdgeID, NodeID0, NodeID1, Type (0=Reg 1=PMaster 2=PSlave 3=CPMaster 4=CPSlave), "<<uidpid<<":\n" \
589
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
590
591
592
593
ARRAY< ARRAY<int>* > vertex_to_edge(mesh.GetNP()+1);
594
for(int i=0; i<=mesh.GetNP(); i++)
595
vertex_to_edge[i] = new ARRAY<int>;
596
597
ARRAY< ARRAY<int,PointIndex::BASE>* > idmaps_edge(idmaps.Size());
598
for(int i=0; i<idmaps_edge.Size(); i++)
599
{
600
idmaps_edge[i] = new ARRAY<int,PointIndex::BASE>(numedges);
601
(*idmaps_edge[i]) = 0;
602
}
603
604
ARRAY<int> possible;
605
for(int i=0; i<edge2node.Size(); i++)
606
{
607
const INDEX_2 & v = edge2node[i];
608
for(int j=0; j<idmaps.Size(); j++)
609
{
610
INDEX_2 vid((*idmaps[j])[v[0]], (*idmaps[j])[v[1]]);
611
if(vid[0] != 0 && vid[0] != v[0] && vid[1] != 0 && vid[1] != v[1])
612
{
613
Intersection(*vertex_to_edge[vid[0]],*vertex_to_edge[vid[1]],possible);
614
if(possible.Size() == 1)
615
{
616
(*idmaps_edge[j])[possible[0]] = i+1;
617
(*idmaps_edge[j])[i+1] = possible[0];
618
}
619
else if(possible.Size() > 0)
620
{
621
cerr << "ERROR: too many possible edge identifications" << endl;
622
(*testout) << "ERROR: too many possible edge identifications" << endl
623
<< "*vertex_to_edge["<<vid[0]<<"] " << *vertex_to_edge[vid[0]] << endl
624
<< "*vertex_to_edge["<<vid[1]<<"] " << *vertex_to_edge[vid[1]] << endl
625
<< "possible " << possible << endl;
626
}
627
}
628
}
629
vertex_to_edge[v[0]]->Append(i+1);
630
vertex_to_edge[v[1]]->Append(i+1);
631
}
632
633
634
for(int i=0; i<vertex_to_edge.Size(); i++)
635
delete vertex_to_edge[i];
636
637
638
id_groups.SetSize(0);
639
id_num.SetSize(numedges+1);
640
id_num = 0;
641
id_type.SetSize(numedges+1);
642
id_type = 0;
643
644
n2 = n4 = n8 = 0;
645
646
for(int i=1; i<=edge2node.Size(); i++)
647
{
648
if(id_num[i] != 0)
649
continue;
650
651
652
ARRAY<int> group;
653
group.Append(i);
654
for(int j=0; j<idmaps_edge.Size(); j++)
655
{
656
startsize = group.Size();
657
for(int k=0; k<startsize; k++)
658
{
659
int id = (*idmaps_edge[j])[group[k]];
660
if(id != 0 && !group.Contains(id))
661
{
662
group.Append(id);
663
id_num[id] = j+1+id_num[group[k]];
664
}
665
}
666
}
667
if(group.Size() > 1)
668
{
669
id_num[i] = 1;
670
id_groups.Append(new ARRAY<int>(group));
671
if(group.Size() == 2)
672
{
673
id_type[i] = 1;
674
id_type[group[1]] = 2;
675
n2++;
676
}
677
else if(group.Size() == 4)
678
{
679
id_type[i] = 3;
680
for(int j=1; j<group.Size(); j++)
681
id_type[group[j]] = 4;
682
n4++;
683
}
684
else
685
{
686
cerr << "ERROR: edge identification group size = " << group.Size() << endl;
687
(*testout) << "edge group " << group << endl;
688
for(int j=0; j<idmaps_edge.Size(); j++)
689
{
690
(*testout) << "edge id map " << j << endl << *idmaps_edge[j] << endl;
691
}
692
}
693
}
694
}
695
696
697
698
for(int i=1; i<=edge2node.Size(); i++)
699
{
700
if(id_num[i] != 0)
701
continue;
702
703
704
ARRAY<int> group;
705
group.Append(i);
706
for(int j=0; j<idmaps_edge.Size(); j++)
707
{
708
startsize = group.Size();
709
for(int k=0; k<startsize; k++)
710
{
711
int id = (*idmaps_edge[j])[group[k]];
712
if(id != 0 && !group.Contains(id))
713
{
714
group.Append(id);
715
id_num[id] = j+1+id_num[group[k]];
716
}
717
}
718
}
719
if(group.Size() > 1)
720
{
721
id_num[i] = 1;
722
id_groups.Append(new ARRAY<int>(group));
723
if(group.Size() == 2)
724
{
725
id_type[i] = 1;
726
id_type[group[1]] = 2;
727
n2++;
728
}
729
else if(group.Size() == 4)
730
{
731
id_type[i] = 3;
732
for(int j=1; j<group.Size(); j++)
733
id_type[group[j]] = 4;
734
n4++;
735
}
736
else
737
{
738
cerr << "ERROR: edge identification group size = " << group.Size() << endl;
739
(*testout) << "edge group " << group << endl;
740
for(int j=0; j<idmaps_edge.Size(); j++)
741
{
742
(*testout) << "edge id map " << j << endl << *idmaps_edge[j] << endl;
743
}
744
}
745
}
746
747
}
748
749
750
for(int i=0; i<edge2node.Size(); i++)
751
outfile << i+1 << " " << nodenum[edge2node[i][0]] << " " << nodenum[edge2node[i][1]]
752
<< " " << id_type[i+1] << " " << edge_ids[i] << "\n";
753
754
outfile << endl;
755
756
757
758
outfile << "// Number of Periodic Master Edges:\n"\
759
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"\
760
<< n2 << "\n" \
761
<< "\n"\
762
<< "// MasterEdgeID, SlaveEdgeID, TranslCode (1=dS1 2=dS2 3=dS1+dS2):\n"\
763
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
764
for(int i=0; i<id_groups.Size(); i++)
765
{
766
if(id_groups[i]->Size() != 2)
767
continue;
768
769
for(int j=0; j<id_groups[i]->Size(); j++)
770
outfile << (*id_groups[i])[j] << " ";
771
for(int j=1; j<id_groups[i]->Size(); j++)
772
outfile << id_num[(*id_groups[i])[j]] << " ";
773
outfile << "\n";
774
775
delete id_groups[i];
776
id_groups[i] = NULL;
777
}
778
outfile << endl;
779
780
outfile << "// Number of Corner Periodic Master Edges:\n" \
781
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"\
782
<< n4 << "\n" \
783
<< "\n"\
784
<< "// MasterEdgeID, 3 SlaveEdgeID's, 3 TranslCode (1=dS1 2=dS2 3=dS1+dS2):\n"\
785
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
786
for(int i=0; i<id_groups.Size(); i++)
787
{
788
if(!id_groups[i] || id_groups[i]->Size() != 4)
789
continue;
790
791
for(int j=0; j<id_groups[i]->Size(); j++)
792
outfile << (*id_groups[i])[j] << " ";
793
for(int j=1; j<id_groups[i]->Size(); j++)
794
outfile << id_num[(*id_groups[i])[j]] << " ";
795
outfile << "\n";
796
797
delete id_groups[i];
798
id_groups[i] = NULL;
799
}
800
outfile << endl;
801
802
803
outfile << "// FaceID, EdgeID0, EdgeID1, EdgeID2, FaceType (0=Reg 1=PMaster 2=PSlave), "<<uidpid<<":\n" \
804
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
805
806
807
808
ARRAY< ARRAY<int>* > edge_to_face(numedges+1);
809
for(int i=0; i<edge_to_face.Size(); i++)
810
edge_to_face[i] = new ARRAY<int>;
811
812
813
for(int i=0; i<idmaps.Size(); i++)
814
{
815
idmaps[i]->SetSize(numfaces);
816
(*idmaps[i]) = 0;
817
}
818
819
820
for(int i=0; i<face2edge.Size(); i++)
821
{
822
for(int j=0; j<idmaps_edge.Size(); j++)
823
{
824
int e1id,e2id,e3id;
825
e1id = (*idmaps_edge[j])[abs(face2edge[i][0])];
826
e2id = (*idmaps_edge[j])[abs(face2edge[i][1])];
827
e3id = (*idmaps_edge[j])[abs(face2edge[i][2])];
828
if(e1id != 0 && e1id != abs(face2edge[i][0]) &&
829
e2id != 0 && e2id != abs(face2edge[i][1]) &&
830
e3id != 0 && e3id != abs(face2edge[i][2]))
831
{
832
Intersection(*edge_to_face[e1id],*edge_to_face[e2id],*edge_to_face[e3id],possible);
833
if(possible.Size() == 1)
834
{
835
(*idmaps[j])[possible[0]] = i+1;
836
(*idmaps[j])[i+1] = possible[0];
837
}
838
else if(possible.Size() > 0)
839
cerr << "ERROR: too many possible face identifications" << endl;
840
}
841
}
842
843
edge_to_face[abs(face2edge[i][0])]->Append(i+1);
844
edge_to_face[abs(face2edge[i][1])]->Append(i+1);
845
edge_to_face[abs(face2edge[i][2])]->Append(i+1);
846
}
847
848
for(int i=0; i<edge_to_face.Size(); i++)
849
delete edge_to_face[i];
850
851
852
for(int i=0; i<idmaps_edge.Size(); i++)
853
delete idmaps_edge[i];
854
855
856
id_groups.SetSize(0);
857
id_num.SetSize(numfaces+1);
858
id_num = 0;
859
860
n2 = n4 = n8 = 0;
861
862
for(int i=1; i<=numfaces; i++)
863
{
864
if(id_num[i] != 0)
865
continue;
866
867
ARRAY<int> group;
868
group.Append(i);
869
for(int j=0; j<idmaps.Size(); j++)
870
{
871
startsize = group.Size();
872
for(int k=0; k<startsize; k++)
873
{
874
int id = (*idmaps[j])[group[k]];
875
if(id != 0 && !group.Contains(id))
876
{
877
group.Append(id);
878
id_num[id] = j+1+id_num[group[k]];
879
}
880
}
881
}
882
if(group.Size() > 1)
883
{
884
id_num[i] = -1;
885
id_groups.Append(new ARRAY<int>(group));
886
if(group.Size() == 2)
887
n2++;
888
else
889
cerr << "ERROR: face identification group size = " << group.Size() << endl;
890
}
891
892
}
893
894
895
for(int i=0; i<idmaps.Size(); i++)
896
delete idmaps[i];
897
898
899
900
901
for(int i=0; i<face2edge.Size(); i++)
902
{
903
outfile << i+1 << " ";
904
for(int j=0; j<3; j++)
905
outfile << face2edge[i][j] << " ";
906
907
if(id_num[i+1] == 0)
908
outfile << 0;
909
else if(id_num[i+1] == -1)
910
outfile << 1;
911
else
912
outfile << 2;
913
914
outfile << " " << face_ids[i] <<"\n";
915
}
916
outfile << endl;
917
918
919
outfile << "// Number of Periodic Master Faces:\n"\
920
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"\
921
<< n2 << "\n" \
922
<< "\n"\
923
<< "// MasterFaceID, SlaveFaceID, TranslCode (1=dS1 2=dS2):\n"\
924
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
925
for(int i=0; i<id_groups.Size(); i++)
926
{
927
if(id_groups[i]->Size() != 2)
928
continue;
929
930
for(int j=0; j<id_groups[i]->Size(); j++)
931
outfile << (*id_groups[i])[j] << " ";
932
for(int j=1; j<id_groups[i]->Size(); j++)
933
outfile << id_num[(*id_groups[i])[j]] << " ";
934
outfile << "\n";
935
936
delete id_groups[i];
937
}
938
outfile << endl;
939
940
941
942
943
outfile << "// ElemID, FaceID0, FaceID1, FaceID2, FaceID3, "<<uidpid<<":\n" \
944
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
945
946
for(ElementIndex i=0; i<mesh.GetNE(); i++)
947
{
948
if(elnum[i] >= 0)
949
{
950
outfile << elnum[i] << " ";
951
for(int j=0; j<4; j++)
952
outfile << element2face[elnum[i]-1][j] << " ";
953
954
outfile << mesh[i].GetIndex() << "\n";
955
}
956
}
957
outfile << endl;
958
959
outfile << "// ElemID, NodeID0, NodeID1, NodeID2, NodeID3:\n" \
960
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
961
962
963
for(ElementIndex i=0; i<mesh.GetNE(); i++)
964
{
965
if(elnum[i] >= 0)
966
outfile << elnum[i] << " "
967
<< nodenum[mesh[i][1]] << " " << nodenum[mesh[i][0]] << " " << nodenum[mesh[i][2]] << " " << nodenum[mesh[i][3]] << "\n";
968
}
969
outfile << endl;
970
971
972
973
974
outfile << "// Physical Object counts (#Obj3D,#Obj2D,#Obj1D,#Obj0D):\n"
975
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
976
<< " "<< numObj3D << " " << numObj2D << " " << numObj1D << " " << numObj0D << "\n" \
977
<< "\n" \
978
<< "// Number of Ports (Ports are a subset of Object2D list):\n" \
979
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \
980
<< numports << "\n" \
981
<< endl;
982
983
984
ARRAY< ARRAY<int> * > groups;
985
986
int maxg = -1;
987
for(int i = 0; i<uid_to_group_3D.Size(); i++)
988
if(uid_to_group_3D[i] > maxg)
989
maxg = uid_to_group_3D[i];
990
for(int i = 0; i<uid_to_group_2D.Size(); i++)
991
if(uid_to_group_2D[i] > maxg)
992
maxg = uid_to_group_2D[i];
993
for(int i = 0; i<uid_to_group_1D.Size(); i++)
994
if(uid_to_group_1D[i] > maxg)
995
maxg = uid_to_group_1D[i];
996
for(int i = 0; i<uid_to_group_0D.Size(); i++)
997
if(uid_to_group_0D[i] > maxg)
998
maxg = uid_to_group_0D[i];
999
1000
groups.SetSize(maxg+1);
1001
for(int i=0; i<groups.Size(); i++)
1002
groups[i] = new ARRAY<int>;
1003
1004
for(ElementIndex i=0; i<mesh.GetNE(); i++)
1005
if(uid_to_group_3D[mesh[i].GetIndex()] >= 0)
1006
groups[uid_to_group_3D[mesh[i].GetIndex()]]->Append(i+1);
1007
1008
1009
1010
1011
outfile << "// Object3D GroupID, #Elems <immediately followed by> ElemID List:\n" \
1012
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
1013
for(int i=0; i<numObj3D; i++)
1014
{
1015
outfile << i << " " << groups[i]->Size() << "\n";
1016
for(int j=0; j<groups[i]->Size(); j++)
1017
outfile << (*groups[i])[j] << "\n";
1018
}
1019
1020
for(int i=0; i<groups.Size(); i++)
1021
groups[i]->SetSize(0);
1022
1023
for(int i=0; i<face_ids.Size(); i++)
1024
if(uid_to_group_2D[face_ids[i]] >= 0)
1025
groups[uid_to_group_2D[face_ids[i]]]->Append(i+1);
1026
1027
1028
outfile << "// Object2D GroupID, #Faces <immediately followed by> FaceID List:\n" \
1029
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
1030
for(int i=0; i<numObj2D; i++)
1031
{
1032
outfile << i << " " << groups[i]->Size() << "\n";
1033
for(int j=0; j<groups[i]->Size(); j++)
1034
{
1035
outfile << (*groups[i])[j];
1036
if(ports.Contains(face_ids[(*groups[i])[j]-1]))
1037
outfile << " P";
1038
outfile << "\n";
1039
}
1040
}
1041
outfile << endl;
1042
1043
1044
for(int i=0; i<groups.Size(); i++)
1045
groups[i]->SetSize(0);
1046
1047
for(int i=0; i<edge_ids.Size(); i++)
1048
if(uid_to_group_1D[edge_ids[i]] >= 0)
1049
groups[uid_to_group_1D[edge_ids[i]]]->Append(i+1);
1050
1051
1052
1053
outfile << "// Object1D GroupID, #Edges <immediately followed by> EdgeID List:\n" \
1054
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
1055
for(int i=0; i<numObj1D; i++)
1056
{
1057
outfile << i << " " << groups[i]->Size() << "\n";
1058
for(int j=0; j<groups[i]->Size(); j++)
1059
outfile << (*groups[i])[j] << "\n";
1060
}
1061
outfile << endl;
1062
1063
1064
for(int i=0; i<groups.Size(); i++)
1065
groups[i]->SetSize(0);
1066
for(PointIndex i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
1067
{
1068
if(i-PointIndex::BASE < point_ids.Size())
1069
{
1070
if(uid_to_group_0D[point_ids[i]] >= 0)
1071
groups[uid_to_group_0D[point_ids[i]]]->Append(i+1-PointIndex::BASE);
1072
}
1073
else
1074
groups[uid_to_group_0D[0]]->Append(i+1-PointIndex::BASE);
1075
}
1076
1077
1078
outfile << "// Object0D GroupID, #Nodes <immediately followed by> NodeID List:\n" \
1079
<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
1080
for(int i=0; i<numObj0D; i++)
1081
{
1082
outfile << i << " " << groups[i]->Size() << "\n";
1083
for(int j=0; j<groups[i]->Size(); j++)
1084
outfile << (*groups[i])[j] << "\n";
1085
}
1086
outfile << endl;
1087
1088
for(int i=0; i<groups.Size(); i++)
1089
delete groups[i];
1090
1091
1092
outfile.close();
1093
1094
cout << ".tet export done" << endl;
1095
}
1096
}
1097
1098