CEPS  24.01
Cardiac ElectroPhysiology Simulator
ReferenceFE.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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
32 
34  m_type (type),
35  m_dim (dimension),
36  m_order (getOrder(type)),
37  m_nbDofs (0u),
38  m_nGeomVertices (0u),
39  m_ownerDeductionRule({})
40 {
41  buildBasisFunction();
42 }
43 
45 {}
46 
49 {
50  return getCategory(m_type);
51 }
52 
55 {
56  return m_order;
57 }
58 
61 {
62  return m_nbDofs;
63 }
64 
67 {
68  const CepsUInt &n = m_basisFunctions.size();
69 
70  CepsMathDynamic1D phi(n);
71  for (CepsUInt i=0U; i<n; i++)
72  phi(i) = computeBasisFunction(i,point);
73  return phi;
74 }
75 
78 {
79  const CepsUInt &n = m_basisFunctions.size();
80 
81  CepsMathDynamic2D gradPhi(n,3);
82  for (CepsUInt iPhi=0U; iPhi<n; iPhi++)
83  {
84  const CepsReal3D &dpdx = computeBasisFunctionDerivative(iPhi, point);
85  for (CepsUInt i=0; i<3; i++)
86  gradPhi(iPhi,i) = dpdx[i];
87  }
88  return gradPhi.transpose();
89 }
90 
93 {
94  return m_vertices;
95 }
96 
97 const CepsReal3D&
99 {
101  "The maximum index for basis vertices is " << getNumberOfBasisVertices()
102  );
103  return m_vertices[i];
104 }
105 
106 CepsInt
108 {
110  "The maximum index for basis vertices is " << getNumberOfBasisVertices()
111  );
112  return m_geomCellIndex[i];
113 }
114 
115 GeomNode*
117 {
119  "The maximum index for basis vertices is " << getNumberOfBasisVertices()
120  );
122  "Passed ptr on cell is null"
123  );
124 
125  auto it = m_ownerDeductionRule[i].begin();
126  GeomNode* res = cell->getNodeAt(*it);
128 
129  for (it++;it!=m_ownerDeductionRule[i].end();it++)
130  if (id > cell->getNodeAt(*it)->getGlobalIndex())
131  {
132  res = cell->getNodeAt(*it);
133  id = res->getGlobalIndex();
134  }
135 
136  // }
137  // Never called, no quads elements implemented
138  // else
139  // CEPS_ABORT("Not implemented");
140 
141  return res;
142 }
143 
146 {
148  "The maximum index for basis vertices is " << getNumberOfBasisVertices()
149  );
151  "Passed ptr on cell is null"
152  );
154  if (m_dim>=1)
155  {
156  auto jac = cell->getJacobianMatrix();
157  for (CepsUInt j=0;j<m_dim;j++)
158  res += m_vertices[i][j]*jac.col(j);
159  }
160  return CepsReal3D({res[0],res[1],res[2]});
161 }
162 
163 CepsUInt
165 {
166  return m_dim;
167 }
168 
169 CepsUInt
171 {
172  return m_nGeomVertices;
173 }
174 
175 CepsUInt
177 {
178  return m_vertices.size();
179 }
180 
181 CepsUInt
183 {
184  return m_basisFunctions.size();
185 }
186 
189 {
190  return m_type;
191 }
192 
193 void
195 {
197  if (type == CepsCellType::Simplex)
198  {
201  );
203  m_nbDofs = m_vertices.size();
204 
205  if (m_dim==1) // Dimension 1 is easy, whatever the order
206  {
207  m_ownerDeductionRule.push_back({0});
208  for (CepsUInt i=1;i<m_order;i++)
209  m_ownerDeductionRule.push_back({0,1});
210  m_ownerDeductionRule.push_back({1});
211  }
212  else
213  {
214  if (m_order==1) // Order 1 is easy, whatever the dimension (nodes coincide with geom)
215  {
216  for (CepsUInt i=0;i<m_nbDofs;i++)
217  m_ownerDeductionRule.push_back({i});
218  }
219  // For now, we write rules for Pk k>1 and dim>1
220  else if (m_dim==2)
221  {
222  // 0,0 node
223  m_ownerDeductionRule.push_back({0});
224  // Nodes on y edge
225  for (CepsUInt i=1;i<m_order;i++)
226  m_ownerDeductionRule.push_back({0,2});
227  // y=1 node
228  m_ownerDeductionRule.push_back({2});
229 
230  for (CepsUInt i=1;i<m_order;i++)
231  {
232  // x edge
233  m_ownerDeductionRule.push_back({0,1});
234  // inside the triangle
235  for (CepsUInt j=1;i<m_order-j;j++)
236  m_ownerDeductionRule.push_back({0,2,1});
237  // diagonal edge
238  m_ownerDeductionRule.push_back({2,1});
239  }
240  // x=1 node
241  m_ownerDeductionRule.push_back({1});
242  }
243  else if (m_dim==3)
244  {
245 
246  // 0,0,0 node
247  m_ownerDeductionRule.push_back({0});
248 
249  // x=0
250 
251  // Nodes on z edge
252  for (CepsUInt i=1;i<m_order;i++)
253  m_ownerDeductionRule.push_back({0,3});
254  // z=1 node
255  m_ownerDeductionRule.push_back({3});
256 
257  for (CepsUInt i=1;i<m_order;i++)
258  {
259  // y edge
260  m_ownerDeductionRule.push_back({0,2});
261  // inside the z,y triangle
262  for (CepsUInt j=1;i<m_order-j;j++)
263  m_ownerDeductionRule.push_back({0,3,2});
264  // diagonal edge z,y
265  m_ownerDeductionRule.push_back({3,2});
266  }
267  // y=1 node
268  m_ownerDeductionRule.push_back({2});
269 
270  // in between slices
271  for (CepsUInt i=1;i<m_order;i++)
272  {
273  // x edge
274  m_ownerDeductionRule.push_back({0,1});
275  // inside z x triangle
276  for (CepsUInt j=1;j<m_order-i;j++)
277  m_ownerDeductionRule.push_back({0,3,1});
278  // x z edge
279  m_ownerDeductionRule.push_back({3,1});
280 
281  // in between lines
282  for (CepsUInt j=1;j<m_order-i;j++)
283  {
284  // y x triangle
285  m_ownerDeductionRule.push_back({0,2,1});
286  // in the meat of the element
287  for (CepsUInt k=1;k<m_order-i-j;k++)
288  m_ownerDeductionRule.push_back({0,1,2,3});
289  // xyz plane
290  m_ownerDeductionRule.push_back({1,2,3});
291  }
292 
293  // xy edge
294  m_ownerDeductionRule.push_back({1,2});
295  }
296 
297  // x=1 node
298  m_ownerDeductionRule.push_back({1});
299  }
300  }
301 
302  }
303  // else // Quads
304  // {
305  // buildPolysBasisFunction(
306  // m_dim, m_order, m_vertices, m_geomCellIndex, m_basisFunctions, buildQuadrilateralUniformPoints
307  // );
308  // m_nGeomVertices = pow(2,m_dim);
309  // }
310 
311  return;
312 }
313 
314 CepsReal
316 {
318  "The maximum index for basis functions is " << getNumberOfBasisFunctions()
319  );
320  return m_basisFunctions[iPhi].eval(point);
321 }
322 
325 {
327  "The maximum index for basis functions is " << getNumberOfBasisFunctions()
328  );
329  return m_basisFunctions[iPhi].gradient(point);
330 }
CepsCellType
Enum for different shapes of cells.
Definition: CepsEnums.hpp:128
@ Simplex
Simplices.
#define CEPS_ABORT_IF(condition, message)
Stops the execution with a message if condition is true. If testing is enabled, only throws a runtime...
Eigen::Matrix< CepsScalar, Eigen::Dynamic, 1 > CepsMathDynamic1D
Dynamic 1D array, eigen format.
Definition: CepsTypes.hpp:139
std::vector< _Type, _Alloc > CepsVector
C++ vector.
Definition: CepsTypes.hpp:155
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
Eigen::Matrix< CepsScalar, 3, 1 > CepsMathVertex
Vertex, eigen format.
Definition: CepsTypes.hpp:135
CepsGlobalIndex CepsNodeGlobalIndex
Indices of nodes.
Definition: CepsTypes.hpp:224
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
Eigen::Matrix< CepsScalar, Eigen::Dynamic, Eigen::Dynamic > CepsMathDynamic2D
Dynamic 2D array, eigen format.
Definition: CepsTypes.hpp:140
CepsCellType getCategory(const CepsFeLagrangeType &type)
Returns either Simplex, of Quad, the type of Lagrange finite element.
Definition: FEType.hpp:66
CepsUInt getOrder(const CepsFeLagrangeType &type)
Returns the order of the Lagrange finite element.
Definition: FEType.hpp:73
std::pair< CepsCellType, CepsUInt > CepsFeLagrangeType
Typedef for descriptor of Lagrange finite elements type.
Definition: FEType.hpp:35
void buildPolysBasisFunction(CepsUInt dim, CepsUInt order, CepsVector< CepsReal3D > &points, CepsVector< CepsInt > &geomCellIndex, CepsVector< Polynomial< 3U >> &polys, void(*pointBuilder)(CepsUInt, CepsUInt, CepsVector< CepsReal3D > &, CepsVector< CepsInt > &))
Constructs the list of base functions in the form of Polynomials.
void buildSimplexUniformPoints(CepsUInt dim, CepsUInt numberOfPoints, CepsVector< CepsReal3D > &points, CepsVector< CepsInt > &geomCellIndex)
Constructs the list of uniform points of the simplex of given dimension.
CepsMathVertex getCoordinatesForEigen() const
Get three coordinates.
Definition: CepsVertex.cpp:186
Abstract class for geometrical cell. On top of index and attributes managament, the cell has informat...
Definition: GeomCell.hpp:48
virtual const JacobianMatrixType & getJacobianMatrix()
Jacobian Matrix of deformation from reference cell (3 rows for R^3, element dimension columns)
Definition: GeomCell.cpp:101
Base class for nodes used in meshes.
Definition: GeomNode.hpp:53
CepsReal3D computeBasisFunctionDerivative(CepsUInt iPhi, const CepsReal3D &point)
Get values of single basis function derivative at given point.
CepsUInt m_order
Order of Lagrangian base polynomial.
CepsUInt getNumberOfBasisFunctions() const
Get number of basis functions.
CepsUInt getNumberOfDofs() const
Number of degrees of freedom.
Definition: ReferenceFE.cpp:60
CepsUInt m_nGeomVertices
Nb of geom vertices the elem is made of.
CepsUInt m_dim
Geometrical dimension.
CepsUInt getDimension() const
Get dimension of geom object.
CepsReal3D getTransformedBasisVertex(CepsUInt i, GeomCell *cell) const
Get vertex 'i' used to create basis functions and transform it on GeomCell.
CepsUInt getPolynomialOrder() const
Order.
Definition: ReferenceFE.cpp:54
CepsInt getBasisVertexGeomCellIndex(CepsUInt i) const
Returns the index in geom cell of a basis vertex. -1 if basis vertex does not match a geom vertex.
void buildBasisFunction()
Build all basis function and Vertex used.
CepsVector< CepsInt > m_geomCellIndex
CepsVector< Polynomial< 3U > > m_basisFunctions
List of basis functions.
CepsMathDynamic1D computeBasisFunctions(const CepsReal3D &point)
Get values of basis functions at given point.
Definition: ReferenceFE.cpp:66
CepsVector< CepsSet< CepsUInt > > m_ownerDeductionRule
Dirty: map that contains rules used to attribute ownership of nodes that do not coincide with geometr...
CepsUInt getNumberOfBasisVertices() const
Get number of vertices used to create basis functions.
CepsVector< CepsReal3D > m_vertices
List of vertex used to build basis functions.
ReferenceFE()=delete
Deleted default constructor.
CepsCellType getCellType() const
CellType.
Definition: ReferenceFE.cpp:48
CepsFeLagrangeType m_type
CepsFeLagrangeType.
const CepsVector< CepsReal3D > & getBasisVertices() const
Get vertices used to create basis functions.
Definition: ReferenceFE.cpp:92
~ReferenceFE()
Destructor.
Definition: ReferenceFE.cpp:44
CepsFeLagrangeType getFEType() const
The type of Lagragian Finite Element return. May change in the future ?
CepsUInt getNumberOfGeomVertices() const
Get number of vertices of the geometric cell the element is based on.
GeomNode * getNodeOfOwnerForBasisVertex(CepsUInt i, GeomCell *cell) const
Returns a node that determines ownership of a basis vertex, especially for those that do not match a ...
CepsReal computeBasisFunction(CepsUInt iPhi, const CepsReal3D &point)
Get values of single basis function at given point.
const CepsReal3D & getBasisVertex(CepsUInt i) const
Get vertex 'i' used to create basis functions.
Definition: ReferenceFE.cpp:98
CepsMathDynamic2D computeBasisFunctionDerivatives(const CepsReal3D &point)
Get values of basis function derivatives at given point.
Definition: ReferenceFE.cpp:77
CepsUInt m_nbDofs
Number of degrees of freedom.
const CepsGlobalIndex & getGlobalIndex() const
Get the index
NodeType * getNodeAt(const CepsUInt &i)
Pointer to the i-th node.
CepsBool isNullPtr(_Type *ptr)
Tells if passed pointer is null.
Definition: CepsMemory.hpp:45