TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
LireMED.cpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <LireMED.h>
17#include <Domaine.h>
18#include <Param.h>
19#include <EChaine.h>
20#include <med++.h>
21#include <NettoieNoeuds.h>
22#include <SFichier.h>
23#include <TRUSTList.h>
24#include <TRUSTTabs.h>
25#include <TRUSTArrays.h>
26#include <Polygone.h>
27#include <Polyedre.h>
28#include <Scatter.h>
29#include <Synonyme_info.h>
30#include <RegroupeBord.h>
31#include <Char_ptr.h>
32#include <fstream>
33#include <TRUST_2_MED.h>
34
35#ifdef MEDCOUPLING_
36#include <MEDCouplingMemArray.hxx>
37
38using namespace MEDCoupling;
39#endif
40
41// XD lire_med_64 Read_MED lire_med_64 INHERITS_BRACE Did the same thing as Read_MED for big (64b) domain
42
43// XD Read_MED interprete lire_med BRACE Keyword to read MED mesh files where 'domain' corresponds to the domain name,
44// XD_CONT 'file' corresponds to the file (written in the MED format) containing the mesh named mesh_name. NL2 Note
45// XD_CONT about naming boundaries: When reading 'file', TRUST will detect boundaries between domains (Raccord) when the
46// XD_CONT name of the boundary begins by 'type_raccord\_'. For example, a boundary named type_raccord_wall in 'file'
47// XD_CONT will be considered by TRUST as a boundary named 'wall' between two domains. NL2 NB: To read several domains
48// XD_CONT from a mesh issued from a MED file, use Read_Med to read the mesh then use Create_domain_from_sub_domain
49// XD_CONT keyword. NL2 NB: If the MED file contains one or several subdomaine defined as a group of volumes, then
50// XD_CONT Read_MED will read it and will create two files domain_name_ssz.geo and domain_name_ssz_par.geo defining the
51// XD_CONT subdomaines for sequential and/or parallel calculations. These subdomaines will be read in sequential in the
52// XD_CONT datafile by including (after Read_Med keyword) something like: NL2 Read_Med .... NL2 Read_file
53// XD_CONT domain_name_ssz.geo ; NL2 During the parallel calculation, you will include something: NL2 Scatter { ... }
54// XD_CONT NL2 Read_file domain_name_ssz_par.geo ;
55Implemente_instanciable_32_64(LireMED_32_64,"Lire_MED",Interprete_geometrique_base_32_64<_T_>);
56Add_synonym(LireMED,"Read_med");
57Add_synonym(LireMED_64,"Read_med_64");
58
59////
60//// Anonymous namespace for local methods to this translation unit:
61////
62namespace
63{
64
65/*! Retrieve connectivity of a mesh in an ArrOfInt_t, casting when necessary.
66 * If the type sizes match, a simple ref is taken, otherwise a hard copy is done.
67 */
68template <typename _SIZE_>
69void retrieve_connec(const MEDCouplingUMesh* mesh, ArrOfInt_T<_SIZE_>& conn, ArrOfInt_T<_SIZE_>& connIndex)
70{
71 mcIdType nb_it_init = mesh->getNodalConnectivity()->getNbOfElems(),
72 nb_it2_init = mesh->getNodalConnectivityIndex()->getNbOfElems();
73
74 if (nb_it_init >= std::numeric_limits<_SIZE_>::max() || nb_it2_init >= std::numeric_limits<_SIZE_>::max())
75 Process::exit("ERROR! You are trying to build a 32b domain with a mesh which is too big (too many elements). Use Domaine_64 / Lire_MED_64.");
76
77 _SIZE_ nb_it = static_cast<_SIZE_>(nb_it_init),
78 nb_it2= static_cast<_SIZE_>(nb_it2_init);
79
80 const mcIdType *c = mesh->getNodalConnectivity()->begin(),
81 *cI = mesh->getNodalConnectivityIndex()->begin();
82 if (std::is_same<_SIZE_, mcIdType>::value)
83 {
84 // I know, wild cast, discarding const ...:
85 conn.ref_data((_SIZE_ *)c, mesh->getNodalConnectivity()->getNbOfElems());
86 connIndex.ref_data((_SIZE_ *)cI, mesh->getNodalConnectivityIndex()->getNbOfElems());
87 }
88 else // Type mismatch - must hardcopy!
89 {
90 conn.resize(nb_it);
91 std::copy(c, c+nb_it, conn.addr());
92 connIndex.resize(nb_it2);
93 std::copy(cI, cI+nb_it2, connIndex.addr());
94 }
95}
96
97template <typename _SIZE_>
98void verifier_modifier_type_elem(Nom& type_elem,const IntTab_T<_SIZE_>& les_elems,const DoubleTab_T<_SIZE_>& sommets)
99{
100 using int_t = _SIZE_;
101 Nom typ_elem_no64 = type_elem;
102 typ_elem_no64.prefix("_64");
103 bool is64 = type_elem != typ_elem_no64;
104
105 if (typ_elem_no64=="Rectangle" || typ_elem_no64=="Hexaedre")
106 {
107 int dimension=sommets.dimension_int(1);
108 int nb_som_elem=les_elems.dimension_int(1);
109 bool ok=true;
110 ArrOfDouble pos(2);
111 for (int_t elem=0; elem<les_elems.dimension(0) && ok; elem++)
112 {
113 // for each element, check that it has right angles
114 for (int dir=0; dir<dimension && ok; dir++)
115 {
116 // count the number of vertex positions in each direction
117 int n=0;
118 for (int s=0; s<nb_som_elem && ok; s++)
119 {
120 double npos=sommets(les_elems(elem,s),dir);
121 bool trouve=false;
122 for (int i=0; i<n; i++)
123 if (est_egal(npos,pos[i])) trouve=1;
124
125 if (!trouve)
126 {
127 if (n==2)
128 {
129 Cerr<<"There is at least the element "<<elem<<" wich seems to not possess a straight angle"<<finl;
130 ok=false;
131 }
132 else
133 {
134 pos[n]=npos;
135 n++;
136 }
137 }
138 }
139 }
140 }
141 if (!ok)
142 {
143 // change type_elem
144 if (typ_elem_no64=="Rectangle")
145 typ_elem_no64="Quadrangle";
146 else if (typ_elem_no64=="Hexaedre")
147 typ_elem_no64="Hexaedre_vef";
148 }
149 }
150 type_elem = typ_elem_no64 + (is64 ? "_64" : "");
151}
152
153template <typename _SIZE_>
154void recuperer_info_des_joints(Noms& noms_des_joints, const Nom& nom_fic, const Nom& nom_dom,
155 std::vector<ArrOfInt_T<_SIZE_>>& corres_joint, ArrOfInt& tab_pe_voisin)
156{
157#ifdef MEDCOUPLING_
158 using namespace MEDCoupling;
159
160 Cerr << " Reading joint informations ... "<<finl;
161 MCAuto<MEDFileJoints> jnts(MEDFileJoints::New(nom_fic.getChar(), nom_dom.getChar()));
162 int njoint = jnts->getNumberOfJoints();
163 corres_joint.resize(njoint);
164 noms_des_joints.dimensionner(njoint);
165 tab_pe_voisin.resize_array(njoint);
166
167 for (int j=0; j<njoint; j++)
168 {
169 // Reading joint meta-infos
170 const MEDFileJoint *jnt = jnts->getJointAtPos(j);
171 std::string jnam = jnt->getJointName(), desc = jnt->getDescription();
172
173 int num_dom = jnt->getDomainNumber();
174 Cerr << " Joint '" << jnam << "' - dom number: " << num_dom << " - '" << desc << "'" << finl;
175 tab_pe_voisin[j] = num_dom;
176 noms_des_joints[j] = jnam;
177
178 // Multi-steps joints not supported
179 int nsteps = jnt->getNumberOfSteps();
180 if (nsteps > 1) Process::exit("LireMED_32_64/ScatterMED: Multi-step joints not supported!!");
181
182 // Reading vertex/vertex connection
183 const MEDFileJointOneStep* jnt1 = jnt->getStepAtPos(0);
184 int nc = jnt1->getNumberOfCorrespondences();
185 if (nc <= 0) Process::exit("LireMED_32_64/ScatterMED: joint with no correspondance!!");
186 Cerr<<(int)nc <<" connecting vertices " <<finl;
187
188 ArrOfInt_T<_SIZE_>& corres_joint_j = corres_joint[j];
189 corres_joint_j.resize_array(nc);
190
191 for (int c=0; c < nc; c++) // lol C++
192 {
193 const MEDFileJointCorrespondence * corr = jnt1->getCorrespondenceAtPos(c);
194 if (!corr->getIsNodal())
195 {
196 Cerr << " Skipping joint - it is not nodal!" << finl;
197 continue;
198 }
199 const DataArrayIdType *da = corr->getCorrespondence();
200 // TODO check this here
201 if (da->getNumberOfTuples() != 1)
202 Process::exit("WOOOPS ?");
203 const mcIdType *daP = da->begin();
204 corres_joint_j[c] = static_cast<_SIZE_>(daP[1]); // overflow check done before
205 }
206 }
207 Cerr << " Done reading joint informations ... "<<finl;
208#endif
209}
210
211} // end anonymous namespace
212
213template <typename _SIZE_>
214LireMED_32_64<_SIZE_>::LireMED_32_64(const Nom& file_name, const Nom& mesh_name) :
215 nom_fichier_(file_name),
216 nom_mesh_(mesh_name)
217{ }
218
219/*! @brief Simple call to: Interprete::printOn(Sortie&)
220 *
221 * @param (Sortie& os) an output stream
222 * @return (Sortie&) the modified output stream
223 */
224template <typename _SIZE_>
226{
227 return Interprete::printOn(os);
228}
229
230/*! @brief Simple call to: Interprete::readOn(Entree&)
231 *
232 * @param (Entree& is) an input stream
233 * @return (Entree&) the modified input stream
234 */
235template <typename _SIZE_>
237{
238 return Interprete::readOn(is);
239}
240
241template <typename _SIZE_>
243{
244#ifndef MED_
245 med_non_installe();
246#else
247 Nom nom_dom_trio;
248
249 is >> nom_dom_trio;
250 if (nom_dom_trio == "{") // New syntax !!
251 {
252 Nom s = "{ ";
253 int cnt = 1;
254 while (cnt)
255 {
256 Nom motlu;
257 is >> motlu;
258 if (motlu == "{") cnt++;
259 if (motlu == "}") cnt --;
260 s += Nom(" ") + motlu;
261 }
262 Param param(this->que_suis_je());
263 param.ajouter_flag("convertAllToPoly", &convertAllToPoly_); // XD_ADD_P flag
264 // XD_CONT Option to convert mesh with mixed cells into polyhedral/polygonal cells
265
266 param.ajouter("domain|domaine", &nom_dom_trio, Param::REQUIRED); // XD_ADD_P ref_domaine
267 // XD_CONT Corresponds to the domain name.
268 param.ajouter("file|fichier", &nom_fichier_, Param::REQUIRED); // XD_ADD_P chaine
269 // XD_CONT File (written in the MED format, with extension '.med') containing the mesh
270
271 param.ajouter("mesh|maillage", &nom_mesh_); // XD_ADD_P chaine
272 // XD_CONT Name of the mesh in med file. If not specified, the first mesh will be read.
273
274 param.ajouter("exclude_groups|exclure_groupes", &exclude_grps_); // XD_ADD_P listchaine
275 // XD_CONT List of face groups to skip in the MED file.
276 param.ajouter("sub_zones|sous_zones", &restrict_ssz_); // XD_ADD_P listchaine
277 // XD_CONT List of subzones to keep in the MED file and write directly in the .geo
278 param.ajouter("include_additional_face_groups|inclure_groupes_faces_additionnels", &internal_face_grps_); // XD_ADD_P listchaine
279 // XD_CONT List of face groups to read and register in the MED file.
280
281 EChaine is2(s);
282 param.lire_avec_accolades(is2);
283 }
284 else // old syntax ?
285 {
286 Cerr << "ERROR: 'Read_MED': expected opening brace '{' - are you using the new syntax?" << finl;
287 Cerr << "If you are still using the old syntax (before TRUST v1.9.3), \nyou can use -convert_data option of your application script:" << finl;
288 Cerr << " trust -convert_data " << Objet_U::nom_du_cas() << ".data" << finl;
290 }
291
292 // Strip _0000 if there, and create proper file name
293 Nom nom_fic2(nom_fichier_);
294 nom_fic2.prefix(".med");
295 if (nom_fic2==nom_fichier_)
296 {
297 Cerr<<"Error, the MED file should have .med as extension."<<finl;
298 Cerr<<"See the syntax of Read_MED keyword." << finl;
300 }
301 Nom nom_fic3(nom_fic2);
302 if (nom_fic3.prefix("_0000") != nom_fic2 )
303 {
304 nom_fic3+=".med";
305 nom_fichier_=nom_fic3.nom_me(this->me());
306 }
307 this->associer_domaine(nom_dom_trio);
308 lire_geom(true);
309#endif
310
311 return is;
312}
313
314
315/*! @brief Returns the TRUST element type corresponding to the given MEDCoupling type:
316 * http://docs.salome-platform.org/6/gui/MED/MEDLoader_8cxx.html
317 */
318#ifdef MEDCOUPLING_
319template <typename _SIZE_>
320Nom LireMED_32_64<_SIZE_>::type_medcoupling_to_type_geo_trio(int type_cell, bool cell_from_boundary) const
321{
322 Nom type_elem;
323 // [ABN] : first make sure the axis type is properly set, this will influence choice of the element
324 // Set up correctly bidim_axi or axi variable according to MED file data.
325 if (axis_type_==MEDCoupling::AX_CYL)
326 {
327 if (type_cell==INTERP_KERNEL::NORM_QUAD4)
328 {
329 if (!Objet_U::axi)
330 {
331 Cerr<<"WARNING, Cylindrical MED coordinates detected - we will use 'axi' keyword."<<finl;
332 Objet_U::axi=1;
333 }
334 }
335 else
336 {
337 Cerr << "Strange error with MED file - should never happen!? MED file with axis type AX_CYL contains elements other than NORM_QUAD4."<< finl;
339 }
340 }
341 if (axis_type_==MEDCoupling::AX_SPHER)
342 {
343 Cerr << "Spherical coordinates read in the MED file - this is unsupported in TRUST!" << finl;
345 }
346
347 //
348 // At this stage 'axi' and 'bidim_axi' are properly set.
349 //
350 if (type_cell==INTERP_KERNEL::NORM_QUAD4)
351 type_elem = cell_from_boundary ? "QUADRANGLE_3D" : (isVEFForce_ ? "Quadrangle" : "Rectangle");
352 else if (type_cell==INTERP_KERNEL::NORM_HEXA8)
353 type_elem=(isVEFForce_ ? "Hexaedre_vef" : "Hexaedre");
354 else if (type_cell==INTERP_KERNEL::NORM_TRI3)
355 type_elem= cell_from_boundary ? "TRIANGLE_3D" : "Triangle";
356 else if (type_cell==INTERP_KERNEL::NORM_TETRA4)
357 type_elem="Tetraedre";
358 else if (type_cell==INTERP_KERNEL::NORM_SEG2)
359 type_elem= cell_from_boundary ? "SEGMENT_2D" : "Segment";
360 else if (type_cell==INTERP_KERNEL::NORM_PENTA6)
361 type_elem="Prisme";
362 else if (type_cell==INTERP_KERNEL::NORM_POLYHED)
363 type_elem="Polyedre";
364 else if (type_cell==INTERP_KERNEL::NORM_PYRA5)
365 type_elem="Pyramide";
366 else if (type_cell==INTERP_KERNEL::NORM_POLYGON)
367 type_elem= cell_from_boundary ? "POLYGONE_3D" : "Polygone";
368 else if(type_cell==INTERP_KERNEL::NORM_HEXGP12)
369 type_elem = "Prisme_hexag";
370 else if(type_cell==INTERP_KERNEL::NORM_POINT1)
371 type_elem = cell_from_boundary ? "POINT_1D" : "Point_1d";
372 else
373 {
374 Cerr<<"Cell type " << type_cell<< " is not supported yet." <<finl;
376 }
377 if(Objet_U::bidim_axi && !(type_cell == INTERP_KERNEL::NORM_QUAD4 || type_cell == INTERP_KERNEL::NORM_SEG2 || type_cell == INTERP_KERNEL::NORM_POLYGON))
378 {
379 Cerr<<"Cell type " << type_cell<< " is not supported for 'bidim_axi' mode." <<finl;
381 }
382 if (Objet_U::axi && !(type_cell == INTERP_KERNEL::NORM_HEXA8 || type_cell == INTERP_KERNEL::NORM_QUAD4))
383 {
384 Cerr<<"Cell type " << type_cell<< " is not supported for 'axi' mode." <<finl;
386 }
387 if (axi1d_ && !(type_cell == INTERP_KERNEL::NORM_SEG2 || type_cell == INTERP_KERNEL::NORM_POINT1))
388 {
389 Cerr<<"Cell type " << type_cell<< " is not supported for 'axi1d' mode." <<finl;
391 }
392 if (Objet_U::bidim_axi && type_cell == INTERP_KERNEL::NORM_QUAD4)
393 type_elem = "Rectangle_2D_axi";
394 if (Objet_U::bidim_axi && type_cell == INTERP_KERNEL::NORM_SEG2)
395 type_elem = "quadrilatere_2D_axi";
396 if (Objet_U::axi)
397 type_elem += "_axi";
398
399 if (axi1d_)
400 type_elem += "_axi";
401 return type_elem;
402}
403#endif
404
405
406/*! @brief Load the mesh from the MED file as a MEDCouplingUMesh, and name it as the domain.
407 */
408#ifdef MEDCOUPLING_
409
410template <typename _SIZE_>
412{
413 std::string fileName = nom_fichier_.getString();
414 std::string meshName = nom_mesh_.getString();
415
416 // Check the mesh name is in the file:
417 //const MCAuto<MEDFileMeshes> data(MEDFileMeshes::New(fileName));
418 std::vector< std::string > meshes_names = MEDCoupling::GetMeshNames(fileName) ;
419 if (std::find(meshes_names.begin(), meshes_names.end(), meshName) == meshes_names.end())
420 {
421 if (meshName == "--any--" && meshes_names.size()==1) meshName = meshes_names[0]; //magic name -> we take the first mesh
422 else
423 {
424 if (meshName == "--any--")
425 Cerr << "You need to specify the mesh name for the med file " << nom_fichier_ << " !" << finl;
426 else
427 Cerr << "Mesh " << nom_mesh_ << " not found in the med file " << nom_fichier_ << " !" << finl;
428 Cerr << "List of meshes found:" << finl;
429 for(unsigned int i = 0; i<meshes_names.size(); i++)
430 Cerr << meshes_names[i] << finl;
431 Process::exit(-1);
432 }
433 }
434
435 mfumesh_ = MEDFileUMesh::New(fileName, meshName);
436 // Name it correctly here so that all extracted MEDCouplingUMesh will be correctly named:
437 mfumesh_->setName( this->domaine().le_nom().getChar());
438
439 axis_type_ = mfumesh_->getAxisType();
440 // Some checks:
441 std::vector<int> nel = mfumesh_->getNonEmptyLevels();
442 assert(nel[0] == 0);
443 // Get the volume mesh:
444 mcumesh_ = mfumesh_->getMeshAtLevel(nel[0]); // ToDo can not make it const because of ArrOfInt
445 space_dim_ = mcumesh_->getSpaceDimension();
446 Cerr << "Detecting a " << (int)mcumesh_->getMeshDimension() << "D mesh in " << space_dim_ << "D space." << finl;
447 if (space_dim_ != Objet_U::dimension)
448 {
449 Cerr << "The mesh space dimension may be higher than the computation space dimension" << finl;
450 Cerr << "as the algorithm will try to detect the useless direction in the mesh." << finl;
451 //assert(dim == dimension);
452 }
453
454 // This option now allows converting any mesh type to polyhedra:
455 if (convertAllToPoly_)
456 {
457 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
458 Cerr << "Conversion to polyedrons and polygons..." << finl;
459 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
460 mcumesh_->convertAllToPoly(); // Convert volume mesh
461 }
462}
463
464#endif
465
466
467/*! Fills in coords and connectivity array from the MC data.
468 */
469#ifdef MEDCOUPLING_
470template <typename _SIZE_>
471void LireMED_32_64<_SIZE_>::prepare_som_and_elem(DoubleTab_t& sommets2, IntTab_t& les_elems2)
472{
473 using Polygone_t = Polygone_32_64<_SIZE_>;
474 using Polyedre_t = Polyedre_32_64<_SIZE_>;
475
476 // Get the nodes: size and fill sommets2:
477 mcIdType nnodes0 = mcumesh_->getNumberOfNodes();
478 if (nnodes0 >= std::numeric_limits<_SIZE_>::max())
479 Process::exit("ERROR! You are trying to build a 32b domain with a mesh which is too big (too many nodes). Use Domaine_64.");
480 int_t nnodes = static_cast<int_t>(nnodes0);
481
482 const double *coord = mcumesh_->getCoords()->begin();
483 Cerr << "Detecting " << nnodes << " nodes." << finl;
484 sommets2.resize(nnodes, space_dim_);
485 std::copy(coord, coord+sommets2.size_array(), sommets2.addr());
486
487 // Get cell connectivity
488 mcIdType ncells0 = mcumesh_->getNumberOfCells();
489 if (ncells0 >= std::numeric_limits<_SIZE_>::max())
490 Process::exit("ERROR! You are trying to build a 32b domain with a mesh which is too big (too many elements). Use Domaine_64.");
491 int_t ncells = static_cast<int_t>(ncells0);
492
493 // Use ArrOfInt to benefit from assert:
494 ArrOfInt_t conn, connIndex;
495 ::retrieve_connec(mcumesh_, conn, connIndex);
496
497 int mesh_type_cell = static_cast<int>(conn[connIndex[0]]); // type is always an int.
498 Nom type_elem_n = type_medcoupling_to_type_geo_trio(mesh_type_cell, false);
499 if (!std::is_same<_SIZE_,int>::value)
500 type_elem_n += "_64";
501 type_elem_.typer(type_elem_n);
502 auto set_of_typs = mcumesh_->getAllGeoTypes();
503 if (set_of_typs.size() > 1)
504 {
505 Cerr << "Elements of kind " << type_elem_n << " have already been read" << finl;
506 Cerr << "New elements type(s) found!!" << finl;
507 if (!convertAllToPoly_)
508 {
509 Cerr << "TRUST does not support different element types for the mesh." << finl;
510 Cerr << "Either you remesh your domain with a single element type," << finl;
511 Cerr << "or convert your cells to polyedrons and polygons by inserting an option in your command line:" << finl;
512 Cerr << " Read_MED { ... convertAllToPoly ... } " << finl;
513 Cerr << "After that, you should use a discretization supporting polyedrons!" << finl;
515 }
516 }
517
518 // Fill les_elem2 : Different treatment according type_elem:
519 if (sub_type(Polyedre_t, type_elem_.valeur()))
520 {
521 int_t marker = 0;
522 int_t conn_size = static_cast<int_t>(mcumesh_->getNodalConnectivity()->getNbOfElems()); // Overflow check done before
523 for (int_t i = 0; i < conn_size; i++)
524 if (conn[i]<0) marker++;
525 int_t num_nodes = conn_size - ncells - marker;
526 int_t nfaces = ncells + marker;
527 ArrOfInt_t nodes(num_nodes), facesIndex(nfaces+1), polyhedronIndex(ncells+1);
528 int_t face=0, node = 0;
529 for (int_t i = 0; i < ncells; i++)
530 {
531 polyhedronIndex[i] = face; // Polyhedron index
532
533 int_t index = connIndex[i] + 1;
534 int nb_som = static_cast<int>(connIndex[i + 1] - index);
535 for (int j = 0; j < nb_som; j++)
536 {
537 if (j==0 || conn[index + j]<0)
538 facesIndex[face++] = node; // Face index
539 if (conn[index + j]>=0)
540 nodes[node++] = conn[index + j]; // Local index of face vertices
541 }
542 }
543 facesIndex[nfaces] = node;
544 polyhedronIndex[ncells] = face;
545 ref_cast(Polyedre_t,type_elem_.valeur()).affecte_connectivite_numero_global(nodes, facesIndex, polyhedronIndex, les_elems2);
546 }
547 else if (sub_type(Polygone_t, type_elem_.valeur()))
548 {
549 int_t conn_size = static_cast<int_t>(mcumesh_->getNodalConnectivity()->getNbOfElems()); // Overflow check done before
550 int_t facesIndexSize = conn_size - ncells;
551 ArrOfInt_t facesIndex(facesIndexSize), polygonIndex(ncells+1);
552 int_t face=0;
553 for (int_t i = 0; i < ncells; i++)
554 {
555 polygonIndex[i] = face; // Polygon index
556
557 int_t index = connIndex[i] + 1;
558 int nb_som = static_cast<int>(connIndex[i + 1] - index);
559 for (int j = 0; j < nb_som; j++)
560 facesIndex[face++] = conn[index + j];
561 }
562 polygonIndex[ncells] = face;
563 ref_cast(Polygone_t,type_elem_.valeur()).affecte_connectivite_numero_global(facesIndex, polygonIndex, les_elems2);
564 }
565 else // All other types
566 {
567 for (int_t i = 0; i < ncells; i++)
568 {
569 int_t index = connIndex[i] + 1;
570 int nb_som = static_cast<int>(connIndex[i + 1] - index);
571 if (i==0) les_elems2.resize(ncells, nb_som); // Size les_elems2
572 for (int j = 0; j < nb_som; j++)
573 les_elems2(i, j) = conn[index + j];
574 }
575 }
576}
577#endif
578
579/*! @brief Fills in sommets in the Domaine, potentially reducing the dimension (flat 3D -> 2D)
580 * by discarding a useless dimension (a flat 2D surface in a 3D space dim for example)
581 * TODO Fixme Adrien : rewrite this in MC style : buildUnique etc ...
582 */
583template <typename _SIZE_>
585{
586 // assign the vertices
588 {
589 Cerr << "One tries to read a meshing written in " << space_dim_ << "D in " << Objet_U::dimension << "D " << finl;
590 // determine the useless direction
591 int_t nbsom=sommets2.dimension(0);
592 int dirinut=-1;
593 const double epsilon = Objet_U::precision_geom;
594 for (int dir=0; dir<space_dim_; dir++)
595 {
596 bool trouve=true;
597 double val1=sommets2(0,dir);
598 for (int_t i=0; i<nbsom; i++)
599 if (std::abs(val1-sommets2(i,dir))>epsilon)
600 {
601 trouve=false;
602 Cerr<<val1 << " "<<sommets2(i,dir)<<finl;
603 break;
604 }
605 if (trouve)
606 {
607 dirinut=dir;
608 break;
609 }
610 }
611 if (dirinut==-1)
612 {
613 Cerr<<"No useless direction "<<finl;
615 }
616 Cerr<<"useless direction "<<dirinut<<finl<<finl;
617
618 sommets.resize(nbsom,Objet_U::dimension);
619 int d=0;
620 for (int dir=0; dir<space_dim_; dir++)
621 if (dir!=dirinut)
622 {
623 for (int_t i=0; i<nbsom; i++)
624 sommets(i,d)=sommets2(i,dir);
625 d++;
626 }
627 }
628 else
629 sommets=sommets2;
630}
631
632/* @brief Write datasets for sub-domains (built from MED element groups) into dedicated files.
633 */
634template <typename _SIZE_>
636{
637#ifdef MEDCOUPLING_
638
639 unsigned nb_volume_groups = (unsigned)mfumesh_->getGroupsOnSpecifiedLev(0).size();
640 if (nb_volume_groups>0 && Process::je_suis_maitre())
641 {
642 Nom nom_dom_trio = this->domaine().le_nom();
643 SFichier jdd_seq(nom_dom_trio + "_ssz.geo");
644 SFichier jdd_par(nom_dom_trio + "_ssz_par.geo");
645 std::vector<std::string> groups;
646 if (restrict_ssz_.size()>0)
647 {
648 for (const auto& name : restrict_ssz_)
649 groups.push_back(name.getString());
650 }
651 else
652 {
653 Cerr << "Reading groups at level 0:" << finl;
654 groups = mfumesh_->getGroupsOnSpecifiedLev(0);
655 }
656
657 for (const auto& gnam: groups)
658 {
659 MCAuto<DataArrayIdType> ids(mfumesh_->getGroupArr(0, gnam, false));
660 const mcIdType *idP = ids->getConstPointer();
661 mcIdType nb_elems0 = ids->getNbOfElems();
662 if (nb_elems0 >= std::numeric_limits<_SIZE_>::max())
663 Process::exit("ERROR! You are trying to build a 32b domain with a mesh which is too big (too many nodes). Use Domaine_64.");
664 mcIdType nb_elems = static_cast<int_t>(nb_elems0);
665
666 const Nom& nom_sous_domaine = gnam; // We take the name of the group for the subzone name
667 Cerr << "Detecting a sub-zone (group name="<< nom_sous_domaine << ") with " << nb_elems << " cells." << finl;
668
669 if (nb_elems == 0) continue;
670
671 Nom file_ssz(nom_dom_trio);
672 file_ssz += "_";
673 file_ssz += nom_sous_domaine;
674 file_ssz += Nom(".file");
675 jdd_seq << "export Sous_Domaine " << nom_sous_domaine << finl;
676 jdd_par << "export Sous_Domaine " << nom_sous_domaine << finl;
677
678 jdd_seq << "Associer " << nom_sous_domaine << " " << nom_dom_trio << finl;
679 jdd_par << "Associer " << nom_sous_domaine << " " << nom_dom_trio << finl;
680 if (restrict_ssz_.size())
681 {
682 // Sequential only:
683 jdd_seq << "Lire " << nom_sous_domaine << " { liste " << nb_elems;
684 for (int_t j = 0; j < nb_elems; j++) jdd_seq << " " << (int) idP[j];
685 jdd_seq << " }" << finl;
686 }
687 else
688 {
689 jdd_seq << "Lire " << nom_sous_domaine << " { fichier " << file_ssz << " }" << finl;
690 jdd_par << "Lire " << nom_sous_domaine << " { fichier " << nom_sous_domaine << ".ssz" << " }" << finl;
691 SFichier f_ssz(file_ssz);
692 f_ssz << nb_elems << finl;
693 for (int_t j = 0; j < nb_elems; j++)
694 f_ssz << (int) idP[j] << " ";
695 f_ssz << finl;
696 }
697 }
698 }
699#endif
700}
701
702/*! @brief Handles the boundaries found in the MED file.
703 *
704 * Get the -1 level mesh, and extract boundaries by reading element groups on this mesh.
705 */
706template <typename _SIZE_>
708{
709#ifdef MEDCOUPLING_
710
711 constexpr bool CELL_FROM_BOUNDARY = true;
712
713 // Get boundary mesh:
714 MCAuto<MEDCouplingUMesh> face_mesh(mfumesh_->getMeshAtLevel(-1)); // ToDo can not make it const because of ArrayOfInt
715 if (Objet_U::dimension==3 && convertAllToPoly_) // In 2D this will be segments anyway
716 face_mesh->convertAllToPoly(); // Convert boundary mesh
717 int_t nfaces = static_cast<int_t>(face_mesh->getNumberOfCells()); // overflow check done in prepare_som_and_elem()
718
719 // Retrieve connectivity - Use ArrOfInt to benefit from assert:
720 ArrOfInt_t conn, connIndex;
721 ::retrieve_connec(face_mesh, conn, connIndex);
722 DataArrayIdType *cI = face_mesh->getNodalConnectivityIndex();
723
724 // Read type from the first face, and check unique type
725 int typ = static_cast<int>(conn[connIndex[0]]); // type is always int
726 type_face_ = type_medcoupling_to_type_geo_trio(typ, CELL_FROM_BOUNDARY);
727 if (type_elem_->nb_type_face() != 1) // should never happen, all is polygon normally.
728 Process::exit("Read_MED: unsupported mesh element type! It has more than a single face type (for example a prism can have triangles or quadrangles as boundary faces).");
729 // Check unique type
730 auto set_of_typs = face_mesh->getAllGeoTypes();
731 if (set_of_typs.size() > 1) // same as a above, should never happen
732 Process::exit("Read_MED: invalid boundary mesh! More than a single face type.");
733
734 // Get max number of vertices per face - in a dedicated scope to destroy dsi quickly
735 int max_som_face;
736 {
737 MCAuto<DataArrayIdType> dsi = cI->deltaShiftIndex();
738 max_som_face = static_cast<int>(dsi->getMaxValueInArray() - 1); // -1 because first slot in connectivity descr is for type
739 }
740
741 // Filling face connectivity:
742 Cerr << "Detecting " << nfaces << " faces (" << type_face_ << ")." << finl;
743 all_faces_bords.resize(nfaces, max_som_face);
744 all_faces_bords = -1;
745 fac_grp_id.resize_array(nfaces);
746 for (int_t i = 0; i < nfaces; i++)
747 {
748 int_t index = connIndex[i] + 1; // +1 to skip MEDCoupling type
749 int nb_som = static_cast<int>(connIndex[i + 1] - index);
750 for (int j = 0; j < nb_som; j++)
751 all_faces_bords(i, j) = conn[index + j] ;
752 }
753
754 Cerr << "Reading groups at level -1:" << finl;
755 auto grp_names = mfumesh_->getGroupsOnSpecifiedLev(-1);
756 int zeid = 0;
757 std::set<mcIdType> id_check;
758 for (const auto& gnam: grp_names)
759 {
760 if (exclude_grps_.search(Nom(gnam)) != -1)
761 {
762 Cerr << " group '" << gnam << "' is skipped, as requested." << finl;
763 continue;
764 }
765 noms_bords_.add(gnam);
766 MCAuto<DataArrayIdType> ids(mfumesh_->getGroupArr(-1, gnam, false));
767 long bef = (long)id_check.size(), nb_faces = (long)ids->getNumberOfTuples();
768 id_check.insert(ids->begin(), ids->begin()+nb_faces);
769 if ((long)id_check.size() - bef < nb_faces)
770 {
771 Cerr << "ERROR: group '" << gnam << "' contains faces which are also in one of the previously read groups." << finl;
772 Cerr << " Fix your mesh, or use the 'exclude_groups' option to prevent reading of this group." << finl;
773 Process::exit(-1);
774 }
775 Cerr << " group_name=" << gnam << " with " << nb_faces << " faces" << finl;
776 for(const auto& id: *ids)
777 {
778 int_t id2 = static_cast<int_t>(id);
779 fac_grp_id[id2] = zeid+1;
780 }
781 zeid++;
782 }
783
784 if (noms_bords_.size()==0)
785 {
786 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
787 Cerr << "Lire_MED: Warning: no boundary detected for the mesh." << finl;
788 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
789 }
790#endif
791}
792
793/*! @brief Fills in all the information relative to Joints, Raccords and Frontiere
794 */
795template <typename _SIZE_>
796void LireMED_32_64<_SIZE_>::fill_frontieres(const BigArrOfInt_& fac_grp_id, const IntTab_t& all_faces_bords)
797{
798 using SmallArrOfTID_t = SmallArrOfTID_T<_SIZE_>;
799
800 using Bord_t = Bord_32_64<_SIZE_>;
801 using Bords_t = Bords_32_64<_SIZE_>;
802 using Groupe_Faces_t = Groupe_Faces_32_64<_SIZE_>;
803 using Groupes_Faces_t = Groupes_Faces_32_64<_SIZE_>;
804 using Frontiere_t = Frontiere_32_64<_SIZE_>;
805 using Raccord_t = OWN_PTR(Raccord_base_32_64<_SIZE_>);
806 using Raccords_t = Raccords_32_64<_SIZE_>;
807 using Joint_t = Joint_32_64<_SIZE_>;
808 using Joints_t = Joints_32_64<_SIZE_>;
809 using Faces_t = Faces_32_64<_SIZE_>;
810
811 Domaine_t& dom = this->domaine();
812 std::vector<ArrOfInt_t> sommets_joints;
813 ArrOfInt tab_pe_voisin;
814
815 int nbord = noms_bords_.size();
816 SmallArrOfTID_t nb_face_per_bord(nbord);
817 Bords_t& faces_bord=dom.faces_bord();
818 faces_bord.vide();
819 Groupes_Faces_t& goupes_faces=dom.groupes_faces();
820 goupes_faces.vide();
821 Raccords_t& faces_raccord=dom.faces_raccord();
822 faces_raccord.vide();
823 Joints_t& faces_joint=dom.faces_joint();
824 faces_joint.vide();
825
826 Noms noms_des_joints;
827 recuperer_info_des_joints(noms_des_joints,nom_fichier_,nom_mesh_,sommets_joints,tab_pe_voisin);
828
829 int_t nfacebord=all_faces_bords.dimension(0);
830 for (int ib=nbord-1; ib>-1; ib--)
831 {
832 int indice_bord=ib+1;
833 if (noms_bords_[ib]=="elems") continue;
834 Bord_t bordprov_;
835 Groupe_Faces_t facesgrpprov;
836 Raccord_t raccprov;
837 Joint_t jointprov;
838 bool israccord=false, isjoint=false, isfacesint=false;
839 if (noms_bords_[ib].debute_par("type_raccord_"))
840 {
841 israccord=true;
842 noms_bords_[ib].suffix("type_raccord_");
843 raccprov.typer("Raccord_local_homogene");
844 }
845 if (internal_face_grps_.search(noms_bords_[ib]) != -1)
846 isfacesint=true;
847
848 int numero_joint=noms_des_joints.search(noms_bords_[ib]);
849 if (numero_joint>-1)
850 {
851 Cerr<<noms_bords_[ib]<<" is considered as a joint "<<finl;
852 isjoint=true;
853 }
854 // retrieve the boundary, whether it is a Bord, Raccord, or Joint
855 Frontiere_t& bordprov = (isjoint?jointprov:(israccord?ref_cast(Frontiere_t,raccprov.valeur()):(isfacesint?ref_cast(Frontiere_t,facesgrpprov):ref_cast(Frontiere_t,bordprov_))));
856
857 bordprov.nommer(noms_bords_[ib]);
858 bordprov.typer_faces(type_face_);
859 int_t nb_face_this_bord=0;
860 int nsomfa=all_faces_bords.dimension_int(1);
861 IntTab_t sommprov(nfacebord,nsomfa);
862 for (int_t j=0; j<nfacebord; j++)
863 {
864 if (fac_grp_id[j]==indice_bord)
865 {
866 for (int k=0; k<nsomfa; k++)
867 sommprov(nb_face_this_bord,k)=all_faces_bords(j,k);
868 nb_face_this_bord++;
869 }
870 }
871 Faces_t& facesi=bordprov.faces();
872 IntTab_t& sommetsfaces=facesi.les_sommets();
873 sommetsfaces.resize(nb_face_this_bord,nsomfa);
874 for (int_t jj=0; jj<nb_face_this_bord; jj++)
875 for (int k=0; k<nsomfa; k++)
876 sommetsfaces(jj,k)=sommprov(jj,k);
877 IntTab_t& facesv=facesi.voisins();
878 facesv.resize(nb_face_this_bord,2);
879 facesv=-1;
880
881 bool vide_0D_a_ecrire=false;
882 if (nb_face_this_bord == 0)
883 {
884 bordprov.typer_faces("vide_0D");
885 vide_0D_a_ecrire = true;
886 }
887 nb_face_per_bord[ib] = nb_face_this_bord;
888 // does not work when adding the elem family
889 if (indice_bord != 0
890 && (nb_face_this_bord>0 || vide_0D_a_ecrire))
891 {
892 if (isjoint)
893 {
894 int PE_voisin=tab_pe_voisin[numero_joint];
895 int epaisseur=1;
896 ArrOfInt_t& sommets_joint=sommets_joints[numero_joint];
897 jointprov.affecte_PEvoisin(PE_voisin);
898 jointprov.affecte_epaisseur(epaisseur);
899 ArrOfInt_t& sommets_du_joint=jointprov.set_joint_item(JOINT_ITEM::SOMMET).set_items_communs();
900 sommets_du_joint=sommets_joint;
901 faces_joint.add(jointprov);
902 }
903 else if (israccord)
904 faces_raccord.add(raccprov);
905 else if (isfacesint)
906 goupes_faces.add(facesgrpprov);
907 else
908 faces_bord.add(bordprov_);
909 }
910 }
911 faces_bord.associer_domaine(dom);
912 faces_raccord.associer_domaine(dom);
913 faces_joint.associer_domaine(dom);
914 goupes_faces.associer_domaine(dom);
916 int nbfr=dom.nb_front_Cl();
917 for (int fr=0; fr<nbfr; fr++)
918 {
919 dom.frontiere(fr).faces().associer_domaine(dom);
920 if (dom.frontiere(fr).faces().type_face() != Type_Face::vide_0D)
921 dom.frontiere(fr).faces().reordonner();
922 }
923}
924
925template <typename _SIZE_>
927{
928#ifndef MED_
929 med_non_installe();
930#else
931#ifdef MEDCOUPLING_
932 Domaine_t& dom = this->domaine();
933 const Nom& nom_dom_trio = dom.le_nom();
934
935 axi1d_ = dom.axi1d();
936 // sanity check
937 if (Objet_U::dimension==0)
938 {
939 Cerr << "Dimension is not defined. Check your data file." << finl;
941 }
942 Cerr << "Trying to read the mesh " << nom_mesh_ << " from the file " << nom_fichier_ << " in order to affect to domain "
943 << nom_dom_trio << "..." << finl;
944
946
947 // Reading vertices and element descriptions:
948 DoubleTab_t sommets2;
949 IntTab_t les_elems2;
950 prepare_som_and_elem(sommets2, les_elems2);
951
952 // Detect and export sub-domains (based on group of volumes);
953 if (subDom)
955
956 // Detect boundary meshes:
957 BigArrOfInt_ fac_grp_id;
958 IntTab_t all_faces_bords;
959 std::vector<int> nel = mfumesh_->getNonEmptyLevels();
960 if (nel.size() > 1)
961 {
962 assert(nel[1] == -1);
963 read_boundaries(fac_grp_id, all_faces_bords);
964 }
965
966 // Converting from MED to TRUST connectivity
967 Nom type_elem_n = type_elem_->que_suis_je(); // prepare_som_and_elem() has performed the 'typer' operation on type_elem_
968 conn_trust_to_med(les_elems2,type_elem_n,false);
969 conn_trust_to_med(all_faces_bords,type_face_,false);
970
972
973 DoubleTab_t& sommets=dom.les_sommets();
974 finalize_sommets(sommets2, sommets);
975
976 // Type and fill domain elements
977 // Before typing, check whether hexahedra need to be converted to Hexa_vef
978 Nom type_elem_orig = type_elem_n;
979 verifier_modifier_type_elem(type_elem_n,les_elems2,sommets);
980
981 dom.type_elem() = type_elem_;
982 // if type_elem was modified
983 if (type_elem_orig != type_elem_n)
984 dom.typer(type_elem_n);
985 dom.type_elem()->associer_domaine(dom);
986 dom.les_elems() = les_elems2;
987
988 fill_frontieres(fac_grp_id, all_faces_bords);
989
990 // Fix connectivity to be compliant with TRUST connectivity conventions
991 // (see doc of Hexaedre/Rectangle for example)
992 if (type_elem_n == "Rectangle" || type_elem_n == "Hexaedre" || type_elem_n == "Rectangle_64" || type_elem_n == "Hexaedre_64"
993 || sub_type(Polyedre_32_64<_SIZE_>,dom.type_elem().valeur()))
994 dom.reordonner();
995
996 if (Process::nproc()==1)
997 {
998 Cerr << " Lire_MED called in sequential => applying NettoieNoeuds" << finl;
1000 }
1001
1003
1004 // MCUMesh object will be rebuilt next time it is retreived:
1005 dom.set_mc_mesh_ready(false);
1006
1007 Cerr<<"Reading of the MED domain ended."<<finl;
1008#endif // MEDCOUPLING_
1009#endif // MED_
1010}
1011
1012
1013template class LireMED_32_64<int>;
1014#if INT_is_64_ == 2
1015template class LireMED_32_64<trustIdType>;
1016#endif
1017
1018
Class Bord This class represents a boundary of a domain, it is a type of frontier.
Definition Bord.h:31
Class Bords This class represents a list of objects of type Bord.
Definition Bords.h:28
int nb_front_Cl() const
Definition Domaine.h:236
DoubleTab_t & les_sommets()
Definition Domaine.h:113
void set_mc_mesh_ready(bool flag) const
Definition Domaine.h:357
Bords_t & faces_bord()
Definition Domaine.h:198
const Frontiere_t & frontiere(int i) const
Definition Domaine.h:539
Raccords_t & faces_raccord()
Definition Domaine.h:253
IntTab_t & les_elems()
Definition Domaine.h:129
void fixer_premieres_faces_frontiere()
Definition Domaine.cpp:1101
void typer(const Nom &)
Sets the element type of the domain using the name passed as parameter.
Definition Domaine.h:457
Joints_t & faces_joint()
Definition Domaine.h:265
Groupes_Faces_t & groupes_faces()
Definition Domaine.h:224
void reordonner()
Definition Domaine.h:104
bool axi1d() const
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
An input stream whose source is a character string.
Definition EChaine.h:31
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Class Faces Faces describes a set of faces by their type (point, segment, triangle or quadrangle),...
Definition Faces.h:50
void associer_domaine(const Domaine_t &z)
Definition Faces.h:94
void reordonner()
Reorders the faces.
Definition Faces.cpp:881
Type_Face type_face() const
Definition Faces.h:65
Class Frontiere.
Definition Frontiere.h:32
const Faces_t & faces() const
Definition Frontiere.h:54
Groupe_Face class — represents a selection of faces read from a med file.
Groupes_Faces class — represents a list of Groupe_Faces objects.
Class Interprete_geometrique_base.
The Joint class is a Frontiere that contains the joint faces and vertices with the neighboring domain...
Definition Joint.h:34
Joints class — represents a list of Joint objects.
Definition Joints.h:28
void lire_geom(bool subDom=true)
Definition LireMED.cpp:926
Nom nom_fichier_
Name of the MED file to read.
Definition LireMED.h:66
Nom nom_mesh_
Name of the mesh in the MED file to read.
Definition LireMED.h:67
void fill_frontieres(const BigArrOfInt_ &familles, const IntTab_t &all_faces_bords)
Fills in all the information relative to Joints, Raccords and Frontiere.
Definition LireMED.cpp:796
Noms restrict_ssz_
Names of the subzones to keep only in the .geo file.
Definition LireMED.h:76
void finalize_sommets(const DoubleTab_t &sommets2, DoubleTab_t &sommets) const
Returns the TRUST element type corresponding to the given MEDCoupling type: http://docs....
Definition LireMED.cpp:584
void read_boundaries(BigArrOfInt_ &familles, IntTab_t &all_faces_bords)
Handles the boundaries found in the MED file.
Definition LireMED.cpp:707
Entree & interpreter_(Entree &) override
Definition LireMED.cpp:242
Nom type_medcoupling_to_type_geo_trio(int type_cell, bool cell_from_boundary) const
Elem_geom_t type_elem_
Highest dimension element type.
Definition LireMED.h:72
Nom type_face_
Boundary element type.
Definition LireMED.h:73
Domaine_32_64< _SIZE_ > Domaine_t
Definition LireMED.h:49
TRUSTArray< int, _SIZE_ > BigArrOfInt_
Definition LireMED.h:45
void write_sub_dom_datasets() const
Definition LireMED.cpp:635
int space_dim_
Space dimension read in the MED file.
Definition LireMED.h:71
ArrOfInt_T< _SIZE_ > ArrOfInt_t
Definition LireMED.h:43
IntTab_T< _SIZE_ > IntTab_t
Definition LireMED.h:44
void prepare_som_and_elem(DoubleTab_t &sommets, IntTab_t &les_elems)
LireMED_32_64(const Nom &file_name, const Nom &mesh_name)
Definition LireMED.cpp:214
Noms noms_bords_
Names of the boundaries.
Definition LireMED.h:74
Noms exclude_grps_
Names of the (face) groups to skip when reading the file.
Definition LireMED.h:75
bool axi1d_
Are we in Axi1D.
Definition LireMED.h:68
_SIZE_ int_t
Definition LireMED.h:42
void retrieve_MC_objects()
DoubleTab_T< _SIZE_ > DoubleTab_t
Definition LireMED.h:46
bool convertAllToPoly_
Should the mesh be converted to polygons/polyedrons.
Definition LireMED.h:69
Noms internal_face_grps_
Names of the internals face groups to read in the file.
Definition LireMED.h:77
static void nettoie(Domaine_t &)
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
const char * getChar() const
Definition Nom.h:91
Nom nom_me(int, const char *prefix=0, int without_padding=0) const
Inserts _prefix000n (n=me() or nproc()) into a file name (e.g. toto.titi) to produce toto_prefix000n....
Definition Nom.cpp:380
Nom & prefix(const char *const)
Definition Nom.cpp:324
const std::string & getString() const
Definition Nom.h:92
An array of character strings (VECT(Nom)).
Definition Noms.h:26
int search(const Nom &t) const
Definition Noms.cpp:39
friend class Entree
Definition Objet_U.h:71
static int dimension
Definition Objet_U.h:94
const Nom & que_suis_je() const
Returns the string identifying the class.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
static double precision_geom
Definition Objet_U.h:81
static const Nom & nom_du_cas()
Returns a constant reference to the case name. This method is static.
Definition Objet_U.cpp:145
static int bidim_axi
Definition Objet_U.h:97
static int axi
Definition Objet_U.h:96
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
Helper class to factorize the readOn method of Objet_U classes.
Definition Param.h:112
void ajouter_flag(const char *keyword, const bool *value)
Register a boolean flag whose mere presence switches it to true.
Definition Param.cpp:474
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
Definition Param.cpp:364
@ REQUIRED
Definition Param.h:115
int lire_avec_accolades(Entree &is)
Alias of lire_avec_accolades_depuis.
Definition Param.h:577
Class Polyedre: represents the Polyedre geometric element.
Definition Polyedre.h:29
Class Polygone represents the geometric element Polygone.
Definition Polygone.h:29
static int nproc()
Returns the number of processors in the current group. See Comm_Group::nproc() and PE_Groups::current...
Definition Process.cpp:102
static int me()
Returns the rank of the local processor in the current communication group. See Comm_Group::rank() an...
Definition Process.cpp:122
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
static int je_suis_maitre()
Returns 1 if on the master processor of the current group (i.e. me() == 0), 0 otherwise.
Definition Process.cpp:82
Class Raccord_base This class is simply a boundary; it is the base class of the.
Class Raccords This represents a list of Raccord type objects.
Definition Raccords.h:29
SFichier is to the C++ ofstream class what Sortie is to the C++ ostream class.
Definition SFichier.h:29
static void init_sequential_domain(Domaine_32_64< _SIZE_ > &dom)
Create parallel descriptors for the vertex and element arrays of the domain (necessary because Scatte...
Definition Scatter.cpp:2739
static void uninit_sequential_domain(Domaine_32_64< _SIZE_ > &dom)
Method used by interpreters that modify the domain (sequential), destroys the descriptors of vertices...
Definition Scatter.cpp:2754
Base class for output streams.
Definition Sortie.h:52
_TYPE_ * addr()
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
void resize(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTArray.h:156
virtual void ref_data(_TYPE_ *ptr, _SIZE_ size)
int dimension_int(int d) const
Definition TRUSTTab.tpp:152
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
_SIZE_ size() const
Definition TRUSTVect.tpp:45