ngsolve 6.2.2506__cp39-cp39-macosx_10_15_universal2.whl → 6.2.2506.post33.dev0__cp39-cp39-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.

Files changed (56) hide show
  1. netgen/include/bem_diffops.hpp +475 -0
  2. netgen/include/bspline.hpp +2 -0
  3. netgen/include/contact.hpp +4 -0
  4. netgen/include/h1lumping.hpp +6 -0
  5. netgen/include/kernels.hpp +654 -0
  6. netgen/include/mp_coefficient.hpp +20 -20
  7. netgen/include/mptools.hpp +244 -118
  8. netgen/include/potentialtools.hpp +2 -2
  9. netgen/libngbla.dylib +0 -0
  10. netgen/libngcomp.dylib +0 -0
  11. netgen/libngfem.dylib +0 -0
  12. netgen/libngla.dylib +0 -0
  13. netgen/libngsbem.dylib +0 -0
  14. netgen/libngsolve.dylib +0 -0
  15. netgen/libngstd.dylib +0 -0
  16. ngsolve/cmake/NGSolveConfig.cmake +1 -1
  17. ngsolve/config/config.py +5 -5
  18. ngsolve/demos/intro/cmagnet.py +19 -22
  19. {ngsolve-6.2.2506.dist-info → ngsolve-6.2.2506.post33.dev0.dist-info}/METADATA +2 -2
  20. {ngsolve-6.2.2506.dist-info → ngsolve-6.2.2506.post33.dev0.dist-info}/RECORD +56 -54
  21. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/Netgen.icns +0 -0
  22. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/bin/ngscxx +0 -0
  23. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/bin/ngsld +0 -0
  24. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/bin/ngsolve.tcl +0 -0
  25. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/bin/ngspy +0 -0
  26. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/beam.geo +0 -0
  27. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/beam.vol +0 -0
  28. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/chip.in2d +0 -0
  29. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/chip.vol +0 -0
  30. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/coil.geo +0 -0
  31. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/coil.vol +0 -0
  32. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/coilshield.geo +0 -0
  33. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/coilshield.vol +0 -0
  34. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/cube.geo +0 -0
  35. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/cube.vol +0 -0
  36. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d10_DGdoubleglazing.pde +0 -0
  37. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d11_chip_nitsche.pde +0 -0
  38. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d1_square.pde +0 -0
  39. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d2_chip.pde +0 -0
  40. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d3_helmholtz.pde +0 -0
  41. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d4_cube.pde +0 -0
  42. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d5_beam.pde +0 -0
  43. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d6_shaft.pde +0 -0
  44. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d7_coil.pde +0 -0
  45. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d8_coilshield.pde +0 -0
  46. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/d9_hybridDG.pde +0 -0
  47. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/doubleglazing.in2d +0 -0
  48. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/doubleglazing.vol +0 -0
  49. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/piezo2d40round4.vol.gz +0 -0
  50. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/shaft.geo +0 -0
  51. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/shaft.vol +0 -0
  52. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/square.in2d +0 -0
  53. {ngsolve-6.2.2506.data → ngsolve-6.2.2506.post33.dev0.data}/data/share/ngsolve/square.vol +0 -0
  54. {ngsolve-6.2.2506.dist-info → ngsolve-6.2.2506.post33.dev0.dist-info}/LICENSE +0 -0
  55. {ngsolve-6.2.2506.dist-info → ngsolve-6.2.2506.post33.dev0.dist-info}/WHEEL +0 -0
  56. {ngsolve-6.2.2506.dist-info → ngsolve-6.2.2506.post33.dev0.dist-info}/top_level.txt +0 -0
@@ -303,7 +303,7 @@ namespace ngsbem
303
303
 
304
304
 
305
305
  // hn1 = jn+ i*yn
