Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/geom2d/spline.cpp
3206 views
1
/*
2
3
Spline curve for Mesh generator
4
5
*/
6
7
#include <mystdlib.h>
8
#include <csg.hpp>
9
#include <linalg.hpp>
10
#include <meshing.hpp>
11
12
namespace netgen
13
{
14
#include "spline.hpp"
15
16
/*
17
template<> void SplineSeg3<2> :: Project (const Point<2> point, Point<2> & point_on_curve, double & t) const
18
{
19
double t_old = 0;
20
t = 0.5;
21
22
Point<2> phi;
23
Vec<2> phip,phipp,phimp;
24
25
int i=0;
26
27
while(fabs(t-t_old) > 1e-8 && i<10)
28
{
29
GetDerivatives(t,phi,phip,phipp);
30
31
t_old = t;
32
33
phimp = phi-point;
34
35
t = min2(max2(t-(phip*phimp)/(phipp*phimp + phip*phip),0.),1.);
36
37
i++;
38
}
39
40
if(i<10)
41
{
42
point_on_curve = GetPoint(t);
43
44
double dist = Dist(point,point_on_curve);
45
46
phi = GetPoint(0);
47
double auxdist = Dist(phi,point);
48
if(auxdist < dist)
49
{
50
t = 0.;
51
point_on_curve = phi;
52
dist = auxdist;
53
}
54
phi = GetPoint(1);
55
auxdist = Dist(phi,point);
56
if(auxdist < dist)
57
{
58
t = 1.;
59
point_on_curve = phi;
60
dist = auxdist;
61
}
62
63
}
64
else
65
{
66
double t0 = 0;
67
double t1 = 0.5;
68
double t2 = 1.;
69
70
double d0,d1,d2;
71
72
73
//(*testout) << "2d newtonersatz" << endl;
74
while(t2-t0 > 1e-8)
75
{
76
77
phi = GetPoint(t0); d0 = Dist(phi,point);
78
phi = GetPoint(t1); d1 = Dist(phi,point);
79
phi = GetPoint(t2); d2 = Dist(phi,point);
80
81
double a = (2.*d0 - 4.*d1 +2.*d2)/pow(t2-t0,2);
82
83
if(a <= 0)
84
{
85
if(d0 < d2)
86
t2 -= 0.3*(t2-t0);
87
else
88
t0 += 0.3*(t2-t0);
89
90
t1 = 0.5*(t2+t0);
91
}
92
else
93
{
94
double b = (d1-d0-a*(t1*t1-t0*t0))/(t1-t0);
95
96
double auxt1 = -0.5*b/a;
97
98
if(auxt1 < t0)
99
{
100
t2 -= 0.4*(t2-t0);
101
t0 = max2(0.,t0-0.1*(t2-t0));
102
}
103
else if (auxt1 > t2)
104
{
105
t0 += 0.4*(t2-t0);
106
t2 = min2(1.,t2+0.1*(t2-t0));
107
}
108
else
109
{
110
t1 = auxt1;
111
auxt1 = 0.25*(t2-t0);
112
t0 = max2(0.,t1-auxt1);
113
t2 = min2(1.,t1+auxt1);
114
}
115
116
t1 = 0.5*(t2+t0);
117
}
118
119
}
120
121
122
phi = GetPoint(t0); d0 = Dist(phi,point);
123
phi = GetPoint(t1); d1 = Dist(phi,point);
124
phi = GetPoint(t2); d2 = Dist(phi,point);
125
126
double mind = d0;
127
t = t0;
128
if(d1 < mind)
129
{
130
t = t1;
131
mind = d1;
132
}
133
if(d2 < mind)
134
{
135
t = t2;
136
mind = d2;
137
}
138
139
point_on_curve = GetPoint(t);
140
141
}
142
}
143
144
template<> void SplineSeg3<3> :: Project (const Point<3> point, Point<3> & point_on_curve, double & t) const
145
{
146
double t_old = -1;
147
148
if(proj_latest_t > 0. && proj_latest_t < 1.)
149
t = proj_latest_t;
150
else
151
t = 0.5;
152
153
Point<3> phi;
154
Vec<3> phip,phipp,phimp;
155
156
int i=0;
157
158
while(fabs(t-t_old) > 1e-8 && t > -0.5 && t < 1.5 && i<10)
159
{
160
GetDerivatives(t,phi,phip,phipp);
161
162
t_old = t;
163
164
phimp = phi-point;
165
166
//t = min2(max2(t-(phip*phimp)/(phipp*phimp + phip*phip),0.),1.);
167
t -= (phip*phimp)/(phipp*phimp + phip*phip);
168
169
i++;
170
}
171
172
//if(i<10 && t > 0. && t < 1.)
173
if(i<10 && t > -0.4 && t < 1.4)
174
{
175
if(t < 0)
176
t = 0.;
177
if(t > 1)
178
t = 1.;
179
180
point_on_curve = GetPoint(t);
181
182
double dist = Dist(point,point_on_curve);
183
184
phi = GetPoint(0);
185
double auxdist = Dist(phi,point);
186
if(auxdist < dist)
187
{
188
t = 0.;
189
point_on_curve = phi;
190
dist = auxdist;
191
}
192
phi = GetPoint(1);
193
auxdist = Dist(phi,point);
194
if(auxdist < dist)
195
{
196
t = 1.;
197
point_on_curve = phi;
198
dist = auxdist;
199
}
200
}
201
else
202
{
203
double t0 = 0;
204
double t1 = 0.5;
205
double t2 = 1.;
206
207
double d0,d1,d2;
208
209
210
//(*testout) << "newtonersatz" << endl;
211
while(t2-t0 > 1e-8)
212
{
213
214
phi = GetPoint(t0); d0 = Dist(phi,point);
215
phi = GetPoint(t1); d1 = Dist(phi,point);
216
phi = GetPoint(t2); d2 = Dist(phi,point);
217
218
double a = (2.*d0 - 4.*d1 +2.*d2)/pow(t2-t0,2);
219
220
if(a <= 0)
221
{
222
if(d0 < d2)
223
t2 -= 0.3*(t2-t0);
224
else
225
t0 += 0.3*(t2-t0);
226
227
t1 = 0.5*(t2+t0);
228
}
229
else
230
{
231
double b = (d1-d0-a*(t1*t1-t0*t0))/(t1-t0);
232
233
double auxt1 = -0.5*b/a;
234
235
if(auxt1 < t0)
236
{
237
t2 -= 0.4*(t2-t0);
238
t0 = max2(0.,t0-0.1*(t2-t0));
239
}
240
else if (auxt1 > t2)
241
{
242
t0 += 0.4*(t2-t0);
243
t2 = min2(1.,t2+0.1*(t2-t0));
244
}
245
else
246
{
247
t1 = auxt1;
248
auxt1 = 0.25*(t2-t0);
249
t0 = max2(0.,t1-auxt1);
250
t2 = min2(1.,t1+auxt1);
251
}
252
253
t1 = 0.5*(t2+t0);
254
}
255
256
}
257
258
259
phi = GetPoint(t0); d0 = Dist(phi,point);
260
phi = GetPoint(t1); d1 = Dist(phi,point);
261
phi = GetPoint(t2); d2 = Dist(phi,point);
262
263
double mind = d0;
264
t = t0;
265
if(d1 < mind)
266
{
267
t = t1;
268
mind = d1;
269
}
270
if(d2 < mind)
271
{
272
t = t2;
273
mind = d2;
274
}
275
276
point_on_curve = GetPoint(t);
277
}
278
//(*testout) << " latest_t " << proj_latest_t << " t " << t << endl;
279
280
proj_latest_t = t;
281
}
282
*/
283
284
void CalcPartition (double l, double h, double r1, double r2,
285
double ra, double elto0, ARRAY<double> & points)
286
{
287
int i, j, n, nel;
288
double sum, t, dt, fun, fperel, oldf, f;
289
290
n = 1000;
291
292
points.SetSize (0);
293
294
sum = 0;
295
dt = l / n;
296
t = 0.5 * dt;
297
for (i = 1; i <= n; i++)
298
{
299
fun = min3 (h/ra, t/elto0 + h/r1, (l-t)/elto0 + h/r2);
300
sum += dt / fun;
301
t += dt;
302
}
303
304
nel = int (sum+1);
305
fperel = sum / nel;
306
307
points.Append (0);
308
309
i = 1;
310
oldf = 0;
311
t = 0.5 * dt;
312
for (j = 1; j <= n && i < nel; j++)
313
{
314
fun = min3 (h/ra, t/elto0 + h/r1, (l-t)/elto0 + h/r2);
315
316
f = oldf + dt / fun;
317
318
while (f > i * fperel && i < nel)
319
{
320
points.Append ( (l/n) * (j-1 + (i * fperel - oldf) / (f - oldf)) );
321
i++;
322
}
323
oldf = f;
324
t += dt;
325
}
326
points.Append (l);
327
}
328
329
template<>
330
double SplineSeg3<2> :: MaxCurvature(void) const
331
{
332
Vec<2> v1 = p1-p2;
333
Vec<2> v2 = p3-p2;
334
double l1 = v1.Length();
335
double l2 = v2.Length();
336
337
double cosalpha = (v1*v2)/(l1*l2);
338
339
340
return sqrt(cosalpha + 1.)/(min2(l1,l2)*(1.-cosalpha));
341
}
342
343
template<>
344
double SplineSeg3<3> :: MaxCurvature(void) const
345
{
346
Vec<3> v1 = p1-p2;
347
Vec<3> v2 = p3-p2;
348
double l1 = v1.Length();
349
double l2 = v2.Length();
350
351
double cosalpha = v1*v2/(l1*l2);
352
353
354
return sqrt(cosalpha + 1.)/(min2(l1,l2)*(1.-cosalpha));
355
}
356
357
358
359
360
}
361
362