CEPS  24.01
Cardiac ElectroPhysiology Simulator
CoeffReader.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 
33 CoeffReader::CoeffReader(const CepsString& fileName, const CepsLocationFlag& loc, Geometry* geom) :
34  FileReader(fileName),
35  m_geom(geom),
36  m_loc(loc)
37 {
38 
40  "Given location of data must be either Cell or Node, not ZeroD"
41  );
42 
43  CEPS_ABORT_IF(ceps::isNullPtr(geom), "Pointer on Geometry is null");
44 
45  // Coefficients over multiple meshes are not implemented
46  // We would need to get the list of meshes from the geometry
47  // and the offsets of nodes/cells to get the correct globalID
48  CepsUInt count = 0;
49  for (CepsUInt d = 1U; d <= 3U; d++)
50  if (geom->hasMeshOfDim(d))
51  count++;
52 
53  if (count != 1)
54  CEPS_ABORT(
55  "Importing coefficients defined on geometry is not implemented" << std::endl <<
56  " when geometry is made from multiple meshes"
57  );
58 
59  m_fileName = fileName;
60 
61  CepsString ext = ceps::getExtension(fileName);
63  "CoeffReader does not support files with extension " << ext << std::endl <<
64  " Supported extensions are .vtk and .msh"
65  );
66 
68 }
69 
71 {
72 }
73 
76 {
77  return ext=="msh" or ext=="vtk";
78 }
79 
80 void
82 {
83  CEPS_ABORT_IF(not hasArray(label,0),
84  "Reader has no scalar array with name " << label << " in file " << m_fileName
85  );
86  read(label,dest);
87  return;
88 }
89 
90 void
92 {
93  CEPS_ABORT_IF(not hasArray(label,1),
94  "Reader has no vector array with name " << label << " in file " << m_fileName
95  );
96  read(label,dest);
97  return;
98 }
99 
100 void
102 {
103  CEPS_ABORT_IF(not hasArray(label,2),
104  "Reader has no tensor array with name " << label << " in file " << m_fileName
105  );
106  read(label,dest);
107  return;
108 }
109 
110 CepsBool
111 CoeffReader::hasArray (const CepsString &label, CepsInt dim) const
112 {
113  CepsBool found = false;
114  CEPS_ABORT_IF(dim<-1 or dim>2,
115  "Provided dimension must be either -1 or 0 1 2"
116  );
117  CepsUInt i = dim==-1 ? 0 : dim;
118  CepsUInt end = dim==-1 ? 3 : dim+1;
119  while (i<end and not found)
120  {
122  found = ceps::contains(m_cellArrayNames[i],label);
124  found = ceps::contains(m_nodeArrayNames[i],label);
125  i++;
126  }
127  return found;
128 }
129 
130 void
132 {
134  if (ext == "vtk")
135  {
136  vtkDataSetReader *reader = vtkDataSetReader::New ();
137  reader->SetFileName(m_fileName.c_str ());
138  reader->SetReadAllScalars(1);
139  reader->SetReadAllVectors(1);
140  reader->SetReadAllNormals(1);
141  reader->SetReadAllTensors(1);
142  reader->SetReadAllFields(1);
143  reader->Update();
144  reader->GetOutput()->Register(reader);
145  m_vtkData = vtkDataSet::SafeDownCast(reader->GetOutput());
146  reader->Delete();
147 
149  for (CepsInt i = 0; i < m_vtkData->GetCellData()->GetNumberOfArrays(); i++)
150  switch(m_vtkData->GetCellData()->GetArray(i)->GetNumberOfComponents())
151  {
152  case 1:
153  m_cellArrayNames[0].push_back(m_vtkData->GetCellData()->GetArrayName(i));
154  break;
155  case 3:
156  m_cellArrayNames[1].push_back(m_vtkData->GetCellData()->GetArrayName(i));
157  break;
158  case 9:
159  m_cellArrayNames[2].push_back(m_vtkData->GetCellData()->GetArrayName(i));
160  break;
161  }
162  else
163  for (CepsInt i = 0; i < m_vtkData->GetPointData()->GetNumberOfArrays(); i++)
164  switch(m_vtkData->GetPointData()->GetArray(i)->GetNumberOfComponents())
165  {
166  case 1:
167  m_nodeArrayNames[0].push_back(m_vtkData->GetPointData()->GetArrayName(i));
168  break;
169  case 3:
170  m_nodeArrayNames[1].push_back(m_vtkData->GetPointData()->GetArrayName(i));
171  break;
172  case 9:
173  m_nodeArrayNames[2].push_back(m_vtkData->GetPointData()->GetArrayName(i));
174  break;
175  }
176  }
177  else // msh
178  {
179  CepsArray<CepsString,2> keywords = {"$ElementData","$NodeData"};
181 
182  for (CepsUInt ii=0;ii<2;ii++)
183  {
184  CepsInt iLine = -1;
186  do
187  {
188  iLine = lineIndex(keywords[ii]);
189  if (iLine != -1)
190  {
191  CepsString line;
192  CepsString e = "in file " + m_fileName + ":\n ";
193  CepsInt nStringTags,nRealTags,nComp;
194 
195  nStringTags = ceps::readInt(m_file,e+"cannot read number of string tags after " + keywords[ii]);
196  for(CepsInt i=0;i<nStringTags+1;i++)
197  std::getline(m_file,line);
198  CepsString label = line.substr(line.find_first_of('\"')+1,line.find_last_of('\"')-1);
199  // Get the nb of components
200  skipLines(0);
201  nRealTags = ceps::readInt (m_file,e+"cannot read number of real tags");
202  for (CepsInt i = 0U; i < nRealTags; i++)
203  ceps::readReal(m_file,e+"cannot read real tag");
204  ceps::readInt (m_file,e+"cannot read number of int tags");
205  ceps::readInt (m_file,e+"cannot read time step index");
206  nComp = ceps::readInt (m_file,"cannot read number of components of coefficients");
207  switch (nComp)
208  {
209  case 1:
210  (*nameArrays[ii])[0].push_back(label);
211  break;
212  case 3:
213  (*nameArrays[ii])[1].push_back(label);
214  break;
215  case 9:
216  (*nameArrays[ii])[2].push_back(label);
217  break;
218  }
219  }
220  } while (iLine != -1);
221  }
222  }
223 }
CepsLocationFlag
DataLocation: an enum that will be used by various elements of the code (pde, readers,...
Definition: CepsEnums.hpp:108
@ Cell
Data is defined at cell centers.
@ Point
Data is defined on each point.
#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::array< _Type, _N > CepsArray
C++ arrays.
Definition: CepsTypes.hpp:159
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
CepsArray< CepsVector< CepsString >, 3 > m_nodeArrayNames
Names of data arrays defined on nodes (array index: scalar, vector, tensor)
void read(const CepsString &label, DistributedInfos< _Result > &dest)
Read the array and stores the data into instance. The label is needed for vtk format.
~CoeffReader() override
Destructor.
Definition: CoeffReader.cpp:70
vtkSmartPointer< vtkDataSet > m_vtkData
Array in the vtk format.
void getData(const CepsString &label, DistributedInfos< CepsMathScalar > &dest)
Extract a distributed data structure of scalars with given label.
Definition: CoeffReader.cpp:81
void buildArrayNamesList()
Stores the names of the arrays for easier access afterwards.
CepsLocationFlag m_loc
Used to choose between point or cell data.
CepsArray< CepsVector< CepsString >, 3 > m_cellArrayNames
Names of data arrays defined on cells (array index: scalar, vector, tensor)
CoeffReader(const CepsString &fileName, const CepsLocationFlag &loc, Geometry *geom)
Constructor from file name, and location flag, linked to geometry.
Definition: CoeffReader.cpp:33
CepsBool isValidExtension(CepsString ext)
Tells if extension is compatible with reader.
Definition: CoeffReader.cpp:75
CepsBool hasArray(const CepsString &label, CepsInt dim=-1) const
Tells if file has data array, dim = 0 for scalars, 1 for vector, 2 for tensor.
A class that manages data that is distributed between processors, not only real values (as in Distrib...
Base class that regroups common reader functionalities.
Definition: FileReader.hpp:43
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
CepsUInt skipLines(CepsUInt nbLines)
Skip given number of lines.
Definition: FileReader.cpp:179
CepsString m_fileName
file to open
Definition: FileReader.hpp:145
std::ifstream m_file
stream
Definition: FileReader.hpp:146
Encapsulates all the geometrical data.
Definition: Geometry.hpp:50
CepsBool hasMeshOfDim(CepsUInt dim) const
true if geometry has data of requested dimension
Definition: Geometry.cpp:167
CepsBool contains(const CepsVector< _Type, _Alloc > &vec, const _Type &item)
Tells if vectors contains a given item.
Definition: CepsVector.hpp:56
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
CepsBool isNullPtr(_Type *ptr)
Tells if passed pointer is null.
Definition: CepsMemory.hpp:45
CepsString getExtension(const CepsString &str)
Returns the extension of a file, if any.
Definition: CepsString.cpp:580
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