306
- class MPSingular
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 MPRegular
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 MultiPole
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
- MultiPole (int aorder, double akappa, double artyp)
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
- MultiPole Truncate(int neworder) const
379
+ SphericalExpansion Truncate(int neworder) const
380
380
  {
381
381
  if (neworder > sh.Order()) neworder=sh.Order();
382
- MultiPole nmp(neworder, kappa, rtyp);
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
- MultiPole & operator+= (const MultiPole & mp2)
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> d, entry_type c);
399
- void AddCurrent (Vec<3> ap, Vec<3> ep, Complex j, int num=100);
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
- double fac = Scale()/newscale;
405
- double prod = 1;
406
- for (int n = 0; n <= sh.Order(); n++, prod*= fac)
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 (MultiPole<TARGET,entry_type> & target, Vec<3> dist) const
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
- // MultiPole<RADIAL,entry_type> tmp{*this};
453
- MultiPole<RADIAL,entry_type> tmp(Order(), kappa, rtyp);
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 (MultiPole<TARGET,entry_type> & target, Vec<3> dist, bool atomic = false) const
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
- MultiPole<TARGET,entry_type> tmp{target};
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, MultiPole<TARGET,entry_type> & target);
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
 
@@ -507,22 +516,22 @@ namespace ngsbem
507
516
 
508
517
 
509
518
  template <typename entry_type=Complex>
