ngsolve 6.2.2501.post83.dev1__cp311-cp311-macosx_10_15_universal2.whl → 6.2.2503__cp311-cp311-macosx_10_15_universal2.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ngsolve might be problematic. Click here for more details.
- netgen/include/facetfespace.hpp +2 -0
- netgen/include/fespace.hpp +4 -2
- netgen/include/intrules_SauterSchwab.hpp +25 -0
- netgen/include/mptools.hpp +380 -95
- netgen/include/ngblas.hpp +14 -0
- netgen/include/potentialtools.hpp +20 -0
- netgen/include/prolongation.hpp +143 -1
- netgen/include/python_ngstd.hpp +1 -0
- netgen/include/sparsecholesky.hpp +1 -1
- netgen/include/sparsematrix_impl.hpp +71 -5
- netgen/include/tangentialfacetfespace.hpp +7 -22
- netgen/include/tensor.hpp +1 -1
- netgen/libngbla.dylib +0 -0
- netgen/libngcomp.dylib +0 -0
- netgen/libngfem.dylib +0 -0
- netgen/libngla.dylib +0 -0
- netgen/libngsbem.dylib +0 -0
- netgen/libngsolve.dylib +0 -0
- netgen/libngstd.dylib +0 -0
- ngsolve/cmake/NGSolveConfig.cmake +5 -5
- ngsolve/cmake/ngsolve-targets-release.cmake +10 -0
- ngsolve/cmake/ngsolve-targets.cmake +9 -2
- ngsolve/config/config.py +6 -6
- ngsolve/ngslib.so +0 -0
- {ngsolve-6.2.2501.post83.dev1.dist-info → ngsolve-6.2.2503.dist-info}/METADATA +2 -2
- {ngsolve-6.2.2501.post83.dev1.dist-info → ngsolve-6.2.2503.dist-info}/RECORD +62 -59
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/Netgen.icns +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/bin/ngscxx +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/bin/ngsld +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/bin/ngsolve.tcl +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/bin/ngspy +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/beam.geo +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/beam.vol +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/chip.in2d +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/chip.vol +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/coil.geo +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/coil.vol +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/coilshield.geo +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/coilshield.vol +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/cube.geo +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/cube.vol +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/d10_DGdoubleglazing.pde +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/d11_chip_nitsche.pde +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/d1_square.pde +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/d2_chip.pde +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/d3_helmholtz.pde +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/d4_cube.pde +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/d5_beam.pde +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/d6_shaft.pde +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/d7_coil.pde +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/d8_coilshield.pde +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/d9_hybridDG.pde +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/doubleglazing.in2d +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/doubleglazing.vol +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/piezo2d40round4.vol.gz +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/shaft.geo +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/shaft.vol +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/square.in2d +0 -0
- {ngsolve-6.2.2501.post83.dev1.data → ngsolve-6.2.2503.data}/data/share/ngsolve/square.vol +0 -0
- {ngsolve-6.2.2501.post83.dev1.dist-info → ngsolve-6.2.2503.dist-info}/LICENSE +0 -0
- {ngsolve-6.2.2501.post83.dev1.dist-info → ngsolve-6.2.2503.dist-info}/WHEEL +0 -0
- {ngsolve-6.2.2501.post83.dev1.dist-info → ngsolve-6.2.2503.dist-info}/top_level.txt +0 -0
netgen/include/mptools.hpp
CHANGED
|
@@ -10,27 +10,32 @@
|
|
|
10
10
|
#include <coefficient.hpp>
|
|
11
11
|
#include <recursive_pol.hpp>
|
|
12
12
|
|
|
13
|
-
namespace ngfem
|
|
14
|
-
{
|
|
15
13
|
|
|
14
|
+
namespace ngcomp
|
|
15
|
+
{
|
|
16
|
+
class Region;
|
|
17
|
+
}
|
|
16
18
|
|
|
19
|
+
namespace ngsbem
|
|
20
|
+
{
|
|
21
|
+
using namespace ngfem;
|
|
17
22
|
|
|
23
|
+
|
|
24
|
+
template <typename entry_type = Complex>
|
|
18
25
|
class NGS_DLL_HEADER SphericalHarmonics
|
|
19
26
|
{
|
|
20
27
|
int order;
|
|
21
|
-
Vector<
|
|
28
|
+
Vector<entry_type> coefs;
|
|
22
29
|
|
|
23
30
|
public:
|
|
24
31
|
SphericalHarmonics (int aorder)
|
|
25
32
|
: order(aorder), coefs(sqr(order+1)) { coefs=0.0; }
|
|
26
33
|
|
|
27
34
|
int Order() const { return order; }
|
|
28
|
-
FlatVector<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
{
|
|
32
|
-
return coefs(n*(n+1) + m);
|
|
33
|
-
}
|
|
35
|
+
FlatVector<entry_type> Coefs() const { return coefs; }
|
|
36
|
+
|
|
37
|
+
entry_type & Coef(int n, int m) { return coefs(n*(n+1) + m); }
|
|
38
|
+
entry_type Coef(int n, int m) const { return coefs(n*(n+1) + m); }
|
|
34
39
|
|
|
35
40
|
auto CoefsN (int n) const
|
|
36
41
|
{
|
|
@@ -53,29 +58,29 @@ namespace ngfem
|
|
|
53
58
|
return { theta, phi };
|
|
54
59
|
}
|
|
55
60
|
|
|
56
|
-
|
|
61
|
+
entry_type Eval (Vec<3> x) const
|
|
57
62
|
{
|
|
58
63
|
auto [theta, phi] = Polar(x);
|
|
59
64
|
return Eval(theta, phi);
|
|
60
65
|
}
|
|
61
66
|
|
|
62
|
-
|
|
67
|
+
entry_type Eval (double theta, double phi) const;
|
|
63
68
|
|
|
64
|
-
|
|
69
|
+
entry_type EvalOrder (int n, Vec<3> x) const
|
|
65
70
|
{
|
|
66
71
|
auto [theta, phi] = Polar (x);
|
|
67
72
|
return EvalOrder(n, theta, phi);
|
|
68
73
|
}
|
|
69
74
|
|
|
70
|
-
|
|
75
|
+
entry_type EvalOrder (int n, double theta, double phi) const;
|
|
71
76
|
|
|
72
|
-
void EvalOrders (Vec<3> x, FlatVector<
|
|
77
|
+
void EvalOrders (Vec<3> x, FlatVector<entry_type> vals) const
|
|
73
78
|
{
|
|
74
79
|
auto [theta, phi] = Polar(x);
|
|
75
80
|
return EvalOrders(theta, phi, vals);
|
|
76
81
|
}
|
|
77
82
|
|
|
78
|
-
void EvalOrders (double theta, double phi, FlatVector<
|
|
83
|
+
void EvalOrders (double theta, double phi, FlatVector<entry_type> vals) const;
|
|
79
84
|
|
|
80
85
|
void Calc (Vec<3> x, FlatVector<Complex> shapes);
|
|
81
86
|
|
|
@@ -106,7 +111,7 @@ namespace ngfem
|
|
|
106
111
|
|
|
107
112
|
// Nail A. Gumerov and Ramani Duraiswami book, formula (2.2.12)
|
|
108
113
|
// add directional derivative divided by kappa to res, both multipoles need same scaling
|
|
109
|
-
void DirectionalDiffAdd (Vec<3> d, SphericalHarmonics & res, double scale = 1);
|
|
114
|
+
void DirectionalDiffAdd (Vec<3> d, SphericalHarmonics<entry_type> & res, double scale = 1) const;
|
|
110
115
|
|
|
111
116
|
};
|
|
112
117
|
|
|
@@ -213,48 +218,87 @@ namespace ngfem
|
|
|
213
218
|
class MPSingular
|
|
214
219
|
{
|
|
215
220
|
public:
|
|
221
|
+
/*
|
|
216
222
|
template <typename T>
|
|
217
223
|
static void Eval (int order, double r, double scale, T && values)
|
|
218
224
|
{
|
|
219
225
|
SphericalHankel1(order, r, scale, values);
|
|
220
226
|
}
|
|
227
|
+
*/
|
|
228
|
+
|
|
229
|
+
template <typename T>
|
|
230
|
+
static void Eval (int order, double kappa, double r, double rtyp, T && values)
|
|
231
|
+
{
|
|
232
|
+
double scale = Scale(kappa, rtyp);
|
|
233
|
+
SphericalHankel1(order, r*kappa, scale, values);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
static double Scale (double kappa, double rtyp)
|
|
237
|
+
{
|
|
238
|
+
return min(1.0, rtyp*kappa);
|
|
239
|
+
}
|
|
221
240
|
};
|
|
241
|
+
|
|
242
|
+
|
|
222
243
|
|
|
223
244
|
// jn
|
|
224
245
|
class MPRegular
|
|
225
246
|
{
|
|
226
|
-
public:
|
|
247
|
+
public:
|
|
248
|
+
/*
|
|
227
249
|
template <typename T>
|
|
228
250
|
static void Eval (int order, double r, double scale, T && values)
|
|
229
251
|
{
|
|
230
252
|
SphericalBessel (order, r, 1.0/scale, values);
|
|
231
253
|
}
|
|
254
|
+
*/
|
|
255
|
+
|
|
256
|
+
template <typename T>
|
|
257
|
+
static void Eval (int order, double kappa, double r, double rtyp, T && values)
|
|
258
|
+
{
|
|
259
|
+
double scale = Scale(kappa, rtyp);
|
|
260
|
+
SphericalBessel (order, r*kappa, 1.0/scale, values);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
static double Scale (double kappa, double rtyp)
|
|
264
|
+
{
|
|
265
|
+
return 1.0/ min(1.0, 0.25*rtyp*kappa);
|
|
266
|
+
}
|
|
267
|
+
|
|
232
268
|
};
|
|
233
269
|
|
|
234
270
|
|
|
235
271
|
|
|
236
272
|
|
|
237
|
-
template <typename RADIAL>
|
|
273
|
+
template <typename RADIAL, typename entry_type=Complex>
|
|
238
274
|
class NGS_DLL_HEADER MultiPole
|
|
239
275
|
{
|
|
240
|
-
SphericalHarmonics sh;
|
|
276
|
+
SphericalHarmonics<entry_type> sh;
|
|
241
277
|
double kappa;
|
|
242
|
-
double
|
|
278
|
+
double rtyp;
|
|
279
|
+
// double scale;
|
|
243
280
|
public:
|
|
281
|
+
/*
|
|
244
282
|
MultiPole (int aorder, double akappa, double ascale = 1)
|
|
245
283
|
: sh(aorder), kappa(akappa), scale(ascale) { }
|
|
284
|
+
*/
|
|
246
285
|
|
|
247
|
-
|
|
286
|
+
MultiPole (int aorder, double akappa, double artyp)
|
|
287
|
+
: sh(aorder), kappa(akappa), rtyp(artyp) { }
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
entry_type & Coef(int n, int m) { return sh.Coef(n,m); }
|
|
248
291
|
auto & SH() { return sh; }
|
|
249
292
|
const auto & SH() const { return sh; }
|
|
250
293
|
double Kappa() const { return kappa; }
|
|
251
|
-
double Scale() const { return
|
|
294
|
+
double Scale() const { return RADIAL::Scale(kappa, rtyp); }
|
|
295
|
+
double RTyp() const { return rtyp; }
|
|
252
296
|
int Order() const { return sh.Order(); }
|
|
253
297
|
|
|
254
|
-
MultiPole
|
|
298
|
+
MultiPole Truncate(int neworder) const
|
|
255
299
|
{
|
|
256
300
|
if (neworder > sh.Order()) neworder=sh.Order();
|
|
257
|
-
MultiPole nmp(neworder, kappa);
|
|
301
|
+
MultiPole nmp(neworder, kappa, rtyp);
|
|
258
302
|
nmp.sh.Coefs() = sh.Coefs().Range(sqr(neworder+1));
|
|
259
303
|
return nmp;
|
|
260
304
|
}
|
|
@@ -266,20 +310,34 @@ namespace ngfem
|
|
|
266
310
|
return *this;
|
|
267
311
|
}
|
|
268
312
|
|
|
269
|
-
|
|
313
|
+
entry_type Eval (Vec<3> x) const;
|
|
314
|
+
entry_type EvalDirectionalDerivative (Vec<3> x, Vec<3> d) const;
|
|
270
315
|
|
|
271
|
-
void AddCharge (Vec<3> x,
|
|
272
|
-
void AddDipole (Vec<3> x, Vec<3> d,
|
|
273
|
-
|
|
316
|
+
void AddCharge (Vec<3> x, entry_type c);
|
|
317
|
+
void AddDipole (Vec<3> x, Vec<3> d, entry_type c);
|
|
318
|
+
void AddCurrent (Vec<3> ap, Vec<3> ep, Complex j, int num=100);
|
|
274
319
|
|
|
320
|
+
/*
|
|
275
321
|
void ChangeScaleTo (double newscale)
|
|
276
322
|
{
|
|
277
|
-
double fac =
|
|
323
|
+
double fac = Scale()/newscale;
|
|
278
324
|
double prod = 1;
|
|
279
325
|
for (int n = 0; n <= sh.Order(); n++, prod*= fac)
|
|
280
326
|
sh.CoefsN(n) *= prod;
|
|
281
327
|
scale = newscale;
|
|
282
328
|
}
|
|
329
|
+
*/
|
|
330
|
+
void ChangeRTypTo (double new_rtyp)
|
|
331
|
+
{
|
|
332
|
+
// double fac = Scale()/newscale;
|
|
333
|
+
double fac = RADIAL::Scale(kappa, rtyp) / RADIAL::Scale(kappa, new_rtyp);
|
|
334
|
+
double prod = 1;
|
|
335
|
+
for (int n = 0; n <= sh.Order(); n++, prod*= fac)
|
|
336
|
+
sh.CoefsN(n) *= prod;
|
|
337
|
+
// scale = newscale;
|
|
338
|
+
rtyp = new_rtyp;
|
|
339
|
+
}
|
|
340
|
+
|
|
283
341
|
|
|
284
342
|
Vector<double> Spectrum (bool scaled) const
|
|
285
343
|
{
|
|
@@ -288,14 +346,14 @@ namespace ngfem
|
|
|
288
346
|
for (int n = 0; n <= Order(); n++)
|
|
289
347
|
{
|
|
290
348
|
spec(n) = fac * L2Norm2(sh.CoefsN(n));
|
|
291
|
-
if (!scaled) fac *= sqr(
|
|
349
|
+
if (!scaled) fac *= sqr(Scale());
|
|
292
350
|
}
|
|
293
351
|
return spec;
|
|
294
352
|
}
|
|
295
353
|
|
|
296
354
|
|
|
297
355
|
template <typename TARGET>
|
|
298
|
-
void Transform (MultiPole<TARGET> & target, Vec<3> dist) const
|
|
356
|
+
void Transform (MultiPole<TARGET,entry_type> & target, Vec<3> dist) const
|
|
299
357
|
{
|
|
300
358
|
if (target.SH().Order() < 0) return;
|
|
301
359
|
if (SH().Order() < 0)
|
|
@@ -321,7 +379,7 @@ namespace ngfem
|
|
|
321
379
|
phi = atan2(dist(1), dist(0));
|
|
322
380
|
|
|
323
381
|
|
|
324
|
-
MultiPole<RADIAL> tmp(*this);
|
|
382
|
+
MultiPole<RADIAL,entry_type> tmp(*this);
|
|
325
383
|
tmp.SH().RotateZ(phi);
|
|
326
384
|
tmp.SH().RotateY(theta);
|
|
327
385
|
|
|
@@ -332,18 +390,18 @@ namespace ngfem
|
|
|
332
390
|
}
|
|
333
391
|
|
|
334
392
|
template <typename TARGET>
|
|
335
|
-
void TransformAdd (MultiPole<TARGET> & target, Vec<3> dist) const
|
|
393
|
+
void TransformAdd (MultiPole<TARGET,entry_type> & target, Vec<3> dist) const
|
|
336
394
|
{
|
|
337
395
|
if (SH().Order() < 0) return;
|
|
338
396
|
if (target.SH().Order() < 0) return;
|
|
339
397
|
|
|
340
|
-
MultiPole<TARGET> tmp{target};
|
|
398
|
+
MultiPole<TARGET,entry_type> tmp{target};
|
|
341
399
|
Transform(tmp, dist);
|
|
342
400
|
target.SH().Coefs() += tmp.SH().Coefs();
|
|
343
401
|
}
|
|
344
402
|
|
|
345
403
|
template <typename TARGET>
|
|
346
|
-
void ShiftZ (double z, MultiPole<TARGET> & target);
|
|
404
|
+
void ShiftZ (double z, MultiPole<TARGET,entry_type> & target);
|
|
347
405
|
|
|
348
406
|
};
|
|
349
407
|
|
|
@@ -351,12 +409,14 @@ namespace ngfem
|
|
|
351
409
|
|
|
352
410
|
// ***************** parameters ****************
|
|
353
411
|
|
|
354
|
-
static int MPOrder (double rho_kappa)
|
|
412
|
+
static constexpr int MPOrder (double rho_kappa)
|
|
355
413
|
{
|
|
356
414
|
return max (20, int(2*rho_kappa));
|
|
357
415
|
}
|
|
358
416
|
static constexpr int maxdirect = 100;
|
|
359
417
|
|
|
418
|
+
|
|
419
|
+
template <typename entry_type=Complex>
|
|
360
420
|
class SingularMLMultiPole
|
|
361
421
|
{
|
|
362
422
|
static Array<size_t> nodes_on_level;
|
|
@@ -367,10 +427,11 @@ namespace ngfem
|
|
|
367
427
|
double r;
|
|
368
428
|
int level;
|
|
369
429
|
std::array<unique_ptr<Node>,8> childs;
|
|
370
|
-
MultiPole<MPSingular> mp;
|
|
430
|
+
MultiPole<MPSingular, entry_type> mp;
|
|
371
431
|
|
|
372
|
-
Array<tuple<Vec<3>,
|
|
373
|
-
Array<tuple<Vec<3>, Vec<3>,
|
|
432
|
+
Array<tuple<Vec<3>, entry_type>> charges;
|
|
433
|
+
Array<tuple<Vec<3>, Vec<3>, entry_type>> dipoles;
|
|
434
|
+
Array<tuple<Vec<3>, Vec<3>, Complex,int>> currents;
|
|
374
435
|
int total_sources;
|
|
375
436
|
|
|
376
437
|
Node (Vec<3> acenter, double ar, int alevel, int order, double kappa)
|
|
@@ -397,7 +458,7 @@ namespace ngfem
|
|
|
397
458
|
}
|
|
398
459
|
|
|
399
460
|
|
|
400
|
-
void AddCharge (Vec<3> x,
|
|
461
|
+
void AddCharge (Vec<3> x, entry_type c)
|
|
401
462
|
{
|
|
402
463
|
if (childs[0])
|
|
403
464
|
{
|
|
@@ -422,13 +483,16 @@ namespace ngfem
|
|
|
422
483
|
AddCharge (x,c);
|
|
423
484
|
for (auto [x,d,c] : dipoles)
|
|
424
485
|
AddDipole (x,d,c);
|
|
486
|
+
for (auto [sp,ep,j,num] : currents)
|
|
487
|
+
AddCurrent (sp,ep,j,num);
|
|
425
488
|
|
|
426
489
|
charges.SetSize0();
|
|
427
|
-
dipoles.SetSize0();
|
|
490
|
+
dipoles.SetSize0();
|
|
491
|
+
currents.SetSize0();
|
|
428
492
|
}
|
|
429
493
|
|
|
430
494
|
|
|
431
|
-
void AddDipole (Vec<3> x, Vec<3> d,
|
|
495
|
+
void AddDipole (Vec<3> x, Vec<3> d, entry_type c)
|
|
432
496
|
{
|
|
433
497
|
if (childs[0])
|
|
434
498
|
{
|
|
@@ -453,15 +517,70 @@ namespace ngfem
|
|
|
453
517
|
AddCharge (x,c);
|
|
454
518
|
for (auto [x,d,c] : dipoles)
|
|
455
519
|
AddDipole (x,d,c);
|
|
520
|
+
for (auto [sp,ep,j,num] : currents)
|
|
521
|
+
AddCurrent (sp,ep,j,num);
|
|
456
522
|
|
|
457
523
|
charges.SetSize0();
|
|
458
524
|
dipoles.SetSize0();
|
|
525
|
+
currents.SetSize0();
|
|
459
526
|
}
|
|
460
527
|
|
|
528
|
+
void AddCurrent (Vec<3> sp, Vec<3> ep, Complex j, int num)
|
|
529
|
+
{
|
|
530
|
+
if (childs[0])
|
|
531
|
+
{
|
|
532
|
+
// split line and send to childs
|
|
533
|
+
Array<double> split;
|
|
534
|
+
split.Append(0);
|
|
535
|
+
for (int i = 0; i < 3; i++)
|
|
536
|
+
if (sp(i) < center(i) != ep(i) < center(i))
|
|
537
|
+
split += (center(i)-sp(i)) / (ep(i)-sp(i)); // segment cuts i-th coordinate plane
|
|
538
|
+
split.Append(1);
|
|
539
|
+
BubbleSort(split);
|
|
540
|
+
|
|
541
|
+
for (int i = 0; i < split.Size()-1; i++)
|
|
542
|
+
if (split[i+1] > split[i])
|
|
543
|
+
{
|
|
544
|
+
Vec<3> spi = sp + split[i]*(ep-sp);
|
|
545
|
+
Vec<3> epi = sp + split[i+1]*(ep-sp);
|
|
546
|
+
|
|
547
|
+
Vec<3> x = 0.5*(spi+epi);
|
|
548
|
+
|
|
549
|
+
int childnum = 0;
|
|
550
|
+
if (x(0) > center(0)) childnum += 1;
|
|
551
|
+
if (x(1) > center(1)) childnum += 2;
|
|
552
|
+
if (x(2) > center(2)) childnum += 4;
|
|
553
|
+
childs[childnum] -> AddCurrent(spi, epi, j, num);
|
|
554
|
+
}
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
currents.Append (tuple{sp,ep,j,num});
|
|
559
|
+
|
|
560
|
+
// if (currents.Size() < maxdirect || r < 1e-8)
|
|
561
|
+
if (currents.Size() < 4 || r < 1e-8)
|
|
562
|
+
return;
|
|
563
|
+
|
|
564
|
+
CreateChilds();
|
|
565
|
+
|
|
566
|
+
for (auto [x,c] : charges)
|
|
567
|
+
AddCharge (x,c);
|
|
568
|
+
for (auto [x,d,c] : dipoles)
|
|
569
|
+
AddDipole (x,d,c);
|
|
570
|
+
for (auto [sp,ep,j,num] : currents)
|
|
571
|
+
AddCurrent (sp,ep,j,num);
|
|
572
|
+
|
|
573
|
+
charges.SetSize0();
|
|
574
|
+
dipoles.SetSize0();
|
|
575
|
+
currents.SetSize0();
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
|
|
461
580
|
|
|
462
|
-
|
|
581
|
+
entry_type Evaluate(Vec<3> p) const
|
|
463
582
|
{
|
|
464
|
-
|
|
583
|
+
entry_type sum{0.0};
|
|
465
584
|
if (childs[0])
|
|
466
585
|
{
|
|
467
586
|
for (auto & child : childs)
|
|
@@ -471,17 +590,63 @@ namespace ngfem
|
|
|
471
590
|
|
|
472
591
|
for (auto [x,c] : charges)
|
|
473
592
|
if (double rho = L2Norm(p-x); rho > 0)
|
|
474
|
-
sum +=
|
|
593
|
+
sum += (1/(4*M_PI))*exp(Complex(0,rho*mp.Kappa())) / rho * c;
|
|
475
594
|
|
|
476
595
|
for (auto [x,d,c] : dipoles)
|
|
477
596
|
if (double rho = L2Norm(p-x); rho > 0)
|
|
478
597
|
{
|
|
479
598
|
Vec<3> drhodp = 1.0/rho * (p-x);
|
|
480
|
-
Complex dGdrho =
|
|
599
|
+
Complex dGdrho = (1/(4*M_PI))*exp(Complex(0,rho*mp.Kappa())) *
|
|
481
600
|
(Complex(0, mp.Kappa())/rho - 1.0/sqr(rho));
|
|
482
|
-
sum += dGdrho * InnerProduct(drhodp, d);
|
|
601
|
+
sum += dGdrho * InnerProduct(drhodp, d) * c;
|
|
483
602
|
}
|
|
484
603
|
|
|
604
|
+
for (auto [sp,ep,j,num] : currents)
|
|
605
|
+
{
|
|
606
|
+
// should use explizit formula instead ...
|
|
607
|
+
|
|
608
|
+
Vec<3> tau = ep-sp;
|
|
609
|
+
Vec<3> tau_num = 1.0/num * tau;
|
|
610
|
+
for (int i = 0; i < num; i++)
|
|
611
|
+
{
|
|
612
|
+
Vec<3> x = sp+(i+0.5)*tau_num;
|
|
613
|
+
|
|
614
|
+
if (double rho = L2Norm(p-x); rho > 0)
|
|
615
|
+
{
|
|
616
|
+
Vec<3> drhodp = 1.0/rho * (p-x);
|
|
617
|
+
Complex dGdrho = (1/(4*M_PI))*exp(Complex(0,rho*mp.Kappa())) *
|
|
618
|
+
(Complex(0, mp.Kappa())/rho - 1.0/sqr(rho));
|
|
619
|
+
|
|
620
|
+
if constexpr (std::is_same<entry_type, Vec<3,Complex>>())
|
|
621
|
+
sum += j*dGdrho * Cross(drhodp, tau_num);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
return sum;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
entry_type EvaluateDeriv(Vec<3> p, Vec<3> d) const
|
|
630
|
+
{
|
|
631
|
+
entry_type sum{0.0};
|
|
632
|
+
if (childs[0])
|
|
633
|
+
{
|
|
634
|
+
for (auto & child : childs)
|
|
635
|
+
sum += child->EvaluateDeriv(p, d);
|
|
636
|
+
return sum;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
if (dipoles.Size())
|
|
640
|
+
throw Exception("EvaluateDeriv not implemented for dipoles in SingularMLMultiPole");
|
|
641
|
+
|
|
642
|
+
for (auto [x,c] : charges)
|
|
643
|
+
if (double rho = L2Norm(p-x); rho > 0)
|
|
644
|
+
{
|
|
645
|
+
Vec<3> drhodp = 1.0/rho * (p-x);
|
|
646
|
+
Complex dGdrho = (1/(4*M_PI))*exp(Complex(0,rho*mp.Kappa())) *
|
|
647
|
+
(Complex(0, mp.Kappa())/rho - 1.0/sqr(rho));
|
|
648
|
+
sum += dGdrho * InnerProduct(drhodp, d) * c;
|
|
649
|
+
}
|
|
485
650
|
return sum;
|
|
486
651
|
}
|
|
487
652
|
|
|
@@ -516,9 +681,9 @@ namespace ngfem
|
|
|
516
681
|
}
|
|
517
682
|
else
|
|
518
683
|
{
|
|
519
|
-
if (charges.Size()+dipoles.Size() == 0)
|
|
684
|
+
if (charges.Size()+dipoles.Size()+currents.Size() == 0)
|
|
520
685
|
{
|
|
521
|
-
mp = MultiPole<MPSingular> (-1, mp.Kappa());
|
|
686
|
+
mp = MultiPole<MPSingular,entry_type> (-1, mp.Kappa(), 1.);
|
|
522
687
|
return;
|
|
523
688
|
}
|
|
524
689
|
|
|
@@ -527,10 +692,13 @@ namespace ngfem
|
|
|
527
692
|
|
|
528
693
|
for (auto [x,d,c] : dipoles)
|
|
529
694
|
mp.AddDipole (x-center, d, c);
|
|
695
|
+
|
|
696
|
+
for (auto [sp,ep,j,num] : currents)
|
|
697
|
+
mp.AddCurrent (sp-center, ep-center, j, num);
|
|
530
698
|
}
|
|
531
699
|
}
|
|
532
700
|
|
|
533
|
-
|
|
701
|
+
entry_type EvaluateMP(Vec<3> p) const
|
|
534
702
|
{
|
|
535
703
|
if (charges.Size() || dipoles.Size())
|
|
536
704
|
return Evaluate(p);
|
|
@@ -541,22 +709,43 @@ namespace ngfem
|
|
|
541
709
|
if (!childs[0]) // || level==1)
|
|
542
710
|
return Evaluate(p);
|
|
543
711
|
|
|
544
|
-
|
|
712
|
+
entry_type sum{0.0};
|
|
545
713
|
for (auto & child : childs)
|
|
546
714
|
sum += child->EvaluateMP(p);
|
|
547
715
|
return sum;
|
|
548
716
|
}
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
717
|
+
|
|
718
|
+
entry_type EvaluateMPDeriv(Vec<3> p, Vec<3> d) const
|
|
719
|
+
{
|
|
720
|
+
// cout << "EvaluateMPDeriv Singular, p = " << p << ", d = " << d << ", r = " << r << ", center = " << center << endl;
|
|
721
|
+
// cout << "Norm: " << L2Norm(p-center) << " > " << 3*r << endl;
|
|
722
|
+
// cout << "charges.Size() = " << charges.Size() << ", dipoles.Size() = " << dipoles.Size() << endl;
|
|
723
|
+
if (charges.Size() || dipoles.Size() || !childs[0])
|
|
724
|
+
return EvaluateDeriv(p, d);
|
|
725
|
+
|
|
726
|
+
if (L2Norm(p-center) > 3*r)
|
|
727
|
+
return mp.EvalDirectionalDerivative(p-center, d);
|
|
728
|
+
|
|
729
|
+
entry_type sum{0.0};
|
|
730
|
+
for (auto & child : childs)
|
|
731
|
+
sum += child->EvaluateMPDeriv(p, d);
|
|
732
|
+
return sum;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
void Print (ostream & ost, size_t childnr = -1) const
|
|
552
736
|
{
|
|
553
|
-
|
|
737
|
+
if (childnr == -1)
|
|
738
|
+
ost << "c = " << center << ", r = " << r << ", level = " << level << endl;
|
|
739
|
+
else
|
|
740
|
+
ost << "c = " << center << ", r = " << r << ", level = " << level << ", childnr = " << childnr << endl;
|
|
554
741
|
// for (int i = 0; i < loc_pnts.Size(); i++)
|
|
555
742
|
for (auto [x,c] : charges)
|
|
556
743
|
ost << "xi = " << x << ", ci = " << c << endl;
|
|
744
|
+
for (auto [x,d,c] : dipoles)
|
|
745
|
+
ost << "xi = " << x << ", di = " << d << ", ci = " << c << endl;
|
|
557
746
|
|
|
558
747
|
for (int i = 0; i < 8; i++)
|
|
559
|
-
if (childs[i]) childs[i] -> Print (ost);
|
|
748
|
+
if (childs[i]) childs[i] -> Print (ost, i);
|
|
560
749
|
}
|
|
561
750
|
|
|
562
751
|
double Norm () const
|
|
@@ -591,16 +780,41 @@ namespace ngfem
|
|
|
591
780
|
|
|
592
781
|
double Kappa() const { return root.mp.Kappa(); }
|
|
593
782
|
|
|
594
|
-
void AddCharge(Vec<3> x,
|
|
783
|
+
void AddCharge(Vec<3> x, entry_type c)
|
|
595
784
|
{
|
|
596
785
|
root.AddCharge(x, c);
|
|
597
786
|
}
|
|
598
787
|
|
|
599
|
-
void AddDipole(Vec<3> x, Vec<3> d,
|
|
788
|
+
void AddDipole(Vec<3> x, Vec<3> d, entry_type c)
|
|
600
789
|
{
|
|
601
790
|
root.AddDipole(x, d, c);
|
|
602
791
|
}
|
|
603
792
|
|
|
793
|
+
void AddCurrent (Vec<3> sp, Vec<3> ep, Complex j, int num)
|
|
794
|
+
{
|
|
795
|
+
if constexpr (!std::is_same<entry_type, Vec<3,Complex>>())
|
|
796
|
+
throw Exception("AddCurrent needs a singular vectorial MP");
|
|
797
|
+
|
|
798
|
+
root.AddCurrent (sp, ep, j, num);
|
|
799
|
+
/*
|
|
800
|
+
// for testing
|
|
801
|
+
Vec<3> tau = ep-sp;
|
|
802
|
+
Vec<3> tau_num = 1.0/num * tau;
|
|
803
|
+
for (int i = 0; i < num; i++)
|
|
804
|
+
{
|
|
805
|
+
for (int k = 0; k < 3; k++)
|
|
806
|
+
{
|
|
807
|
+
Vec<3> ek{0.0}; ek(k) = 1;
|
|
808
|
+
Vec<3> cp = Cross(tau, ek);
|
|
809
|
+
Vec<3,Complex> source{0.0};
|
|
810
|
+
source(k) = j/double(num);
|
|
811
|
+
if constexpr (std::is_same<entry_type, Vec<3,Complex>>())
|
|
812
|
+
root.AddDipole (sp+(i+0.5)*tau_num, cp, source);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
*/
|
|
816
|
+
}
|
|
817
|
+
|
|
604
818
|
void Print (ostream & ost) const
|
|
605
819
|
{
|
|
606
820
|
root.Print(ost);
|
|
@@ -634,7 +848,7 @@ namespace ngfem
|
|
|
634
848
|
havemp = true;
|
|
635
849
|
}
|
|
636
850
|
|
|
637
|
-
|
|
851
|
+
entry_type Evaluate (Vec<3> p) const
|
|
638
852
|
{
|
|
639
853
|
if (havemp)
|
|
640
854
|
return root.EvaluateMP(p);
|
|
@@ -642,17 +856,20 @@ namespace ngfem
|
|
|
642
856
|
return root.Evaluate(p);
|
|
643
857
|
}
|
|
644
858
|
|
|
859
|
+
template <typename entry_type2>
|
|
645
860
|
friend class RegularMLMultiPole;
|
|
646
861
|
};
|
|
647
862
|
|
|
648
863
|
|
|
649
|
-
|
|
864
|
+
template <typename entry_type>
|
|
865
|
+
inline ostream & operator<< (ostream & ost, const SingularMLMultiPole<entry_type> & mlmp)
|
|
650
866
|
{
|
|
651
867
|
mlmp.Print(ost);
|
|
652
868
|
return ost;
|
|
653
869
|
}
|
|
654
870
|
|
|
655
871
|
|
|
872
|
+
template <typename elem_type=Complex>
|
|
656
873
|
class NGS_DLL_HEADER RegularMLMultiPole
|
|
657
874
|
{
|
|
658
875
|
static Array<size_t> nodes_on_level;
|
|
@@ -663,11 +880,11 @@ namespace ngfem
|
|
|
663
880
|
double r;
|
|
664
881
|
int level;
|
|
665
882
|
std::array<unique_ptr<Node>,8> childs;
|
|
666
|
-
MultiPole<MPRegular> mp;
|
|
883
|
+
MultiPole<MPRegular,elem_type> mp;
|
|
667
884
|
Array<Vec<3>> targets;
|
|
668
885
|
int total_targets;
|
|
669
886
|
|
|
670
|
-
Array<const SingularMLMultiPole
|
|
887
|
+
Array<const typename SingularMLMultiPole<elem_type>::Node*> singnodes;
|
|
671
888
|
|
|
672
889
|
Node (Vec<3> acenter, double ar, int alevel, int order, double kappa)
|
|
673
890
|
: center(acenter), r(ar), level(alevel), mp(MPOrder(ar*kappa), kappa, 1.0/min(1.0, 0.25*r*kappa))
|
|
@@ -692,7 +909,7 @@ namespace ngfem
|
|
|
692
909
|
}
|
|
693
910
|
}
|
|
694
911
|
|
|
695
|
-
void AddSingularNode (const SingularMLMultiPole
|
|
912
|
+
void AddSingularNode (const typename SingularMLMultiPole<elem_type>::Node & singnode, bool allow_refine)
|
|
696
913
|
{
|
|
697
914
|
if (mp.SH().Order() < 0) return;
|
|
698
915
|
if (singnode.mp.SH().Order() < 0) return;
|
|
@@ -781,15 +998,15 @@ namespace ngfem
|
|
|
781
998
|
mp.TransformAdd (ch->mp, ch->center-center);
|
|
782
999
|
ch->LocalizeExpansion(allow_refine);
|
|
783
1000
|
}
|
|
784
|
-
mp = MultiPole<MPRegular>(-1, mp.Kappa());
|
|
1001
|
+
mp = MultiPole<MPRegular,elem_type>(-1, mp.Kappa(), 1.);
|
|
785
1002
|
//mp.SH().Coefs()=0.0;
|
|
786
1003
|
}
|
|
787
1004
|
}
|
|
788
1005
|
|
|
789
|
-
|
|
1006
|
+
elem_type Evaluate (Vec<3> p) const
|
|
790
1007
|
{
|
|
791
1008
|
// *testout << "eval p = " << p << ", level = " << level << ", center = " << center << ", r = " << r << endl;
|
|
792
|
-
|
|
1009
|
+
elem_type sum{0.0};
|
|
793
1010
|
/*
|
|
794
1011
|
if (childs[0])
|
|
795
1012
|
{
|
|
@@ -817,6 +1034,28 @@ namespace ngfem
|
|
|
817
1034
|
return sum;
|
|
818
1035
|
}
|
|
819
1036
|
|
|
1037
|
+
elem_type EvaluateDirectionalDerivative (Vec<3> p, Vec<3> d) const
|
|
1038
|
+
{
|
|
1039
|
+
elem_type sum{0.0};
|
|
1040
|
+
// cout << "EvaluateDirectionalDerivative RegularMLMP, r = " << r << ", level = " << level << ", center = " << center << endl;
|
|
1041
|
+
// cout << "Singnodes: " << singnodes.Size() << ", childs: " << childs[0] << endl;
|
|
1042
|
+
|
|
1043
|
+
int childnum = 0;
|
|
1044
|
+
if (p(0) > center(0)) childnum += 1;
|
|
1045
|
+
if (p(1) > center(1)) childnum += 2;
|
|
1046
|
+
if (p(2) > center(2)) childnum += 4;
|
|
1047
|
+
if (childs[childnum])
|
|
1048
|
+
sum = childs[childnum]->EvaluateDirectionalDerivative(p, d);
|
|
1049
|
+
else
|
|
1050
|
+
sum = mp.EvalDirectionalDerivative(p-center, d);
|
|
1051
|
+
|
|
1052
|
+
static Timer t("mptool direct evaluate deriv"); RegionTimer r(t);
|
|
1053
|
+
for (auto sn : singnodes)
|
|
1054
|
+
sum += sn->EvaluateMPDeriv(p, d);
|
|
1055
|
+
|
|
1056
|
+
return sum;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
820
1059
|
double Norm() const
|
|
821
1060
|
{
|
|
822
1061
|
double norm = L2Norm(mp.SH().Coefs());
|
|
@@ -883,16 +1122,30 @@ namespace ngfem
|
|
|
883
1122
|
}
|
|
884
1123
|
|
|
885
1124
|
if (total_targets == 0)
|
|
886
|
-
mp = MultiPole<MPRegular>(-1, mp.Kappa());
|
|
1125
|
+
mp = MultiPole<MPRegular,elem_type>(-1, mp.Kappa(),1.);
|
|
887
1126
|
}
|
|
888
1127
|
|
|
1128
|
+
|
|
1129
|
+
void Print (ostream & ost, size_t childnr = -1) const
|
|
1130
|
+
{
|
|
1131
|
+
if (childnr == -1)
|
|
1132
|
+
ost << "c = " << center << ", r = " << r << ", level = " << level << endl;
|
|
1133
|
+
else
|
|
1134
|
+
ost << "c = " << center << ", r = " << r << ", level = " << level << ", childnr = " << childnr << endl;
|
|
1135
|
+
for (auto x : targets)
|
|
1136
|
+
ost << "xi = " << x << endl;
|
|
1137
|
+
|
|
1138
|
+
for (int i = 0; i < 8; i++)
|
|
1139
|
+
if (childs[i]) childs[i] -> Print (ost, i);
|
|
1140
|
+
}
|
|
1141
|
+
|
|
889
1142
|
};
|
|
890
1143
|
|
|
891
1144
|
Node root;
|
|
892
|
-
shared_ptr<SingularMLMultiPole
|
|
1145
|
+
shared_ptr<SingularMLMultiPole<elem_type>> singmp;
|
|
893
1146
|
|
|
894
1147
|
public:
|
|
895
|
-
|
|
1148
|
+
RegularMLMultiPole (shared_ptr<SingularMLMultiPole<elem_type>> asingmp, Vec<3> center, double r, int order)
|
|
896
1149
|
: root(center, r, 0, order, asingmp->Kappa()), singmp(asingmp)
|
|
897
1150
|
{
|
|
898
1151
|
if (!singmp->havemp) throw Exception("first call Calc for singular MP");
|
|
@@ -934,7 +1187,7 @@ namespace ngfem
|
|
|
934
1187
|
root.AddTarget (t);
|
|
935
1188
|
}
|
|
936
1189
|
|
|
937
|
-
void CalcMP(shared_ptr<SingularMLMultiPole
|
|
1190
|
+
void CalcMP(shared_ptr<SingularMLMultiPole<elem_type>> asingmp)
|
|
938
1191
|
{
|
|
939
1192
|
singmp = asingmp;
|
|
940
1193
|
|
|
@@ -955,6 +1208,11 @@ namespace ngfem
|
|
|
955
1208
|
root.LocalizeExpansion(false);
|
|
956
1209
|
}
|
|
957
1210
|
|
|
1211
|
+
void Print (ostream & ost) const
|
|
1212
|
+
{
|
|
1213
|
+
root.Print(ost);
|
|
1214
|
+
}
|
|
1215
|
+
|
|
958
1216
|
double Norm() const
|
|
959
1217
|
{
|
|
960
1218
|
return root.Norm();
|
|
@@ -965,21 +1223,26 @@ namespace ngfem
|
|
|
965
1223
|
return root.NumCoefficients();
|
|
966
1224
|
}
|
|
967
1225
|
|
|
968
|
-
|
|
1226
|
+
elem_type Evaluate (Vec<3> p) const
|
|
969
1227
|
{
|
|
970
1228
|
// static Timer t("mptool Eval MLMP regular"); RegionTimer r(t);
|
|
971
|
-
if (L2Norm(p-root.center) > root.r) return 0.0;
|
|
1229
|
+
if (L2Norm(p-root.center) > root.r) return elem_type{0.0};
|
|
972
1230
|
return root.Evaluate(p);
|
|
973
1231
|
}
|
|
974
1232
|
|
|
975
|
-
|
|
1233
|
+
elem_type EvaluateDirectionalDerivative (Vec<3> p, Vec<3> d) const
|
|
1234
|
+
{
|
|
1235
|
+
if (L2Norm(p-root.center) > root.r) return elem_type{0.0};
|
|
1236
|
+
return root.EvaluateDirectionalDerivative(p, d);
|
|
1237
|
+
}
|
|
1238
|
+
|
|
976
1239
|
};
|
|
977
|
-
|
|
978
1240
|
|
|
979
|
-
|
|
1241
|
+
template <typename elem_type>
|
|
1242
|
+
inline ostream & operator<< (ostream & ost, const RegularMLMultiPole<elem_type> & mlmp)
|
|
980
1243
|
{
|
|
981
|
-
|
|
982
|
-
ost << "RegularMLMultiPole" << endl;
|
|
1244
|
+
mlmp.Print(ost);
|
|
1245
|
+
// ost << "RegularMLMultiPole" << endl;
|
|
983
1246
|
return ost;
|
|
984
1247
|
}
|
|
985
1248
|
|
|
@@ -993,7 +1256,7 @@ namespace ngfem
|
|
|
993
1256
|
|
|
994
1257
|
class SphericalHarmonicsCF : public CoefficientFunction
|
|
995
1258
|
{
|
|
996
|
-
SphericalHarmonics sh;
|
|
1259
|
+
SphericalHarmonics<Complex> sh;
|
|
997
1260
|
public:
|
|
998
1261
|
SphericalHarmonicsCF (int order)
|
|
999
1262
|
: CoefficientFunction(1, true), sh(order) { }
|
|
@@ -1021,16 +1284,19 @@ namespace ngfem
|
|
|
1021
1284
|
|
|
1022
1285
|
|
|
1023
1286
|
|
|
1024
|
-
template <typename
|
|
1287
|
+
template <typename entry_type> class RegularMLMultiPoleCF;
|
|
1288
|
+
|
|
1289
|
+
|
|
1290
|
+
template <typename RADIAL, typename entry_type=Complex>
|
|
1025
1291
|
class MultiPoleCF : public CoefficientFunction
|
|
1026
1292
|
{
|
|
1027
|
-
MultiPole<RADIAL> mp;
|
|
1293
|
+
MultiPole<RADIAL, entry_type> mp;
|
|
1028
1294
|
Vec<3> center;
|
|
1029
1295
|
public:
|
|
1030
1296
|
MultiPoleCF (int order, double kappa, Vec<3> acenter, double scale = 1)
|
|
1031
|
-
: CoefficientFunction(
|
|
1297
|
+
: CoefficientFunction(sizeof(entry_type)/sizeof(Complex), true), mp(order, kappa, scale), center(acenter) { }
|
|
1032
1298
|
|
|
1033
|
-
|
|
1299
|
+
entry_type & Coef(int n, int m) { return mp.Coef(n,m); }
|
|
1034
1300
|
auto & SH() { return mp.SH(); }
|
|
1035
1301
|
auto & MP() { return mp; }
|
|
1036
1302
|
Vec<3> Center() const { return center; }
|
|
@@ -1040,56 +1306,75 @@ namespace ngfem
|
|
|
1040
1306
|
|
|
1041
1307
|
virtual void Evaluate (const BaseMappedIntegrationPoint & mip, FlatVector<Complex> values) const override
|
|
1042
1308
|
{
|
|
1043
|
-
|
|
1309
|
+
if constexpr (std::is_same<entry_type, Complex>())
|
|
1310
|
+
values(0) = mp.Eval(mip.GetPoint()-center);
|
|
1311
|
+
else
|
|
1312
|
+
values = mp.Eval(mip.GetPoint()-center);
|
|
1044
1313
|
}
|
|
1045
1314
|
|
|
1046
1315
|
template <typename TARGET>
|
|
1047
|
-
void ShiftZ (double z, MultiPole<TARGET> & target) { mp.ShiftZ(z, target); }
|
|
1316
|
+
void ShiftZ (double z, MultiPole<TARGET, entry_type> & target) { mp.ShiftZ(z, target); }
|
|
1048
1317
|
|
|
1049
1318
|
using CoefficientFunction::Transform;
|
|
1050
1319
|
template <typename TARGET>
|
|
1051
|
-
void Transform (MultiPoleCF<TARGET> & target)
|
|
1320
|
+
void Transform (MultiPoleCF<TARGET, entry_type> & target)
|
|
1052
1321
|
{
|
|
1053
1322
|
mp.Transform (target.MP(), target.Center()-center);
|
|
1054
1323
|
}
|
|
1055
1324
|
};
|
|
1056
1325
|
|
|
1057
|
-
|
|
1326
|
+
template <typename entry_type>
|
|
1058
1327
|
class SingularMLMultiPoleCF : public CoefficientFunction
|
|
1059
1328
|
{
|
|
1060
|
-
shared_ptr<SingularMLMultiPole
|
|
1329
|
+
shared_ptr<SingularMLMultiPole<entry_type>> mlmp;
|
|
1061
1330
|
public:
|
|
1062
1331
|
SingularMLMultiPoleCF (Vec<3> center, double r, int order, double kappa)
|
|
1063
|
-
: CoefficientFunction(
|
|
1332
|
+
: CoefficientFunction(sizeof(entry_type)/sizeof(Complex), true), mlmp{make_shared<SingularMLMultiPole<entry_type>>(center, r, order, kappa)} { }
|
|
1064
1333
|
|
|
1065
1334
|
virtual double Evaluate (const BaseMappedIntegrationPoint & ip) const override
|
|
1066
1335
|
{ throw Exception("real eval not available"); }
|
|
1067
1336
|
|
|
1068
1337
|
virtual void Evaluate (const BaseMappedIntegrationPoint & mip, FlatVector<Complex> values) const override
|
|
1069
1338
|
{
|
|
1070
|
-
values(0) = mlmp->Evaluate(mip.GetPoint());
|
|
1339
|
+
// values(0) = mlmp->Evaluate(mip.GetPoint());
|
|
1340
|
+
|
|
1341
|
+
if constexpr (std::is_same<entry_type, Complex>())
|
|
1342
|
+
values(0) = mlmp->Evaluate(mip.GetPoint());
|
|
1343
|
+
else
|
|
1344
|
+
values = mlmp->Evaluate(mip.GetPoint());
|
|
1345
|
+
|
|
1346
|
+
|
|
1071
1347
|
}
|
|
1072
1348
|
|
|
1073
|
-
shared_ptr<SingularMLMultiPole
|
|
1349
|
+
shared_ptr<SingularMLMultiPole<entry_type>> MLMP() const { return mlmp; }
|
|
1350
|
+
shared_ptr<RegularMLMultiPoleCF<entry_type>> CreateRegularExpansion(Vec<3> center, double r) const;
|
|
1074
1351
|
};
|
|
1075
1352
|
|
|
1076
1353
|
|
|
1354
|
+
template <typename entry_type>
|
|
1077
1355
|
class RegularMLMultiPoleCF : public CoefficientFunction
|
|
1078
1356
|
{
|
|
1079
|
-
shared_ptr<RegularMLMultiPole
|
|
1357
|
+
shared_ptr<RegularMLMultiPole<entry_type>> mlmp;
|
|
1080
1358
|
public:
|
|
1081
|
-
RegularMLMultiPoleCF (shared_ptr<SingularMLMultiPoleCF
|
|
1082
|
-
: CoefficientFunction(
|
|
1359
|
+
RegularMLMultiPoleCF (shared_ptr<SingularMLMultiPoleCF<entry_type>> asingmp, Vec<3> center, double r, int order)
|
|
1360
|
+
: CoefficientFunction(sizeof(entry_type)/sizeof(Complex), true), mlmp{make_shared<RegularMLMultiPole<entry_type>>(asingmp->MLMP(), center, r, order)} { }
|
|
1361
|
+
RegularMLMultiPoleCF (shared_ptr<SingularMLMultiPole<entry_type>> asingmp, Vec<3> center, double r, int order)
|
|
1362
|
+
: CoefficientFunction(sizeof(entry_type)/sizeof(Complex), true), mlmp{make_shared<RegularMLMultiPole<entry_type>>(asingmp, center, r, order)} { }
|
|
1083
1363
|
|
|
1084
1364
|
virtual double Evaluate (const BaseMappedIntegrationPoint & ip) const override
|
|
1085
1365
|
{ throw Exception("real eval not available"); }
|
|
1086
1366
|
|
|
1087
1367
|
virtual void Evaluate (const BaseMappedIntegrationPoint & mip, FlatVector<Complex> values) const override
|
|
1088
1368
|
{
|
|
1089
|
-
values(0) = mlmp->Evaluate(mip.GetPoint());
|
|
1369
|
+
// values(0) = mlmp->Evaluate(mip.GetPoint());
|
|
1370
|
+
|
|
1371
|
+
if constexpr (std::is_same<entry_type, Complex>())
|
|
1372
|
+
values(0) = mlmp->Evaluate(mip.GetPoint());
|
|
1373
|
+
else
|
|
1374
|
+
values = mlmp->Evaluate(mip.GetPoint());
|
|
1090
1375
|
}
|
|
1091
1376
|
|
|
1092
|
-
shared_ptr<RegularMLMultiPole
|
|
1377
|
+
shared_ptr<RegularMLMultiPole<entry_type>> MLMP() { return mlmp; }
|
|
1093
1378
|
};
|
|
1094
1379
|
|
|
1095
1380
|
|