CEPS  24.01
Cardiac ElectroPhysiology Simulator
AbstractPdeProblem.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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
34 
36  Geometry* geom,
37  InputParameters* params
38 ):
39  m_geom (geom),
40  m_parameters (params),
41  m_discr (nullptr),
42  m_ownedDiscr (false),
43  m_analyticSolution (nullptr),
44  m_ownedRefSol (false),
45  m_refSolFiles (""),
46  m_refSolSnapDt (1.),
47  m_functions (ceps::getNew<FunctionDictionary>()),
48  m_boundaryConditions(ceps::getNew<BoundaryConditionManager>(m_functions)),
49  m_sourceTerms (ceps::getNew<SourceTermManager>(m_functions)),
50  m_ownedFunctions (true),
51  m_ownedBCs (true),
52  m_ownedSrcs (true),
53  m_outputFileBase ("./result"),
54  m_outputFormat (CepsOutputFormat::ParaviewSeries),
55  m_writeGlobalIDs (false),
56  m_probePoints ({}),
57  m_ignoreZeroDError (false)
58 {
60  "When instantiating pde problem : passed ptr to Geometry is null"
61  );
62  if (m_parameters)
64 }
65 
67 {
68  for (auto u: m_unknowns)
70  for (auto ui: m_unknownsInteractions)
72  if (m_ownedSrcs)
74  if (m_ownedBCs)
76  if (m_ownedFunctions)
78  if (m_ownedDiscr)
80  if (m_ownedRefSol)
82 }
83 
86 {
87  return m_parameters;
88 }
89 
90 void
92 {
93  setOutputFileBase (params->getString("output file name",m_outputFileBase));
94  if (params->hasKey("output format"))
95  {
96  CepsString otype = ceps::toUpper(params->getString("output format"));
97  if (otype == "MUSICARDIO" or otype=="VTK_LEGACY")
99  else if (otype == "PARAVIEW_SERIES" or otype == "PSERIES") // default
101  else if (otype == "CEPS")
103  //else if (otype == "MEDIT")
104  // m_outputFormat = CepsOutputFormat::Medit;
105  else CEPS_ABORT(
106  "Unknown output format : " << otype << ". Valid types are\n" <<
107  " MUSICARDIO, VTK_LEGACY, PARAVIEW_SERIES, PSERIES (default), CEPS"
108  );
109  }
110 
111  writeGlobalIndices(params->isActiveOption("output global indices"));
112  if (params->hasKey("probe points"))
113  {
114  auto spoints = ceps::split(params->getString("probe points"),",");
115  for (CepsString spoint: spoints)
116  {
117  std::stringstream ss(spoint);
118  CepsReal3D v = ceps::readVertex(ss,"Cannot read probe point with input string "
119  + params->getString("probe points"));
120  m_probePoints.push_back(v);
121  }
122  }
123 
124  m_refSolFiles = params->getString("reference solution files" ,m_refSolFiles );
125  m_refSolSnapDt = params->getReal ("reference solution output period",m_refSolSnapDt);
126 
127  m_ignoreZeroDError = params->isActiveOption("convergence ignore 0D unknowns");
128 
129 }
130 
131 void
133 {
134 }
135 
136 void
138 {
139  m_name = name;
140 }
141 
142 CepsString
144 {
145  return m_name;
146 }
147 
148 Geometry*
150 {
151  return m_geom;
152 }
153 
156 {
157  return m_discr;
158 }
159 
160 void
162 {
163  if (m_ownedDiscr)
165  m_discr = d;
166  m_ownedDiscr = false;
167 }
168 
169 void
171 {
172  CEPS_ABORT_IF(m_unknowns.empty(), "no unknowns in this problem");
173 
174  CepsString dtype = "FE 1"; // default value
175  if (m_parameters)
176  dtype = m_parameters->getString("spatial discretization",dtype);
177 
178  CepsVector<CepsString> words = ceps::split(dtype);
179  CEPS_ABORT_IF(words.size()<2,
180  "When creating spatial discretization, not enough parameters to deduce the type of discretization"
181  );
182 
183  if (ceps::toKey(words[0])=="FE")
184  m_discr = ceps::getNew<FiniteElements>(this,ceps::toUInt(words[1]));
185  else
186  CEPS_ABORT("No other discretization than finite elements implemented yet");
187 
188  // Link dofs to source terms and boundary conditions
191 
192  m_ownedDiscr = true;
193 }
194 
195 // -----------------------------------------------------------------------------------------
196 // UNKNOWNS
197 
200 {
201  return m_unknowns;
202 }
203 
204 Unknown*
206 {
207  Unknown* res = nullptr;
208  for (Unknown* u:m_unknowns)
209  if (ceps::toKey(u->getName())==ceps::toKey(label))
210  res = u;
211  return res;
212 }
213 
214 Unknown*
216 {
217  Unknown* res = nullptr;
218  for (Unknown* u:m_unknowns)
219  if (u->getIdentifier()==uid)
220  res = u;
221  return res;
222 }
223 
226 {
227  return m_unknownsInteractions;
228 }
229 
232 {
234  for (Unknown* u:m_unknowns)
235  if (u->isSpatial())
236  res.push_back(u);
237  return res;
238 }
239 
242 {
244 
245  for (Unknown* u:m_unknowns)
246  if (u->getLocation()==CepsLocationFlag::ZeroD)
247  res.push_back(u);
248 
249  return res;
250 }
251 
252 CepsBool
254  Unknown* u1,
255  Unknown* u2,
256  const CepsSet<CepsAttribute>& attrs
257 ) const
258 {
259  if (u1==u2)
260  return true;
262  {
263  if ((ui->u1==u1 and ui->u2==u2) or (ui->u2==u1 and ui->u1==u2))
264  if (attrs.contains(CepsUniversal) or ui->hasOneOfAttributes(attrs)
265  or ui->hasAttribute(CepsUniversal) or ui->getNumberOfAttributes()==0)
266  return true;
267  }
268 
269  return false;
270 }
271 
272 CepsBool
274 {
275  return m_ignoreZeroDError;
276 }
277 
278 
279 // -----------------------------------------------------------------------------------------
280 
281 CepsBool
283 {
285 }
286 
289 {
290  return m_analyticSolution;
291 }
292 
293 void
295 {
296  m_analyticSolution = nullptr;
297 
298  if (not m_refSolFiles.empty())
299  {
301  }
302 }
303 
304 void
306 {
307  CEPS_SAYS("Loading reference solution from " + m_refSolFiles + "*");
308  m_analyticSolution = ceps::getNew<FileInterpolatorSAFunc>(this,snapDt,m_refSolFiles,3);
309  m_ownedRefSol = true;
310 }
311 
312 CepsBool
314 {
315  return hasAnalyticSolution() and not m_refSolFiles.empty();
316 }
317 
318 CepsReal
320 {
321  return m_refSolSnapDt;
322 }
323 
326 {
327  return m_functions;
328 }
329 
330 void
332 {
333  if (m_ownedFunctions)
335  m_functions = dico;
336  m_ownedFunctions = false;
337 }
338 
339 void
341 {
342 }
343 
346 {
347  return m_boundaryConditions;
348 }
349 
350 void
352 {
353  if (m_ownedBCs)
355  m_boundaryConditions = bcm;
356  m_ownedBCs = false;
357 }
358 
359 void
361 {
362 }
363 
366 {
367  return m_sourceTerms;
368 }
369 
370 void
372 {
373  if (m_ownedSrcs)
375  m_sourceTerms = stm;
376  m_ownedSrcs = false;
377 }
378 
379 void
381 {
382  this->defineUnknowns();
385  CEPS_SAYS("Setting up elements of the problem...");
386  this->defineSourceTerms();
387  this->defineBoundaryConditions();
388  this->defineAnalyticSolution();
389 }
390 
391 // -----------------------------------------------------------------------------------------
392 
395 {
396  return m_outputFileBase;
397 }
398 
399 void
401 {
403 }
404 
407 {
408  return m_outputFormat;
409 }
410 
411 void
413 {
414  m_outputFormat = opt;
415 }
416 
417 CepsBool
419 {
420  return m_writeGlobalIDs;
421 }
422 
423 void
425 {
426  m_writeGlobalIDs = opt;
427 }
428 
431 {
432  return m_probePoints;
433 }
434 
435 CepsReal
437 {
438  return 0;
439 }
440 
441 CepsReal
443 {
444  return 0;
445 }
446 
447 
448 CepsReal
450 {
451  return 0;
452 }
453 
454 // -----------------------------------------------------------------------------------------
455 
456 
457 void
459  CepsLocationFlag loc, const CepsString& unit)
460 {
461  Unknown* u = ceps::getNew<Unknown>(m_unknowns.size(),label);
462  if (attrs.empty())
464  else
465  u->setAttributes(attrs.begin(),attrs.end());
466  u->setUnit(unit);
467  u->setLocation(loc);
468  m_unknowns.push_back(u);
469 }
470 
471 void
473 {
474  Unknown* u = ceps::getNew<Unknown>(m_unknowns.size(),label);
476  u->setUnit(unit);
478  m_unknowns.push_back(u);
479 }
480 
481 void
483 {
484  Unknown* u1 = nullptr;
485  Unknown* u2 = nullptr;
486 
487  for (Unknown* u: m_unknowns)
488  {
489  if (ceps::toKey(u->getName())==ceps::toKey(label1))
490  u1 = u;
491  if (ceps::toKey(u->getName())==ceps::toKey(label2))
492  u2 = u;
493  }
494 
496  "When setting up interactions between unknowns : cannot find unknown " << std::quoted(label1)
497  );
499  "When setting up interactions between unknowns : cannot find unknown " << std::quoted(label2)
500  );
501  CEPS_ABORT_IF(u1==u2,
502  "When setting up interactions between unknowns : unknwons are the same!"
503  );
504 
505  // Check if given attributes concern the unknowns...
506  if (not(attrs.empty() or attrs.contains(CepsUniversal)))
507  {
508  CEPS_ABORT_IF(not u1->hasAttribute(CepsUniversal) and not u1->hasOneOfAttributes(attrs),
509  "When setting up interactions between unknowns : unknown " << std::quoted(label1) <<
510  "\n is not defined on any of the given attributes"
511  );
512  CEPS_ABORT_IF(not u2->hasAttribute(CepsUniversal) and not u2->hasOneOfAttributes(attrs),
513  "When setting up interactions between unknowns : unknown " << std::quoted(label2) <<
514  "\n is not defined on any of the given attributes"
515  );
516  }
517 
518  UnknownInteraction* ui = ceps::getNew<UnknownInteraction>();
519  ui->u1 = u1;
520  ui->u2 = u2;
521  ui->setAttributes(attrs.begin(),attrs.end());
522  m_unknownsInteractions.push_back(ui);
523 
524  u1->addUnknownInteraction(u2);
525  u2->addUnknownInteraction(u1);
526 
527 }
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.
CepsOutputFormat
Style of output files.
Definition: CepsEnums.hpp:179
@ VTKCeps
vtk_ceps format, use contrib/CepsParaviewPlugin.py (5.11)
@ ParaviewSeries
Paraview files series, JSON + VTU/PVTU.
@ Music
MUSIC files, VTKLegacy and xml.
#define CEPS_ABORT(message)
Stops the execution with a message. If testing is enabled, only throws a runtime_error.
#define CEPS_SAYS(message)
Writes a message in the debug log and in the terminal (stdio).
#define CEPS_ABORT_IF(condition, message)
Stops the execution with a message if condition is true. If testing is enabled, only throws a runtime...
#define CEPS_SEPARATOR
Writes a separator in the debug log and in the terminal.
std::basic_string< CepsChar > CepsString
C++ format string.
Definition: CepsTypes.hpp:128
CepsIndex CepsUnknownIndex
For unknowns.
Definition: CepsTypes.hpp:217
std::set< _Type, _Compare, _Alloc > CepsSet
C++ set.
Definition: CepsTypes.hpp:209
std::vector< _Type, _Alloc > CepsVector
C++ vector.
Definition: CepsTypes.hpp:155
bool CepsBool
Booleans.
Definition: CepsTypes.hpp:124
float CepsReal
Need single precision floating point.
Definition: CepsTypes.hpp:100
CepsArray3< CepsReal > CepsReal3D
Three real scalars, used like this for compatibility in polynomials.
Definition: CepsTypes.hpp:178
constexpr CepsAttribute CepsUniversal
This attribute means "everywhere".
Definition: CepsTypes.hpp:232
Abstract Class for all numerical method (FE, FD, FV etc)
DistributedInfos< DegreeOfFreedom * > * getDistributedDofs() const
Get the stored Degree Of Freedom repartition.
CepsString m_name
Name of the problem.
CepsOutputFormat getOutputFormat() const
Tells if output is binary or ascii.
CepsVector< Unknown * > getSpatialUnknowns() const
A vector of all unknowns of pb defined on cells or points.
ScalarFunction * getAnalyticSolution() const
Pointer on analytic or refScalarFunction solution.
virtual void defineUnknowns()=0
Define all the unknowns of the problem here. Must be overriden, and call all necessary addUnknown,...
CepsBool hasAnalyticSolution() const
Tells if there is an analytic or reference solution.
void setProblemName(const CepsString &name)
Set the name of the problem.
virtual void defineBoundaryConditions()
Define the boundary conditions. Should be defined in derived classes. Default is no BC.
CepsString getOutputFileBase() const
Output file name includes the directory.
virtual CepsReal getSnapshotTime() const
Returns 0. Here for compatibility.
CepsBool m_ownedDiscr
True if instance used new to create discretization.
virtual void setupWithParameters(InputParameters *params)
Set attributes from input file. Parameters are passed as arguments in case one wants to use other par...
const CepsVector< UnknownInteraction * > & getUnknownsInteractions() const
All the interactions between unknowns.
FunctionDictionary * getFunctionDictionary() const
Get functions manager.
SourceTermManager * getSourceTermManager() const
Get boundary condition manager.
virtual void defineAnalyticSolution()
Set directly the analytic function, default sets no solution, unless there is a collection of referen...
CepsString m_outputFileBase
File names prefix.
CepsVector< CepsReal3D > getProbePoints() const
Returns points where single data output should be written.
CepsString m_refSolFiles
base name of reference solution file, if any
AbstractDiscretization * m_discr
Discretization method (eg FE for now)
AbstractPdeProblem(Geometry *geom, InputParameters *params=nullptr)
Constructor with geometry and optional parameters.
void setFunctionDictionary(FunctionDictionary *)
Set functions manager.
SourceTermManager * m_sourceTerms
All source terms.
virtual ~AbstractPdeProblem()
destructor
CepsReal m_refSolSnapDt
reference solution output period
void addUnknown(const CepsString &label, CepsSet< CepsAttribute > attrs={}, CepsLocationFlag flag=CepsLocationFlag::Point, const CepsString &unit="")
Register a new unknown.
CepsBool ignoreZeroDUnknownsForError() const
Tells if 0D must not be taken into account in error computation.
CepsString getProblemName() const
Get the name of the problem.
void setOutputFormat(CepsOutputFormat opt)
Enable/disable binary output.
void addZeroDUnknown(CepsString label, const CepsString &unit="")
Register a new unknown, defined outside of geometry.
CepsVector< UnknownInteraction * > m_unknownsInteractions
Describes how unknowns interact.
CepsBool m_ignoreZeroDError
Ignore 0D unknowns when computing errors.
void addUnknownInteraction(CepsString label1, CepsString label2, CepsSet< CepsAttribute > attrs={})
Register interaction between unknowns. Also sets the interaction within Unknown instances label1 and ...
CepsBool unknownsInteract(Unknown *u1, Unknown *u2, const CepsSet< CepsAttribute > &attrs={CepsUniversal}) const
Tells if unknowns interact on an entity with attributes.
AbstractDiscretization * getSpatialDiscretization() const
Link to the spatial discretization (FE, FV, etc)
InputParameters * getParameters() const
Text parameters.
CepsOutputFormat m_outputFormat
Output format selector.
CepsVector< Unknown * > m_unknowns
All maths unknowns of the problem.
CepsBool usesReferenceSolution() const
Tells if analytic solution and if it is loaded from files.
Unknown * getUnknown(const CepsString &label) const
Get an unknown by its name.
CepsVector< CepsReal3D > m_probePoints
Single point data outputs.
CepsBool writesGlobalIndices() const
Tells if global indices are written on top of solution.
virtual void run()
Computes the solution to the problem. Default does nothing, override it !
InputParameters * m_parameters
Input file data.
CepsBool m_ownedSrcs
True if instance used new to create src term manager.
void setOutputFileBase(CepsString fileName)
Output file name includes the directory.
virtual void initializeEquation()
Initializes equations (unknowns, bc, source term) and creates the spatial discretization This method ...
CepsReal getReferenceSolutionOutputPeriod() const
Output dt of reference.
CepsBool m_ownedRefSol
Flag for reference ownership.
Geometry * m_geom
Link to geometry on which the pb is defined.
void setSpatialDiscretization(AbstractDiscretization *discr)
Link to the spatial discretization (FE, FV, etc)
void writeGlobalIndices(CepsBool opt)
Activate/deactivate global indices writing.
BoundaryConditionManager * getBoundaryConditionManager() const
Get boundary condition manager.
virtual void defineSourceTerms()
Define the source terms. Should be defined in derived classes. Default is no src term.
void setSourceTermManager(SourceTermManager *stm)
Set boundary condition manager.
virtual CepsReal getStartTime() const
Returns 0. Here for compatibility.
void createSpatialDiscretization()
Compute the discretization structure.
Geometry * getGeometry() const
Link to geometry on which the pb is defined.
virtual CepsReal getEndTime() const
Returns 0. Here for compatibility.
ScalarFunction * m_analyticSolution
analytic or reference solution
CepsBool m_ownedBCs
True if instance used new to create BC manager.
BoundaryConditionManager * m_boundaryConditions
All BCs should be there.
CepsBool m_ownedFunctions
True if instance used new to create dictionary.
FunctionDictionary * m_functions
Collection of custom functions.
CepsVector< Unknown * > getZeroDUnknowns() const
A vector of all zeroD unknowns of the pb.
void setBoundaryConditionManager(BoundaryConditionManager *bcm)
Set boundary condition manager.
void setReferenceSolution(const CepsString &baseFiles, CepsReal snapDt)
Externally define the referece solution from files. Can be used for convergence tests.
CepsBool m_writeGlobalIDs
Writes CEPS indices as well.
const CepsVector< Unknown * > & getUnknowns() const
List of unknowns of the pb.
Boundary condition to manage Dirichlet, Neumann and Robin conditions.
void setDofsInfos(DistributedInfos< DegreeOfFreedom * > *dof)
Set dofs infos in this class.
FunctionDictionary that holds functions which can be used to define source terms, boundary conditions...
Encapsulates all the geometrical data.
Definition: Geometry.hpp:50
Reads and stores simulation configuration.
CepsBool hasKey(const keyType &key) const
Tells if key exists in input file.
CepsBool isActiveOption(const keyType &key) const
Tells if key exists in configuration and is of "1","YES","ON" or "TRUE".
CepsString getString(const keyType &key) const
Reads a CepsString from configuration.
CepsReal getReal(const keyType &key) const
Reads a floating point value from configuration.
Source term manager to create and manage SourceTerm objects.
void setDofsInfos(DistributedInfos< DegreeOfFreedom * > *dofs)
Set dofs infos in this class.
Data describing how two unknowns are coupled.
Definition: Unknown.hpp:130
Unknown * u2
Second unknown in the coupling.
Definition: Unknown.hpp:135
Unknown * u1
First unknown in the coupling.
Definition: Unknown.hpp:134
A class used to defined an unknown of a PDE problem The unknown can be defined on a specific region,...
Definition: Unknown.hpp:45
void setUnit(const CepsString &unit)
Set the unit of the unknown.
Definition: Unknown.cpp:94
void addUnknownInteraction(Unknown *u, CepsBool addReciprocal=true)
Add an unknown this one interacts with.
Definition: Unknown.cpp:126
void setLocation(const CepsLocationFlag &location)
Set the data location of the unknown.
Definition: Unknown.cpp:113
void addAttribute(const CepsAttribute &name)
Adds an attribute to the entity.
CepsBool hasOneOfAttributes(const CepsSet< CepsAttribute > &attributes) const
Tells if the entity has one of the attributes in argument.
void setAttributes(const CepsVector< CepsAttribute > &attributes)
Sets the attributes of the entity.
CepsBool hasAttribute(const CepsAttribute &name) const
Tells if the entity has the attribute in argument.
A namespace for all utility methods.
CepsString getDir(const CepsString &str)
Get a substring of s, from beginning of s to the last '/' character. Example: "/home/someone/file....
Definition: CepsString.cpp:521
CepsString toKey(const CepsString &s)
Transform to key type a std::string, upper case and no spaces.
Definition: CepsString.cpp:157
CepsBool isValidPtr(_Type *ptr)
Tells if pointer is not null.
Definition: CepsMemory.hpp:61
_Type * getNew(_Args... args)
Allocates memory for one object. Be careful, the expansion of arguments may produce some weird result...
Definition: CepsMemory.hpp:170
CepsReal3D readVertex(std::istream &file, const CepsString &errorMessage="")
Reads an integral number from an istream, aborts if conversion fails advances the stream by 1 word.
Definition: CepsString.cpp:693
CepsBool isNullPtr(_Type *ptr)
Tells if passed pointer is null.
Definition: CepsMemory.hpp:45
CepsVector< CepsString > split(const CepsString &s, const CepsString &delimiters=CepsString(" \t"))
Splits a string using mulitple delimiters in a single string.
Definition: CepsString.cpp:38
CepsUInt toUInt(const CepsString &s)
Cast CepsString to CepsUInt.
Definition: CepsString.cpp:296
CepsString toUpper(const CepsString &s)
Switches all characters to upper case.
Definition: CepsString.cpp:124
CepsString getBaseName(const CepsString &str)
Extracts the base of a file name, without path, nor extension. Ex: getBaseName("/path/to/myfile....
Definition: CepsString.cpp:563
void destroyObject(_Type &)
Destroy[delete] any type.
Definition: CepsMemory.hpp:116
function caller : abstract base, only contains an variadic operator()