510
- class SingularMLMultiPole
519
+ class SingularMLExpansion
511
520
  {
512
521
  using simd_entry_type = decltype(MakeSimd(declval<std::array<entry_type,FMM_SW>>()));
513
522
  static Array<size_t> nodes_on_level;
514
523
 
515
524
  struct RecordingSS
516
525
  {
517
- const MultiPole<MPSingular,entry_type> * mp_source;
518
- MultiPole<MPSingular,entry_type> * mp_target;
526
+ const SphericalExpansion<Singular,entry_type> * mp_source;
527
+ SphericalExpansion<Singular,entry_type> * mp_target;
519
528
  Vec<3> dist;
520
529
  double len, theta, phi;
521
530
  bool flipz;
522
531
  public:
523
532
  RecordingSS() = default;
524
- RecordingSS (const MultiPole<MPSingular,entry_type> * amp_source,
525
- MultiPole<MPSingular,entry_type> * amp_target,
533
+ RecordingSS (const SphericalExpansion<Singular,entry_type> * amp_source,
534
+ SphericalExpansion<Singular,entry_type> * amp_target,
526
535
  Vec<3> adist)
527
536
  : mp_source(amp_source), mp_target(amp_target), dist(adist)
528
537
  {
@@ -580,8 +589,8 @@ namespace ngsbem
580
589
  static void ProcessVectorizedBatch(FlatArray<RecordingSS*> batch, double len, double theta) {
581
590
 
582
591
  // *testout << "Processing vectorized S->S batch of size " << batch.Size() << ", with N = " << N << ", vec_length = " << vec_length << ", len = " << len << ", theta = " << theta << endl;
583
- MultiPole<MPSingular, Vec<N,Complex>> vec_source(batch[0]->mp_source->Order(), batch[0]->mp_source->Kappa(), batch[0]->mp_source->RTyp());
584
- MultiPole<MPSingular, Vec<N,Complex>> vec_target(batch[0]->mp_target->Order(), batch[0]->mp_target->Kappa(), batch[0]->mp_target->RTyp());
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());
585
594
 
586
595
  // Copy multipoles into vectorized multipole
587
596
  for (int i = 0; i < batch.Size(); i++)
@@ -618,15 +627,18 @@ namespace ngsbem
618
627
  double r;
619
628
  int level;
620
629
  std::array<unique_ptr<Node>,8> childs;
621
- MultiPole<MPSingular, entry_type> mp;
630
+ SphericalExpansion<Singular, entry_type> mp;
622
631
 
623
632
  Array<tuple<Vec<3>, entry_type>> charges;
624
633
  Array<tuple<Vec<3>, Vec<3>, entry_type>> dipoles;
634
+ Array<tuple<Vec<3>, entry_type, Vec<3>, entry_type>> chargedipoles;
625
635
  Array<tuple<Vec<3>, Vec<3>, Complex,int>> currents;
626
636
 
627
637
  using simd_entry_type = decltype(MakeSimd(declval<std::array<entry_type,FMM_SW>>()));
628
638
  Array<tuple<Vec<3,SIMD<double,FMM_SW>>, simd_entry_type>> simd_charges;
629
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;
630
642
 
631
643
  int total_sources;
632
644
  std::mutex node_mutex;
@@ -639,7 +651,15 @@ namespace ngsbem
639
651
  nodes_on_level[level]++;
640
652
  }
641
653
 
642
-
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
+
643
663
  void CreateChilds()
644
664
  {
645
665
  if (childs[0]) throw Exception("have already childs");
@@ -655,15 +675,32 @@ namespace ngsbem
655
675
  }
656
676
 
657
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
+
658
698
  void AddCharge (Vec<3> x, entry_type c)
659
699
  {
660
700
  if (have_childs) // quick check without locking
661
701
  {
662
702
  // directly send to childs:
663
- int childnum = 0;
664
- if (x(0) > center(0)) childnum += 1;
665
- if (x(1) > center(1)) childnum += 2;
666
- if (x(2) > center(2)) childnum += 4;
703
+ int childnum = GetChildNum(x);
667
704
  childs[childnum] -> AddCharge(x, c);
668
705
  return;
669
706
  }
@@ -672,36 +709,19 @@ namespace ngsbem
672
709
 
673
710
  if (have_childs) // test again after locking
674
711
  {
675
- // directly send to childs:
676
- int childnum = 0;
677
- if (x(0) > center(0)) childnum += 1;
678
- if (x(1) > center(1)) childnum += 2;
679
- if (x(2) > center(2)) childnum += 4;
712
+ int childnum = GetChildNum(x);
680
713
  childs[childnum] -> AddCharge(x, c);
681
714
  return;
682
715
  }
683
716
 
684
-
685
-
686
717
  charges.Append( tuple{x,c} );
687
718
 
688
719
  // if (r*mp.Kappa() < 1e-8) return;
689
720
  if (level > 20) return;
690
721
  if (charges.Size() < maxdirect && r*mp.Kappa() < 1)
691
722
  return;
692
-
693
- CreateChilds();
694
-
695
- for (auto [x,c] : charges)
696
- AddCharge (x,c);
697
- for (auto [x,d,c] : dipoles)
698
- AddDipole (x,d,c);
699
- for (auto [sp,ep,j,num] : currents)
700
- AddCurrent (sp,ep,j,num);
701
723
 
702
- charges.SetSize0();
703
- dipoles.SetSize0();
704
- currents.SetSize0();
724
+ SendSourcesToChilds();
705
725
  }
706
726
 
707
727
 
@@ -710,11 +730,7 @@ namespace ngsbem
710
730
  if (have_childs)
711
731
  {
712
732
  // directly send to childs:
713
-
714
- int childnum = 0;
715
- if (x(0) > center(0)) childnum += 1;
716
- if (x(1) > center(1)) childnum += 2;
717
- if (x(2) > center(2)) childnum += 4;
733
+ int childnum = GetChildNum(x);
718
734
  childs[childnum] -> AddDipole(x, d, c);
719
735
  return;
720
736
  }
@@ -724,37 +740,54 @@ namespace ngsbem
724
740
  if (have_childs)
725
741
  {
726
742
  // directly send to childs:
727
-
728
- int childnum = 0;
729
- if (x(0) > center(0)) childnum += 1;
730
- if (x(1) > center(1)) childnum += 2;
731
- if (x(2) > center(2)) childnum += 4;
743
+ int childnum = GetChildNum(x);
732
744
  childs[childnum] -> AddDipole(x, d, c);
733
745
  return;
734
746
  }
735
-
736
-
737
-
738
747
 
739
748
  dipoles.Append (tuple{x,d,c});
740
749
 
741
750
  if (dipoles.Size() < maxdirect || r < 1e-8)
742
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
+ }
743
776
 
744
- CreateChilds();
777
+ chargedipoles.Append (tuple{x,c,dir,c2});
745
778
 
746
- for (auto [x,c] : charges)
747
- AddCharge (x,c);
748
- for (auto [x,d,c] : dipoles)
749
- AddDipole (x,d,c);
750
- for (auto [sp,ep,j,num] : currents)
751
- AddCurrent (sp,ep,j,num);
779
+ if (chargedipoles.Size() < maxdirect || r < 1e-8)
780
+ return;
752
781
 
753
- charges.SetSize0();
754
- dipoles.SetSize0();
755
- currents.SetSize0();
782
+ SendSourcesToChilds();
783
+
784
+ /*
785
+ AddCharge (x, c);
786
+ AddDipole (x, dir, c2);
787
+ */
756
788
  }
757
789
 
790
+
758
791
  // not parallel yet
759
792
  void AddCurrent (Vec<3> sp, Vec<3> ep, Complex j, int num)
760
793
  {
@@ -788,6 +821,12 @@ namespace ngsbem
788
821
 
789
822
  currents.Append (tuple{sp,ep,j,num});
790
823
 
824
+ // if (currents.Size() < maxdirect || r < 1e-8)
825
+ if (currents.Size() < 4 || r < 1e-8)
826
+ return;
827
+
828
+ SendSourcesToChilds();
829
+ /*
791
830
  // if (currents.Size() < maxdirect || r < 1e-8)
792
831
  if (currents.Size() < 4 || r < 1e-8)
793
832
  return;
@@ -804,6 +843,7 @@ namespace ngsbem
804
843
  charges.SetSize0();
805
844
  dipoles.SetSize0();
806
845
  currents.SetSize0();
846
+ */
807
847
  }
808
848
 
809
849
 
@@ -824,7 +864,7 @@ namespace ngsbem
824
864
  // t.AddFlops (charges.Size());
825
865
  if (simd_charges.Size())
826
866
  {
827
- // static Timer t("regmp, evaluate, simd charges"); RegionTimer r(t);
867
+ // static Timer t("mptool singmp, evaluate, simd charges"); RegionTimer r(t);
828
868
 
829
869
  simd_entry_type vsum{0.0};
830
870
  if (mp.Kappa() < 1e-12)
@@ -875,6 +915,8 @@ namespace ngsbem
875
915
 
876
916
  if (simd_dipoles.Size())
877
917
  {
918
+ // static Timer t("mptool singmp, evaluate, simd dipoles"); RegionTimer r(t);
919
+
878
920
  simd_entry_type vsum{0.0};
879
921
  for (auto [x,d,c] : simd_dipoles)
880
922
  {
@@ -901,6 +943,52 @@ namespace ngsbem
901
943
  }
902
944
  }
903
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
+
904
992
  for (auto [sp,ep,j,num] : currents)
905
993
  {
906
994
  // should use explizit formula instead ...
@@ -937,7 +1025,9 @@ namespace ngsbem
937
1025
  }
938
1026
 
939
1027
  if (dipoles.Size())
940
- throw Exception("EvaluateDeriv not implemented for dipoles in SingularMLMultiPole");
1028
+ throw Exception("EvaluateDeriv not implemented for dipoles in SingularMLExpansion");
1029
+ if (chargedipoles.Size())
1030
+ throw Exception("EvaluateDeriv not implemented for dipoles in SingularMLExpansion");
941
1031
 
942
1032
  for (auto [x,c] : charges)
943
1033
  if (double rho = L2Norm(p-x); rho > 0)
@@ -952,7 +1042,7 @@ namespace ngsbem
952
1042
 
953
1043
  void CalcTotalSources()
954
1044
  {
955
- total_sources = charges.Size() + dipoles.Size();
1045
+ total_sources = charges.Size() + dipoles.Size() + chargedipoles.Size();
956
1046
  for (auto & child : childs)
957
1047
  if (child)
958
1048
  {
@@ -985,9 +1075,9 @@ namespace ngsbem
985
1075
  }
986
1076
  else
987
1077
  {
988
- if (charges.Size()+dipoles.Size()+currents.Size() == 0)
1078
+ if (charges.Size()+dipoles.Size()+chargedipoles.Size()+currents.Size() == 0)
989
1079
  {
990
- mp = MultiPole<MPSingular,entry_type> (-1, mp.Kappa(), 1.);
1080
+ mp = SphericalExpansion<Singular,entry_type> (-1, mp.Kappa(), 1.);
991
1081
  return;
992
1082
  }
993
1083
 
@@ -1026,6 +1116,26 @@ namespace ngsbem
1026
1116
  simd_dipoles[ii] = MakeSimd(di);
1027
1117
  }
1028
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
+
1029
1139
 
1030
1140
  if (nodes_to_process)
1031
1141
  *nodes_to_process += this;
@@ -1036,6 +1146,9 @@ namespace ngsbem
1036
1146
  for (auto [x,d,c] : dipoles)
1037
1147
  mp.AddDipole (x-center, d, c);
1038
1148
 
1149
+ for (auto [x,c,d,c2] : chargedipoles)
1150
+ mp.AddChargeDipole (x-center, c, d, c2);
1151
+
1039
1152
  for (auto [sp,ep,j,num] : currents)
1040
1153
  mp.AddCurrent (sp-center, ep-center, j, num);
1041
1154
  }
@@ -1044,7 +1157,7 @@ namespace ngsbem
1044
1157
 
1045
1158
  entry_type EvaluateMP(Vec<3> p) const
1046
1159
  {
1047
- if (charges.Size() || dipoles.Size())
1160
+ if (charges.Size() || dipoles.Size() || chargedipoles.Size())
1048
1161
  return Evaluate(p);
1049
1162
 
1050
1163
  if (L2Norm(p-center) > 3*r)
@@ -1064,7 +1177,7 @@ namespace ngsbem
1064
1177
  // cout << "EvaluateMPDeriv Singular, p = " << p << ", d = " << d << ", r = " << r << ", center = " << center << endl;
1065
1178
  // cout << "Norm: " << L2Norm(p-center) << " > " << 3*r << endl;
1066
1179
  // cout << "charges.Size() = " << charges.Size() << ", dipoles.Size() = " << dipoles.Size() << endl;
1067
- if (charges.Size() || dipoles.Size() || !childs[0])
1180
+ if (charges.Size() || dipoles.Size() || chargedipoles.Size() || !childs[0])
1068
1181
  return EvaluateDeriv(p, d);
1069
1182
 
1070
1183
  if (L2Norm(p-center) > 3*r)
@@ -1087,6 +1200,8 @@ namespace ngsbem
1087
1200
  ost << "xi = " << x << ", ci = " << c << endl;
1088
1201
  for (auto [x,d,c] : dipoles)
1089
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;
1090
1205
 
1091
1206
  for (int i = 0; i < 8; i++)
1092
1207
  if (childs[i]) childs[i] -> Print (ost, i);
@@ -1115,7 +1230,7 @@ namespace ngsbem
1115
1230
  bool havemp = false;
1116
1231
 
1117
1232
  public:
1118
- SingularMLMultiPole (Vec<3> center, double r, double kappa)
1233
+ SingularMLExpansion (Vec<3> center, double r, double kappa)
1119
1234
  : root(center, r, 0, kappa)
1120
1235
  {
1121
1236
  nodes_on_level = 0;
@@ -1134,6 +1249,11 @@ namespace ngsbem
1134
1249
  root.AddDipole(x, d, c);
1135
1250
  }
1136
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
+
1137
1257
  void AddCurrent (Vec<3> sp, Vec<3> ep, Complex j, int num)
1138
1258
  {
1139
1259
  if constexpr (!std::is_same<entry_type, Vec<3,Complex>>())
@@ -1215,6 +1335,8 @@ namespace ngsbem
1215
1335
  node->mp.AddCharge(x-node->center, c);
1216
1336
  for (auto [x,d,c]: node->dipoles)
1217
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);
1218
1340
  for (auto [sp,ep,j,num]: node->currents)
1219
1341
  node->mp.AddCurrent(sp-node->center, ep-node->center, j, num);
1220
1342
  }, TasksPerThread(4));
@@ -1286,12 +1408,12 @@ namespace ngsbem
1286
1408
  }
