Feellgood
fmm_demag.h
Go to the documentation of this file.
1 #ifndef FMM_DEMAG_H
2 #define FMM_DEMAG_H
3 
9 #include "Components/FParticleType.hpp"
10 #include "Components/FTypedLeaf.hpp"
11 #include "Containers/FOctree.hpp"
12 #include "Core/FFmmAlgorithmThreadTsm.hpp"
13 #include "Kernels/P2P/FP2PParticleContainerIndexed.hpp"
14 #include "Kernels/Rotation/FRotationCell.hpp"
15 #include "Kernels/Rotation/FRotationKernel.hpp"
16 
17 #include "mesh.h"
18 
23 namespace scal_fmm
24  {
25 const int P = 9;
26 const int NbLevels = 6;
27 const int SizeSubLevels = 3;
29 typedef double FReal;
31 typedef FTypedRotationCell<FReal, P>
34 typedef FP2PParticleContainerIndexed<FReal>
37 typedef FTypedLeaf<FReal, ContainerClass>
40 typedef FOctree<FReal, CellClass, ContainerClass, LeafClass>
43 typedef FRotationKernel<FReal, CellClass, ContainerClass, P>
46 typedef FFmmAlgorithmThreadTsm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>
50 const double boxWidth = 2.01;
51 const FPoint<FReal> boxCenter(0., 0., 0.);
57 class fmm
58  {
59 public:
62  inline fmm(Mesh::mesh &msh ,
63  std::vector<Tetra::prm> & prmTet ,
64  std::vector<Facette::prm> & prmFac ,
65  const int ScalfmmNbThreads )
66  : prmTetra(prmTet), prmFacette(prmFac),
68  {
69  omp_set_num_threads(ScalfmmNbThreads);
70  norm = 2. / msh.l.maxCoeff();
71 
72  FSize idxPart = 0;
73  for (idxPart = 0; idxPart < msh.getNbNodes(); ++idxPart)
74  {
75  if (msh.magNode[idxPart])
76  {
77  Eigen::Vector3d pTarget = norm*(msh.getNode_p(idxPart) - msh.c);
78  tree.insert(FPoint<FReal>(pTarget.x(), pTarget.y(), pTarget.z()),
79  FParticleType::FParticleTypeTarget, idxPart);
80  }
81  }
82 
83  insertCharges<Tetra::Tet, Tetra::NPI>(msh.tet, msh.magTet, idxPart, msh.c);
84  insertCharges<Facette::Fac, Facette::NPI>(msh.fac, msh.magFac, idxPart, msh.c);
85 
86  srcDen.resize( msh.magFac.size()*Facette::NPI + msh.magTet.size()*Tetra::NPI );
87  corr.resize(msh.magNode.size());
88  }
89 
93  void calc_demag(Mesh::mesh &msh )
94  {
95  demag(Nodes::get_u<Nodes::NEXT>, Nodes::set_phi, msh);
96  demag(Nodes::get_v<Nodes::NEXT>, Nodes::set_phiv, msh);
97  }
98 
100  std::vector<double> srcDen;
101 
103  std::vector<double> corr;
104 
106  const std::vector<Tetra::prm> &prmTetra;
107 
109  const std::vector<Facette::prm> &prmFacette;
110 
111 private:
114 
117 
119  double norm;
120 
127  template<class T, const int NPI>
128  void insertCharges(std::vector<T> const &container, std::vector<int> const &idxContainer,
129  FSize &idx, Eigen::Ref<Eigen::Vector3d> const c)
130  {
131  std::for_each(idxContainer.begin(), idxContainer.end(),
132  [this,&container, c, &idx](int const &idxElem)
133  {
134  T const &elem = container[idxElem];
135  Eigen::Matrix<double,Nodes::DIM,NPI> gauss;
136  elem.getPtGauss(gauss);
137 
138  for (int j = 0; j < NPI; j++, idx++)
139  {
140  double x = norm*(gauss(0,j) - c.x());
141  double y = norm*(gauss(1,j) - c.y());
142  double z = norm*(gauss(2,j) - c.z());
143  tree.insert(FPoint<FReal>(x,y,z), FParticleType::FParticleTypeSource, idx, 0.0);
144  }
145  });
146  }
147 
150  void calc_charges(std::function<const Eigen::Vector3d(Nodes::Node)> getter, Mesh::mesh &msh)
151  {
152  int nsrc(0);
153  std::fill(srcDen.begin(),srcDen.end(),0);
154  std::for_each(msh.magTet.begin(),msh.magTet.end(),[this, &msh, getter, &nsrc](const int idx)
155  {
156  Tetra::Tet &t = msh.tet[idx];
157  t.charges(prmTetra[t.idxPrm], getter, srcDen, nsrc);
158  });
159  std::fill(corr.begin(),corr.end(),0);
160  std::for_each(msh.magFac.begin(),msh.magFac.end(),[this, &msh, getter, &nsrc](const int idx)
161  {
162  Facette::Fac &f = msh.fac[idx];
163  f.charges(prmFacette[f.idxPrm], getter, srcDen, nsrc, corr);
164  });
165  }
166 
170  void demag(std::function<const Eigen::Vector3d(Nodes::Node)> getter,
171  std::function<void(Nodes::Node &, const double)> setter, Mesh::mesh &msh)
172  {
173  FmmClass algo(&tree, &kernels);
174  calc_charges(getter, msh);
175 
176  auto nbMagNodes = msh.magNode.size();
177  // reset potentials and forces - physicalValues[idxPart] = Q
178  tree.forEachLeaf(
179  [this,&nbMagNodes](LeafClass *leaf)
180  {
181  const int nbParticlesInLeaf = leaf->getSrc()->getNbParticles();
182  const auto &indexes = leaf->getSrc()->getIndexes();
183  FReal *const physicalValues = leaf->getSrc()->getPhysicalValues();
184  for (int idxPart = 0; idxPart < nbParticlesInLeaf; ++idxPart)
185  {
186  physicalValues[idxPart] = srcDen[indexes[idxPart] - nbMagNodes];
187  }
188 
189  std::fill_n(leaf->getTargets()->getPotentials(),
190  leaf->getTargets()->getNbParticles(), 0);
191  });
192 
193  tree.forEachCell([](CellClass *cell) { cell->resetToInitialState(); });
194 
195  algo.execute();
196 
197  tree.forEachLeaf(
198  [this, &msh, setter](LeafClass *leaf)
199  {
200  const FReal *const potentials = leaf->getTargets()->getPotentials();
201  const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
202  const auto &indexes = leaf->getTargets()->getIndexes();
203  for (int idxPart = 0; idxPart < nbParticlesInLeaf; ++idxPart)
204  {
205  const int indexPartOrig = indexes[idxPart];
206  msh.set(indexPartOrig, setter,
207  (potentials[idxPart] * norm + corr[indexPartOrig]) / (4 * M_PI));
208  }
209  });
210  }
211  }; // end class fmm
212 
213  } // namespace scal_fmm
214 #endif
Definition: mesh.h:27
const Eigen::Vector3d getNode_p(const int i) const
Definition: mesh.h:144
Eigen::Vector3d l
Definition: mesh.h:190
std::vector< int > magTet
Definition: mesh.h:334
Eigen::Vector3d c
Definition: mesh.h:187
int getNbNodes(void) const
Definition: mesh.h:135
std::vector< bool > magNode
Definition: mesh.h:331
std::vector< Tetra::Tet > tet
Definition: mesh.h:202
std::vector< Facette::Fac > fac
Definition: mesh.h:199
std::vector< int > magFac
Definition: mesh.h:337
void set(const int i, std::function< void(Nodes::Node &, const double)> what_to_set, const double val)
Definition: mesh.h:308
Definition: fmm_demag.h:58
double norm
Definition: fmm_demag.h:119
fmm(Mesh::mesh &msh, std::vector< Tetra::prm > &prmTet, std::vector< Facette::prm > &prmFac, const int ScalfmmNbThreads)
Definition: fmm_demag.h:62
std::vector< double > corr
Definition: fmm_demag.h:103
void insertCharges(std::vector< T > const &container, std::vector< int > const &idxContainer, FSize &idx, Eigen::Ref< Eigen::Vector3d > const c)
Definition: fmm_demag.h:128
void calc_demag(Mesh::mesh &msh)
Definition: fmm_demag.h:93
const std::vector< Facette::prm > & prmFacette
Definition: fmm_demag.h:109
std::vector< double > srcDen
Definition: fmm_demag.h:100
void calc_charges(std::function< const Eigen::Vector3d(Nodes::Node)> getter, Mesh::mesh &msh)
Definition: fmm_demag.h:150
OctreeClass tree
Definition: fmm_demag.h:113
void demag(std::function< const Eigen::Vector3d(Nodes::Node)> getter, std::function< void(Nodes::Node &, const double)> setter, Mesh::mesh &msh)
Definition: fmm_demag.h:170
const std::vector< Tetra::prm > & prmTetra
Definition: fmm_demag.h:106
KernelClass kernels
Definition: fmm_demag.h:116
class mesh, readMesh is expecting a mesh file in gmsh format either text or binary,...
const int NPI
Definition: facette.h:18
void set_phiv(Node &n, double val)
Definition: node.h:168
void set_phi(Node &n, double val)
Definition: node.h:165
const int NPI
Definition: tetra.h:22
const FPoint< FReal > boxCenter(0., 0., 0.)
FRotationKernel< FReal, CellClass, ContainerClass, P > KernelClass
Definition: fmm_demag.h:44
FP2PParticleContainerIndexed< FReal > ContainerClass
Definition: fmm_demag.h:35
FTypedRotationCell< FReal, P > CellClass
Definition: fmm_demag.h:32
FTypedLeaf< FReal, ContainerClass > LeafClass
Definition: fmm_demag.h:38
FOctree< FReal, CellClass, ContainerClass, LeafClass > OctreeClass
Definition: fmm_demag.h:41
const int P
Definition: fmm_demag.h:25
const double boxWidth
Definition: fmm_demag.h:50
const int SizeSubLevels
Definition: fmm_demag.h:27
const int NbLevels
Definition: fmm_demag.h:26
double FReal
Definition: fmm_demag.h:29
FFmmAlgorithmThreadTsm< OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass
Definition: fmm_demag.h:47
Definition: node.h:61