ngsolve 6.2.2505.post105.dev0__cp311-cp311-macosx_10_15_universal2.whl → 6.2.2506.post33.dev0__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/analytic_integrals.hpp +10 -0
- netgen/include/bdbequations.hpp +20 -0
- netgen/include/bem_diffops.hpp +475 -0
- netgen/include/bspline.hpp +2 -0
- netgen/include/contact.hpp +4 -0
- netgen/include/h1lumping.hpp +6 -0
- netgen/include/hcurl_equations.hpp +29 -0
- netgen/include/hdivfe_utils.hpp +1 -0
- netgen/include/kernels.hpp +654 -0
- netgen/include/mp_coefficient.hpp +20 -20
- netgen/include/mptools.hpp +268 -123
- netgen/include/potentialtools.hpp +2 -2
- netgen/include/thdivfe_impl.hpp +66 -0
- 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 +1 -1
- ngsolve/config/config.py +6 -6
- ngsolve/demos/intro/cmagnet.py +19 -22
- ngsolve/solve_implementation.py +4 -0
- {ngsolve-6.2.2505.post105.dev0.dist-info → ngsolve-6.2.2506.post33.dev0.dist-info}/METADATA +2 -2
- {ngsolve-6.2.2505.post105.dev0.dist-info → ngsolve-6.2.2506.post33.dev0.dist-info}/RECORD +62 -59
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/Netgen.icns +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/bin/ngscxx +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/bin/ngsld +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/bin/ngsolve.tcl +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/bin/ngspy +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/beam.geo +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/beam.vol +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/chip.in2d +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/chip.vol +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/coil.geo +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/coil.vol +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/coilshield.geo +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/coilshield.vol +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/cube.geo +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/cube.vol +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d10_DGdoubleglazing.pde +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d11_chip_nitsche.pde +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d1_square.pde +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d2_chip.pde +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d3_helmholtz.pde +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d4_cube.pde +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d5_beam.pde +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d6_shaft.pde +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d7_coil.pde +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d8_coilshield.pde +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d9_hybridDG.pde +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/doubleglazing.in2d +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/doubleglazing.vol +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/piezo2d40round4.vol.gz +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/shaft.geo +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/shaft.vol +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/square.in2d +0 -0
- {ngsolve-6.2.2505.post105.dev0.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/square.vol +0 -0
- {ngsolve-6.2.2505.post105.dev0.dist-info → ngsolve-6.2.2506.post33.dev0.dist-info}/LICENSE +0 -0
- {ngsolve-6.2.2505.post105.dev0.dist-info → ngsolve-6.2.2506.post33.dev0.dist-info}/WHEEL +0 -0
- {ngsolve-6.2.2505.post105.dev0.dist-info → ngsolve-6.2.2506.post33.dev0.dist-info}/top_level.txt +0 -0
netgen/include/mptools.hpp
CHANGED
|
@@ -303,7 +303,7 @@ namespace ngsbem
|
|
|
303
303
|
|
|
304
304
|
|
|
305
305
|
// hn1 = jn+ i*yn
|
|
306
|
-
class
|
|
306
|
+
class Singular
|
|
307
307
|
{
|
|
308
308
|
public:
|
|
309
309
|
template <typename T>
|
|
@@ -329,7 +329,7 @@ namespace ngsbem
|
|
|
329
329
|
|
|
330
330
|
|
|
331
331
|
// jn
|
|
332
|
-
class
|
|
332
|
+
class Regular
|
|
333
333
|
{
|
|
334
334
|
public:
|
|
335
335
|
template <typename T>
|
|
@@ -357,14 +357,14 @@ namespace ngsbem
|
|
|
357
357
|
|
|
358
358
|
|
|
359
359
|
template <typename RADIAL, typename entry_type=Complex>
|
|
360
|
-
class NGS_DLL_HEADER
|
|
360
|
+
class NGS_DLL_HEADER SphericalExpansion
|
|
361
361
|
{
|
|
362
362
|
SphericalHarmonics<entry_type> sh;
|
|
363
363
|
double kappa;
|
|
364
364
|
double rtyp;
|
|
365
365
|
public:
|
|
366
366
|
|
|
367
|
-
|
|
367
|
+
SphericalExpansion (int aorder, double akappa, double artyp)
|
|
368
368
|
: sh(aorder), kappa(akappa), rtyp(artyp) { }
|
|
369
369
|
|
|
370
370
|
|
|
@@ -376,15 +376,15 @@ namespace ngsbem
|
|
|
376
376
|
double RTyp() const { return rtyp; }
|
|
377
377
|
int Order() const { return sh.Order(); }
|
|
378
378
|
|
|
379
|
-
|
|
379
|
+
SphericalExpansion Truncate(int neworder) const
|
|
380
380
|
{
|
|
381
381
|
if (neworder > sh.Order()) neworder=sh.Order();
|
|
382
|
-
|
|
382
|
+
SphericalExpansion nmp(neworder, kappa, rtyp);
|
|
383
383
|
nmp.sh.Coefs() = sh.Coefs().Range(sqr(neworder+1));
|
|
384
384
|
return nmp;
|
|
385
385
|
}
|
|
386
386
|
|
|
387
|
-
|
|
387
|
+
SphericalExpansion & operator+= (const SphericalExpansion & mp2)
|
|
388
388
|
{
|
|
389
389
|
size_t commonsize = min(SH().Coefs().Size(), mp2.SH().Coefs().Size());
|
|
390
390
|
SH().Coefs().Range(commonsize) += mp2.SH().Coefs().Range(commonsize);
|
|
@@ -395,27 +395,24 @@ namespace ngsbem
|
|
|
395
395
|
entry_type EvalDirectionalDerivative (Vec<3> x, Vec<3> d) const;
|
|
396
396
|
|
|
397
397
|
void AddCharge (Vec<3> x, entry_type c);
|
|
398
|
-
void AddDipole (Vec<3> x, Vec<3>
|
|
399
|
-
void
|
|
400
|
-
|
|
401
|
-
/*
|
|
402
|
-
void ChangeScaleTo (double newscale)
|
|
398
|
+
void AddDipole (Vec<3> x, Vec<3> dir, entry_type c);
|
|
399
|
+
void AddChargeDipole (Vec<3> x, entry_type c, Vec<3> dir, entry_type c2)
|
|
403
400
|
{
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
sh.CoefsN(n) *= prod;
|
|
408
|
-
scale = newscale;
|
|
401
|
+
// TODO: add them at once
|
|
402
|
+
AddCharge (x, c);
|
|
403
|
+
AddDipole (x, dir, c2);
|
|
409
404
|
}
|
|
410
|
-
|
|
405
|
+
|
|
406
|
+
void AddPlaneWave (Vec<3> d, entry_type c);
|
|
407
|
+
void AddCurrent (Vec<3> ap, Vec<3> ep, Complex j, int num=100);
|
|
408
|
+
|
|
409
|
+
|
|
411
410
|
void ChangeRTypTo (double new_rtyp)
|
|
412
411
|
{
|
|
413
|
-
// double fac = Scale()/newscale;
|
|
414
412
|
double fac = RADIAL::Scale(kappa, rtyp) / RADIAL::Scale(kappa, new_rtyp);
|
|
415
413
|
double prod = 1;
|
|
416
414
|
for (int n = 0; n <= sh.Order(); n++, prod*= fac)
|
|
417
415
|
sh.CoefsN(n) *= prod;
|
|
418
|
-
// scale = newscale;
|
|
419
416
|
rtyp = new_rtyp;
|
|
420
417
|
}
|
|
421
418
|
|
|
@@ -434,7 +431,7 @@ namespace ngsbem
|
|
|
434
431
|
|
|
435
432
|
|
|
436
433
|
template <typename TARGET>
|
|
437
|
-
void Transform (
|
|
434
|
+
void Transform (SphericalExpansion<TARGET,entry_type> & target, Vec<3> dist) const
|
|
438
435
|
{
|
|
439
436
|
if (target.SH().Order() < 0) return;
|
|
440
437
|
if (SH().Order() < 0)
|
|
@@ -449,8 +446,8 @@ namespace ngsbem
|
|
|
449
446
|
auto [len, theta, phi] = SphericalCoordinates(dist);
|
|
450
447
|
|
|
451
448
|
|
|
452
|
-
//
|
|
453
|
-
|
|
449
|
+
// SphericalExpansion<RADIAL,entry_type> tmp{*this};
|
|
450
|
+
SphericalExpansion<RADIAL,entry_type> tmp(Order(), kappa, rtyp);
|
|
454
451
|
tmp.SH().Coefs() = SH().Coefs();
|
|
455
452
|
|
|
456
453
|
tmp.SH().RotateZ(phi);
|
|
@@ -463,12 +460,12 @@ namespace ngsbem
|
|
|
463
460
|
}
|
|
464
461
|
|
|
465
462
|
template <typename TARGET>
|
|
466
|
-
void TransformAdd (
|
|
463
|
+
void TransformAdd (SphericalExpansion<TARGET,entry_type> & target, Vec<3> dist, bool atomic = false) const
|
|
467
464
|
{
|
|
468
465
|
if (SH().Order() < 0) return;
|
|
469
466
|
if (target.SH().Order() < 0) return;
|
|
470
467
|
|
|
471
|
-
|
|
468
|
+
SphericalExpansion<TARGET,entry_type> tmp{target};
|
|
472
469
|
Transform(tmp, dist);
|
|
473
470
|
if (!atomic)
|
|
474
471
|
target.SH().Coefs() += tmp.SH().Coefs();
|
|
@@ -478,8 +475,20 @@ namespace ngsbem
|
|
|
478
475
|
}
|
|
479
476
|
|
|
480
477
|
template <typename TARGET>
|
|
481
|
-
void ShiftZ (double z,
|
|
478
|
+
void ShiftZ (double z, SphericalExpansion<TARGET,entry_type> & target);
|
|
479
|
+
|
|
482
480
|
|
|
481
|
+
template <typename TARGET>
|
|
482
|
+
void In2Out (SphericalExpansion<TARGET,entry_type> & target, double r) const
|
|
483
|
+
{
|
|
484
|
+
Vector<Complex> rad(Order()+1);
|
|
485
|
+
Vector<Complex> radout(target.Order()+1);
|
|
486
|
+
RADIAL::Eval(Order(), kappa, r, RTyp(), rad);
|
|
487
|
+
TARGET::Eval(target.Order(), kappa, r, target.RTyp(), radout);
|
|
488
|
+
target.SH().Coefs() = 0;
|
|
489
|
+
for (int j = 0; j <= std::min(Order(), target.Order()); j++)
|
|
490
|
+
target.SH().CoefsN(j) = rad(j)/radout(j) * SH().CoefsN(j);
|
|
491
|
+
}
|
|
483
492
|
};
|
|
484
493
|
|
|
485
494
|
|
|
@@ -488,7 +497,8 @@ namespace ngsbem
|
|
|
488
497
|
|
|
489
498
|
static constexpr int MPOrder (double rho_kappa)
|
|
490
499
|
{
|
|
491
|
-
return max (20, int(2*rho_kappa));
|
|
500
|
+
// return max (20, int(2*rho_kappa));
|
|
501
|
+
return 20+int(2*rho_kappa);
|
|
492
502
|
}
|
|
493
503
|
static constexpr int maxdirect = 100;
|
|
494
504
|
|
|
@@ -506,22 +516,22 @@ namespace ngsbem
|
|
|
506
516
|
|
|
507
517
|
|
|
508
518
|
template <typename entry_type=Complex>
|
|
509
|
-
class
|
|
519
|
+
class SingularMLExpansion
|
|
510
520
|
{
|
|
511
521
|
using simd_entry_type = decltype(MakeSimd(declval<std::array<entry_type,FMM_SW>>()));
|
|
512
522
|
static Array<size_t> nodes_on_level;
|
|
513
523
|
|
|
514
524
|
struct RecordingSS
|
|
515
525
|
{
|
|
516
|
-
const
|
|
517
|
-
|
|
526
|
+
const SphericalExpansion<Singular,entry_type> * mp_source;
|
|
527
|
+
SphericalExpansion<Singular,entry_type> * mp_target;
|
|
518
528
|
Vec<3> dist;
|
|
519
529
|
double len, theta, phi;
|
|
520
530
|
bool flipz;
|
|
521
531
|
public:
|
|
522
532
|
RecordingSS() = default;
|
|
523
|
-
RecordingSS (const
|
|
524
|
-
|
|
533
|
+
RecordingSS (const SphericalExpansion<Singular,entry_type> * amp_source,
|
|
534
|
+
SphericalExpansion<Singular,entry_type> * amp_target,
|
|
525
535
|
Vec<3> adist)
|
|
526
536
|
: mp_source(amp_source), mp_target(amp_target), dist(adist)
|
|
527
537
|
{
|
|
@@ -579,8 +589,8 @@ namespace ngsbem
|
|
|
579
589
|
static void ProcessVectorizedBatch(FlatArray<RecordingSS*> batch, double len, double theta) {
|
|
580
590
|
|
|
581
591
|
// *testout << "Processing vectorized S->S batch of size " << batch.Size() << ", with N = " << N << ", vec_length = " << vec_length << ", len = " << len << ", theta = " << theta << endl;
|
|
582
|
-
|
|
583
|
-
|
|
592
|
+
SphericalExpansion<Singular, Vec<N,Complex>> vec_source(batch[0]->mp_source->Order(), batch[0]->mp_source->Kappa(), batch[0]->mp_source->RTyp());
|
|
593
|
+
SphericalExpansion<Singular, Vec<N,Complex>> vec_target(batch[0]->mp_target->Order(), batch[0]->mp_target->Kappa(), batch[0]->mp_target->RTyp());
|
|
584
594
|
|
|
585
595
|
// Copy multipoles into vectorized multipole
|
|
586
596
|
for (int i = 0; i < batch.Size(); i++)
|
|
@@ -617,15 +627,18 @@ namespace ngsbem
|
|
|
617
627
|
double r;
|
|
618
628
|
int level;
|
|
619
629
|
std::array<unique_ptr<Node>,8> childs;
|
|
620
|
-
|
|
630
|
+
SphericalExpansion<Singular, entry_type> mp;
|
|
621
631
|
|
|
622
632
|
Array<tuple<Vec<3>, entry_type>> charges;
|
|
623
633
|
Array<tuple<Vec<3>, Vec<3>, entry_type>> dipoles;
|
|
634
|
+
Array<tuple<Vec<3>, entry_type, Vec<3>, entry_type>> chargedipoles;
|
|
624
635
|
Array<tuple<Vec<3>, Vec<3>, Complex,int>> currents;
|
|
625
636
|
|
|
626
637
|
using simd_entry_type = decltype(MakeSimd(declval<std::array<entry_type,FMM_SW>>()));
|
|
627
638
|
Array<tuple<Vec<3,SIMD<double,FMM_SW>>, simd_entry_type>> simd_charges;
|
|
628
639
|
Array<tuple<Vec<3,SIMD<double,FMM_SW>>, Vec<3,SIMD<double,FMM_SW>>, simd_entry_type>> simd_dipoles;
|
|
640
|
+
Array<tuple<Vec<3,SIMD<double,FMM_SW>>, simd_entry_type,
|
|
641
|
+
Vec<3,SIMD<double,FMM_SW>>, simd_entry_type>> simd_chargedipoles;
|
|
629
642
|
|
|
630
643
|
int total_sources;
|
|
631
644
|
std::mutex node_mutex;
|
|
@@ -638,7 +651,15 @@ namespace ngsbem
|
|
|
638
651
|
nodes_on_level[level]++;
|
|
639
652
|
}
|
|
640
653
|
|
|
641
|
-
|
|
654
|
+
int GetChildNum (Vec<3> x) const
|
|
655
|
+
{
|
|
656
|
+
int childnum = 0;
|
|
657
|
+
if (x(0) > center(0)) childnum += 1;
|
|
658
|
+
if (x(1) > center(1)) childnum += 2;
|
|
659
|
+
if (x(2) > center(2)) childnum += 4;
|
|
660
|
+
return childnum;
|
|
661
|
+
}
|
|
662
|
+
|
|
642
663
|
void CreateChilds()
|
|
643
664
|
{
|
|
644
665
|
if (childs[0]) throw Exception("have already childs");
|
|
@@ -654,15 +675,32 @@ namespace ngsbem
|
|
|
654
675
|
}
|
|
655
676
|
|
|
656
677
|
|
|
678
|
+
void SendSourcesToChilds()
|
|
679
|
+
{
|
|
680
|
+
CreateChilds();
|
|
681
|
+
|
|
682
|
+
for (auto [x,c] : charges)
|
|
683
|
+
AddCharge (x,c);
|
|
684
|
+
for (auto [x,d,c] : dipoles)
|
|
685
|
+
AddDipole (x,d,c);
|
|
686
|
+
for (auto [x,c,d,c2] : chargedipoles)
|
|
687
|
+
AddChargeDipole (x,c,d,c2);
|
|
688
|
+
for (auto [sp,ep,j,num] : currents)
|
|
689
|
+
AddCurrent (sp,ep,j,num);
|
|
690
|
+
|
|
691
|
+
charges.SetSize0();
|
|
692
|
+
dipoles.SetSize0();
|
|
693
|
+
chargedipoles.SetSize0();
|
|
694
|
+
currents.SetSize0();
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
|
|
657
698
|
void AddCharge (Vec<3> x, entry_type c)
|
|
658
699
|
{
|
|
659
700
|
if (have_childs) // quick check without locking
|
|
660
701
|
{
|
|
661
702
|
// directly send to childs:
|
|
662
|
-
int childnum
|
|
663
|
-
if (x(0) > center(0)) childnum += 1;
|
|
664
|
-
if (x(1) > center(1)) childnum += 2;
|
|
665
|
-
if (x(2) > center(2)) childnum += 4;
|
|
703
|
+
int childnum = GetChildNum(x);
|
|
666
704
|
childs[childnum] -> AddCharge(x, c);
|
|
667
705
|
return;
|
|
668
706
|
}
|
|
@@ -671,36 +709,19 @@ namespace ngsbem
|
|
|
671
709
|
|
|
672
710
|
if (have_childs) // test again after locking
|
|
673
711
|
{
|
|
674
|
-
|
|
675
|
-
int childnum = 0;
|
|
676
|
-
if (x(0) > center(0)) childnum += 1;
|
|
677
|
-
if (x(1) > center(1)) childnum += 2;
|
|
678
|
-
if (x(2) > center(2)) childnum += 4;
|
|
712
|
+
int childnum = GetChildNum(x);
|
|
679
713
|
childs[childnum] -> AddCharge(x, c);
|
|
680
714
|
return;
|
|
681
715
|
}
|
|
682
716
|
|
|
683
|
-
|
|
684
|
-
|
|
685
717
|
charges.Append( tuple{x,c} );
|
|
686
718
|
|
|
687
719
|
// if (r*mp.Kappa() < 1e-8) return;
|
|
688
720
|
if (level > 20) return;
|
|
689
721
|
if (charges.Size() < maxdirect && r*mp.Kappa() < 1)
|
|
690
722
|
return;
|
|
691
|
-
|
|
692
|
-
CreateChilds();
|
|
693
|
-
|
|
694
|
-
for (auto [x,c] : charges)
|
|
695
|
-
AddCharge (x,c);
|
|
696
|
-
for (auto [x,d,c] : dipoles)
|
|
697
|
-
AddDipole (x,d,c);
|
|
698
|
-
for (auto [sp,ep,j,num] : currents)
|
|
699
|
-
AddCurrent (sp,ep,j,num);
|
|
700
723
|
|
|
701
|
-
|
|
702
|
-
dipoles.SetSize0();
|
|
703
|
-
currents.SetSize0();
|
|
724
|
+
SendSourcesToChilds();
|
|
704
725
|
}
|
|
705
726
|
|
|
706
727
|
|
|
@@ -709,11 +730,7 @@ namespace ngsbem
|
|
|
709
730
|
if (have_childs)
|
|
710
731
|
{
|
|
711
732
|
// directly send to childs:
|
|
712
|
-
|
|
713
|
-
int childnum = 0;
|
|
714
|
-
if (x(0) > center(0)) childnum += 1;
|
|
715
|
-
if (x(1) > center(1)) childnum += 2;
|
|
716
|
-
if (x(2) > center(2)) childnum += 4;
|
|
733
|
+
int childnum = GetChildNum(x);
|
|
717
734
|
childs[childnum] -> AddDipole(x, d, c);
|
|
718
735
|
return;
|
|
719
736
|
}
|
|
@@ -723,37 +740,54 @@ namespace ngsbem
|
|
|
723
740
|
if (have_childs)
|
|
724
741
|
{
|
|
725
742
|
// directly send to childs:
|
|
726
|
-
|
|
727
|
-
int childnum = 0;
|
|
728
|
-
if (x(0) > center(0)) childnum += 1;
|
|
729
|
-
if (x(1) > center(1)) childnum += 2;
|
|
730
|
-
if (x(2) > center(2)) childnum += 4;
|
|
743
|
+
int childnum = GetChildNum(x);
|
|
731
744
|
childs[childnum] -> AddDipole(x, d, c);
|
|
732
745
|
return;
|
|
733
746
|
}
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
747
|
|
|
738
748
|
dipoles.Append (tuple{x,d,c});
|
|
739
749
|
|
|
740
750
|
if (dipoles.Size() < maxdirect || r < 1e-8)
|
|
741
751
|
return;
|
|
752
|
+
|
|
753
|
+
SendSourcesToChilds();
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
void AddChargeDipole (Vec<3> x, entry_type c, Vec<3> dir, entry_type c2)
|
|
758
|
+
{
|
|
759
|
+
if (have_childs)
|
|
760
|
+
{
|
|
761
|
+
// directly send to childs:
|
|
762
|
+
int childnum = GetChildNum(x);
|
|
763
|
+
childs[childnum] -> AddChargeDipole(x, c, dir, c2);
|
|
764
|
+
return;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
lock_guard<mutex> guard(node_mutex);
|
|
768
|
+
|
|
769
|
+
if (have_childs)
|
|
770
|
+
{
|
|
771
|
+
// directly send to childs:
|
|
772
|
+
int childnum = GetChildNum(x);
|
|
773
|
+
childs[childnum] -> AddChargeDipole(x, c, dir, c2);
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
742
776
|
|
|
743
|
-
|
|
777
|
+
chargedipoles.Append (tuple{x,c,dir,c2});
|
|
744
778
|
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
for (auto [x,d,c] : dipoles)
|
|
748
|
-
AddDipole (x,d,c);
|
|
749
|
-
for (auto [sp,ep,j,num] : currents)
|
|
750
|
-
AddCurrent (sp,ep,j,num);
|
|
779
|
+
if (chargedipoles.Size() < maxdirect || r < 1e-8)
|
|
780
|
+
return;
|
|
751
781
|
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
782
|
+
SendSourcesToChilds();
|
|
783
|
+
|
|
784
|
+
/*
|
|
785
|
+
AddCharge (x, c);
|
|
786
|
+
AddDipole (x, dir, c2);
|
|
787
|
+
*/
|
|
755
788
|
}
|
|
756
789
|
|
|
790
|
+
|
|
757
791
|
// not parallel yet
|
|
758
792
|
void AddCurrent (Vec<3> sp, Vec<3> ep, Complex j, int num)
|
|
759
793
|
{
|
|
@@ -787,6 +821,12 @@ namespace ngsbem
|
|
|
787
821
|
|
|
788
822
|
currents.Append (tuple{sp,ep,j,num});
|
|
789
823
|
|
|
824
|
+
// if (currents.Size() < maxdirect || r < 1e-8)
|
|
825
|
+
if (currents.Size() < 4 || r < 1e-8)
|
|
826
|
+
return;
|
|
827
|
+
|
|
828
|
+
SendSourcesToChilds();
|
|
829
|
+
/*
|
|
790
830
|
// if (currents.Size() < maxdirect || r < 1e-8)
|
|
791
831
|
if (currents.Size() < 4 || r < 1e-8)
|
|
792
832
|
return;
|
|
@@ -803,6 +843,7 @@ namespace ngsbem
|
|
|
803
843
|
charges.SetSize0();
|
|
804
844
|
dipoles.SetSize0();
|
|
805
845
|
currents.SetSize0();
|
|
846
|
+
*/
|
|
806
847
|
}
|
|
807
848
|
|
|
808
849
|
|
|
@@ -823,7 +864,20 @@ namespace ngsbem
|
|
|
823
864
|
// t.AddFlops (charges.Size());
|
|
824
865
|
if (simd_charges.Size())
|
|
825
866
|
{
|
|
867
|
+
// static Timer t("mptool singmp, evaluate, simd charges"); RegionTimer r(t);
|
|
868
|
+
|
|
826
869
|
simd_entry_type vsum{0.0};
|
|
870
|
+
if (mp.Kappa() < 1e-12)
|
|
871
|
+
{
|
|
872
|
+
for (auto [x,c] : simd_charges)
|
|
873
|
+
{
|
|
874
|
+
auto rho2 = L2Norm2(p-x);
|
|
875
|
+
auto kernel = (1/(4*M_PI)) * rsqrt(rho2);
|
|
876
|
+
kernel = If(rho2 > 0.0, kernel, SIMD<double,FMM_SW>(0.0));
|
|
877
|
+
vsum += kernel * c;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
else
|
|
827
881
|
if (mp.Kappa() < 1e-8)
|
|
828
882
|
for (auto [x,c] : simd_charges)
|
|
829
883
|
{
|
|
@@ -861,6 +915,8 @@ namespace ngsbem
|
|
|
861
915
|
|
|
862
916
|
if (simd_dipoles.Size())
|
|
863
917
|
{
|
|
918
|
+
// static Timer t("mptool singmp, evaluate, simd dipoles"); RegionTimer r(t);
|
|
919
|
+
|
|
864
920
|
simd_entry_type vsum{0.0};
|
|
865
921
|
for (auto [x,d,c] : simd_dipoles)
|
|
866
922
|
{
|
|
@@ -887,6 +943,52 @@ namespace ngsbem
|
|
|
887
943
|
}
|
|
888
944
|
}
|
|
889
945
|
|
|
946
|
+
|
|
947
|
+
|
|
948
|
+
if (simd_chargedipoles.Size())
|
|
949
|
+
{
|
|
950
|
+
// static Timer t("mptool singmp, evaluate, simd chargedipoles"); RegionTimer r(t);
|
|
951
|
+
|
|
952
|
+
simd_entry_type vsum{0.0};
|
|
953
|
+
for (auto [x,c,d,c2] : simd_chargedipoles)
|
|
954
|
+
{
|
|
955
|
+
auto rho = L2Norm(p-x);
|
|
956
|
+
auto rhokappa = rho*mp.Kappa();
|
|
957
|
+
auto invrho = If(rho>0.0, 1.0/rho, SIMD<double,FMM_SW>(0.0));
|
|
958
|
+
auto [si,co] = sincos(rhokappa);
|
|
959
|
+
|
|
960
|
+
auto kernelc = (1/(4*M_PI))*invrho*SIMD<Complex,FMM_SW>(co,si);
|
|
961
|
+
vsum += kernelc * c;
|
|
962
|
+
|
|
963
|
+
auto kernel =
|
|
964
|
+
invrho*invrho * InnerProduct(p-x, d) *
|
|
965
|
+
kernelc * SIMD<Complex,FMM_SW>(-1.0, rhokappa);
|
|
966
|
+
|
|
967
|
+
vsum += kernel * c2;
|
|
968
|
+
}
|
|
969
|
+
sum += HSum(vsum);
|
|
970
|
+
}
|
|
971
|
+
else
|
|
972
|
+
{
|
|
973
|
+
// static Timer t("mptool singmp, evaluate, chargedipoles"); RegionTimer r(t);
|
|
974
|
+
|
|
975
|
+
for (auto [x,c,d,c2] : chargedipoles)
|
|
976
|
+
if (double rho = L2Norm(p-x); rho > 0)
|
|
977
|
+
{
|
|
978
|
+
sum += (1/(4*M_PI))*exp(Complex(0,rho*mp.Kappa())) / rho * c;
|
|
979
|
+
|
|
980
|
+
Vec<3> drhodp = 1.0/rho * (p-x);
|
|
981
|
+
Complex dGdrho = (1/(4*M_PI))*exp(Complex(0,rho*mp.Kappa())) *
|
|
982
|
+
(Complex(0, mp.Kappa())/rho - 1.0/sqr(rho));
|
|
983
|
+
|
|
984
|
+
sum += dGdrho * InnerProduct(drhodp, d) * c2;
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
|
|
989
|
+
|
|
990
|
+
|
|
991
|
+
|
|
890
992
|
for (auto [sp,ep,j,num] : currents)
|
|
891
993
|
{
|
|
892
994
|
// should use explizit formula instead ...
|
|
@@ -923,7 +1025,9 @@ namespace ngsbem
|
|
|
923
1025
|
}
|
|
924
1026
|
|
|
925
1027
|
if (dipoles.Size())
|
|
926
|
-
throw Exception("EvaluateDeriv not implemented for dipoles in
|
|
1028
|
+
throw Exception("EvaluateDeriv not implemented for dipoles in SingularMLExpansion");
|
|
1029
|
+
if (chargedipoles.Size())
|
|
1030
|
+
throw Exception("EvaluateDeriv not implemented for dipoles in SingularMLExpansion");
|
|
927
1031
|
|
|
928
1032
|
for (auto [x,c] : charges)
|
|
929
1033
|
if (double rho = L2Norm(p-x); rho > 0)
|
|
@@ -938,7 +1042,7 @@ namespace ngsbem
|
|
|
938
1042
|
|
|
939
1043
|
void CalcTotalSources()
|
|
940
1044
|
{
|
|
941
|
-
total_sources = charges.Size() + dipoles.Size();
|
|
1045
|
+
total_sources = charges.Size() + dipoles.Size() + chargedipoles.Size();
|
|
942
1046
|
for (auto & child : childs)
|
|
943
1047
|
if (child)
|
|
944
1048
|
{
|
|
@@ -971,9 +1075,9 @@ namespace ngsbem
|
|
|
971
1075
|
}
|
|
972
1076
|
else
|
|
973
1077
|
{
|
|
974
|
-
if (charges.Size()+dipoles.Size()+currents.Size() == 0)
|
|
1078
|
+
if (charges.Size()+dipoles.Size()+chargedipoles.Size()+currents.Size() == 0)
|
|
975
1079
|
{
|
|
976
|
-
mp =
|
|
1080
|
+
mp = SphericalExpansion<Singular,entry_type> (-1, mp.Kappa(), 1.);
|
|
977
1081
|
return;
|
|
978
1082
|
}
|
|
979
1083
|
|
|
@@ -1012,6 +1116,26 @@ namespace ngsbem
|
|
|
1012
1116
|
simd_dipoles[ii] = MakeSimd(di);
|
|
1013
1117
|
}
|
|
1014
1118
|
|
|
1119
|
+
|
|
1120
|
+
simd_chargedipoles.SetSize( (chargedipoles.Size()+FMM_SW-1)/FMM_SW);
|
|
1121
|
+
i = 0, ii = 0;
|
|
1122
|
+
for ( ; i+FMM_SW <= chargedipoles.Size(); i+=FMM_SW, ii++)
|
|
1123
|
+
{
|
|
1124
|
+
std::array<tuple<Vec<3>,entry_type,Vec<3>,entry_type>, FMM_SW> di;
|
|
1125
|
+
for (int j = 0; j < FMM_SW; j++) di[j] = chargedipoles[i+j];
|
|
1126
|
+
simd_chargedipoles[ii] = MakeSimd(di);
|
|
1127
|
+
}
|
|
1128
|
+
if (i < chargedipoles.Size())
|
|
1129
|
+
{
|
|
1130
|
+
std::array<tuple<Vec<3>,entry_type,Vec<3>,entry_type>, FMM_SW> di;
|
|
1131
|
+
int j = 0;
|
|
1132
|
+
for ( ; i+j < chargedipoles.Size(); j++) di[j] = chargedipoles[i+j];
|
|
1133
|
+
for ( ; j < FMM_SW; j++) di[j] = tuple( get<0>(di[0]), entry_type{0.0}, get<2>(di[0]), entry_type{0.0} );
|
|
1134
|
+
simd_chargedipoles[ii] = MakeSimd(di);
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
|
|
1138
|
+
|
|
1015
1139
|
|
|
1016
1140
|
if (nodes_to_process)
|
|
1017
1141
|
*nodes_to_process += this;
|
|
@@ -1022,6 +1146,9 @@ namespace ngsbem
|
|
|
1022
1146
|
for (auto [x,d,c] : dipoles)
|
|
1023
1147
|
mp.AddDipole (x-center, d, c);
|
|
1024
1148
|
|
|
1149
|
+
for (auto [x,c,d,c2] : chargedipoles)
|
|
1150
|
+
mp.AddChargeDipole (x-center, c, d, c2);
|
|
1151
|
+
|
|
1025
1152
|
for (auto [sp,ep,j,num] : currents)
|
|
1026
1153
|
mp.AddCurrent (sp-center, ep-center, j, num);
|
|
1027
1154
|
}
|
|
@@ -1030,7 +1157,7 @@ namespace ngsbem
|
|
|
1030
1157
|
|
|
1031
1158
|
entry_type EvaluateMP(Vec<3> p) const
|
|
1032
1159
|
{
|
|
1033
|
-
if (charges.Size() || dipoles.Size())
|
|
1160
|
+
if (charges.Size() || dipoles.Size() || chargedipoles.Size())
|
|
1034
1161
|
return Evaluate(p);
|
|
1035
1162
|
|
|
1036
1163
|
if (L2Norm(p-center) > 3*r)
|
|
@@ -1050,7 +1177,7 @@ namespace ngsbem
|
|
|
1050
1177
|
// cout << "EvaluateMPDeriv Singular, p = " << p << ", d = " << d << ", r = " << r << ", center = " << center << endl;
|
|
1051
1178
|
// cout << "Norm: " << L2Norm(p-center) << " > " << 3*r << endl;
|
|
1052
1179
|
// cout << "charges.Size() = " << charges.Size() << ", dipoles.Size() = " << dipoles.Size() << endl;
|
|
1053
|
-
if (charges.Size() || dipoles.Size() || !childs[0])
|
|
1180
|
+
if (charges.Size() || dipoles.Size() || chargedipoles.Size() || !childs[0])
|
|
1054
1181
|
return EvaluateDeriv(p, d);
|
|
1055
1182
|
|
|
1056
1183
|
if (L2Norm(p-center) > 3*r)
|
|
@@ -1073,6 +1200,8 @@ namespace ngsbem
|
|
|
1073
1200
|
ost << "xi = " << x << ", ci = " << c << endl;
|
|
1074
1201
|
for (auto [x,d,c] : dipoles)
|
|
1075
1202
|
ost << "xi = " << x << ", di = " << d << ", ci = " << c << endl;
|
|
1203
|
+
for (auto [x,c,d,c2] : chargedipoles)
|
|
1204
|
+
ost << "xi = " << x << ", c = " << c << ", di = " << d << ", ci = " << c2 << endl;
|
|
1076
1205
|
|
|
1077
1206
|
for (int i = 0; i < 8; i++)
|
|
1078
1207
|
if (childs[i]) childs[i] -> Print (ost, i);
|
|
@@ -1101,7 +1230,7 @@ namespace ngsbem
|
|
|
1101
1230
|
bool havemp = false;
|
|
1102
1231
|
|
|
1103
1232
|
public:
|
|
1104
|
-
|
|
1233
|
+
SingularMLExpansion (Vec<3> center, double r, double kappa)
|
|
1105
1234
|
: root(center, r, 0, kappa)
|
|
1106
1235
|
{
|
|
1107
1236
|
nodes_on_level = 0;
|
|
@@ -1120,6 +1249,11 @@ namespace ngsbem
|
|
|
1120
1249
|
root.AddDipole(x, d, c);
|
|
1121
1250
|
}
|
|
1122
1251
|
|
|
1252
|
+
void AddChargeDipole(Vec<3> x, entry_type c, Vec<3> dir, entry_type c2)
|
|
1253
|
+
{
|
|
1254
|
+
root.AddChargeDipole(x, c, dir, c2);
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1123
1257
|
void AddCurrent (Vec<3> sp, Vec<3> ep, Complex j, int num)
|
|
1124
1258
|
{
|
|
1125
1259
|
if constexpr (!std::is_same<entry_type, Vec<3,Complex>>())
|
|
@@ -1201,6 +1335,8 @@ namespace ngsbem
|
|
|
1201
1335
|
node->mp.AddCharge(x-node->center, c);
|
|
1202
1336
|
for (auto [x,d,c]: node->dipoles)
|
|
1203
1337
|
node->mp.AddDipole(x-node->center, d, c);
|
|
1338
|
+
for (auto [x,c,d,c2]: node->chargedipoles)
|
|
1339
|
+
node->mp.AddChargeDipole(x-node->center, c, d, c2);
|
|
1204
1340
|
for (auto [sp,ep,j,num]: node->currents)
|
|
1205
1341
|
node->mp.AddCurrent(sp-node->center, ep-node->center, j, num);
|
|
1206
1342
|
}, TasksPerThread(4));
|
|
@@ -1272,12 +1408,12 @@ namespace ngsbem
|
|
|
1272
1408
|
}
|
|
1273
1409
|
|
|
1274
1410
|
template <typename entry_type2>
|
|
1275
|
-
friend class
|
|
1411
|
+
friend class RegularMLExpansion;
|
|
1276
1412
|
};
|
|
1277
1413
|
|
|
1278
1414
|
|
|
1279
1415
|
template <typename entry_type>
|
|
1280
|
-
inline ostream & operator<< (ostream & ost, const
|
|
1416
|
+
inline ostream & operator<< (ostream & ost, const SingularMLExpansion<entry_type> & mlmp)
|
|
1281
1417
|
{
|
|
1282
1418
|
mlmp.Print(ost);
|
|
1283
1419
|
return ost;
|
|
@@ -1285,21 +1421,21 @@ namespace ngsbem
|
|
|
1285
1421
|
|
|
1286
1422
|
|
|
1287
1423
|
template <typename elem_type=Complex>
|
|
1288
|
-
class NGS_DLL_HEADER
|
|
1424
|
+
class NGS_DLL_HEADER RegularMLExpansion
|
|
1289
1425
|
{
|
|
1290
1426
|
static Array<size_t> nodes_on_level;
|
|
1291
1427
|
|
|
1292
1428
|
|
|
1293
1429
|
struct RecordingRS
|
|
1294
1430
|
{
|
|
1295
|
-
const
|
|
1296
|
-
|
|
1431
|
+
const SphericalExpansion<Singular,elem_type> * mpS;
|
|
1432
|
+
SphericalExpansion<Regular,elem_type> * mpR;
|
|
1297
1433
|
Vec<3> dist;
|
|
1298
1434
|
double len, theta, phi;
|
|
1299
1435
|
public:
|
|
1300
1436
|
RecordingRS() = default;
|
|
1301
|
-
RecordingRS (const
|
|
1302
|
-
|
|
1437
|
+
RecordingRS (const SphericalExpansion<Singular,elem_type> * ampS,
|
|
1438
|
+
SphericalExpansion<Regular,elem_type> * ampR,
|
|
1303
1439
|
Vec<3> adist)
|
|
1304
1440
|
: mpS(ampS), mpR(ampR), dist(adist)
|
|
1305
1441
|
{
|
|
@@ -1381,10 +1517,10 @@ namespace ngsbem
|
|
|
1381
1517
|
// static Timer tfrombatch("mptools - copy from batch 2");
|
|
1382
1518
|
|
|
1383
1519
|
// *testout << "Processing vectorized batch of size " << batch.Size() << ", with N = " << N << ", vec_length = " << vec_length << ", len = " << len << ", theta = " << theta << endl;
|
|
1384
|
-
|
|
1385
|
-
//
|
|
1386
|
-
|
|
1387
|
-
|
|
1520
|
+
SphericalExpansion<Singular, Vec<N,Complex>> vec_source(batch[0]->mpS->Order(), batch[0]->mpS->Kappa(), batch[0]->mpS->RTyp());
|
|
1521
|
+
// SphericalExpansion<Singular, elem_type> tmp_source{*batch[0]->mpS};
|
|
1522
|
+
SphericalExpansion<Regular, elem_type> tmp_target{*batch[0]->mpR};
|
|
1523
|
+
SphericalExpansion<Regular, Vec<N,Complex>> vec_target(batch[0]->mpR->Order(), batch[0]->mpR->Kappa(), batch[0]->mpR->RTyp());
|
|
1388
1524
|
|
|
1389
1525
|
// Copy multipoles into vectorized multipole
|
|
1390
1526
|
// ttobatch.Start();
|
|
@@ -1432,13 +1568,13 @@ namespace ngsbem
|
|
|
1432
1568
|
double r;
|
|
1433
1569
|
int level;
|
|
1434
1570
|
std::array<unique_ptr<Node>,8> childs;
|
|
1435
|
-
|
|
1571
|
+
SphericalExpansion<Regular,elem_type> mp;
|
|
1436
1572
|
Array<Vec<3>> targets;
|
|
1437
1573
|
int total_targets;
|
|
1438
1574
|
std::mutex node_mutex;
|
|
1439
1575
|
atomic<bool> have_childs{false};
|
|
1440
1576
|
|
|
1441
|
-
Array<const typename
|
|
1577
|
+
Array<const typename SingularMLExpansion<elem_type>::Node*> singnodes;
|
|
1442
1578
|
|
|
1443
1579
|
Node (Vec<3> acenter, double ar, int alevel, double kappa)
|
|
1444
1580
|
: center(acenter), r(ar), level(alevel), mp(MPOrder(ar*kappa), kappa, ar) // 1.0/min(1.0, 0.25*r*kappa))
|
|
@@ -1464,7 +1600,7 @@ namespace ngsbem
|
|
|
1464
1600
|
have_childs = true;
|
|
1465
1601
|
}
|
|
1466
1602
|
|
|
1467
|
-
void AddSingularNode (const typename
|
|
1603
|
+
void AddSingularNode (const typename SingularMLExpansion<elem_type>::Node & singnode, bool allow_refine,
|
|
1468
1604
|
Array<RecordingRS> * recording)
|
|
1469
1605
|
{
|
|
1470
1606
|
if (mp.SH().Order() < 0) return;
|
|
@@ -1546,7 +1682,7 @@ namespace ngsbem
|
|
|
1546
1682
|
void LocalizeExpansion(bool allow_refine)
|
|
1547
1683
|
{
|
|
1548
1684
|
if (allow_refine)
|
|
1549
|
-
if (mp.Order() >
|
|
1685
|
+
if (mp.Order() > 30 && !childs[0])
|
|
1550
1686
|
CreateChilds();
|
|
1551
1687
|
|
|
1552
1688
|
if (childs[0])
|
|
@@ -1567,7 +1703,7 @@ namespace ngsbem
|
|
|
1567
1703
|
mp.TransformAdd (childs[nr]->mp, childs[nr]->center-center);
|
|
1568
1704
|
childs[nr]->LocalizeExpansion(allow_refine);
|
|
1569
1705
|
});
|
|
1570
|
-
mp =
|
|
1706
|
+
mp = SphericalExpansion<Regular,elem_type>(-1, mp.Kappa(), 1.);
|
|
1571
1707
|
//mp.SH().Coefs()=0.0;
|
|
1572
1708
|
}
|
|
1573
1709
|
}
|
|
@@ -1583,11 +1719,16 @@ namespace ngsbem
|
|
|
1583
1719
|
if (childs[childnum])
|
|
1584
1720
|
sum = childs[childnum]->Evaluate(p);
|
|
1585
1721
|
else
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1722
|
+
{
|
|
1723
|
+
// static Timer t("mptool regmp, evaluate reg"); RegionTimer r(t);
|
|
1724
|
+
sum = mp.Eval(p-center);
|
|
1725
|
+
}
|
|
1590
1726
|
|
|
1727
|
+
{
|
|
1728
|
+
// static Timer t("mptool regmp, evaluate, singnode"); RegionTimer r(t);
|
|
1729
|
+
for (auto sn : singnodes)
|
|
1730
|
+
sum += sn->EvaluateMP(p);
|
|
1731
|
+
}
|
|
1591
1732
|
return sum;
|
|
1592
1733
|
}
|
|
1593
1734
|
|
|
@@ -1695,7 +1836,7 @@ namespace ngsbem
|
|
|
1695
1836
|
}
|
|
1696
1837
|
|
|
1697
1838
|
if (total_targets == 0)
|
|
1698
|
-
mp =
|
|
1839
|
+
mp = SphericalExpansion<Regular,elem_type>(-1, mp.Kappa(),1.);
|
|
1699
1840
|
}
|
|
1700
1841
|
|
|
1701
1842
|
|
|
@@ -1715,10 +1856,10 @@ namespace ngsbem
|
|
|
1715
1856
|
};
|
|
1716
1857
|
|
|
1717
1858
|
Node root;
|
|
1718
|
-
shared_ptr<
|
|
1859
|
+
shared_ptr<SingularMLExpansion<elem_type>> singmp;
|
|
1719
1860
|
|
|
1720
1861
|
public:
|
|
1721
|
-
|
|
1862
|
+
RegularMLExpansion (shared_ptr<SingularMLExpansion<elem_type>> asingmp, Vec<3> center, double r)
|
|
1722
1863
|
: root(center, r, 0, asingmp->Kappa()), singmp(asingmp)
|
|
1723
1864
|
{
|
|
1724
1865
|
if (!singmp->havemp) throw Exception("first call Calc for singular MP");
|
|
@@ -1748,7 +1889,7 @@ namespace ngsbem
|
|
|
1748
1889
|
}
|
|
1749
1890
|
}
|
|
1750
1891
|
|
|
1751
|
-
|
|
1892
|
+
RegularMLExpansion (Vec<3> center, double r, double kappa)
|
|
1752
1893
|
: root(center, r, 0, kappa)
|
|
1753
1894
|
{
|
|
1754
1895
|
nodes_on_level = 0;
|
|
@@ -1760,7 +1901,7 @@ namespace ngsbem
|
|
|
1760
1901
|
root.AddTarget (t);
|
|
1761
1902
|
}
|
|
1762
1903
|
|
|
1763
|
-
void CalcMP(shared_ptr<
|
|
1904
|
+
void CalcMP(shared_ptr<SingularMLExpansion<elem_type>> asingmp, bool onlytargets = true)
|
|
1764
1905
|
{
|
|
1765
1906
|
static Timer t("mptool regular MLMP"); RegionTimer rg(t);
|
|
1766
1907
|
static Timer trec("mptool regular MLMP - recording");
|
|
@@ -1769,15 +1910,17 @@ namespace ngsbem
|
|
|
1769
1910
|
singmp = asingmp;
|
|
1770
1911
|
|
|
1771
1912
|
root.CalcTotalTargets();
|
|
1772
|
-
|
|
1913
|
+
if (onlytargets)
|
|
1914
|
+
root.RemoveEmptyTrees();
|
|
1773
1915
|
|
|
1774
1916
|
|
|
1775
|
-
// root.AddSingularNode(singmp->root,
|
|
1917
|
+
// root.AddSingularNode(singmp->root, !onlytargets, nullptr);
|
|
1918
|
+
|
|
1776
1919
|
// /*
|
|
1777
1920
|
Array<RecordingRS> recording;
|
|
1778
1921
|
{
|
|
1779
1922
|
RegionTimer rrec(trec);
|
|
1780
|
-
root.AddSingularNode(singmp->root,
|
|
1923
|
+
root.AddSingularNode(singmp->root, !onlytargets, &recording);
|
|
1781
1924
|
}
|
|
1782
1925
|
|
|
1783
1926
|
// cout << "recorded: " << recording.Size() << endl;
|
|
@@ -1828,15 +1971,15 @@ namespace ngsbem
|
|
|
1828
1971
|
|
|
1829
1972
|
/*
|
|
1830
1973
|
int maxlevel = 0;
|
|
1831
|
-
for (auto [i,num] : Enumerate(
|
|
1974
|
+
for (auto [i,num] : Enumerate(RegularMLExpansion::nodes_on_level))
|
|
1832
1975
|
if (num > 0) maxlevel = i;
|
|
1833
1976
|
|
|
1834
1977
|
for (int i = 0; i <= maxlevel; i++)
|
|
1835
|
-
cout << "reg " << i << ": " <<
|
|
1978
|
+
cout << "reg " << i << ": " << RegularMLExpansion::nodes_on_level[i] << endl;
|
|
1836
1979
|
*/
|
|
1837
1980
|
|
|
1838
1981
|
static Timer tloc("mptool regular localize expansion"); RegionTimer rloc(tloc);
|
|
1839
|
-
root.LocalizeExpansion(
|
|
1982
|
+
root.LocalizeExpansion(!onlytargets);
|
|
1840
1983
|
}
|
|
1841
1984
|
|
|
1842
1985
|
void Print (ostream & ost) const
|
|
@@ -1857,7 +2000,9 @@ namespace ngsbem
|
|
|
1857
2000
|
elem_type Evaluate (Vec<3> p) const
|
|
1858
2001
|
{
|
|
1859
2002
|
// static Timer t("mptool Eval MLMP regular"); RegionTimer r(t);
|
|
1860
|
-
if (L2Norm(p-root.center) > root.r) return elem_type{0.0};
|
|
2003
|
+
// if (L2Norm(p-root.center) > root.r) return elem_type{0.0};
|
|
2004
|
+
if (MaxNorm(p-root.center) > root.r)
|
|
2005
|
+
return singmp->Evaluate(p);
|
|
1861
2006
|
return root.Evaluate(p);
|
|
1862
2007
|
}
|
|
1863
2008
|
|
|
@@ -1871,10 +2016,10 @@ namespace ngsbem
|
|
|
1871
2016
|
|
|
1872
2017
|
|
|
1873
2018
|
template <typename elem_type>
|
|
1874
|
-
inline ostream & operator<< (ostream & ost, const
|
|
2019
|
+
inline ostream & operator<< (ostream & ost, const RegularMLExpansion<elem_type> & mlmp)
|
|
1875
2020
|
{
|
|
1876
2021
|
mlmp.Print(ost);
|
|
1877
|
-
// ost << "
|
|
2022
|
+
// ost << "RegularMLExpansion" << endl;
|
|
1878
2023
|
return ost;
|
|
1879
2024
|
}
|
|
1880
2025
|
|