CEPS  24.01
Cardiac ElectroPhysiology Simulator
AbstractDiscretization.cpp
Go to the documentation of this file.
1 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2  This file is part of CEPS.
3 
4  CEPS is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  CEPS is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with CEPS (see file LICENSE at root of project).
16  If not, see <https://www.gnu.org/licenses/>.
17 
18 
19  Copyright 2019-2024 Inria, Universite de Bordeaux
20 
21  Authors, in alphabetical order:
22 
23  Pierre-Elliott BECUE, Florian CARO, Yves COUDIERE(*), Andjela DAVIDOVIC,
24  Charlie DOUANLA-LONTSI, Marc FUENTES, Mehdi JUHOOR, Michael LEGUEBE(*),
25  Pauline MIGERDITICHAN, Valentin PANNETIER(*), Nejib ZEMZEMI.
26  * : currently active authors
27 
28 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
33 
35  CepsObject (),
36  m_problem (problem),
37  m_distributedDofs (new DistributedInfos<DegreeOfFreedom*>()),
38  m_dofsFactory (nullptr),
39  m_dofsBuilt (false),
40  m_spatialUnknownsLocation(CepsLocationFlag::ZeroD), // Voluntarily wrong
41  m_extraAdjacencyToSend ({}),
42  m_extraAdjacencyToRecv ({})
43 {
44  CEPS_ABORT_IF(ceps::isNullPtr(m_problem),"Pde problem pointer is nullptr");
45  m_geometry = problem->getGeometry();
46  CEPS_ABORT_IF(m_problem->getUnknowns().empty(),
47  "Problem has no unknowns set ! Make sure to call defineUnknowns() of the problem class"
48  );
49  m_extraAdjacencyToSend.resize(ceps::getGridSize());
50 }
51 
53 {
54  // Clear dofs
55  for (CepsUInt i=0;i<CepsLocationFlagSize;i++)
56  for (auto [gID,dofs] : m_dofsTree[i])
57  for (DegreeOfFreedom* dof: dofs)
59 
62 }
63 
66 {
67  return m_problem;
68 }
69 
72 {
73  return m_dofsFactory;
74 }
75 
78 {
79  return m_distributedDofs;
80 }
81 
84 {
85  return m_dofsTree;
86 }
87 
90 {
91  return m_dofsForUnknown;
92 }
93 
96 {
97  return m_dofsForUnknown.at(uId);
98 }
99 
102 {
103  return m_dofsForUnknown.at(u->getIdentifier());
104 }
105 
106 Geometry*
108 {
109  return m_geometry;
110 }
111 
112 void
114 {
116 }
117 
118  //=================================================================================================
119 
120 DVecPtr
122 {
124 }
125 
126 DHVecPtr
128 {
130 }
131 
132 DMatPtr
134 {
136 }
137 
140 {
141  DegreeOfFreedom * dof = m_distributedDofs->getOwnedMapping()->atGlobal(globalDofId,nullptr);
142  if (ceps::isNullPtr(dof))
143  dof = m_distributedDofs->getHaloMapping()->atGlobal(globalDofId,nullptr);
144  return dof;
145 }
146 
147 const DegreeOfFreedom*
149 {
150  const DegreeOfFreedom* dof = m_distributedDofs->getHaloMapping()->atGlobal(globalDofId,nullptr);
151  if (ceps::isNullPtr(dof))
152  dof = m_distributedDofs->getHaloMapping()->atGlobal(globalDofId,nullptr);
153  return dof;
154 }
155 
158 {
159  return m_distributedDofs->getOwned();
160 }
161 
164 {
165  return m_distributedDofs->getHalo();
166 }
167 
168 void
171  DHVecPtr v,
172  CepsReal t
173 ) const
174 {
175  v->zero();
176  v->getLocalData();
177  for (auto toParse: {m_distributedDofs->getOwned(),
179  for (DegreeOfFreedom* dof : toParse)
180  {
182  args.t = t;
183  (*v)[dof->getGlobalIndex()] = func->operator()(args);
184  }
185  v->releaseLocalData();
186 }
187 
188 void
190 {
191  auto distanceToX = [&x] (CepsVertex y) {
192  return std::sqrt(pow(x[0]-y[0],2) + pow(x[1]-y[1],2) + pow(x[2]-y[2],2));
193  };
194 
195  // Find the local minimum on current process
197  CepsDofGlobalIndex iMin = -1;
199  if (dof->getUnknown()==u)
200  {
201  CepsReal d = distanceToX(*dof->getVertex());
202  if (d < dMin)
203  {
204  dMin = d;
205  iMin = dof->getGlobalIndex();
206  }
207  }
208 
210  myD[ceps::getRank()] = dMin;
211  MPI_Allreduce(myD.data(),d.data(),ceps::getGridSize(),CEPS_MPI_REAL,MPI_SUM,ceps::getCommunicator());
212  owner = ceps::argmin(d);
213 
214  MPI_Bcast(&iMin,1,CEPS_MPI_GLOBAL_INDEX,owner,ceps::getCommunicator());
215  dofId = iMin;
216 
217  return;
218 }
219 
220 CepsReal
222 {
224  CepsReal value = 0.0;
225 
226  sol->getLocalData();
227  if (dof->getOwner() == ceps::getRank())
228  value = (*sol)[dof->getGlobalIndex()];
229  sol->releaseLocalData();
230 
231  MPI_Bcast(&value, 1, CEPS_MPI_REAL, dof->getOwner(), ceps::getCommunicator());
232  return value;
233 }
234 
235 CepsReal
237  DHVecPtr v,
238  CepsBool boundary,
239  const CepsSet<CepsAttribute>& attrs,
240  const CepsVector<Unknown*>& unknowns
241 )
242 {
243  DHVecPtr av (ceps::getNew<DistributedHaloVector>(*v));
244  DHVecPtr one(ceps::getNew<DistributedHaloVector>(*v));
245  av ->abs();
246  one->fill(1.);
247  return this->dotProduct(one,av,boundary,attrs,unknowns);
248 }
249 
250 CepsReal
252  DHVecPtr v,
253  CepsBool boundary,
254  const CepsSet<CepsAttribute>& attrs,
255  const CepsVector<Unknown*>& unknowns
256 )
257 {
258  return std::sqrt(this->dotProduct(v,v,boundary,attrs,unknowns));
259 }
260 
261  //=================================================================================================
262 
263 void
265 {
266 
267  // 1. Build the dofs according to their location and number
268  // (FE P1, FE P2, FV, etc...) from data in the unknown manager and geometry
269  this->buildDofsTree();
270 
271  // 2. Build the local ID to global ID mapping for dofs
273 
274  // 3. Add dofs for zero D unknowns, if any
276 
277  // 4. Set the interactions between dofs
280 
281  // 5. Setup the dofs factory
283 
284  m_dofsBuilt = true;
285 }
286 
287 void
289 {
290  const CepsUInt& rank = ceps::getRank ();
291  // ---------------------------------------------------------
292  // Count owned and halo
293  CepsUInt nbOwned = 0U;
294  CepsUInt nbHalo = 0U;
295  for (auto locSlice: m_dofsTree)
296  for (auto [gid,setOfDofs]: locSlice)
297  for (auto dof: setOfDofs)
298  if (dof->getOwner()==rank)
299  nbOwned++;
300  else
301  nbHalo++;
302 
303  m_distributedDofs->getOwnedMapping()->reserve(nbOwned);
304  m_distributedDofs->getHaloMapping ()->reserve(nbHalo);
305 
306  // ---------------------------------------------------------
307  // Create dofs owned and halo, with hash from (u.identifier and dof gid)
308  CepsUInt nu = m_problem->getUnknowns().size();
309  for (auto locSlice: m_dofsTree)
310  for (auto [gid,setOfDofs]: locSlice)
311  {
312  for (auto dof: setOfDofs)
313  {
314  CepsHash hash = ceps::hash::get(dof->getUnknown()->getIdentifier()+nu*dof->getDiscrId());
315  m_distributedDofs->add(dof,hash,dof->getOwner());
316  }
317  }
318 
319  // ---------------------------------------------------------
320  // Synchronize each procs
321  m_distributedDofs->synchronize(true, &setGlobalIndexFunction<DegreeOfFreedom>);
322 
323  // ---------------------------------------------------------
324  // Construct the "reversed" map (unknown -> dofId)
325  m_dofsForUnknown.clear();
326 
327  for (Unknown* u : m_problem->getUnknowns())
328  m_dofsForUnknown[u->getIdentifier()] = {};
329 
330  for (auto toParse : {m_distributedDofs->getOwned(),m_distributedDofs->getHalo()})
331  for (DegreeOfFreedom* dof: toParse)
332  m_dofsForUnknown[dof->getUnknown()->getIdentifier()].push_back(dof);
333 
334  return;
335 }
336 
337 void
339 {
340  // The new dofs will be registered after all spatial dofs.
341  // So they will be placed in the last rows of the linear system.
342  // We give them to the last CPU of the computational grid.
343 
345 
346  CepsUInt iloc = static_cast<CepsUInt> (CepsLocationFlag::ZeroD);
347 
348  for (Unknown*u : m_problem->getUnknowns())
349  if (u->getLocation()==CepsLocationFlag::ZeroD)
350  {
351  // The status of the dof is different from spatial dofs.
352  // We give it attribute -1, and the unknown's id as geom id.
353 
354  CepsUnknownIndex uId = u->getIdentifier();
355 
356  auto dof = ceps::getNew<DegreeOfFreedom>(
358  uId,dofId,ceps::getGridSize()-1
359  );
360  // Insert dof in tree
361  // CepsGlobalIndex guId = CepsGlobalIndex(uId);
362  // CepsMap<CepsGlobalIndex,CepsSet<DegreeOfFreedom*>> tmp;
363  // tmp[guId] = {};
364  // tmp[guId].insert(dof);
365  m_dofsTree[iloc][CepsGlobalIndex(uId)] = {dof};
366  // Insert dof in distributed info
367  m_distributedDofs->add(dof,dofId,dofId,ceps::getGridSize()-1);
368 
369  // Insert dof in reverse map
370  m_dofsForUnknown[u->getIdentifier()].push_back(dof);
371  dofId++; // next zeroD unknown
372 
373  }
374 
375  m_distributedDofs->synchronize(false,nullptr);
376 }
377 
378 void
380 {
381 
383  {
384  Unknown* u1 = ui->u1;
385  Unknown* u2 = ui->u2;
386  if (not (u1->isSpatial() and u2->isSpatial()))
387  {
388  // At least one of those two has only one element
391  {
392  CepsBool okAttributeI = ui->hasAttribute(CepsUniversal)
393  or ui->getNumberOfAttributes()==0;
394  CepsBool okAttribute1 = dof1->hasAttribute(CepsUniversal) or (not okAttributeI and
395  dof1->hasOneOfAttributes(ui->getAttributes()));
396  CepsBool okAttribute2 = dof2->hasAttribute(CepsUniversal) or (not okAttributeI and
397  dof2->hasOneOfAttributes(ui->getAttributes()));
398 
399  if (okAttributeI or (okAttribute1 and okAttribute2))
400  {
401  dof1->addNeighbor(dof2);
402  dof2->addNeighbor(dof1);
403  }
404  }
405 
406  }
407  }
408 
409 }
410 
411 void
413 {
414 
415  ceps::barrier();
416  // Get information on number of dofs
419 
420  // Prepare the non zero template
421  CepsVector<CepsInt> dNnz,oNnz;
422 
423  dNnz.resize(nLDofs,0U);
424  oNnz.resize(nLDofs,0U);
425 
426  // Neighbours can be built asymetrically, so the oNnz is not correct if deduced directly
428 
429  for (CepsUInt j=0U; j<nLDofs; ++j)
430  {
431  // Fetch dof adjacency seen by other cpus
433  CepsDofGlobalIndex dofId = dof->getGlobalIndex();
435 
436  for (DegreeOfFreedom *ndof: m_distributedDofs->getOwned(j)->getNeighbors())
437  {
438  CepsProcId owner = ndof->getOwner();
439  CepsDofGlobalIndex ndofId = ndof->getGlobalIndex();
440 
441  extraNgb.erase(ndofId);
442  if (owner!=ceps::getRank())
443  {
444  oNnz[j]++;
445  if (not othersONnz[owner].contains(ndofId))
446  othersONnz[owner][ndofId] = 1;
447  else
448  othersONnz[owner][ndofId]++;
449  }
450  else
451  dNnz[j]++;
452  }
453 
454  // +1 in diagonal because we need to count the dof itself
455  // + the dofs relationships that were seen by other processors only
456  dNnz[j] += 1+extraNgb.size();
457 
458  }
459 
460  // Some interactions can be missing in the halo, when other dofs are
461  // distributed with two other processes
463  {
464  CepsProcId hOwner = hdof->getOwner();
465  for (DegreeOfFreedom* ndof: hdof->getNeighbors())
466  {
467  CepsProcId nOwner = ndof->getOwner();
468  CepsDofGlobalIndex nDofId = ndof->getGlobalIndex();
469  if (hOwner!=nOwner)
470  {
471  if (not othersONnz[nOwner].contains(nDofId))
472  othersONnz[nOwner][nDofId] = 1;
473  else
474  othersONnz[nOwner][nDofId]++;
475  }
476  }
477  }
478 
479 
480  // Send othersONnz data. Not optimal but
481  // From cpu1 to cpu2
482  ceps::barrier();
483  CepsProcId rank = ceps::getRank();
484  CepsUInt gridSize = ceps::getGridSize();
485  for (CepsProcId cpu1 = 0; cpu1<gridSize; cpu1++)
486  for (CepsProcId cpu2 = 0; cpu2<gridSize; cpu2++)
487  {
488 
489  if (cpu1!=cpu2 and (rank==cpu1 or rank==cpu2))
490  {
492  if (rank==cpu1)
493  {
494  tmpMap = othersONnz[cpu2];
495  }
496 
497  // For cpu2, otherONnz[cpu2] is empty before this call (NO!!!!!!!)
498  ceps::sendMap(cpu1,cpu2,tmpMap,gridSize*gridSize,cpu1*gridSize+cpu2);
499  if (rank==cpu2)
500  {
501  for (auto [row,nNz] : tmpMap)
502  {
503  // get local index on cpu2. The global index may not have been registered though...
504  // we have to do it manually
505  oNnz[row-m_distributedDofs->getGlobalIndexOffset(cpu2)] += nNz;
506  }
507  }
508  }
509  ceps::barrier();
510  }
511 
512 
513  for (CepsUInt j=0U; j<nLDofs; ++j)
514  {
515  // Sometimes the patch the othersONnz leads to unused allocated space, that can, in some cases,
516  // even exceed the total size of the matrix (e.g. a lagrangian coefficient)
517  oNnz[j] = std::min(oNnz[j],CepsInt(nDofs-nLDofs));
518 
519  // CEPS_ABORT_IF(CepsUInt(dNnz[j]+oNnz[j])>nDofs,
520  // "Total number of nnz on line " << j << " exceeds size of matrix.\n"
521  // " Global size: " << nDofs << " x " << nDofs << "\n" <<
522  // " Local size: " << nLDofs << " x " << nLDofs << "\n" <<
523  // " In diagonal block: " << dNnz[j] << "\n" <<
524  // " In off-diagonal blocks: " << oNnz[j] << "\n" <<
525  // " Total number of coefficients on this row: " << dNnz[j]+oNnz[j] << "\n" <<
526  // " othersONnz " << othersONnz[0] << " " << othersONnz[1] << " " << othersONnz[2] << "\n"
527  // );
528  }
529 
530  CepsVector<CepsIndex> haloIndices;
531  haloIndices.reserve(m_distributedDofs->getHalo().size());
533  {
534  haloIndices.push_back(dof->getGlobalIndex());
535  }
536 
537  // Get the factory
538  m_dofsFactory = ceps::getNew<DistributedFactory>(nDofs,nDofs,nLDofs,nLDofs,dNnz,oNnz);
539  m_dofsFactory->setHaloIndices(haloIndices.data(),haloIndices.size(),haloIndices.data(),haloIndices.size());
540 
541 }
542 
543 void
545  const CepsUnknownIndex& uId,
546  DVecPtr vec,
547  CepsVector<CepsIndex>& indices,
548  CepsVector<CepsReal>& values,
549  CepsBool sendToMaster,
550  CepsBool returnGeomIndices,
551  std::function<CepsBool(DegreeOfFreedom*)>& selector
552 )
553 {
554  // Firstly, test if the u exists
555  CepsBool hasUnknown = false;
556  for (Unknown* u: m_problem->getUnknowns())
557  hasUnknown = hasUnknown or u->getIdentifier()==uId;
558 
559  if (not hasUnknown or not m_dofsForUnknown.contains(uId))
560  return;
561 
564 
565  // Be careful of sizes ! If regroup on master: remove halo nodes
566  CepsVector<DegreeOfFreedom*> dofs = m_dofsForUnknown.at(static_cast<CepsSize>(uId));
567 
568  CepsUInt resSize = 0u;
569  for (DegreeOfFreedom* dof:dofs)
570  if (selector(dof))
571  resSize++;
572 
573  // Resize to correct size the IndicesValues struct
574  resI.reserve(resSize);
575  for (DegreeOfFreedom* dof:dofs)
576  if (selector(dof))
577  resI.push_back(dof->getGlobalIndex());
578 
579  // Get the correct entries of the vector
580  resV.resize(resSize,0.);
581  vec->getLocalData();
582  vec->getValues(resV.data(),resSize,resI.data());
583  vec->releaseLocalData();
584 
585  // Overwrite with geom indices if needed
586  if (returnGeomIndices)
587  {
588  resI.clear();
589  resI.reserve(resSize);
590  for (DegreeOfFreedom* dof:dofs)
591  if (selector(dof))
592  resI.push_back(this->getDofSpatialId(dof));
593  }
594 
595  if (sendToMaster)
596  {
597  ceps::allGatherv(resI,resI.size(),indices,true);
598  ceps::allGatherv(resV,resV.size(),values ,true);
599  }
600  else
601  {
602  values = resV;
603  indices = resI;
604  }
605 
606  return;
607 }
CepsArray< CepsMap< CepsGlobalIndex, CepsVector< DegreeOfFreedom * > >, CepsLocationFlagSize > DegreeOfFreedomTree
Data structure that classifies all the degrees of freedom.
CepsLocationFlag
DataLocation: an enum that will be used by various elements of the code (pde, readers,...
Definition: CepsEnums.hpp:108
@ ZeroD
Data is defined once.
constexpr CepsUInt CepsLocationFlagSize
Size of enum CepsLocationFlag.
Definition: CepsEnums.hpp:114
#define CEPS_ABORT_IF(condition, message)
Stops the execution with a message if condition is true. If testing is enabled, only throws a runtime...
CepsIndex CepsUnknownIndex
For unknowns.
Definition: CepsTypes.hpp:217
std::map< _Key, _Tp, _Compare, _Alloc > CepsMap
C++ map.
Definition: CepsTypes.hpp:196
CepsSize CepsHash
Hashes for distributed data.
Definition: CepsTypes.hpp:220
std::set< _Type, _Compare, _Alloc > CepsSet
C++ set.
Definition: CepsTypes.hpp:209
#define CEPS_MPI_GLOBAL_INDEX
Definition: CepsTypes.hpp:345
std::vector< _Type, _Alloc > CepsVector
C++ vector.
Definition: CepsTypes.hpp:155
bool CepsBool
Booleans.
Definition: CepsTypes.hpp:124
#define CEPS_MPI_REAL
Definition: CepsTypes.hpp:315
size_t CepsSize
Size unsigned.
Definition: CepsTypes.hpp:126
CepsGlobalIndex CepsDofGlobalIndex
Indices of degrees of freedom.
Definition: CepsTypes.hpp:226
CepsIndex CepsGlobalIndex
Many uses. Has to be signed for PETSc.
Definition: CepsTypes.hpp:218
std::make_unsigned_t< CepsInt > CepsUInt
Unsigned version on CepsInt.
Definition: CepsTypes.hpp:109
float CepsReal
Need single precision floating point.
Definition: CepsTypes.hpp:100
CepsUInt CepsProcId
For CPU indices.
Definition: CepsTypes.hpp:123
CepsArray3< CepsReal > CepsReal3D
Three real scalars, used like this for compatibility in polynomials.
Definition: CepsTypes.hpp:178
int32_t CepsInt
Need 32 bit integer.
Definition: CepsTypes.hpp:106
constexpr CepsAttribute CepsUniversal
This attribute means "everywhere".
Definition: CepsTypes.hpp:232
std::shared_ptr< DistributedHaloVector > DHVecPtr
Typedef for pointer on Distributed Halo CepsVector.
std::shared_ptr< DistributedMatrix > DMatPtr
Short typedef for pointer on dist matrix.
std::shared_ptr< DistributedVector > DVecPtr
Short typedef for pointer on distributed vector.
CepsStandardArgs getStandardArgsFrom(GeomCell *cell)
Returns a CepsStandardArgs structure with data from given cell.
Definition: GeomCell.cpp:203
DHVecPtr newDofHaloVector() const
Get a new vector from the factory, with halo data.
const DegreeOfFreedomTree & getDegreeOfFreedomTree() const
The sorted degrees of freedom.
void extractValuesForUnknownInternal(const CepsUnknownIndex &uId, DVecPtr vec, CepsVector< CepsIndex > &indices, CepsVector< CepsReal > &values, CepsBool sendToMaster, CepsBool returnGeomIndices, std::function< CepsBool(DegreeOfFreedom *)> &selector)
Slicing method that extracts the data corresponding to a specific unknown.
DistributedInfos< DegreeOfFreedom * > * getDistributedDofs() const
Get the stored Degree Of Freedom repartition.
AbstractPdeProblem * m_problem
[not owned] Pointer on the pde problem
const CepsMap< CepsUnknownIndex, CepsVector< DegreeOfFreedom * > > & getDegreesOfFreedomForUnknown()
Dofs sorted by unknown.
AbstractPdeProblem * getProblem() const
Return link to pde problem.
DistributedFactory * m_dofsFactory
[owned] The factory that builds vectors and matrices
virtual CepsReal dotProduct(DHVecPtr u, DHVecPtr v, CepsBool boundary=false, const CepsSet< CepsAttribute > &attrs={}, const CepsVector< Unknown * > &unknowns={})=0
Returns the dot product of two vectors of degrees of freedom.
void createDofsForZeroDUnknowns()
Adds one dof for each zeroD unknown, must be called after all other dofs are distributed.
void evaluateFunctionOnDofs(ceps::Function< CepsReal(CepsStandardArgs)> *func, DHVecPtr v, CepsReal t=0.) const
Fills vector v with values of function func at owned and halo dofs and time t.
CepsMap< CepsDofGlobalIndex, CepsSet< CepsDofGlobalIndex > > m_extraAdjacencyToRecv
A map to correct the missing adjacency that can occur in rare occasions in 3D.
~AbstractDiscretization() override
Destructor.
CepsBool m_dofsBuilt
Tells if the class has setup all the dofs.
AbstractDiscretization()=delete
Deleted default constructor.
CepsReal l1Norm(DHVecPtr v, CepsBool boundary=false, const CepsSet< CepsAttribute > &attrs={}, const CepsVector< Unknown * > &unknowns={})
L1-norm of a given vector.
CepsReal getZeroDValue(Unknown *u, DHVecPtr sol)
Get the value of a 0D unknown into a solution vector.
virtual void setZeroDUnknownsDofsInteractions()
Updates neighboring lists with interaction with 0D unknowns.
Geometry * getGeometry() const
Get the stored Geometry.
CepsMap< CepsUnknownIndex, CepsVector< DegreeOfFreedom * > > m_dofsForUnknown
Reverse mapping of dofs, with unknown index as key.
DVecPtr newDofVector() const
Get a new vector from the factory.
void buildDofsDistributedInfo()
Builds the degrees of freedom distribution from the dofs tree.
DistributedInfos< DegreeOfFreedom * > * m_distributedDofs
[owned] Pointer on the dofs structure
void findClosestDof(const CepsReal3D &x, Unknown *u, CepsDofGlobalIndex &dofId, CepsProcId &owner)
Set dofId to that if the closest to position x, also sets owner.
DistributedFactory * getDofsFactory() const
Get the stored DistributedFactory.
Geometry * m_geometry
[not owned] Pointer on the geometry
CepsReal l2Norm(DHVecPtr v, CepsBool boundary=false, const CepsSet< CepsAttribute > &attrs={}, const CepsVector< Unknown * > &unknowns={})
L2-norm of a given vector. Computation of dotproduct depends on the discretization.
DMatPtr newDofMatrix() const
Get a new matrix from the factory.
CepsLocationFlag m_spatialUnknownsLocation
Where unknowns are located. Must be set in child classes.
void setupDofsFactory()
Prepare the factory that will generate vectors of dofs.
CepsVector< DegreeOfFreedom * > getHaloDofs() const
Get the degrees of freedom owned by other processes.
virtual CepsIndex getDofSpatialId(const DegreeOfFreedom *dof) const =0
Return the spatial id (CellId or NodeId) for this row number.
DegreeOfFreedomTree m_dofsTree
[owned] Pointer on the distributed degree of freedom tree
virtual void setSpatialUnknownsDofsInteractions()=0
Build dofs neighboring list for spatial unknowns. Different in FE (same element dofs) and VF,...
virtual void buildDofsTree()=0
Builds the degrees of freedom tree from the PDE data.
CepsVector< DegreeOfFreedom * > getOwnedDofs() const
Get the degrees of freedom owned by process.
void buildDofs()
Builds the degrees of freedom data structures from the PDE data.
virtual void registerSpatialUnkown(Unknown *u)
Changes the location of unknown u to be adapted to the discrectization for example CepsLocationFlag::...
DegreeOfFreedom * getDof(CepsGlobalIndex globalDofId)
Get the dof with given globalID, nullptr if not found.
Base class for creating PDEs to solve.
const CepsVector< UnknownInteraction * > & getUnknownsInteractions() const
All the interactions between unknowns.
const CepsVector< Unknown * > & getUnknowns() const
List of unknowns of the pb.
Base class for other (big) CEPS classes. All classes can get a pointer to this base class and also co...
Definition: CepsObject.hpp:40
A degree of freedom for any kind of problem The dof can be associated to a geometrical element or not...
const CepsSet< DegreeOfFreedom * > & getNeighbors() const
Neighbor dofs.
void setHaloIndices(CepsIndex *haloRows, CepsUInt nHaloRows, CepsIndex *haloCols, CepsUInt nHaloCols)
Local halo rows and columns.
DVecPtr getDistributedVector() const
Pointer to created distributed vector.
DHVecPtr getDistributedHaloVector() const
Pointer on a created distributed vector that has additional memory allocated to enable the exchange o...
DMatPtr getDistributedMatrix() const
Pointer to created distributed matrix.
A class that manages data that is distributed between processors, not only real values (as in Distrib...
CepsUInt getGlobalIndexOffset(CepsProcId pId) const
Return the number of elements on the processes before pId This supposes that synchronizeTotalSize has...
CepsUInt getTotalNumberOfEntities() const
Total number of distributed data amongst all process.
const CepsVector< _Type > & getOwned() const
Get data owned by the processor, const.
LocalGlobalMapping< _Type, _Hash > * getHaloMapping()
Mapping between global and local index of halo data.
void add(const _Type &x, const _Hash &hashValue, const CepsGlobalIndex &globalId, const CepsUInt &pId)
Add entry with global ID to the container, hash must be provided, pId selects owned or halo.
void synchronize(CepsBool setGlobalIndicesFromLocals, std::function< void(_Type &, CepsGlobalIndex)> update=nullptr)
Recomputes global indices from all local indices, build correct halo global indices.
CepsUInt getNumberOfOwned() const
Number of owned data stored.
LocalGlobalMapping< _Type, _Hash > * getOwnedMapping()
Mapping between global and local index of owned data.
const CepsVector< _Type > & getHalo() const
Get halo data owned by neighbor processor, const.
Encapsulates all the geometrical data.
Definition: Geometry.hpp:50
Data describing how two unknowns are coupled.
Definition: Unknown.hpp:130
A class used to defined an unknown of a PDE problem The unknown can be defined on a specific region,...
Definition: Unknown.hpp:45
CepsBool isSpatial() const
Tells if unknown is defined on geometrical elements.
Definition: Unknown.cpp:120
void setLocation(const CepsLocationFlag &location)
Set the data location of the unknown.
Definition: Unknown.cpp:113
CepsUnknownIndex getIdentifier() const
Get the identifier of the unknown.
Definition: Unknown.cpp:82
CepsBool hasAttribute(const CepsAttribute &name) const
Tells if the entity has the attribute in argument.
const CepsGlobalIndex & getGlobalIndex() const
Get the index
const CepsProcId & getOwner() const
Get owner (processus id) of this entity.
constexpr CepsHash get(_Type const &i)
get a hash from a single value
CepsBool contains(const CepsVector< _Type, _Alloc > &vec, const _Type &item)
Tells if vectors contains a given item.
Definition: CepsVector.hpp:56
CepsUInt getRank()
Returns current processor rank.
MPI_Comm getCommunicator()
Get the communicator.
CepsUInt argmin(CepsVector< _Type, _Alloc > &vec)
Returns the position of the minimum in a whole vector.
Definition: CepsVector.hpp:356
const _Type & max(const CepsVector< _Type, _Alloc > &vec)
Returns the maximum of the vector, const version.
Definition: CepsVector.hpp:464
const _Type & min(const CepsVector< _Type, _Alloc > &vec)
Returns the minimum of the vector, const version.
Definition: CepsVector.hpp:448
int sendMap(const CepsUInt &sender, const CepsUInt &receiver, _Container< _Key, _Val > &table, const CepsUInt &nComms=1, const CepsUInt &commId=1)
send a map or mutlimap from a cpu to another
CepsUInt getGridSize()
Returns the number of process on the computing grid.
CepsBool isNullPtr(_Type *ptr)
Tells if passed pointer is null.
Definition: CepsMemory.hpp:45
void barrier()
Explicit barrier: wait for all processors before continuing.
int allGatherv(const CepsVector< T > &localTab, int localSize, CepsVector< T > &globalTab, CepsBool masterOnly=false)
Gather all the local orig vector in the global dest vector.
void destroyObject(_Type &)
Destroy[delete] any type.
Definition: CepsMemory.hpp:116
Structure used to pass arguments to SAFunc (see pde directory) The flags of the SAFunc allows extract...
Definition: CepsTypes.hpp:239
CepsReal t
time
Definition: CepsTypes.hpp:240
function caller : abstract base, only contains an variadic operator()