Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/interface/writejcm.cpp
3206 views
1
//
2
// Write JCMwave file
3
// 07.07.2005, Sven Burger, ZIB Berlin
4
//
5
6
7
#include <mystdlib.h>
8
#include <myadt.hpp>
9
#include <linalg.hpp>
10
#include <csg.hpp>
11
#include <meshing.hpp>
12
#include <sys/stat.h>
13
14
namespace netgen
15
{
16
#include "writeuser.hpp"
17
18
void WriteJCMFormat (const Mesh & mesh,
19
const CSGeometry & geom,
20
const string & filename)
21
{
22
if (mesh.GetDimension() != 3)
23
{
24
cout <<"\n Error: Dimension 3 only supported by this output format!"<<endl;
25
return;
26
}
27
28
int bc_at_infinity = 0;
29
int i, j, jj, ct(0), counter;
30
double dx1, dx2, dx3, dy1, dy2, dy3, dz1, dz2, dz3, vol;
31
32
// number of points
33
int np = mesh.GetNP();
34
35
// Identic points
36
ARRAY<int,1> identmap1, identmap2, identmap3;
37
mesh.GetIdentifications().GetMap(1, identmap1);
38
mesh.GetIdentifications().GetMap(2, identmap2);
39
mesh.GetIdentifications().GetMap(3, identmap3);
40
41
// number of volume elements
42
int ne = mesh.GetNE();
43
int ntets = 0;
44
int nprisms = 0;
45
for (i = 1; i <= ne; i++)
46
{
47
Element el = mesh.VolumeElement(i);
48
if (el.GetNP() == 4)
49
{
50
ntets++;
51
// Check that no two points on a tetrahedron are identified with each other
52
for (j = 1; j <= 4; j++)
53
for (jj = 1; jj <=4; jj++)
54
{
55
if (identmap1.Elem(el.PNum(j)) == el.PNum(jj))
56
{
57
cout << "\n Error: two points on a tetrahedron identified (1) with each other"
58
<< "\n REFINE MESH !" << endl;
59
return;
60
}
61
if (identmap2.Elem(el.PNum(j)) == el.PNum(jj))
62
{
63
cout << "\n Error: two points on a tetrahedron identified (2) with each other"
64
<< "\n REFINE MESH !" << endl;
65
return;
66
}
67
if (identmap3.Elem(el.PNum(j)) == el.PNum(jj))
68
{
69
cout << "\n Error: two points on a tetrahedron identified (3) with each other"
70
<< "\n REFINE MESH !" << endl;
71
return;
72
}
73
}
74
75
}
76
else if (el.GetNP() == 6)
77
nprisms++;
78
}
79
if ( ne != (ntets+nprisms))
80
{
81
cout<< "\n Error in determining number of volume elements!\n"
82
<< "\n Prisms and tetrahedra only implemented in the JCMwave format!\n"<<endl;
83
return;
84
}
85
86
if (nprisms > 0)
87
cout << " Please note: Boundaries at infinity have to carry the bc-attribute '-bc="
88
<< bc_at_infinity <<"'."<<endl;
89
90
// number of surface elements
91
int nse = mesh.GetNSE();
92
// number of boundary triangles
93
int nbtri = 0;
94
// number of boundary quadrilaterals
95
int nbquad = 0;
96
// array with 1 if point on any tetra, 0 else
97
// this is needed in order to arrange the prism points in the right order
98
ARRAY<int,1> pointsOnTetras;
99
pointsOnTetras.SetSize (mesh.GetNP());
100
pointsOnTetras = 0;
101
for (i = 1; i <= ne; i++)
102
{
103
Element el = mesh.VolumeElement(i);
104
if (el.GetNP() == 4)
105
{
106
for (j = 1; j <= 4; j++)
107
pointsOnTetras.Set(el.PNum(j).GetInt(),1);
108
}
109
}
110
111
// number of boundary triangles and boundary quadrilaterals
112
for (i = 1; i <= nse; i++)
113
{
114
Element2d el = mesh.SurfaceElement(i);
115
if (el.GetNP() == 3 &&
116
( mesh.GetFaceDescriptor (el.GetIndex()).DomainIn()==0 ||
117
mesh.GetFaceDescriptor (el.GetIndex()).DomainOut()==0 ) )
118
nbtri++;
119
else if (el.GetNP() == 4 &&
120
( mesh.GetFaceDescriptor (el.GetIndex()).DomainIn()==0 ||
121
mesh.GetFaceDescriptor (el.GetIndex()).DomainOut()==0 ) )
122
nbquad++;
123
}
124
125
ofstream outfile (filename.c_str());
126
outfile.precision(6);
127
outfile.setf (ios::fixed, ios::floatfield);
128
outfile.setf (ios::showpoint);
129
130
outfile << "/* <BLOBHead>\n";
131
outfile << "__BLOBTYPE__=Grid\n";
132
outfile << "__OWNER__=JCMwave\n";
133
outfile << "<I>SpaceDim=3\n";
134
outfile << "<I>ManifoldDim=3\n";
135
outfile << "<I>NRefinementSteps=0\n";
136
outfile << "<I>NPoints="<<np<<"\n";
137
outfile << "<I>NTetrahedra="<<ntets<<"\n";
138
outfile << "<I>NPrisms="<<nprisms<<"\n";
139
outfile << "<I>NBoundaryTriangles="<<nbtri<<"\n";
140
outfile << "<I>NBoundaryQuadrilaterals="<<nbquad<<"\n";
141
outfile << "*/\n";
142
outfile << "\n";
143
outfile << "# output from Netgen\n\n";
144
int nDomains=mesh.GetNDomains();
145
for (i=1; i<=nDomains; i++)
146
{
147
if (mesh.GetMaterial(i))
148
outfile << "#" << mesh.GetMaterial(i)
149
<< ": Material ID = "
150
<< i << "\n";
151
}
152
153
outfile << "# Points\n";
154
cout << " Please note: The unit of length in the .geo file is assumed to be 'microns'."<<endl;
155
for (i = 1; i <= np; i++)
156
{
157
const Point<3> & p = mesh.Point(i);
158
outfile << i << "\n";
159
outfile << p(0) << "e-6\n";
160
outfile << p(1) << "e-6\n";
161
outfile << p(2) << "e-6\n\n";
162
}
163
164
outfile << "\n";
165
outfile << "# Tetrahedra\n";
166
counter = 0;
167
for (i = 1; i <= ne; i++)
168
{
169
Element el = mesh.VolumeElement(i);
170
if (el.GetNP() == 4)
171
{
172
counter++;
173
dx1 = mesh.Point(el.PNum(2))(0) - mesh.Point(el.PNum(1))(0);
174
dx2 = mesh.Point(el.PNum(3))(0) - mesh.Point(el.PNum(1))(0);
175
dx3 = mesh.Point(el.PNum(4))(0) - mesh.Point(el.PNum(1))(0);
176
dy1 = mesh.Point(el.PNum(2))(1) - mesh.Point(el.PNum(1))(1);
177
dy2 = mesh.Point(el.PNum(3))(1) - mesh.Point(el.PNum(1))(1);
178
dy3 = mesh.Point(el.PNum(4))(1) - mesh.Point(el.PNum(1))(1);
179
dz1 = mesh.Point(el.PNum(2))(2) - mesh.Point(el.PNum(1))(2);
180
dz2 = mesh.Point(el.PNum(3))(2) - mesh.Point(el.PNum(1))(2);
181
dz3 = mesh.Point(el.PNum(4))(2) - mesh.Point(el.PNum(1))(2);
182
vol = (dy1*dz2-dz1*dy2)*dx3 + (dz1*dx2-dx1*dz2)*dy3 + (dx1*dy2-dy1*dx2)*dz3;
183
184
if ( vol > 0 )
185
for (j = 1; j <= 4; j++)
186
outfile << el.PNum(j)<<"\n";
187
else
188
{
189
for (j = 2; j >= 1; j--)
190
outfile << el.PNum(j)<<"\n";
191
for (j = 3; j <= 4; j++)
192
outfile << el.PNum(j)<<"\n";
193
}
194
outfile << el.GetIndex() << "\n\n";
195
}
196
}
197
if ( counter != ntets)
198
{
199
cout<< "\n Error in determining number of tetras!\n"<<endl;
200
return;
201
}
202
203
outfile << "\n";
204
outfile << "# Prisms\n";
205
counter = 0;
206
for (i = 1; i <= ne; i++)
207
{
208
Element el = mesh.VolumeElement(i);
209
if (el.GetNP() == 6)
210
{
211
counter++;
212
dx1 = mesh.Point(el.PNum(2))(0) - mesh.Point(el.PNum(1))(0);
213
dx2 = mesh.Point(el.PNum(3))(0) - mesh.Point(el.PNum(1))(0);
214
dx3 = mesh.Point(el.PNum(4))(0) - mesh.Point(el.PNum(1))(0);
215
dy1 = mesh.Point(el.PNum(2))(1) - mesh.Point(el.PNum(1))(1);
216
dy2 = mesh.Point(el.PNum(3))(1) - mesh.Point(el.PNum(1))(1);
217
dy3 = mesh.Point(el.PNum(4))(1) - mesh.Point(el.PNum(1))(1);
218
dz1 = mesh.Point(el.PNum(2))(2) - mesh.Point(el.PNum(1))(2);
219
dz2 = mesh.Point(el.PNum(3))(2) - mesh.Point(el.PNum(1))(2);
220
dz3 = mesh.Point(el.PNum(4))(2) - mesh.Point(el.PNum(1))(2);
221
vol = (dy1*dz2-dz1*dy2)*dx3 + (dz1*dx2-dx1*dz2)*dy3 + (dx1*dy2-dy1*dx2)*dz3;
222
223
if (pointsOnTetras.Get(el.PNum(1)) &&
224
pointsOnTetras.Get(el.PNum(2)) &&
225
pointsOnTetras.Get(el.PNum(3)))
226
{
227
if (vol > 0)
228
for (j = 1; j <= 6; j++)
229
outfile << el.PNum(j)<<"\n";
230
else
231
{
232
for (j = 3; j >= 1; j--)
233
outfile << el.PNum(j)<<"\n";
234
for (j = 6; j >= 4; j--)
235
outfile << el.PNum(j)<<"\n";
236
}
237
}
238
else if ( pointsOnTetras.Get(el.PNum(4)) &&
239
pointsOnTetras.Get(el.PNum(5)) &&
240
pointsOnTetras.Get(el.PNum(6)) )
241
{
242
if ( vol < 0 )
243
{
244
for (j = 4; j <= 6; j++)
245
outfile << el.PNum(j)<<"\n";
246
for (j = 1; j <= 3; j++)
247
outfile << el.PNum(j)<<"\n";
248
}
249
else
250
{
251
for (j = 6; j >= 4; j--)
252
outfile << el.PNum(j)<<"\n";
253
for (j = 3; j >= 1; j--)
254
outfile << el.PNum(j)<<"\n";
255
}
256
}
257
else
258
{
259
cout << "\n Error in determining prism point numbering!\n"<<endl;
260
return;
261
}
262
outfile << el.GetIndex() << "\n\n";
263
}
264
}
265
if ( counter != nprisms)
266
{
267
cout<< "\n Error in determining number of prisms!\n"<<endl;
268
return;
269
}
270
271
int npid1 = 0;
272
int npid2 = 0;
273
int npid3 = 0;
274
for (i=1; i<=np; i++)
275
{
276
if (identmap1.Elem(i))
277
npid1++;
278
if (identmap2.Elem(i))
279
npid2++;
280
if (identmap3.Elem(i))
281
npid3++;
282
}
283
284
outfile << "\n";
285
outfile << "# Boundary triangles\n";
286
outfile << "# Number of identified points in 1-direction: " << npid1 << "\n";
287
outfile << "# Number of identified points in 2-direction: " << npid2 << "\n";
288
outfile << "# Number of identified points in 3-direction: " << npid3 << "\n";
289
for (i = 1; i <= nse; i++)
290
{
291
Element2d el = mesh.SurfaceElement(i);
292
if (el.GetNP() == 3
293
&& (mesh.GetFaceDescriptor (el.GetIndex()).DomainIn()==0
294
|| mesh.GetFaceDescriptor (el.GetIndex()).DomainOut()==0))
295
{
296
outfile <<"# T\n";
297
for (j = 1; j <= 3; j++)
298
outfile << el.PNum(j)<<"\n";
299
if (mesh.GetFaceDescriptor (el.GetIndex()).BCProperty()==bc_at_infinity)
300
outfile << 1000 << "\n";
301
else
302
outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << "\n";
303
if (mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() == bc_at_infinity)
304
outfile << "-2\n\n";
305
else if (identmap1.Elem(el.PNum(1))
306
&&identmap1.Elem(el.PNum(2))
307
&&identmap1.Elem(el.PNum(3)))
308
{
309
outfile << "-1\n";
310
for (j = 1; j <= 3; j++)
311
outfile << identmap1.Elem(el.PNum(j))<<"\n";
312
outfile << "\n";
313
}
314
else if (identmap2.Elem(el.PNum(1))
315
&&identmap2.Elem(el.PNum(2))
316
&&identmap2.Elem(el.PNum(3)))
317
{
318
outfile << "-1\n";
319
for (j = 1; j <= 3; j++)
320
outfile << identmap2.Elem(el.PNum(j))<<"\n";
321
outfile << "\n";
322
}
323
else if (identmap3.Elem(el.PNum(1))
324
&&identmap3.Elem(el.PNum(2))
325
&&identmap3.Elem(el.PNum(3)))
326
{
327
outfile << "-1\n";
328
for (j = 1; j <= 3; j++)
329
outfile << identmap3.Elem(el.PNum(j))<<"\n";
330
outfile << "\n";
331
}
332
else
333
outfile << "1\n\n";
334
335
}
336
}
337
338
outfile << "\n";
339
outfile << "# Boundary quadrilaterals\n";
340
for (i = 1; i <= nse; i++)
341
{
342
Element2d el = mesh.SurfaceElement(i);
343
344
if (el.GetNP() == 4
345
&& (mesh.GetFaceDescriptor (el.GetIndex()).DomainIn()==0
346
|| mesh.GetFaceDescriptor (el.GetIndex()).DomainOut()==0))
347
{
348
if (pointsOnTetras.Get(el.PNum(1)) &&
349
pointsOnTetras.Get(el.PNum(2)))
350
ct = 0;
351
else if (pointsOnTetras.Get(el.PNum(2)) &&
352
pointsOnTetras.Get(el.PNum(3)))
353
ct = 1;
354
else if (pointsOnTetras.Get(el.PNum(3)) &&
355
pointsOnTetras.Get(el.PNum(4)))
356
ct = 2;
357
else if (pointsOnTetras.Get(el.PNum(4)) &&
358
pointsOnTetras.Get(el.PNum(1)))
359
ct = 3;
360
else
361
cout << "\nWarning: Quadrilateral with inconsistent points found!"<<endl;
362
363
for (j = 1; j <= 4; j++)
364
{
365
jj = j + ct;
366
if ( jj >= 5 )
367
jj = jj - 4;
368
outfile << el.PNum(jj)<<"\n";
369
}
370
outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << "\n";
371
if (mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() == bc_at_infinity)
372
{
373
outfile << "-2\n\n";
374
cout << "\nWarning: Quadrilateral at infinity found (this should not occur)!"<<endl;
375
}
376
else if ( identmap1.Elem(el.PNum(1)) &&
377
identmap1.Elem(el.PNum(2)) &&
378
identmap1.Elem(el.PNum(3)) &&
379
identmap1.Elem(el.PNum(4)) )
380
{
381
outfile << "-1\n";
382
for (j = 1; j <= 4; j++)
383
{
384
jj = j + ct;
385
if ( jj >= 5 )
386
jj = jj - 4;
387
outfile << identmap1.Elem(el.PNum(jj))<<"\n";
388
}
389
outfile << "\n";
390
}
391
else if ( identmap2.Elem(el.PNum(1)) &&
392
identmap2.Elem(el.PNum(2)) &&
393
identmap2.Elem(el.PNum(3)) &&
394
identmap2.Elem(el.PNum(4)) )
395
{
396
outfile << "-1\n";
397
for (j = 1; j <= 4; j++)
398
{
399
jj = j + ct;
400
if ( jj >= 5 )
401
jj = jj - 4;
402
outfile << identmap2.Elem(el.PNum(jj))<<"\n";
403
}
404
outfile << "\n";
405
}
406
else if ( identmap3.Elem(el.PNum(1)) &&
407
identmap3.Elem(el.PNum(2)) &&
408
identmap3.Elem(el.PNum(3)) &&
409
identmap3.Elem(el.PNum(4)) )
410
{
411
outfile << "-1\n";
412
for (j = 1; j <= 4; j++)
413
{
414
jj = j + ct;
415
if ( jj >= 5 )
416
jj = jj - 4;
417
outfile << identmap3.Elem(el.PNum(jj))<<"\n";
418
}
419
outfile << "\n";
420
}
421
else
422
outfile << "1\n\n";
423
}
424
}
425
426
cout << " JCMwave grid file written." << endl;
427
}
428
429
}
430
431
432