1287
1409
 
1288
1410
  template <typename entry_type2>
1289
- friend class RegularMLMultiPole;
1411
+ friend class RegularMLExpansion;
1290
1412
  };
1291
1413
 
1292
1414
 
1293
1415
  template <typename entry_type>
1294
- inline ostream & operator<< (ostream & ost, const SingularMLMultiPole<entry_type> & mlmp)
1416
+ inline ostream & operator<< (ostream & ost, const SingularMLExpansion<entry_type> & mlmp)
1295
1417
  {
1296
1418
  mlmp.Print(ost);
1297
1419
  return ost;
@@ -1299,21 +1421,21 @@ namespace ngsbem
1299
1421
 
1300
1422
 
1301
1423
  template <typename elem_type=Complex>
1302
- class NGS_DLL_HEADER RegularMLMultiPole
1424
+ class NGS_DLL_HEADER RegularMLExpansion
1303
1425
  {
1304
1426
  static Array<size_t> nodes_on_level;
1305
1427
 
1306
1428
 
1307
1429
  struct RecordingRS
1308
1430
  {
1309
- const MultiPole<MPSingular,elem_type> * mpS;
1310
- MultiPole<MPRegular,elem_type> * mpR;
1431
+ const SphericalExpansion<Singular,elem_type> * mpS;
1432
+ SphericalExpansion<Regular,elem_type> * mpR;
1311
1433
  Vec<3> dist;
1312
1434
  double len, theta, phi;
1313
1435
  public:
1314
1436
  RecordingRS() = default;
1315
- RecordingRS (const MultiPole<MPSingular,elem_type> * ampS,
1316
- MultiPole<MPRegular,elem_type> * ampR,
1437
+ RecordingRS (const SphericalExpansion<Singular,elem_type> * ampS,
1438
+ SphericalExpansion<Regular,elem_type> * ampR,
1317
1439
  Vec<3> adist)
1318
1440
  : mpS(ampS), mpR(ampR), dist(adist)
1319
1441
  {
@@ -1395,10 +1517,10 @@ namespace ngsbem
1395
1517
  // static Timer tfrombatch("mptools - copy from batch 2");
1396
1518
 
1397
1519
  // *testout << "Processing vectorized batch of size " << batch.Size() << ", with N = " << N << ", vec_length = " << vec_length << ", len = " << len << ", theta = " << theta << endl;
1398
- MultiPole<MPSingular, Vec<N,Complex>> vec_source(batch[0]->mpS->Order(), batch[0]->mpS->Kappa(), batch[0]->mpS->RTyp());
1399
- // MultiPole<MPSingular, elem_type> tmp_source{*batch[0]->mpS};
1400
- MultiPole<MPRegular, elem_type> tmp_target{*batch[0]->mpR};
1401
- MultiPole<MPRegular, Vec<N,Complex>> vec_target(batch[0]->mpR->Order(), batch[0]->mpR->Kappa(), batch[0]->mpR->RTyp());
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());
1402
1524
 
1403
1525
  // Copy multipoles into vectorized multipole
1404
1526
  // ttobatch.Start();
@@ -1446,13 +1568,13 @@ namespace ngsbem
1446
1568
  double r;
1447
1569
  int level;
1448
1570
  std::array<unique_ptr<Node>,8> childs;
1449
- MultiPole<MPRegular,elem_type> mp;
1571
+ SphericalExpansion<Regular,elem_type> mp;
1450
1572
  Array<Vec<3>> targets;
1451
1573
  int total_targets;
1452
1574
  std::mutex node_mutex;
1453
1575
  atomic<bool> have_childs{false};
1454
1576
 
1455
- Array<const typename SingularMLMultiPole<elem_type>::Node*> singnodes;
1577
+ Array<const typename SingularMLExpansion<elem_type>::Node*> singnodes;
1456
1578
 
1457
1579
  Node (Vec<3> acenter, double ar, int alevel, double kappa)
1458
1580
  : center(acenter), r(ar), level(alevel), mp(MPOrder(ar*kappa), kappa, ar) // 1.0/min(1.0, 0.25*r*kappa))
@@ -1478,7 +1600,7 @@ namespace ngsbem
1478
1600
  have_childs = true;
1479
1601
  }
1480
1602
 
1481
- void AddSingularNode (const typename SingularMLMultiPole<elem_type>::Node & singnode, bool allow_refine,
1603
+ void AddSingularNode (const typename SingularMLExpansion<elem_type>::Node & singnode, bool allow_refine,
1482
1604
  Array<RecordingRS> * recording)
1483
1605
  {
1484
1606
  if (mp.SH().Order() < 0) return;
@@ -1581,7 +1703,7 @@ namespace ngsbem
1581
1703
  mp.TransformAdd (childs[nr]->mp, childs[nr]->center-center);
1582
1704
  childs[nr]->LocalizeExpansion(allow_refine);
1583
1705
  });
1584
- mp = MultiPole<MPRegular,elem_type>(-1, mp.Kappa(), 1.);
1706
+ mp = SphericalExpansion<Regular,elem_type>(-1, mp.Kappa(), 1.);
1585
1707
  //mp.SH().Coefs()=0.0;
1586
1708
  }
1587
1709
  }
@@ -1597,12 +1719,16 @@ namespace ngsbem
1597
1719
  if (childs[childnum])
1598
1720
  sum = childs[childnum]->Evaluate(p);
1599
1721
  else
1600
- sum = mp.Eval(p-center);
1601
-
1602
- // static Timer t("regmp, evaluate, singnode"); RegionTimer r(t);
1603
- for (auto sn : singnodes)
1604
- sum += sn->EvaluateMP(p);
1722
+ {
1723
+ // static Timer t("mptool regmp, evaluate reg"); RegionTimer r(t);
1724
+ sum = mp.Eval(p-center);
1725
+ }
1605
1726
 
1727
+ {
1728
+ // static Timer t("mptool regmp, evaluate, singnode"); RegionTimer r(t);
1729
+ for (auto sn : singnodes)
1730
+ sum += sn->EvaluateMP(p);
1731
+ }
1606
1732
  return sum;
1607
1733
  }
