Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/geom2d/genmesh2d.cpp
3206 views
1
#include <mystdlib.h>
2
#include <csg.hpp>
3
#include <geometry2d.hpp>
4
#include "meshing.hpp"
5
6
namespace netgen
7
{
8
9
// static ARRAY<Point<2> > points2;
10
// static ARRAY<int> lp1, lp2;
11
12
13
extern void Optimize2d (Mesh & mesh, MeshingParameters & mp);
14
15
16
17
18
19
20
21
void MeshFromSpline2D (SplineGeometry2d & geometry,
22
Mesh *& mesh,
23
MeshingParameters & mp)
24
{
25
PrintMessage (1, "Generate Mesh from spline geometry");
26
27
double h = mp.maxh;
28
29
Box<2> bbox = geometry.GetBoundingBox ();
30
31
if (bbox.Diam() < h)
32
{
33
h = bbox.Diam();
34
mp.maxh = h;
35
}
36
37
mesh = new Mesh;
38
mesh->SetDimension (2);
39
40
geometry.PartitionBoundary (h, *mesh);
41
42
// marks mesh points for hp-refinement
43
for (int i = 0; i < geometry.GetNP(); i++)
44
if (geometry.GetPoint(i).hpref)
45
{
46
double mindist = 1e99;
47
PointIndex mpi(0);
48
Point<2> gp = geometry.GetPoint(i);
49
Point<3> gp3(gp(0), gp(1), 0);
50
for (PointIndex pi = PointIndex::BASE;
51
pi < mesh->GetNP()+PointIndex::BASE; pi++)
52
if (Dist2(gp3, (*mesh)[pi]) < mindist)
53
{
54
mpi = pi;
55
mindist = Dist2(gp3, (*mesh)[pi]);
56
}
57
(*mesh)[mpi].Singularity(1.);
58
}
59
60
61
int maxdomnr = 0;
62
for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++)
63
{
64
if ( (*mesh)[si].domin > maxdomnr) maxdomnr = (*mesh)[si].domin;
65
if ( (*mesh)[si].domout > maxdomnr) maxdomnr = (*mesh)[si].domout;
66
}
67
68
mesh->ClearFaceDescriptors();
69
for (int i = 1; i <= maxdomnr; i++)
70
mesh->AddFaceDescriptor (FaceDescriptor (i, 0, 0, i));
71
72
// set ARRAY<string*> bcnames...
73
// number of bcnames
74
int maxsegmentindex = 0;
75
for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++)
76
{
77
if ( (*mesh)[si].si > maxsegmentindex) maxsegmentindex = (*mesh)[si].si;
78
}
79
80
mesh->SetNBCNames(maxsegmentindex);
81
82
for ( int sindex = 0; sindex < maxsegmentindex; sindex++ )
83
{
84
mesh->SetBCName ( sindex, geometry.GetBCName( sindex+1 ) );
85
}
86
87
for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++)
88
{
89
(*mesh)[si].SetBCName ( (*mesh).GetBCNamePtr( (*mesh)[si].si-1 ) );
90
}
91
Point3d pmin(bbox.PMin()(0), bbox.PMin()(1), -bbox.Diam());
92
Point3d pmax(bbox.PMax()(0), bbox.PMax()(1), bbox.Diam());
93
94
mesh->SetLocalH (pmin, pmax, mparam.grading);
95
mesh->SetGlobalH (h);
96
97
mesh->CalcLocalH();
98
99
int bnp = mesh->GetNP(); // boundary points
100
101
int hquad = mparam.quad;
102
103
104
for (int domnr = 1; domnr <= maxdomnr; domnr++)
105
if (geometry.GetDomainTensorMeshing (domnr))
106
{ // tensor product mesh
107
108
ARRAY<PointIndex, PointIndex::BASE> nextpi(bnp);
109
ARRAY<int, PointIndex::BASE> si1(bnp), si2(bnp);
110
PointIndex firstpi;
111
112
nextpi = -1;
113
si1 = -1;
114
si2 = -1;
115
for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++)
116
{
117
int p1 = -1, p2 = -2;
118
119
if ( (*mesh)[si].domin == domnr)
120
{ p1 = (*mesh)[si].p1; p2 = (*mesh)[si].p2; }
121
if ( (*mesh)[si].domout == domnr)
122
{ p1 = (*mesh)[si].p2; p2 = (*mesh)[si].p1; }
123
124
if (p1 == -1) continue;
125
126
nextpi[p1] = p2; // counter-clockwise
127
128
int index = (*mesh)[si].si;
129
if (si1[p1] != index && si2[p1] != index)
130
{ si2[p1] = si1[p1]; si1[p1] = index; }
131
if (si1[p2] != index && si2[p2] != index)
132
{ si2[p2] = si1[p2]; si1[p2] = index; }
133
}
134
135
PointIndex c1(0), c2, c3, c4; // 4 corner points
136
int nex = 1, ney = 1;
137
138
for (PointIndex pi = 1; pi <= si2.Size(); pi++)
139
if (si2[pi] != -1)
140
{ c1 = pi; break; }
141
142
for (c2 = nextpi[c1]; si2[c2] == -1; c2 = nextpi[c2], nex++);
143
for (c3 = nextpi[c2]; si2[c3] == -1; c3 = nextpi[c3], ney++);
144
for (c4 = nextpi[c3]; si2[c4] == -1; c4 = nextpi[c4]);
145
146
147
148
ARRAY<PointIndex> pts ( (nex+1) * (ney+1) ); // x ... inner loop
149
pts = -1;
150
151
for (PointIndex pi = c1, i = 0; pi != c2; pi = nextpi[pi], i++)
152
pts[i] = pi;
153
for (PointIndex pi = c2, i = 0; pi != c3; pi = nextpi[pi], i++)
154
pts[(nex+1)*i+nex] = pi;
155
for (PointIndex pi = c3, i = 0; pi != c4; pi = nextpi[pi], i++)
156
pts[(nex+1)*(ney+1)-i-1] = pi;
157
for (PointIndex pi = c4, i = 0; pi != c1; pi = nextpi[pi], i++)
158
pts[(nex+1)*(ney-i)] = pi;
159
160
161
for (PointIndex pix = nextpi[c1], ix = 0; pix != c2; pix = nextpi[pix], ix++)
162
for (PointIndex piy = nextpi[c2], iy = 0; piy != c3; piy = nextpi[piy], iy++)
163
{
164
Point<3> p = (*mesh)[pix] + ( (*mesh)[piy] - (*mesh)[c2] );
165
pts[(nex+1)*(iy+1) + ix+1] = mesh -> AddPoint (p , 1, FIXEDPOINT);
166
}
167
168
for (int i = 0; i < ney; i++)
169
for (int j = 0; j < nex; j++)
170
{
171
Element2d el(QUAD);
172
el[0] = pts[i*(nex+1)+j];
173
el[1] = pts[i*(nex+1)+j+1];
174
el[2] = pts[(i+1)*(nex+1)+j+1];
175
el[3] = pts[(i+1)*(nex+1)+j];
176
el.SetIndex (domnr);
177
178
mesh -> AddSurfaceElement (el);
179
}
180
}
181
182
183
184
185
for (int domnr = 1; domnr <= maxdomnr; domnr++)
186
{
187
if (geometry.GetDomainTensorMeshing (domnr)) continue;
188
189
if ( geometry.GetDomainMaxh ( domnr ) > 0 )
190
h = geometry.GetDomainMaxh(domnr);
191
192
193
PrintMessage (3, "Meshing domain ", domnr, " / ", maxdomnr);
194
195
int oldnf = mesh->GetNSE();
196
197
mparam.quad = hquad || geometry.GetDomainQuadMeshing (domnr);
198
199
Meshing2 meshing (Box<3> (pmin, pmax));
200
201
for (PointIndex pi = PointIndex::BASE; pi < bnp+PointIndex::BASE; pi++)
202
meshing.AddPoint ( (*mesh)[pi], pi);
203
204
205
PointGeomInfo gi;
206
gi.trignum = 1;
207
for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++)
208
{
209
if ( (*mesh)[si].domin == domnr)
210
meshing.AddBoundaryElement ( (*mesh)[si].p1 + 1 - PointIndex::BASE,
211
(*mesh)[si].p2 + 1 - PointIndex::BASE, gi, gi);
212
if ( (*mesh)[si].domout == domnr)
213
meshing.AddBoundaryElement ( (*mesh)[si].p2 + 1 - PointIndex::BASE,
214
(*mesh)[si].p1 + 1 - PointIndex::BASE, gi, gi);
215
}
216
217
218
mparam.checkoverlap = 0;
219
220
meshing.GenerateMesh (*mesh, h, domnr);
221
222
for (SurfaceElementIndex sei = oldnf; sei < mesh->GetNSE(); sei++)
223
(*mesh)[sei].SetIndex (domnr);
224
225
226
// astrid
227
char * material;
228
geometry.GetMaterial( domnr, material );
229
if ( material )
230
{
231
(*mesh).SetMaterial ( domnr, material );
232
}
233
234
}
235
236
mparam.quad = hquad;
237
238
239
240
int hsteps = mp.optsteps2d;
241
242
mp.optimize2d = "smcm";
243
mp.optsteps2d = hsteps/2;
244
Optimize2d (*mesh, mp);
245
246
mp.optimize2d = "Smcm";
247
mp.optsteps2d = (hsteps+1)/2;
248
Optimize2d (*mesh, mp);
249
250
mp.optsteps2d = hsteps;
251
252
mesh->Compress();
253
mesh -> SetNextMajorTimeStamp();
254
255
256
#ifdef OPENGL
257
extern void Render();
258
Render();
259
#endif
260
261
}
262
263
264
265
266
267
268
269
270
}
271
272