Feellgood
fmm_demag.h
Go to the documentation of this file.
1 #ifndef FMM_DEMAG_H
2 #define FMM_DEMAG_H
3 
10 #include "Components/FParticleType.hpp"
11 #include "Components/FTypedLeaf.hpp"
12 #include "Containers/FOctree.hpp"
13 #include "Core/FFmmAlgorithmThreadTsm.hpp"
14 #include "Kernels/P2P/FP2PParticleContainerIndexed.hpp"
15 #include "Kernels/Rotation/FRotationCell.hpp"
16 #include "Kernels/Rotation/FRotationKernel.hpp"
17 
18 #include "mesh.h"
19 
24 namespace scal_fmm
25  {
26 const int P = 9;
27 const int NbLevels = 6;
28 const int SizeSubLevels = 3;
30 typedef double FReal;
33 typedef FTypedRotationCell<FReal, P>
36 typedef FP2PParticleContainerIndexed<FReal>
39 typedef FTypedLeaf<FReal, ContainerClass>
42 typedef FOctree<FReal, CellClass, ContainerClass, LeafClass>
45 typedef FRotationKernel<FReal, CellClass, ContainerClass, P>
48 typedef FFmmAlgorithmThreadTsm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>
52 const double boxWidth = 2.01;
53 const FPoint<FReal> boxCenter(0., 0., 0.);
59 class fmm
60  {
61 public:
64  inline fmm(Mesh::mesh &msh ,
65  std::vector<Tetra::prm> & prmTet ,
66  std::vector<Triangle::prm> & prmTri ,
67  const int ScalfmmNbThreads )
68  : prmTetra(prmTet), prmTriangle(prmTri),
70  {
71  omp_set_num_threads(ScalfmmNbThreads);
72  norm = 2. / msh.l.maxCoeff();
73 
74  FSize idxPart = 0;
75  for (idxPart = 0; idxPart < (FSize)msh.magNode.size(); ++idxPart)
76  {
77  if (msh.magNode[idxPart])
78  {
79  Eigen::Vector3d pTarget = norm*(msh.getNode_p(idxPart) - msh.c);
80  tree.insert(FPoint<FReal>(pTarget.x(), pTarget.y(), pTarget.z()),
81  FParticleType::FParticleTypeTarget, idxPart);
82  }
83  }
84 
85  insertCharges<Tetra::Tet, Tetra::NPI>(msh.tet, msh.magTet, idxPart, msh.c);
86  insertCharges<Triangle::Tri, Triangle::NPI>(msh.tri, msh.magTri, idxPart, msh.c);
87 
88  srcDen.resize( msh.magTri.size()*Triangle::NPI + msh.magTet.size()*Tetra::NPI );
89  corr.resize(msh.magNode.size());
90  }
91 
96  void calc_demag(Mesh::mesh &msh )
97  {
98  demag(Nodes::get_u<Nodes::NEXT>, Nodes::set_phi, msh);
99  if (!FIRST_ORDER)
100  { demag(Nodes::get_v<Nodes::NEXT>, Nodes::set_phiv, msh); }
101  }
102 
104  std::vector<double> corr;
105 
107  const std::vector<Tetra::prm> &prmTetra;
108 
110  const std::vector<Triangle::prm> &prmTriangle;
111 
112 private:
114  std::vector<double> srcDen;
115 
118 
121 
123  double norm;
124 
131  template<class T, const int NPI>
132  void insertCharges(const std::vector<T> &container, const std::vector<int> &idxContainer,
133  FSize &idx, const Eigen::Ref<const Eigen::Vector3d> c)
134  {
135  std::for_each(idxContainer.begin(), idxContainer.end(),
136  [this,&container, c, &idx](const int idxElem)
137  {
138  const T &elem = container[idxElem];
139  Eigen::Matrix<double,Nodes::DIM,NPI> gauss = elem.getPtGauss();
140 
141  for (int j = 0; j < NPI; j++, idx++)
142  {
143  double x = norm*(gauss(0,j) - c.x());
144  double y = norm*(gauss(1,j) - c.y());
145  double z = norm*(gauss(2,j) - c.z());
146  tree.insert(FPoint<FReal>(x,y,z), FParticleType::FParticleTypeSource,
147  idx, 0.0);
148  }
149  });
150  }
151 
155  void calc_charges(const std::function<const Eigen::Vector3d(const Nodes::Node&)>& getter,
156  Mesh::mesh &msh)
157  {
158  int nsrc(0);
159  std::fill(srcDen.begin(),srcDen.end(),0);
160  std::for_each(msh.magTet.begin(),msh.magTet.end(),[this, &msh, &getter, &nsrc](const int idx)
161  {
162  Tetra::Tet &t = msh.tet[idx];
163  Eigen::Matrix<double,Tetra::NPI,1> result =
164  t.charges(prmTetra[t.idxPrm].Ms, getter);
165  for(int i=0;i<Tetra::NPI;i++)
166  { srcDen[nsrc+i] = result(i); }
167  nsrc += Tetra::NPI;
168  });
169  std::fill(corr.begin(),corr.end(),0);
170  std::for_each(msh.magTri.begin(),msh.magTri.end(),[this, &msh, &getter, &nsrc](const int idx)
171  {
172  Triangle::Tri &f = msh.tri[idx];
173  Eigen::Matrix<double,Triangle::NPI,1> result = f.charges(f.dMs, getter);
174  for(int i=0;i<Triangle::NPI;i++)
175  { srcDen[nsrc+i] = result(i); }
176  nsrc += Triangle::NPI;
177  f.correctionCharges(getter,result,corr);
178  });
179  }
180 
184  void demag(const std::function<const Eigen::Vector3d(const Nodes::Node&)>& getter,
185  const std::function<void(Nodes::Node &, const double)>& setter, Mesh::mesh &msh)
186  {
187  FmmClass algo(&tree, &kernels);
188  calc_charges(getter, msh);
189 
190  auto nbMagNodes = msh.magNode.size();
191  // reset potentials and forces - physicalValues[idxPart] = Q
192  tree.forEachLeaf(
193  [this,&nbMagNodes](LeafClass *leaf)
194  {
195  const int nbParticlesInLeaf = leaf->getSrc()->getNbParticles();
196  const auto &indexes = leaf->getSrc()->getIndexes();
197  FReal *const physicalValues = leaf->getSrc()->getPhysicalValues();
198  for (int idxPart = 0; idxPart < nbParticlesInLeaf; ++idxPart)
199  {
200  physicalValues[idxPart] = srcDen[indexes[idxPart] - nbMagNodes];
201  }
202 
203  std::fill_n(leaf->getTargets()->getPotentials(),
204  leaf->getTargets()->getNbParticles(), 0);
205  });
206 
207  tree.forEachCell([](CellClass *cell) { cell->resetToInitialState(); });
208 
209  algo.execute();
210 
211  tree.forEachLeaf(
212  [this, &msh, setter](LeafClass *leaf)
213  {
214  const FReal *const potentials = leaf->getTargets()->getPotentials();
215  const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
216  const auto &indexes = leaf->getTargets()->getIndexes();
217  for (int idxPart = 0; idxPart < nbParticlesInLeaf; ++idxPart)
218  {
219  const int indexPartOrig = indexes[idxPart];
220  msh.set(indexPartOrig, setter,
221  (potentials[idxPart] * norm + corr[indexPartOrig]) / (4 * M_PI));
222  }
223  });
224  }
225  }; // end class fmm
226 
227  } // namespace scal_fmm
228 #endif
Definition: mesh.h:34
const Eigen::Vector3d getNode_p(const int i) const
Definition: mesh.h:153
Eigen::Vector3d l
Definition: mesh.h:199
std::vector< int > magTet
Definition: mesh.h:366
Eigen::Vector3d c
Definition: mesh.h:196
std::vector< bool > magNode
Definition: mesh.h:363
std::vector< Tetra::Tet > tet
Definition: mesh.h:214
std::vector< int > magTri
Definition: mesh.h:372
void set(const int i, const std::function< void(Nodes::Node &, const double)> &what_to_set, const double val)
Definition: mesh.h:328
std::vector< Triangle::Tri > tri
Definition: mesh.h:208
Definition: fmm_demag.h:60
void insertCharges(const std::vector< T > &container, const std::vector< int > &idxContainer, FSize &idx, const Eigen::Ref< const Eigen::Vector3d > c)
Definition: fmm_demag.h:132
double norm
Definition: fmm_demag.h:123
const std::vector< Triangle::prm > & prmTriangle
Definition: fmm_demag.h:110
fmm(Mesh::mesh &msh, std::vector< Tetra::prm > &prmTet, std::vector< Triangle::prm > &prmTri, const int ScalfmmNbThreads)
Definition: fmm_demag.h:64
std::vector< double > corr
Definition: fmm_demag.h:104
void calc_demag(Mesh::mesh &msh)
Definition: fmm_demag.h:96
std::vector< double > srcDen
Definition: fmm_demag.h:114
void demag(const std::function< const Eigen::Vector3d(const Nodes::Node &)> &getter, const std::function< void(Nodes::Node &, const double)> &setter, Mesh::mesh &msh)
Definition: fmm_demag.h:184
OctreeClass tree
Definition: fmm_demag.h:117
const std::vector< Tetra::prm > & prmTetra
Definition: fmm_demag.h:107
void calc_charges(const std::function< const Eigen::Vector3d(const Nodes::Node &)> &getter, Mesh::mesh &msh)
Definition: fmm_demag.h:155
KernelClass kernels
Definition: fmm_demag.h:120
class mesh, readMesh is expecting a mesh file in gmsh format either text or binary,...
void set_phi(Node &n, const double val)
Definition: node.h:165
void set_phiv(Node &n, const double val)
Definition: node.h:168
const int NPI
Definition: tetra.h:50
const int NPI
Definition: triangle.h:43
const FPoint< FReal > boxCenter(0., 0., 0.)
FRotationKernel< FReal, CellClass, ContainerClass, P > KernelClass
Definition: fmm_demag.h:46
FP2PParticleContainerIndexed< FReal > ContainerClass
Definition: fmm_demag.h:37
FTypedRotationCell< FReal, P > CellClass
Definition: fmm_demag.h:34
FTypedLeaf< FReal, ContainerClass > LeafClass
Definition: fmm_demag.h:40
FOctree< FReal, CellClass, ContainerClass, LeafClass > OctreeClass
Definition: fmm_demag.h:43
const int P
Definition: fmm_demag.h:26
const double boxWidth
Definition: fmm_demag.h:52
const int SizeSubLevels
Definition: fmm_demag.h:28
const int NbLevels
Definition: fmm_demag.h:27
double FReal
Definition: fmm_demag.h:30
FFmmAlgorithmThreadTsm< OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass
Definition: fmm_demag.h:49
Definition: node.h:60