CEPS  24.01
Cardiac ElectroPhysiology Simulator
GeometryReader.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  const CepsVector<CepsString> &volumicMeshes,
35  const CepsVector<CepsString> &surfacicMeshes,
36  const CepsVector<CepsString> &cableMeshes,
37  const CepsString &coupledNodesFile
38 ) :
39  m_totalNbNodes (0u),
40  m_totalNbCells (0u),
41  m_totalNbBdryCells (0u)
42 {
43  // How many meshes do we have ?
44  CepsUInt nVolumic = volumicMeshes.size ();
45  CepsUInt nSurfacic = surfacicMeshes.size ();
46  CepsUInt nCable = cableMeshes.size ();
47 
48  m_nbMeshes = nVolumic + nSurfacic + nCable;
49 
50  // Allocate structures
51  m_meshFileNames.resize (m_nbMeshes);
52  m_readers = ceps::newArray<MeshReader *> (m_nbMeshes, nullptr);
53  m_readerType = ceps::newArray<CepsUInt> (m_nbMeshes, 0u);
54  m_nodeOffsets = ceps::newArray<CepsUInt> (m_nbMeshes + 1, 0u);
55  m_cellOffsets = ceps::newArray<CepsUInt> (m_nbMeshes + 1, 0u);
56  m_meshNbNodes = ceps::newArray<CepsUInt> (m_nbMeshes, 0u);
57  m_meshNbCells = ceps::newArray<CepsUInt> (m_nbMeshes, 0u);
58  m_meshNbBdryCells = ceps::newArray<CepsUInt> (m_nbMeshes, 0u);
59 
60  CepsUInt index = 0U;
61  // save mesh reader type, and build the reader
62  for (CepsUInt i = 0U; i < nVolumic; i++, index++)
63  {
65  m_readers[index] = this->getMeshReaderFor (volumicMeshes[i], index, 3);
66  }
67  for (CepsUInt i = 0U; i < nSurfacic; i++, index++)
68  {
70  m_readers[index] = this->getMeshReaderFor (surfacicMeshes[i], index, 2);
71  }
72  for (CepsUInt i = 0U; i < nCable; i++, index++)
73  {
75  m_readers[index] = this->getMeshReaderFor (cableMeshes[i], index, 1);
76  }
77 
78  // Read meshes
80 
81  // Deal with coupled nodes and/or junctions
82  m_hasCoupledNodes = not coupledNodesFile.empty();
84  readCoupledNodes(coupledNodesFile);
85 
86  // Update cell counts
87  for (CepsUInt i = 0U; i < m_nbMeshes; i++)
88  {
92  }
93 }
94 
96 {
97  if (m_nbMeshes)
98  {
99  for (CepsUInt i=0U; i<m_nbMeshes; i++)
108  }
109 }
110 
111 void
113 {
114  memset (cellOffsets, 0, 4*sizeof(CepsUInt));
115  for (CepsUInt i=0; i<m_nbMeshes; i++)
116  {
117  // Fill next types with mesh nb of cells
118  CepsUInt nbCells = m_readers[i]->getNbCells() + m_readers[i]->getNbBdryCells();
119  for (CepsUInt j = m_readerType[i]+1; j<4; j++)
120  cellOffsets[j] += nbCells;
121  }
122  return;
123 }
124 
125 void
127 {
128  offsets.clear();
129  offsets.resize(m_nbMeshes + 1);
130  offsets[0] = 0U;
131  for (CepsUInt i=0U; i<m_nbMeshes; i++)
132  offsets[i+1] = offsets[i]
133  + m_readers[i]->getNbCells()
134  + m_readers[i]->getNbBdryCells();
135  return;
136 }
137 
138 void
140 {
141  memset(offsets, 0, 4*sizeof(CepsUInt));
142  for (CepsUInt i=0U; i<m_nbMeshes; i++)
143  {
144  CepsUInt nbNodes = m_readers[i]->getNbNodes ();
145  for (CepsUInt j = m_readerType[i]+1; j<4; j++)
146  offsets[j] += nbNodes;
147  }
148  return;
149 }
150 
151 void
153 {
154  offsets.clear();
155  offsets.resize(m_nbMeshes+1);
156  offsets[0] = 0U;
157  for (CepsUInt i=0U; i<m_nbMeshes; i++)
158  offsets[i+1] = offsets[i] + m_readers[i]->getNbNodes();
159 }
160 
161 CepsUInt
163 {
164  return m_totalNbNodes;
165 }
166 
167 CepsUInt
169 {
170  return m_totalNbCells;
171 }
172 
173 CepsUInt
175 {
176  return m_totalNbBdryCells;
177 }
178 
179 CepsUInt
181  CepsUInt indexStart,
182  CepsUInt nbNodesToRead,
183  CepsVector<CepsReal>& coords,
185  CepsVector<CepsUInt>& attrPtr,
186  CepsUInt& attrSize
187 )
188 {
189  // 0. No nodes to read. Abort
190  if (nbNodesToRead < 1)
191  {
192  attrSize = 0;
193  return 1;
194  }
195 
196  // 1. -----------------------------------------------------
197  // We must determine in which meshes we have to read nodes,
198  // and for each mesh, where to start, where to end, and number
199  // of node attributes
200 
201  CepsVector<CepsUInt> meshesToRead;
202  CepsVector<CepsInt> meshesStart;
203  CepsVector<CepsInt> meshesEnd;
204  CepsVector<CepsUInt> meshesNbAttr;
205 
206  // 1.1 Where do we start ?
207  CepsUInt iMesh;
208  for (iMesh = 0; ((CepsInt)indexStart-(CepsInt)m_nodeOffsets[iMesh+1]) >= 0; iMesh++)
209  {}
210 
211  CEPS_ABORT_IF(iMesh >= m_nbMeshes,
212  "GeometryReader: starting node index is larger than number of nodes in all meshes"
213  );
214 
215  meshesToRead.push_back(iMesh);
216  meshesStart .push_back((CepsInt)(indexStart-m_nodeOffsets[iMesh]));
217  meshesNbAttr.push_back(m_readers[iMesh]->getNbAttributesPerNode());
218 
219  // 1.2 Register next meshes
220  CepsBool finished = false;
221  CepsUInt indexEnd = indexStart + nbNodesToRead;
222 
223  while (not finished)
224  {
225  if ((CepsInt)(indexEnd-m_nodeOffsets[iMesh+1]) <= 0)
226  {
227  // We end with this mesh, read remaining nodes
228  meshesEnd.push_back((CepsInt) (indexEnd-m_nodeOffsets[iMesh]));
229  finished = true;
230  }
231  else
232  {
233  if (iMesh+1 == m_nbMeshes)
234  {
235  CEPS_ABORT("Number of nodes to read is too large!");
236  return 0;
237  }
238 
239  // Must read all this mesh remaining cells and boundary cells
240  meshesEnd.push_back((CepsInt)(m_nodeOffsets[iMesh + 1] - m_nodeOffsets[iMesh]));
241 
242  // Onto next mesh
243  meshesToRead.push_back(iMesh+1);
244  meshesStart .push_back(0);
245  meshesNbAttr.push_back(m_readers[iMesh+1]->getNbAttributesPerNode());
246 
247  // since we read contiguously:
248  iMesh++;
249  }
250  } // We now know what is going to be read
251 
252  // 2. -----------------------------------------------------
253  // Prepare data arrays
254 
255  // Memory size for coords
256  coords.resize(3 * nbNodesToRead);
257 
258  // Memory size of attr
259  CepsUInt memorySize = 0U;
260  for (CepsUInt i=0U; i<meshesToRead.size(); i++)
261  memorySize += meshesNbAttr[i]*(meshesEnd[i]-meshesStart[i]);
262 
263  if (memorySize>0)
264  attr.resize(memorySize, 0);
265 
266  attrPtr.resize(nbNodesToRead+1, 0);
267  // Make sure its zero, just in case.
268  attrPtr[0] = 0;
269 
270  // 3. -----------------------------------------------------
271  // Now fill the arrays
272 
273  CepsUInt nbNodesRead(0u), start(0u), end(0u), toRead(0u);
274  // Loop on meshes
275  for (CepsUInt i=0U; i<meshesToRead.size(); i++)
276  {
277  toRead = meshesToRead[i];
278  start = meshesStart [i];
279  end = meshesEnd [i];
280  m_readers[toRead]->readNodes(start,end,nbNodesRead,coords,attr,attrPtr);
281  nbNodesRead += end-start;
282  }
283  attrSize = memorySize;
284  return 0;
285 }
286 
287 CepsUInt
289  CepsUInt indexStart,
290  CepsUInt nbCellsToRead,
291  CepsVector<CepsNodeGlobalIndex> &nodeIndices,
292  CepsVector<CepsUInt> &nodeIndicesPtr,
294  CepsVector<CepsUInt> &attrPtr,
295  CepsVector<CepsChar> &isBoundary,
296  CepsUInt &nNodeIndices,
297  CepsUInt &nAttr
298 )
299 {
300  // 0. ------------------------------------------------------------
301  // Nothing to read
302  if (nbCellsToRead < 1)
303  {
304  nAttr = 0;
305  return 1;
306  }
307 
308  // 1. ------------------------------------------------------------
309  // Determine which mesh will be read
310  CepsUInt indexEnd = indexStart + nbCellsToRead;
311  CepsInt offset = indexStart;
312 
313  // build 2 arrays that will respectively hold the number of cells
314  // and the number of boundary cells to read for each type
315  CepsUInt nbCells[3] = {0, 0, 0};
316  CepsUInt nbBdryCells[3] = {0, 0, 0};
317  CepsVector<CepsUInt> meshesToRead;
318  CepsVector<CepsInt> meshesStart;
319  CepsVector<CepsInt> meshesEnd;
320 
321  // 1.1 what is the first mesh we must read ?
322  CepsUInt iMesh;
323  for (iMesh=0U; ((CepsInt)indexStart-(CepsInt)m_cellOffsets[iMesh+1]) >= 0; iMesh++)
324  {}
325  CEPS_ABORT_IF (iMesh >= m_nbMeshes,
326  "GeometryReader: starting cell index is larger than # of cells in all meshes"
327  );
328  offset -= m_cellOffsets[iMesh];
329 
330  meshesToRead.push_back (iMesh);
331  meshesStart.push_back (offset);
332 
333  // 1.2 Register next meshes
334  CepsBool finished = false;
335  CepsUInt cellAttrSize = 0U;
336  while (not finished)
337  {
338  // Reading will be finished with this mesh
339  if ((CepsInt) (indexEnd - m_cellOffsets[iMesh + 1]) <= 0)
340  {
341  CepsInt totalRemainingCells = indexEnd - m_cellOffsets[iMesh] - offset;
342  CepsInt remainingBdry = 0;
343  CepsInt remainingCells = 0;
344  // Only boundary cells to read
345  if (offset >= (CepsInt) m_meshNbCells[iMesh])
346  {
347  if (m_meshNbBdryCells[iMesh] == 0)
348  {
349  CEPS_ABORT ("Cannot read last boundary cells in mesh " << m_meshFileNames[iMesh]);
350  return 0;
351  }
352  remainingBdry = totalRemainingCells;
353  }
354  // Cells and maybe boundary cells to read
355  else
356  {
357  CepsInt temp = m_meshNbCells[iMesh] - offset;
358  if (temp < totalRemainingCells)
359  {
360  // will read boundary
361  remainingCells = temp;
362  remainingBdry = totalRemainingCells - temp;
363  }
364  else
365  {
366  // only cells
367  remainingCells = totalRemainingCells;
368  }
369  }
370 
371  nbCells [m_readerType[iMesh]] += remainingCells;
372  nbBdryCells[m_readerType[iMesh]] += remainingBdry;
373 
374  cellAttrSize += remainingCells * m_readers[iMesh]->getNbAttributesPerCell () +
375  remainingBdry * m_readers[iMesh]->getNbAttributesPerBdryCell();
376 
377  meshesEnd.push_back(offset + totalRemainingCells);
378  // We're done with this mesh
379  finished = true;
380  }
381  else
382  {
383  // We will have to read all cells and boundary cells in this mesh,
384  // starting from offset.
385 
386  CEPS_ABORT_IF(iMesh+1 == m_nbMeshes,
387  "Number of nodes to read is too large!"
388  );
389 
390  CepsInt remainingCells = 0;
391  if (offset <= (CepsInt)m_meshNbCells[iMesh])
392  remainingCells = m_meshNbCells[iMesh]-offset;
393  CepsInt remainingBdry = m_cellOffsets[iMesh+1]-m_cellOffsets[iMesh]-offset-remainingCells;
394 
395  // Last cell (or boundary) of current mesh
396  meshesEnd.push_back((CepsInt)m_cellOffsets[iMesh+1]-m_cellOffsets[iMesh]);
397  // Next mesh
398  meshesToRead.push_back(iMesh+1);
399  meshesStart .push_back(0);
400 
401  // update cells to read
402  nbCells [m_readerType[iMesh]] += remainingCells;
403  nbBdryCells[m_readerType[iMesh]] += remainingBdry;
404 
405  cellAttrSize += remainingCells*m_readers[iMesh]->getNbAttributesPerCell () +
406  remainingBdry *m_readers[iMesh]->getNbAttributesPerBdryCell();
407  // since we read contiguously:
408  iMesh++;
409  offset = 0;
410  }
411  }
412 
413  // 2. ------------------------------------------------------------
414  // We now know what is going to be read
415 
416  // Memory size for node indices
417  CepsUInt niSize = computeNumberOfNodeIndices(nbCells,nbBdryCells);
418  nodeIndices .resize(niSize);
419  nodeIndicesPtr.resize(nbCellsToRead+1);
420  isBoundary .resize(nbCellsToRead);
421 
422  // Memory size of attr
423  if (cellAttrSize > 0)
424  attr.resize(cellAttrSize,0);
425  attrPtr.resize(nbCellsToRead+1,0);
426 
427  // 3. ------------------------------------------------------------
428  // Fill these arrays !
429  CepsInt nbCellsRead = 0;
430  CepsUInt toRead(0u),start(0u),end(0u);
431  // Loop on meshes
432  for (CepsUInt i=0U; i<meshesToRead.size(); i++)
433  {
434  toRead = meshesToRead[i];
435  start = meshesStart [i];
436  end = meshesEnd [i];
437  m_readers[toRead]->readCells(
438  start,end,m_nodeOffsets[toRead],m_cellOffsets[toRead],
439  nodeIndices,nodeIndicesPtr,attr,attrPtr,isBoundary
440  );
441  nbCellsRead += end-start;
442  }
443 
444  nNodeIndices = nodeIndices.size();
445  nAttr = cellAttrSize;
446  return 0;
447 }
448 
451 {
452  return m_coupledNodes;
453 }
454 
455 MeshReader *
457 {
458  // Store string given by user
459  m_meshFileNames.at (index) = meshName;
460 
461  CepsString dir = ceps::getDir (meshName);
462  CepsString fileName = ceps::getFilename (meshName);
463 
464  // Test missing extensions
465  if (ceps::fileExists (fileName + ".mesh", dir))
466  fileName.append (".mesh");
467  else if (ceps::fileExists (fileName + ".ele", dir))
468  fileName.append (".ele");
469  else if (ceps::fileExists (fileName + ".msh", dir))
470  fileName.append (".msh");
471  else if (ceps::fileExists (fileName + ".pvtu", dir))
472  fileName.append (".pvtu");
473  else if (ceps::fileExists (fileName + ".vtk", dir))
474  fileName.append (".vtk");
475 
476  // Resolve relative paths
477  fileName = dir + "/" + fileName;
478 
479  CepsString ext = ceps::getExtension (fileName);
480  if (ext == "mesh")
481  return ceps::getNew<MeditMeshReader>(fileName, dim);
482  // Tetgen format file
483  else if (ext == "ele")
484  return ceps::getNew<TetgenMeshReader>(fileName, dim);
485  else if (ext == "msh")
486  return ceps::getNew<GmshMeshReader>(fileName, dim);
487  else if (ext == "vtk" or ext == "pvtu")
488  return ceps::getNew<VtkMeshReader>(fileName, dim);
489  else
490  CEPS_ABORT ("Unsupported mesh format for file: " << fileName);
491 
492  return nullptr;
493 }
494 
495 void
497 {
498  for (CepsUInt i = 0; i < m_nbMeshes; i++)
499  {
500  m_readers[i]->initialize ();
501  m_meshNbNodes[i] = m_readers[i]->getNbNodes ();
502  m_meshNbCells[i] = m_readers[i]->getNbCells ();
504 
505  // Update node, cell and boundary offsets
506  m_nodeOffsets[i + 1] = m_nodeOffsets[i] + m_meshNbNodes[i];
508  }
509 }
510 
511 void
513 {
514  CoupledNodesReader *r = ceps::getNew<CoupledNodesReader>(fileName);
515  using couple_t = std::pair<CepsNodeGlobalIndex, CepsNodeGlobalIndex>;
517  {
518  CepsInt meshIndexA (ceps::argVector (m_meshFileNames, nc.getMesh (0)));
519  CepsInt meshIndexB (ceps::argVector (m_meshFileNames, nc.getMesh (1)));
520  CepsUInt offsetA (m_nodeOffsets[meshIndexA]);
521  CepsUInt offsetB (m_nodeOffsets[meshIndexB]);
522  for (couple_t c : nc.getNodeCouples ())
523  {
524  // We store a bi-directional link
525  m_coupledNodes.insert (couple_t (c.first + offsetA, c.second + offsetB));
526  m_coupledNodes.insert (couple_t (c.second + offsetB, c.first + offsetA));
527  }
528  }
529 }
530 
531 CepsUInt
533 {
534  GeomCell *c3 = ceps::getNew<GeomSimplex<3u>>();
535  GeomCell *c2 = ceps::getNew<GeomSimplex<2u>>();
536  GeomCell *c1 = ceps::getNew<GeomSimplex<1u>>();
537  GeomCell *c0 = ceps::getNew<GeomSimplex<0u>>();
538 
539  CepsUInt res = nbCells[0] * c3->getNumberOfNodes () +
540  (nbCells[1] + nbBoundary[0]) * c2->getNumberOfNodes () +
541  (nbCells[2] + nbBoundary[1]) * c1->getNumberOfNodes () +
542  nbBoundary[2] * c0->getNumberOfNodes ();
543 
548 
549  return res;
550 }
#define CEPS_ABORT(message)
Stops the execution with a message. If testing is enabled, only throws a runtime_error.
#define CEPS_ABORT_IF(condition, message)
Stops the execution with a message if condition is true. If testing is enabled, only throws a runtime...
std::basic_string< CepsChar > CepsString
C++ format string.
Definition: CepsTypes.hpp:128
std::vector< _Type, _Alloc > CepsVector
C++ vector.
Definition: CepsTypes.hpp:155
bool CepsBool
Booleans.
Definition: CepsTypes.hpp:124
std::make_unsigned_t< CepsInt > CepsUInt
Unsigned version on CepsInt.
Definition: CepsTypes.hpp:109
int32_t CepsInt
Need 32 bit integer.
Definition: CepsTypes.hpp:106
std::unordered_multimap< _Key, _Tp, _Hash, _KeyEqual, _Alloc > CepsMultiMap
C++ multimap.
Definition: CepsTypes.hpp:205
@ offset
Offset phase.
A derived class of FileReader that is used when reading coupled Nodes files.
CepsVector< NodeCoupling > getCoupledNodesBetween(const CepsVector< CepsString > &meshes)
Returns all given couples between current meshes,.
Abstract class for geometrical cell. On top of index and attributes managament, the cell has informat...
Definition: GeomCell.hpp:48
virtual CepsUInt getNumberOfNodes() const =0
Volume for 3D, area for 2D, length for 1D, 0 for points.
CepsUInt m_totalNbBdryCells
Total # of boundary cells across all meshes.
CepsUInt * m_meshNbBdryCells
Number of boundary cells in each mesh.
void getNodeOffsetPerMesh(CepsVector< CepsUInt > &offsets)
Fills vector with cell offset for each mesh.
CepsUInt * m_meshNbCells
Number of cells in each mesh.
CepsUInt getNbNodes()
All meshes number of nodes.
CepsBool m_hasCoupledNodes
Flag to activate coupled nodes.
void initializeDataStructures()
Reads each mesh in order.
CepsUInt getNbBdryCells()
All meshes number of boundary cells.
CepsUInt readNodes(CepsUInt indexStart, CepsUInt nbNodesToRead, CepsVector< CepsReal > &coords, CepsVector< CepsAttribute > &attr, CepsVector< CepsUInt > &attrOffset, CepsUInt &attrSize)
Reads nbNodesToRead nodes, using global indices.
CepsUInt * m_nodeOffsets
GeomNode offsets for each mesh.
CepsUInt getNbCells()
All meshes number of cells.
CepsUInt * m_readerType
Type of mesh being read.
CepsUInt * m_cellOffsets
Cell offsets for each mesh (bdry included)
CepsUInt m_totalNbNodes
Total # of nodes across all meshes.
CepsVector< CepsString > m_meshFileNames
File names of each mesh.
~GeometryReader()
Destructor.
void getCellOffsetsPerMeshType(CepsUInt cellOffsets[4])
Fills array with cell offsets for each mesh type.
CepsUInt m_nbMeshes
Number of meshes to read.
void getNodeOffsetsPerMeshType(CepsUInt offsets[4])
Fills array with node offsets for each mesh type.
const CepsMultiMap< CepsNodeGlobalIndex, CepsNodeGlobalIndex > & getCoupledNodes()
Returns the hashtable of coupled nodes.
GeometryReader(const CepsVector< CepsString > &volumicMeshes, const CepsVector< CepsString > &surfacicMeshes, const CepsVector< CepsString > &cableMeshes, const CepsString &coupledNodesFile="")
Constructor. Actually runs the reading routines.
void getCellOffsetPerMesh(CepsVector< CepsUInt > &offsets)
Fills vector with cell offset for each mesh.
MeshReader ** m_readers
Array (dimension x type) holding the readers on all meshes.
void readCoupledNodes(const CepsString &fileName)
Get coupled nodes list using CoupledNodesReader.
CepsMultiMap< CepsNodeGlobalIndex, CepsNodeGlobalIndex > m_coupledNodes
Edges linking meshes.
MeshReader * getMeshReaderFor(const CepsString &meshName, CepsInt index, CepsUInt dim)
Initializes a mesh reader depending on the mesh file extension.
CepsUInt m_totalNbCells
Total # of cells across all meshes.
CepsUInt * m_meshNbNodes
Number of nodes in each mesh.
CepsUInt readCells(CepsUInt indexStart, CepsUInt nbCellsToRead, CepsVector< CepsNodeGlobalIndex > &nodeIndices, CepsVector< CepsUInt > &nodeIndicesOffset, CepsVector< CepsAttribute > &attr, CepsVector< CepsUInt > &attrOffset, CepsVector< CepsChar > &isBoundary, CepsUInt &eindSize, CepsUInt &attrSize)
Reads nbCellsToRead cells, using global indices.
CepsUInt computeNumberOfNodeIndices(CepsUInt nbCells[3], CepsUInt nbBoundary[3])
Returns the number of nodes given numbers of cells and boundary cells.
Abstract base class that encapsulates primary functionalities of each mesh reader.
Definition: MeshReader.hpp:42
virtual void readNodes(CepsUInt indexStart, CepsUInt indexEnd, CepsUInt nodeOffset, CepsVector< CepsReal > &coords, CepsVector< CepsAttribute > &attr, CepsVector< CepsUInt > &attrPtr)=0
Reads several nodes in mesh file.
virtual CepsInt getNbAttributesPerCell() const
Number of attributes per cell.
Definition: MeshReader.cpp:111
CepsUInt getNbNodes() const
Number of nodes of current mesh.
Definition: MeshReader.cpp:87
virtual void readCells(CepsUInt indexStart, CepsUInt indexEnd, CepsUInt nodeOffset, CepsUInt cellOffset, CepsVector< CepsNodeGlobalIndex > &nodeIndices, CepsVector< CepsUInt > &nodeIndicesPtr, CepsVector< CepsAttribute > &cellAttr, CepsVector< CepsUInt > &cellAttrPtr, CepsVector< CepsChar > &isBoundaryCell)=0
Reads several cells in mesh file.
CepsUInt getNbBdryCells() const
Number of boundary cell of current mesh.
Definition: MeshReader.cpp:99
virtual CepsInt getNbAttributesPerBdryCell() const
Number of attributes per boundary cell.
Definition: MeshReader.cpp:117
CepsUInt getNbCells() const
Number of cell of current mesh.
Definition: MeshReader.cpp:93
virtual void initialize()=0
The routine MUST set the number of nodes and cells.
Meta-cell for connections between meshes.
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
void destroyTabular(_Type &)
Destroy[delete] any type.
Definition: CepsMemory.hpp:149
CepsString getFilename(const CepsString &str)
Returns a substring corresponding to the string after the last '/' character. Example: "/home/someone...
Definition: CepsString.cpp:556
CepsInt argVector(const CepsVector< _Type, _Alloc > &vec, const _Type &value)
Get position of element in vector, -1 if not found.
Definition: CepsVector.hpp:200
CepsString getExtension(const CepsString &str)
Returns the extension of a file, if any.
Definition: CepsString.cpp:580
void destroyObject(_Type &)
Destroy[delete] any type.
Definition: CepsMemory.hpp:116
CepsBool fileExists(const CepsString &fileName, const CepsString &directory)
Definition: CepsString.cpp:595