Directory: | ./ |
---|---|
File: | InputOutput/ensight.hpp |
Date: | 2024-04-14 07:32:34 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 19 | 30 | 63.3% |
Branches: | 4 | 8 | 50.0% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | // ______ ______ _ _ _____ ______ | ||
2 | // | ____| ____| | (_)/ ____| | ____| | ||
3 | // | |__ | |__ | | _| (___ ___| |__ | ||
4 | // | __| | __| | | | |\___ \ / __| __| | ||
5 | // | | | |____| |____| |____) | (__| |____ | ||
6 | // |_| |______|______|_|_____/ \___|______| | ||
7 | // Finite Elements for Life Sciences and Engineering | ||
8 | // | ||
9 | // License: LGL2.1 License | ||
10 | // FELiScE default license: LICENSE in root folder | ||
11 | // | ||
12 | // Main authors: J.Castelneau & J.Foulon | ||
13 | // | ||
14 | |||
15 | /*! | ||
16 | \file ensight.hpp | ||
17 | \authors J.Castelneau & J.Foulon | ||
18 | \date 04/05/2010 | ||
19 | \brief File containing object to use Ensight software | ||
20 | */ | ||
21 | |||
22 | #ifndef _ENSIGHT_HPP | ||
23 | #define _ENSIGHT_HPP | ||
24 | |||
25 | // System includes | ||
26 | #include <cfloat> | ||
27 | #include <list> | ||
28 | #include <unordered_map> | ||
29 | #include <set> | ||
30 | #include <sstream> | ||
31 | #include <string> | ||
32 | #include <vector> | ||
33 | |||
34 | // External includes | ||
35 | |||
36 | // Project includes | ||
37 | #include "Core/felisceParam.hpp" | ||
38 | #include "Core/felisceTransient.hpp" | ||
39 | #include "Geometry/geometricMeshRegion.hpp" | ||
40 | |||
41 | namespace felisce { | ||
42 | /*! | ||
43 | \class EnsightTime | ||
44 | |||
45 | \brief class to handle a time set (in ensight format). | ||
46 | |||
47 | \author Jean-Frederic Gerbeau | ||
48 | */ | ||
49 | |||
50 | static constexpr double Infinity = std::numeric_limits<double>::infinity(); | ||
51 | |||
52 | enum OutputFileFormat {ENSIGHT6=0, ENSIGHTGOLD=1, ENSIGHT6BIN=2, ENSIGHTGOLDBIN=3}; | ||
53 | |||
54 | class EnsightTimeBis { | ||
55 | /// This class consists of a std::vector<double> m_time_values containig all the time instants. | ||
56 | /// There is a method to compute the index of a given time instant, | ||
57 | /// such index contains m_filename_start_number ( see int timeIndex( double time ) const; ) | ||
58 | private: | ||
59 | int m_num_steps; ///< The current number of time steps, i.e. the size of m_time_values. | ||
60 | int m_filename_start_number; ///< set into the constructor is used in the function timeIndex. | ||
61 | int m_filename_increment; ///< I am not sure it is used anywhere (matteo 10/15) | ||
62 | std::vector<double> m_time_values; ///< The std::vector containing all the values of the time instants | ||
63 | public: | ||
64 | 8 | EnsightTimeBis() = default; | |
65 | EnsightTimeBis(int time_set, int num_steps, int filename_start_number, int filename_increment); /// The constructor | ||
66 | /// Getter const | ||
67 | double timeValue(int i) const { | ||
68 | return m_time_values[i]; | ||
69 | } | ||
70 | /// Getter non const | ||
71 | 155532 | double& timeValue(int i) { | |
72 | 155532 | return m_time_values[i]; | |
73 | } | ||
74 | /// Given a time instant it returns ( the correct index in the std::vector m_time_values ) + m_filename_start_number | ||
75 | int timeIndex(double time) const; | ||
76 | int nbSteps() const { | ||
77 | return m_num_steps; | ||
78 | } | ||
79 | 161708 | int nbSteps() { /// I think it should return a reference (matteo) | |
80 | 161708 | return m_num_steps; | |
81 | } | ||
82 | /// getter | ||
83 | 3112 | int fileNameStartNumber() const { | |
84 | 3112 | return m_filename_start_number; | |
85 | } | ||
86 | /// getter | ||
87 | 3112 | int fileNameIncrement() const { | |
88 | 3112 | return m_filename_increment; | |
89 | } | ||
90 | /// push_back into the std::vector | ||
91 | void addTimeValue(double& time); | ||
92 | }; | ||
93 | |||
94 | |||
95 | //======================================================================================= | ||
96 | /*! | ||
97 | \class EnsightVariable | ||
98 | |||
99 | \brief class to handle a solution (in ensight format). | ||
100 | |||
101 | \author Jean-Frederic Gerbeau | ||
102 | */ | ||
103 | |||
104 | class EnsightVariable { | ||
105 | public: | ||
106 | enum TypeVar {Unknown = -1, ScalarPerNode = 0, VectorPerNode = 1}; | ||
107 | private: | ||
108 | TypeVar m_type; // vector or scalar | ||
109 | /*! number of solution values ( with previous example size=n ) */ | ||
110 | felInt m_size; | ||
111 | std::string m_description; | ||
112 | std::string m_filename; | ||
113 | std::string m_filename_wildcard; | ||
114 | /*! pointer on solution values ( [u_x_1, u_x_2, u_x_3, ..., u_x_n, | ||
115 | u_y_1, u_y_2, u_y_3,...,u_y_n, u_z_1, u_z_2, u_z_3, ...,u_z_n,] ). */ | ||
116 | const double* m_solution; | ||
117 | /// define if class manage desallocation or not after post-processing. | ||
118 | bool m_manageMemory; | ||
119 | std::map<felInt, std::vector<felInt> > m_ref2list; | ||
120 | |||
121 | ✗ | char* local_strncpy(char* destination,const char* source, std::size_t num) | |
122 | { | ||
123 | #if defined(__GNUC__) && (__GNUC___ > 8) | ||
124 | #pragma GCC diagnostic push | ||
125 | #pragma GCC diagnostic ignored "-Wstringop-truncation" | ||
126 | return strncpy(destination, source, num); | ||
127 | #pragma GCC diagnostic pop | ||
128 | #else | ||
129 | ✗ | return strncpy(destination, source, num); | |
130 | #endif | ||
131 | } | ||
132 | |||
133 | public: | ||
134 | 12 | EnsightVariable() = default; | |
135 | EnsightVariable(const std::string& type, int time_set, int file_set, | ||
136 | const std::string& description, const std::string& filename); | ||
137 | |||
138 | EnsightVariable(const EnsightVariable::TypeVar& type, const std::string& nameVariable, | ||
139 | const double* solution, felInt size, bool manageMemory=false); | ||
140 | |||
141 | 5378 | TypeVar type() { | |
142 | 5378 | return m_type; | |
143 | } | ||
144 | felInt size() { | ||
145 | return m_size; | ||
146 | } | ||
147 | std::string variableFile() const; | ||
148 | std::string variableFileInput(int istep); | ||
149 | std::string variableFileOutput(const std::string& outputDirectory, int istep); | ||
150 | std::string description() const; | ||
151 | std::string wildCard(int indexTime); | ||
152 | |||
153 | void write(const std::string& outputDirectory, int indexTime); | ||
154 | void writeScalarEnsight6(const std::string& outputDirectory, int indexTime); | ||
155 | void writeScalarEnsight6Bin(const std::string& outputDirectory, int indexTime); | ||
156 | void writeScalarEnsightGold(const std::string& outputDirectory, int indexTime); | ||
157 | void writeVectorEnsight6(const std::string& outputDirectory, int indexTime); | ||
158 | void writeVectorEnsight6Bin(const std::string& outputDirectory, int indexTime); | ||
159 | void writeVectorEnsightGold(const std::string& outputDirectory, int indexTime); | ||
160 | 5378 | void clear() { | |
161 |
2/4✓ Branch 0 taken 5378 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5378 times.
✗ Branch 3 not taken.
|
5378 | if (m_manageMemory) delete [] m_solution; |
162 | 5378 | } | |
163 | |||
164 | ✗ | inline void setRefToListOfIds(std::map<felInt, std::vector<felInt> > ref2list) { | |
165 | ✗ | m_ref2list = ref2list; | |
166 | } | ||
167 | }; | ||
168 | |||
169 | //======================================================================================= | ||
170 | /*! | ||
171 | \class EnsightCase | ||
172 | |||
173 | \brief class to handle a ensight casef | ||
174 | |||
175 | \author Jean-Frederic Gerbeau | ||
176 | */ | ||
177 | |||
178 | class EnsightCase { | ||
179 | int m_verbose; | ||
180 | int m_domainDim; | ||
181 | bool m_createNormalTangent; | ||
182 | /// Directory where the case file is | ||
183 | std::string m_directory; | ||
184 | /// Case file name (including the postfix '.case') | ||
185 | std::string m_filename; | ||
186 | /// Lines of the case file | ||
187 | std::vector<std::string> m_line; | ||
188 | /// Index of the line where the format section starts | ||
189 | int m_sectionFormat; | ||
190 | /// Index of the line where the geometry section starts | ||
191 | int m_sectionGeometry; | ||
192 | /// Index of the line where the variable section starts | ||
193 | int m_sectionVariable; | ||
194 | /// Index of the line where the time section starts | ||
195 | int m_sectionTime; | ||
196 | /// Time set in the 'model' subsection of Geometry section (-1 if not provided) | ||
197 | int m_model_time_set; | ||
198 | /// File set int the 'model' subsection of Geometry section (-1 if not provided) | ||
199 | int m_model_file_set; | ||
200 | /// Optional field in the 'model' subsection of Geometry section (false if not provided) | ||
201 | bool m_change_coords_only; | ||
202 | /// cstep in change_coords_only item (0 if not provided) | ||
203 | int m_change_coords_only_cstep; | ||
204 | /// name of the geometry file (ex crosse.0010.geo) | ||
205 | std::string m_geo_file; | ||
206 | /// name of the geometry file with wildcard (ex crosse.****.geo) | ||
207 | std::string m_geo_file_wildcard; | ||
208 | /// number of wildcard characters (i.e. character '*') | ||
209 | int m_num_wildcard; | ||
210 | /// number of variables | ||
211 | int m_num_variable; | ||
212 | /// variable | ||
213 | std::vector<EnsightVariable> m_var; | ||
214 | std::vector<EnsightTimeBis> m_time; | ||
215 | |||
216 | public: | ||
217 | EnsightCase(); | ||
218 | EnsightCase(int verbose); | ||
219 | void initialize(const std::string& nameGeoFile, int time_set, | ||
220 | int num_steps, int filename_start_number, | ||
221 | int filename_increment ); | ||
222 | void read(const std::string& directory, const std::string& case_file); | ||
223 | std::string geometryFile() const; | ||
224 | std::string geometryFile(int istep) const; | ||
225 | EnsightVariable const& variable(int ivar) const; | ||
226 | EnsightVariable& variable(int ivar); | ||
227 | EnsightTimeBis& timeSet(int iset = 0); | ||
228 | |||
229 | int timeIndex(double time) const; | ||
230 | int variableIndex(std::string description) const; | ||
231 | |||
232 | /// dim is the number of nodes for a scalar and 3*nb of nodes for a std::vector | ||
233 | void readVariable(int idVariable,int indexTime, double* vec,felInt size); | ||
234 | void readScalar(const std::string& fileName, double* vec, felInt size); | ||
235 | void readVector(const std::string& fileName, double* vec, felInt size); | ||
236 | |||
237 | ///Output functions. | ||
238 | void addVariable(const EnsightVariable::TypeVar& type, const std::string& nameVariable, | ||
239 | const double* solution, felInt size, bool manageMemory=false); | ||
240 | void postProcess(const std::string& outputDirectory, | ||
241 | const std::string& nameCase, | ||
242 | int optionMultiCase, | ||
243 | double& time); | ||
244 | void writeVariable(const std::string& outputDirectory, const std::string& nameVariable, int indexTime); | ||
245 | void writeCaseFile(const std::string& outputDirectory, const std::string& nameCase, int optionMultiCase); | ||
246 | void case_mesh_section(FILE* pFile); | ||
247 | void case_mesh_multiple_section(FILE* pFile); | ||
248 | void case_mesh_by_variable(FILE* pFile, int iVar); | ||
249 | void case_geometricVec(FILE* pFile); | ||
250 | void case_variable_section(FILE* pFile); | ||
251 | void case_variable_by_variable(FILE* pFile, int iVar); | ||
252 | void case_time_section(FILE* pFile); | ||
253 | int getNumNodeFromGeoFile(std::string dir) const; | ||
254 | void SetDomainDim_case(int domainDim); | ||
255 | void SetCreateNormalTangent_case(bool createNormalTangent); | ||
256 | ✗ | inline std::size_t numVariables() { | |
257 | ✗ | return m_var.size(); | |
258 | } | ||
259 | // inline int domainDim() { | ||
260 | // return m_domainDim; | ||
261 | //} | ||
262 | }; | ||
263 | |||
264 | |||
265 | /** | ||
266 | * \class Ensight | ||
267 | * \authors J. Castelneau, J. Foulon | ||
268 | * \brief Class managing input and output for using Ensight6 | ||
269 | * \date 04/05/2010 | ||
270 | * | ||
271 | * An Ensight object contains a prefix name, a name directory and a list of EnsightData | ||
272 | * | ||
273 | */ | ||
274 | |||
275 | class Ensight { | ||
276 | public: | ||
277 | typedef GeometricMeshRegion::ElementType ElementType; | ||
278 | typedef std::unordered_map<std::string, std::pair<ElementType, std::string> > StringToEns6Pair_type; | ||
279 | typedef std::unordered_map<std::string, ElementType > StringToElementType_type; | ||
280 | typedef std::vector< std::string > PartNumberToDescriptionLine_type; | ||
281 | private: | ||
282 | /*!< \todo: build a dataSolution to manage all solution information | ||
283 | ( prefix names, solution directory, ... ) */ | ||
284 | int m_indexStep; | ||
285 | int m_domainDim; | ||
286 | bool m_createNormalTangent; | ||
287 | /*!<std::unordered_map to link element geometric name in felisce to ensight format */ | ||
288 | static StringToEns6Pair_type m_eltFelNameToEns6Pair; | ||
289 | /*!<std::unordered_mapping on ensight element name and geometric elementType enum */ | ||
290 | static StringToElementType_type m_eltEns6NameToEnum; | ||
291 | /*!<Contains a short description of the part*/ | ||
292 | PartNumberToDescriptionLine_type m_partIdToDescLine; | ||
293 | /*! Function to initialize m_eltFelNameToEns6Pair & m_eltEns6NameToEnum std::unordered_maps */ | ||
294 | void initMap(); | ||
295 | |||
296 | EnsightCase m_caseInput; | ||
297 | EnsightCase m_caseOutput; | ||
298 | |||
299 | std::string m_inputDirectory; | ||
300 | std::string m_inputFile; | ||
301 | std::string m_inputMesh; | ||
302 | std::string m_outputMesh; | ||
303 | std::string m_meshDir; | ||
304 | std::string m_resultDir; | ||
305 | |||
306 | std::map<felInt, std::vector<felInt> > m_refToListOfIds; | ||
307 | |||
308 | ✗ | char* local_strncpy(char* destination,const char* source, std::size_t num) | |
309 | { | ||
310 | #if defined(__GNUC__) && (__GNUC___ > 8) | ||
311 | #pragma GCC diagnostic push | ||
312 | #pragma GCC diagnostic ignored "-Wstringop-truncation" | ||
313 | return strncpy(destination, source, num); | ||
314 | #pragma GCC diagnostic pop | ||
315 | #else | ||
316 | ✗ | return strncpy(destination, source, num); | |
317 | #endif | ||
318 | } | ||
319 | |||
320 | std::string getKeyword(const ElementType eltType); | ||
321 | |||
322 | void prepareElemIndexes(std::vector<std::vector<felInt>>& elem, const ElementType eltType); | ||
323 | |||
324 | void getElemIndexes(GeometricMeshRegion& mesh, const ElementType eltType, const felInt iel, std::vector<std::vector<felInt>>& elem, const felInt startindex, const bool incr_vert_id); | ||
325 | |||
326 | int getNumberPointsElement(const ElementType eltType); | ||
327 | |||
328 | felInt getNumberOfElements(GeometricMeshRegion& mesh, const ElementType eltType, const int the_ref); | ||
329 | |||
330 | public: | ||
331 | //Construtor | ||
332 |
2/4✓ Branch 2 taken 1055 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1055 times.
✗ Branch 6 not taken.
|
1055 | Ensight() = default; |
333 | Ensight(const std::string& inputDirectory,const std::string& inputFile,const std::string& inputMesh,const std::string& outputMesh,const std::string& meshDir,const std::string& resultDir); | ||
334 | void initialize(const std::string& inputDirectory,const std::string& inputFile,const std::string& inputMesh,const std::string& outputMesh,const std::string& meshDir,const std::string& resultDir); | ||
335 | 1077 | ~Ensight() = default; | |
336 | |||
337 | /// Copy constructor, to avoid warning due to user-declared destructor. | ||
338 | Ensight(const Ensight&) = default; | ||
339 | |||
340 | void initializeOutput(const std::string& nameGeoFile,int time_set, | ||
341 | int num_steps,int filename_start_number, | ||
342 | int filename_increment ); | ||
343 | // Set manually the directory to write results | ||
344 | void setResultDir(const std::string resultDir); | ||
345 | //read input case file. | ||
346 | void readCaseFile(); | ||
347 | //read data of a variable store in file. | ||
348 | void readVariable(int idVariable, double time, double* valueOfVariable, felInt size); | ||
349 | |||
350 | // Variable functions | ||
351 | /*!< add Variable/Solution which is manage by ensight*/ | ||
352 | void addVariable(/*const EnsightVariable::TypeVar& type*/int typeVariable, const std::string nameVariable, | ||
353 | const double* solution, const felInt size, bool manageMemory=false); | ||
354 | |||
355 | |||
356 | // Mesh functions | ||
357 | /*!< read ensight geoFile to create geometricMeshRegion object */ | ||
358 | void readerGeo(GeometricMeshRegion& mesh, double spaceUnit); | ||
359 | /*!< write ensight geoFile from geometricMeshRegion object */ | ||
360 | void writerGeo(GeometricMeshRegion& mesh, std::string nameOfGeoFile); | ||
361 | /*!< write ensight binary geoFile from geometricMeshRegion object */ | ||
362 | void writerGeoBin(GeometricMeshRegion& mesh, std::string nameOfGeoFile); | ||
363 | /*!< to create the news connectivities between quad9 and 4 quad1 */ | ||
364 | void convertQuad9To4Quad1(std::vector <felInt>& listVertQ1Elem); | ||
365 | //to visualize in ensight normal and tangent std::vector | ||
366 | void writeNormalTangent(const std::string outPutFileVec, const std::vector<Point>& vect); | ||
367 | /*!< write ensight gold geoFile */ | ||
368 | void writerGeoGold(GeometricMeshRegion& mesh, std::string nameOfGeoFile); | ||
369 | /*!< write ensight geoFile from geometricMeshRegion object from processor rank-th*/ | ||
370 | void writerGeo(GeometricMeshRegion& mesh,int rank); | ||
371 | |||
372 | |||
373 | // Post-processing function | ||
374 | /*!< write all output (variable files, case file,...) */ | ||
375 | void postProcess(const std::string& outputDirectory, | ||
376 | const std::string& nameCase, | ||
377 | int optionMultiCase, | ||
378 | double& time); | ||
379 | //Access functions | ||
380 | 110 | inline StringToEns6Pair_type & eltFelNameToEns6Pair() { | |
381 | 110 | return m_eltFelNameToEns6Pair; | |
382 | } | ||
383 | |||
384 | ✗ | inline void setRefToListOfIds(std::map<felInt, std::vector<felInt> > ref2list) { | |
385 | ✗ | m_refToListOfIds = ref2list; | |
386 | } | ||
387 | |||
388 | inline int domainDim() { | ||
389 | return m_domainDim; | ||
390 | } | ||
391 | ✗ | inline EnsightCase& caseInput(){return m_caseInput;} | |
392 | inline EnsightCase& caseOutput(){return m_caseOutput;} | ||
393 | }; | ||
394 | } | ||
395 | |||
396 | #endif | ||
397 |