1608
1734
 
@@ -1710,7 +1836,7 @@ namespace ngsbem
1710
1836
  }
1711
1837
 
1712
1838
  if (total_targets == 0)
1713
- mp = MultiPole<MPRegular,elem_type>(-1, mp.Kappa(),1.);
1839
+ mp = SphericalExpansion<Regular,elem_type>(-1, mp.Kappa(),1.);
1714
1840
  }
1715
1841
 
1716
1842
 
@@ -1730,10 +1856,10 @@ namespace ngsbem
1730
1856
  };
1731
1857
 
1732
1858
  Node root;
1733
- shared_ptr<SingularMLMultiPole<elem_type>> singmp;
1859
+ shared_ptr<SingularMLExpansion<elem_type>> singmp;
1734
1860
 
1735
1861
  public:
1736
- RegularMLMultiPole (shared_ptr<SingularMLMultiPole<elem_type>> asingmp, Vec<3> center, double r)
1862
+ RegularMLExpansion (shared_ptr<SingularMLExpansion<elem_type>> asingmp, Vec<3> center, double r)
1737
1863
  : root(center, r, 0, asingmp->Kappa()), singmp(asingmp)
1738
1864
  {
1739
1865
  if (!singmp->havemp) throw Exception("first call Calc for singular MP");
@@ -1763,7 +1889,7 @@ namespace ngsbem
1763
1889
  }
