CEPS  24.01
Cardiac ElectroPhysiology Simulator
MeditMeshReader.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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
31 #include "MeditMeshReader.hpp"
32 
33 MeditMeshReader::MeditMeshReader(const CepsString &fileName, const CepsUInt &dim, CepsBool quads) :
34  MeshReader(fileName, dim, quads),
35  m_indexOffset(0),
36  m_boundaryIndexOffset(0)
37 {
39  m_nbAttrPerCell = 1;
41  m_extension = "mesh";
42  checkExtension ();
43 }
44 
46 {
47  close();
48 }
49 
50 void
52  CepsUInt indexStart,
53  CepsUInt indexEnd,
54  CepsUInt nodeOffset,
55  CepsVector<CepsReal>& coords,
57  CepsVector<CepsUInt>& attrPtr
58 )
59 {
60  checkCanReadNodes(indexStart,indexEnd);
61 
62  // Skip to the correct line
63  this->close();
64  this->open ();
65  CepsInt nbToRead = indexEnd-indexStart;
66  CepsString dummy;
67  for (CepsUInt i=0U; i<indexStart+m_nodesBegin; i++)
68  std::getline(m_file,dummy);
69 
70  std::stringstream h;
71  h << "Medit mesh reader: in file " << m_fileName << "," << std::endl
72  << " unable to read ";
73 
74  for (CepsInt i=0; i<nbToRead; i++)
75  {
76  CepsUInt nodeId = nodeOffset+i;
77  CepsString n = ceps::toString(i+1);
78  for (CepsUInt j=0; j<3;j++)
79  coords[3*nodeId+j] = ceps::readReal(m_file,h.str()+"coordinates of point #"+n);
80 
81  for (CepsUInt j=0; j<(CepsUInt)m_nbAttrPerNode; j++)
82  attr[attrPtr[nodeId]+j] = ceps::readInt(m_file,h.str()+"attributes of point #"+n);
83 
84  attrPtr[nodeId+1] = attrPtr[nodeId] + m_nbAttrPerNode;
85  }
86 
87 }
88 
89 void
91  CepsUInt indexStart,
92  CepsUInt indexEnd,
93  CepsUInt nodeOffset,
94  CepsUInt cellOffset,
96  CepsVector<CepsUInt>& nodeIndicesPtr,
97  CepsVector<CepsAttribute>& cellAttr,
98  CepsVector<CepsUInt>& cellAttrPtr,
99  CepsVector<CepsChar>& isBoundaryCell
100 )
101 {
102  checkCanReadCells(indexStart,indexEnd);
103 
104  // 0. Init
105  this->reset();
106  CepsInt nbToRead = indexEnd-indexStart;
107 
108  CepsInt nbCellsToRead = 0;
109  CepsInt nbBoundaryToRead = 0;
110 
111  // 1. Reach starting line:
112 
113  // If only boundary cells to read
114  if (indexStart >= m_nbCells)
115  {
116  nbBoundaryToRead = nbToRead;
117  CepsString dummy;
118  for (CepsInt i=0; i<(CepsInt)(m_bdryCellsBegin+(indexStart-m_nbCells)); i++)
119  std::getline(m_file,dummy);
120  }
121  // Both kinds of cells to read
122  else
123  {
124  nbCellsToRead = (CepsInt)(m_nbCells-indexStart);
125  nbBoundaryToRead = nbToRead-nbCellsToRead;
126  CepsString dummy;
127  for (CepsInt i = 0; i < (CepsInt) (m_cellsBegin+indexStart); i++)
128  std::getline(m_file,dummy);
129  }
130 
131  // 2. Read cells (if any to read)
132  CepsInt i;
133  for (i=0; i<nbCellsToRead; i++)
134  getNextCell(
135  cellOffset+i,i,nodeOffset,nodeIndices,nodeIndicesPtr,cellAttr,cellAttrPtr,isBoundaryCell,false
136  );
137 
138  // 2.5 Finished reading cells. Now place stream on the boundary cells
139  if (indexStart <= m_nbCells)
140  {
141  CepsString dummy;
142  this->reset();
143  for (CepsInt j=0; j<(CepsInt)m_bdryCellsBegin; j++)
144  std::getline(m_file,dummy);
145  }
146 
147  // 3. Read boundary cells
148  for (; i < nbBoundaryToRead+nbCellsToRead; i++)
149  getNextCell(
150  cellOffset+i,i,nodeOffset,nodeIndices,nodeIndicesPtr,cellAttr,cellAttrPtr,isBoundaryCell,true
151  );
152 
153  return;
154 }
155 
156 void
158  CepsUInt cellId,
159  CepsUInt fileCellId,
160  CepsUInt nodeOffset,
161  CepsVector<CepsNodeGlobalIndex>& nodeIndices,
162  CepsVector<CepsUInt>& nodeIndicesPtr,
163  CepsVector<CepsAttribute>& cellAttr,
164  CepsVector<CepsUInt>& cellAttrPtr,
165  CepsVector<CepsChar>& isBoundaryCell,
166  CepsBool boundaryFlag
167 )
168 {
169  std::stringstream hh;
170  hh << "Medit mesh reader: in file " << m_fileName << "," << std::endl << " unable to read ";
171  CepsString c = ceps::toString(fileCellId+1);
172  CepsString h = hh.str();
173 
174  CepsUInt nbPts = boundaryFlag ? m_nbNodesPerBdryCell : m_nbNodesPerCell;
175  CepsUInt nAttr = boundaryFlag ? m_nbAttrPerBdryCell : m_nbAttrPerCell ;
176 
177  for (CepsUInt i=0; i<nbPts; i++)
178  nodeIndices[nodeIndicesPtr[cellId]+i] = ceps::readInt(m_file,h+"node IDs of cell #"+c) + nodeOffset - m_indexOffset;
179 
180  for (CepsUInt i=0;i<nAttr;i++)
181  cellAttr[cellAttrPtr[cellId]] = ceps::readInt(m_file,h+"attributes of cell #"+c);
182 
183  cellAttrPtr [cellId+1] = cellAttrPtr [cellId] + nAttr;
184  nodeIndicesPtr[cellId+1] = nodeIndicesPtr[cellId] + nbPts;
185 
186  isBoundaryCell[cellId] = boundaryFlag;
187 
188  if (boundaryFlag)
189  m_bdryCellsRead++;
190  else
191  m_cellsRead++;
192 }
193 
194 
195 void
197 {
198  CEPS_SAYS (" Reading " << m_fileName << " for dimension " << m_expectedDim);
199 
200  this->reset ();
201 
202  // find the vertices
203  CepsString keyword ("Vertices");
204  CepsInt line = this->lineIndex (keyword);
205  CEPS_ABORT_IF(line==-1, "Failed to find any nodes in mesh file.");
206 
207  // next line is nb nodes
208  m_nbNodes = ceps::readInt(m_file,"Medit mesh reader: could not read number of nodes");
209  // nodes begin at next line
210  m_nodesBegin = line + 2;
211  m_nbAttrPerNode = 1;
212 
213  // try to find cells first
216 
217  this->reset ();
218  line = this->lineIndex (kwV);
219  CEPS_ABORT_IF (line==-1,
220  "Could not find any cells of type \"" << kwV << "\" in current Medit mesh file." << m_fileName
221  );
222 
223  // next line is nb cells
224  m_nbCells = ceps::readInt(m_file,"Medit mesh reader: could not read number of cells");
225  m_cellsBegin = line + 2;
226 
227  // look for boundary cell now
228  this->reset ();
229  line = this->lineIndex (kwB);
230  if (line == -1)
231  {
232  // no boundary cells
233  CEPS_WARNS ("No boundary cells found for mesh " << m_fileName);
234  m_bdryCellsBegin = 0;
235  m_nbBdryCells = 0;
236  }
237  else
238  {
239  m_nbBdryCells = ceps::readInt(m_file,"Medit mesh reader: could not read number of bdry cells");
240  m_bdryCellsBegin = line + 2;
241  }
242 
243  m_indexOffset = 1;
245 
246  this->reset ();
248  m_initialized = true;
249 }
#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_WARNS(message)
Writes a warning in the debug log and in the terminal (stderr).
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
CepsInt lineIndex(const CepsString &word)
Index of first line starting with word, search starting from the current stream position.
Definition: FileReader.cpp:209
void reset()
Set file stream to the beginning of the file.
Definition: FileReader.cpp:98
virtual CepsBool open()
Opens the designated file in read mode.
Definition: FileReader.cpp:70
CepsString m_fileName
file to open
Definition: FileReader.hpp:145
std::ifstream m_file
stream
Definition: FileReader.hpp:146
virtual void close()
Close the file.
Definition: FileReader.cpp:84
CepsVector< CepsString > m_keywordsT
Keywords used to separate cells in medit format, for simplices.
void initialize() override
Get the number of nodes cells and boundary cells before reading.
~MeditMeshReader() override
Destructor.
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) override
Reads several cells in mesh file.
MeditMeshReader(const CepsString &fileName, const CepsUInt &dim, CepsBool quads=false)
Constructor with full fileName and expected dimension.
void readNodes(CepsUInt indexStart, CepsUInt indexEnd, CepsUInt nodeOffset, CepsVector< CepsReal > &coords, CepsVector< CepsAttribute > &attr, CepsVector< CepsUInt > &attrPtr) override
Reads several nodes in mesh file.
void getNextCell(CepsUInt cellId, CepsUInt fileCellId, CepsUInt nodeOffset, CepsVector< CepsNodeGlobalIndex > &nodeIndices, CepsVector< CepsUInt > &nodeIndicesPtr, CepsVector< CepsAttribute > &cellAttr, CepsVector< CepsUInt > &cellAttrPtr, CepsVector< CepsChar > &isBoundaryCell, CepsBool boundaryFlag) override
Reads a single cell in mesh file.
CepsInt m_boundaryIndexOffset
Internal offset.
CepsVector< CepsString > m_keywordsQ
Keywords used to separate cells in medit format, for quads.
CepsInt m_indexOffset
Internal offset.
Abstract base class that encapsulates primary functionalities of each mesh reader.
Definition: MeshReader.hpp:42
CepsInt m_nodesBegin
line start of nodes
Definition: MeshReader.hpp:183
CepsUInt m_nbAttrPerCell
attributes per cell
Definition: MeshReader.hpp:194
CepsBool m_initialized
Flag to ensure call of initializeReader()
Definition: MeshReader.hpp:176
void checkCanReadNodes(CepsUInt indexStart, CepsUInt indexEnd) const
Aborts if passed indices are wrong.
Definition: MeshReader.cpp:137
CepsUInt m_nbNodesPerBdryCell
nb nodes per boundary cell
Definition: MeshReader.hpp:181
CepsBool m_quads
Reader for quadratic cells.
Definition: MeshReader.hpp:175
CepsUInt m_bdryCellsRead
Keeps track of already read boundary cells.
Definition: MeshReader.hpp:180
CepsUInt m_nbNodesPerCell
nb nodes per cell
Definition: MeshReader.hpp:179
CepsUInt m_nbBdryCells
number of boundary cells in mesh, appropriate for dimension
Definition: MeshReader.hpp:191
CepsUInt m_nbAttrPerBdryCell
attributes per boundary cell
Definition: MeshReader.hpp:195
CepsUInt m_cellsRead
Keeps track of already read cells.
Definition: MeshReader.hpp:178
CepsUInt m_nbAttrPerNode
attributes per node
Definition: MeshReader.hpp:193
virtual CepsBool checkExtension() const
Stop if extension is not ok, extension must be defined in child classes.
Definition: MeshReader.cpp:123
CepsInt m_cellsBegin
line start of cells
Definition: MeshReader.hpp:186
CepsUInt m_expectedDim
Expected dimension of mesh.
Definition: MeshReader.hpp:174
CepsUInt m_nbCellsTotal
number of all cells in file
Definition: MeshReader.hpp:188
CepsInt m_bdryCellsBegin
line start of boundary cells
Definition: MeshReader.hpp:190
CepsString m_extension
File name extension.
Definition: MeshReader.hpp:172
CepsUInt m_nbNodes
number of nodes in mesh
Definition: MeshReader.hpp:184
CepsUInt m_nbCells
number of cells in mesh, appropriate for dimension
Definition: MeshReader.hpp:187
void checkCanReadCells(CepsUInt indexStart, CepsUInt indexEnd) const
Aborts if passed indices are wrong.
Definition: MeshReader.cpp:151
CepsString toString(_Tp value)
Convert a given value to a string (input has to be compatible with std::to_string)
Definition: CepsString.hpp:409
CepsInt readInt(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:677
CepsReal readReal(std::istream &file, const CepsString &errorMessage="")
Reads a floating point number from an istream, aborts if conversion fails advances the stream by 1 wo...
Definition: CepsString.cpp:661