1764
1890
  }
1765
1891
 
1766
- RegularMLMultiPole (Vec<3> center, double r, double kappa)
1892
+ RegularMLExpansion (Vec<3> center, double r, double kappa)
1767
1893
  : root(center, r, 0, kappa)
1768
1894
  {
1769
1895
  nodes_on_level = 0;
@@ -1775,7 +1901,7 @@ namespace ngsbem
1775
1901
  root.AddTarget (t);
1776
1902
  }
1777
1903
 
1778
- void CalcMP(shared_ptr<SingularMLMultiPole<elem_type>> asingmp, bool onlytargets = true)
1904
+ void CalcMP(shared_ptr<SingularMLExpansion<elem_type>> asingmp, bool onlytargets = true)
1779
1905
  {
1780
1906
  static Timer t("mptool regular MLMP"); RegionTimer rg(t);
1781
1907
  static Timer trec("mptool regular MLMP - recording");
@@ -1845,11 +1971,11 @@ namespace ngsbem
1845
1971
 
1846
1972
  /*
1847
1973
  int maxlevel = 0;
1848
- for (auto [i,num] : Enumerate(RegularMLMultiPole::nodes_on_level))
1974
+ for (auto [i,num] : Enumerate(RegularMLExpansion::nodes_on_level))
1849
1975
  if (num > 0) maxlevel = i;
1850
1976
 
1851
1977
  for (int i = 0; i <= maxlevel; i++)
1852
- cout << "reg " << i << ": " << RegularMLMultiPole::nodes_on_level[i] << endl;
1978
+ cout << "reg " << i << ": " << RegularMLExpansion::nodes_on_level[i] << endl;
1853
1979
  */
1854
1980
 
1855
1981
  static Timer tloc("mptool regular localize expansion"); RegionTimer rloc(tloc);
@@ -1890,10 +2016,10 @@ namespace ngsbem
1890
2016
 
1891
2017
 
1892
2018
  template <typename elem_type>
1893
- inline ostream & operator<< (ostream & ost, const RegularMLMultiPole<elem_type> & mlmp)
2019
+ inline ostream & operator<< (ostream & ost, const RegularMLExpansion<elem_type> & mlmp)
1894
2020
  {
1895
2021
  mlmp.Print(ost);
1896
- // ost << "RegularMLMultiPole" << endl;
2022
+ // ost << "RegularMLExpansion" << endl;
1897
2023
  return ost;
1898
2024
  }
1899
2025