TRUST 1.9.8
HPC thermohydraulic platform
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 // pour chaque elt on verifie si il est bien a angle droit
114 for (int dir=0; dir<dimension && ok; dir++)
115 {
116 // on compte le nombre de pos de sommmets dans chaque 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 // on 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 appel a: Interprete::printOn(Sortie&)
220 *
221 * @param (Sortie& os) un flot de sortie
222 * @return (Sortie&) le flot de sortie modifie
223 */
224template <typename _SIZE_>
226{
227 return Interprete::printOn(os);
228}
229
230/*! @brief Simple appel a: Interprete::readOn(Entree&)
231 *
232 * @param (Entree& is) un flot d'entree
233 * @return (Entree&) le flot d'entree modifie
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 renvoie le type trio a partir du type medocoupling : http://docs.salome-platform.org/6/gui/MED/MEDLoader_8cxx.html
316 */
317#ifdef MEDCOUPLING_
318template <typename _SIZE_>
319Nom LireMED_32_64<_SIZE_>::type_medcoupling_to_type_geo_trio(int type_cell, bool cell_from_boundary) const
320{
321 Nom type_elem;
322 // [ABN] : first make sure the axis type is properly set, this will influence choice of the element
323 // Set up correctly bidim_axi or axi variable according to MED file data.
324 if (axis_type_==MEDCoupling::AX_CYL)
325 {
326 if (type_cell==INTERP_KERNEL::NORM_QUAD4)
327 {
328 if (!Objet_U::axi)
329 {
330 Cerr<<"WARNING, Cylindrical MED coordinates detected - we will use 'axi' keyword."<<finl;
331 Objet_U::axi=1;
332 }
333 }
334 else
335 {
336 Cerr << "Strange error with MED file - should never happen!? MED file with axis type AX_CYL contains elements other than NORM_QUAD4."<< finl;
338 }
339 }
340 if (axis_type_==MEDCoupling::AX_SPHER)
341 {
342 Cerr << "Spherical coordinates read in the MED file - this is unsupported in TRUST!" << finl;
344 }
345
346 //
347 // At this stage 'axi' and 'bidim_axi' are properly set.
348 //
349 if (type_cell==INTERP_KERNEL::NORM_QUAD4)
350 type_elem = cell_from_boundary ? "QUADRANGLE_3D" : (isVEFForce_ ? "Quadrangle" : "Rectangle");
351 else if (type_cell==INTERP_KERNEL::NORM_HEXA8)
352 type_elem=(isVEFForce_ ? "Hexaedre_vef" : "Hexaedre");
353 else if (type_cell==INTERP_KERNEL::NORM_TRI3)
354 type_elem= cell_from_boundary ? "TRIANGLE_3D" : "Triangle";
355 else if (type_cell==INTERP_KERNEL::NORM_TETRA4)
356 type_elem="Tetraedre";
357 else if (type_cell==INTERP_KERNEL::NORM_SEG2)
358 type_elem= cell_from_boundary ? "SEGMENT_2D" : "Segment";
359 else if (type_cell==INTERP_KERNEL::NORM_PENTA6)
360 type_elem="Prisme";
361 else if (type_cell==INTERP_KERNEL::NORM_POLYHED)
362 type_elem="Polyedre";
363 else if (type_cell==INTERP_KERNEL::NORM_PYRA5)
364 type_elem="Pyramide";
365 else if (type_cell==INTERP_KERNEL::NORM_POLYGON)
366 type_elem= cell_from_boundary ? "POLYGONE_3D" : "Polygone";
367 else if(type_cell==INTERP_KERNEL::NORM_HEXGP12)
368 type_elem = "Prisme_hexag";
369 else if(type_cell==INTERP_KERNEL::NORM_POINT1)
370 type_elem = cell_from_boundary ? "POINT_1D" : "Point_1d";
371 else
372 {
373 Cerr<<"Cell type " << type_cell<< " is not supported yet." <<finl;
375 }
376 if(Objet_U::bidim_axi && !(type_cell == INTERP_KERNEL::NORM_QUAD4 || type_cell == INTERP_KERNEL::NORM_SEG2 || type_cell == INTERP_KERNEL::NORM_POLYGON))
377 {
378 Cerr<<"Cell type " << type_cell<< " is not supported for 'bidim_axi' mode." <<finl;
380 }
381 if (Objet_U::axi && !(type_cell == INTERP_KERNEL::NORM_HEXA8 || type_cell == INTERP_KERNEL::NORM_QUAD4))
382 {
383 Cerr<<"Cell type " << type_cell<< " is not supported for 'axi' mode." <<finl;
385 }
386 if (axi1d_ && !(type_cell == INTERP_KERNEL::NORM_SEG2 || type_cell == INTERP_KERNEL::NORM_POINT1))
387 {
388 Cerr<<"Cell type " << type_cell<< " is not supported for 'axi1d' mode." <<finl;
390 }
391 if (Objet_U::bidim_axi && type_cell == INTERP_KERNEL::NORM_QUAD4)
392 type_elem = "Rectangle_2D_axi";
393 if (Objet_U::bidim_axi && type_cell == INTERP_KERNEL::NORM_SEG2)
394 type_elem = "quadrilatere_2D_axi";
395 if (Objet_U::axi)
396 type_elem += "_axi";
397
398 if (axi1d_)
399 type_elem += "_axi";
400 return type_elem;
401}
402#endif
403
404
405/*! @brief Load the mesh from the MED file as a MEDCouplingUMesh, and name it as the domain.
406 */
407#ifdef MEDCOUPLING_
408
409template <typename _SIZE_>
411{
412 std::string fileName = nom_fichier_.getString();
413 std::string meshName = nom_mesh_.getString();
414
415 // Check the mesh name is in the file:
416 //const MCAuto<MEDFileMeshes> data(MEDFileMeshes::New(fileName));
417 std::vector< std::string > meshes_names = MEDCoupling::GetMeshNames(fileName) ;
418 if (std::find(meshes_names.begin(), meshes_names.end(), meshName) == meshes_names.end())
419 {
420 if (meshName == "--any--" && meshes_names.size()==1) meshName = meshes_names[0]; //magic name -> we take the first mesh
421 else
422 {
423 if (meshName == "--any--")
424 Cerr << "You need to specify the mesh name for the med file " << nom_fichier_ << " !" << finl;
425 else
426 Cerr << "Mesh " << nom_mesh_ << " not found in the med file " << nom_fichier_ << " !" << finl;
427 Cerr << "List of meshes found:" << finl;
428 for(unsigned int i = 0; i<meshes_names.size(); i++)
429 Cerr << meshes_names[i] << finl;
430 Process::exit(-1);
431 }
432 }
433
434 mfumesh_ = MEDFileUMesh::New(fileName, meshName);
435 // Name it correctly here so that all extracted MEDCouplingUMesh will be correctly named:
436 mfumesh_->setName( this->domaine().le_nom().getChar());
437
438 axis_type_ = mfumesh_->getAxisType();
439 // Some checks:
440 std::vector<int> nel = mfumesh_->getNonEmptyLevels();
441 assert(nel[0] == 0);
442 // Get the volume mesh:
443 mcumesh_ = mfumesh_->getMeshAtLevel(nel[0]); // ToDo can not make it const because of ArrOfInt
444 space_dim_ = mcumesh_->getSpaceDimension();
445 Cerr << "Detecting a " << (int)mcumesh_->getMeshDimension() << "D mesh in " << space_dim_ << "D space." << finl;
446 if (space_dim_ != Objet_U::dimension)
447 {
448 Cerr << "The mesh space dimension may be higher than the computation space dimension" << finl;
449 Cerr << "as the algorithm will try to detect the useless direction in the mesh." << finl;
450 //assert(dim == dimension);
451 }
452
453 // Desormais l'option permet de convertir tout type de maillage vers des polyedres:
454 if (convertAllToPoly_)
455 {
456 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
457 Cerr << "Conversion to polyedrons and polygons..." << finl;
458 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
459 mcumesh_->convertAllToPoly(); // Conversion maillage volumique
460 }
461}
462
463#endif
464
465
466/*! Fills in coords and connectivity array from the MC data.
467 */
468#ifdef MEDCOUPLING_
469template <typename _SIZE_>
470void LireMED_32_64<_SIZE_>::prepare_som_and_elem(DoubleTab_t& sommets2, IntTab_t& les_elems2)
471{
472 using Polygone_t = Polygone_32_64<_SIZE_>;
473 using Polyedre_t = Polyedre_32_64<_SIZE_>;
474
475 // Get the nodes: size and fill sommets2:
476 mcIdType nnodes0 = mcumesh_->getNumberOfNodes();
477 if (nnodes0 >= std::numeric_limits<_SIZE_>::max())
478 Process::exit("ERROR! You are trying to build a 32b domain with a mesh which is too big (too many nodes). Use Domaine_64.");
479 int_t nnodes = static_cast<int_t>(nnodes0);
480
481 const double *coord = mcumesh_->getCoords()->begin();
482 Cerr << "Detecting " << nnodes << " nodes." << finl;
483 sommets2.resize(nnodes, space_dim_);
484 std::copy(coord, coord+sommets2.size_array(), sommets2.addr());
485
486 // Get cell connectivity
487 mcIdType ncells0 = mcumesh_->getNumberOfCells();
488 if (ncells0 >= std::numeric_limits<_SIZE_>::max())
489 Process::exit("ERROR! You are trying to build a 32b domain with a mesh which is too big (too many elements). Use Domaine_64.");
490 int_t ncells = static_cast<int_t>(ncells0);
491
492 // Use ArrOfInt to benefit from assert:
493 ArrOfInt_t conn, connIndex;
494 ::retrieve_connec(mcumesh_, conn, connIndex);
495
496 int mesh_type_cell = static_cast<int>(conn[connIndex[0]]); // type is always an int.
497 Nom type_elem_n = type_medcoupling_to_type_geo_trio(mesh_type_cell, false);
498 if (!std::is_same<_SIZE_,int>::value)
499 type_elem_n += "_64";
500 type_elem_.typer(type_elem_n);
501 auto set_of_typs = mcumesh_->getAllGeoTypes();
502 if (set_of_typs.size() > 1)
503 {
504 Cerr << "Elements of kind " << type_elem_n << " have already been read" << finl;
505 Cerr << "New elements type(s) found!!" << finl;
506 if (!convertAllToPoly_)
507 {
508 Cerr << "TRUST does not support different element types for the mesh." << finl;
509 Cerr << "Either you remesh your domain with a single element type," << finl;
510 Cerr << "or convert your cells to polyedrons and polygons by inserting an option in your command line:" << finl;
511 Cerr << " Read_MED { ... convertAllToPoly ... } " << finl;
512 Cerr << "After that, you should use a discretization supporting polyedrons!" << finl;
514 }
515 }
516
517 // Fill les_elem2 : Different treatment according type_elem:
518 if (sub_type(Polyedre_t, type_elem_.valeur()))
519 {
520 int_t marker = 0;
521 int_t conn_size = static_cast<int_t>(mcumesh_->getNodalConnectivity()->getNbOfElems()); // Overflow check done before
522 for (int_t i = 0; i < conn_size; i++)
523 if (conn[i]<0) marker++;
524 int_t num_nodes = conn_size - ncells - marker;
525 int_t nfaces = ncells + marker;
526 ArrOfInt_t nodes(num_nodes), facesIndex(nfaces+1), polyhedronIndex(ncells+1);
527 int_t face=0, node = 0;
528 for (int_t i = 0; i < ncells; i++)
529 {
530 polyhedronIndex[i] = face; // Index des polyedres
531
532 int_t index = connIndex[i] + 1;
533 int nb_som = static_cast<int>(connIndex[i + 1] - index);
534 for (int j = 0; j < nb_som; j++)
535 {
536 if (j==0 || conn[index + j]<0)
537 facesIndex[face++] = node; // Index des faces:
538 if (conn[index + j]>=0)
539 nodes[node++] = conn[index + j]; // Index local des sommets de la face
540 }
541 }
542 facesIndex[nfaces] = node;
543 polyhedronIndex[ncells] = face;
544 ref_cast(Polyedre_t,type_elem_.valeur()).affecte_connectivite_numero_global(nodes, facesIndex, polyhedronIndex, les_elems2);
545 }
546 else if (sub_type(Polygone_t, type_elem_.valeur()))
547 {
548 int_t conn_size = static_cast<int_t>(mcumesh_->getNodalConnectivity()->getNbOfElems()); // Overflow check done before
549 int_t facesIndexSize = conn_size - ncells;
550 ArrOfInt_t facesIndex(facesIndexSize), polygonIndex(ncells+1);
551 int_t face=0;
552 for (int_t i = 0; i < ncells; i++)
553 {
554 polygonIndex[i] = face; // Index des polygones
555
556 int_t index = connIndex[i] + 1;
557 int nb_som = static_cast<int>(connIndex[i + 1] - index);
558 for (int j = 0; j < nb_som; j++)
559 facesIndex[face++] = conn[index + j];
560 }
561 polygonIndex[ncells] = face;
562 ref_cast(Polygone_t,type_elem_.valeur()).affecte_connectivite_numero_global(facesIndex, polygonIndex, les_elems2);
563 }
564 else // Tous les autres types
565 {
566 for (int_t i = 0; i < ncells; i++)
567 {
568 int_t index = connIndex[i] + 1;
569 int nb_som = static_cast<int>(connIndex[i + 1] - index);
570 if (i==0) les_elems2.resize(ncells, nb_som); // Size les_elems2
571 for (int j = 0; j < nb_som; j++)
572 les_elems2(i, j) = conn[index + j];
573 }
574 }
575}
576#endif
577
578/*! @brief Fills in sommets in the Domaine, potentially reducing the dimension (flat 3D -> 2D)
579 * by discarding a useless dimension (a flat 2D surface in a 3D space dim for example)
580 * TODO Fixme Adrien : rewrite this in MC style : buildUnique etc ...
581 */
582template <typename _SIZE_>
584{
585 // affectation des sommets
587 {
588 Cerr << "One tries to read a meshing written in " << space_dim_ << "D in " << Objet_U::dimension << "D " << finl;
589 // determination de la direction inutile
590 int_t nbsom=sommets2.dimension(0);
591 int dirinut=-1;
592 const double epsilon = Objet_U::precision_geom;
593 for (int dir=0; dir<space_dim_; dir++)
594 {
595 bool trouve=true;
596 double val1=sommets2(0,dir);
597 for (int_t i=0; i<nbsom; i++)
598 if (std::abs(val1-sommets2(i,dir))>epsilon)
599 {
600 trouve=false;
601 Cerr<<val1 << " "<<sommets2(i,dir)<<finl;
602 break;
603 }
604 if (trouve)
605 {
606 dirinut=dir;
607 break;
608 }
609 }
610 if (dirinut==-1)
611 {
612 Cerr<<"No useless direction "<<finl;
614 }
615 Cerr<<"useless direction "<<dirinut<<finl<<finl;
616
617 sommets.resize(nbsom,Objet_U::dimension);
618 int d=0;
619 for (int dir=0; dir<space_dim_; dir++)
620 if (dir!=dirinut)
621 {
622 for (int_t i=0; i<nbsom; i++)
623 sommets(i,d)=sommets2(i,dir);
624 d++;
625 }
626 }
627 else
628 sommets=sommets2;
629}
630
631/* @brief Write datasets for sub-domains (built from MED element groups) into dedicated files.
632 */
633template <typename _SIZE_>
635{
636#ifdef MEDCOUPLING_
637
638 unsigned nb_volume_groups = (unsigned)mfumesh_->getGroupsOnSpecifiedLev(0).size();
639 if (nb_volume_groups>0 && Process::je_suis_maitre())
640 {
641 Nom nom_dom_trio = this->domaine().le_nom();
642 SFichier jdd_seq(nom_dom_trio + "_ssz.geo");
643 SFichier jdd_par(nom_dom_trio + "_ssz_par.geo");
644 std::vector<std::string> groups;
645 if (restrict_ssz_.size()>0)
646 {
647 for (const auto& name : restrict_ssz_)
648 groups.push_back(name.getString());
649 }
650 else
651 {
652 Cerr << "Reading groups at level 0:" << finl;
653 groups = mfumesh_->getGroupsOnSpecifiedLev(0);
654 }
655
656 for (const auto& gnam: groups)
657 {
658 MCAuto<DataArrayIdType> ids(mfumesh_->getGroupArr(0, gnam, false));
659 const mcIdType *idP = ids->getConstPointer();
660 mcIdType nb_elems0 = ids->getNbOfElems();
661 if (nb_elems0 >= std::numeric_limits<_SIZE_>::max())
662 Process::exit("ERROR! You are trying to build a 32b domain with a mesh which is too big (too many nodes). Use Domaine_64.");
663 mcIdType nb_elems = static_cast<int_t>(nb_elems0);
664
665 const Nom& nom_sous_domaine = gnam; // We take the name of the group for the subzone name
666 Cerr << "Detecting a sub-zone (group name="<< nom_sous_domaine << ") with " << nb_elems << " cells." << finl;
667
668 if (nb_elems == 0) continue;
669
670 Nom file_ssz(nom_dom_trio);
671 file_ssz += "_";
672 file_ssz += nom_sous_domaine;
673 file_ssz += Nom(".file");
674 jdd_seq << "export Sous_Domaine " << nom_sous_domaine << finl;
675 jdd_par << "export Sous_Domaine " << nom_sous_domaine << finl;
676
677 jdd_seq << "Associer " << nom_sous_domaine << " " << nom_dom_trio << finl;
678 jdd_par << "Associer " << nom_sous_domaine << " " << nom_dom_trio << finl;
679 if (restrict_ssz_.size())
680 {
681 // Sequential only:
682 jdd_seq << "Lire " << nom_sous_domaine << " { liste " << nb_elems;
683 for (int_t j = 0; j < nb_elems; j++) jdd_seq << " " << (int) idP[j];
684 jdd_seq << " }" << finl;
685 }
686 else
687 {
688 jdd_seq << "Lire " << nom_sous_domaine << " { fichier " << file_ssz << " }" << finl;
689 jdd_par << "Lire " << nom_sous_domaine << " { fichier " << nom_sous_domaine << ".ssz" << " }" << finl;
690 SFichier f_ssz(file_ssz);
691 f_ssz << nb_elems << finl;
692 for (int_t j = 0; j < nb_elems; j++)
693 f_ssz << (int) idP[j] << " ";
694 f_ssz << finl;
695 }
696 }
697 }
698#endif
699}
700
701/*! @brief Handles the boundaries found in the MED file.
702 *
703 * Get the -1 level mesh, and extract boundaries by reading element groups on this mesh.
704 */
705template <typename _SIZE_>
707{
708#ifdef MEDCOUPLING_
709
710 constexpr bool CELL_FROM_BOUNDARY = true;
711
712 // Get boundary mesh:
713 MCAuto<MEDCouplingUMesh> face_mesh(mfumesh_->getMeshAtLevel(-1)); // ToDo can not make it const because of ArrayOfInt
714 if (Objet_U::dimension==3 && convertAllToPoly_) // In 2D this will be segments anyway
715 face_mesh->convertAllToPoly(); // Conversion maillage frontiere
716 int_t nfaces = static_cast<int_t>(face_mesh->getNumberOfCells()); // overflow check done in prepare_som_and_elem()
717
718 // Retrieve connectivity - Use ArrOfInt to benefit from assert:
719 ArrOfInt_t conn, connIndex;
720 ::retrieve_connec(face_mesh, conn, connIndex);
721 DataArrayIdType *cI = face_mesh->getNodalConnectivityIndex();
722
723 // Read type from the first face, and check unique type
724 int typ = static_cast<int>(conn[connIndex[0]]); // type is always int
725 type_face_ = type_medcoupling_to_type_geo_trio(typ, CELL_FROM_BOUNDARY);
726 if (type_elem_->nb_type_face() != 1) // should never happen, all is polygon normally.
727 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).");
728 // Check unique type
729 auto set_of_typs = face_mesh->getAllGeoTypes();
730 if (set_of_typs.size() > 1) // same as a above, should never happen
731 Process::exit("Read_MED: invalid boundary mesh! More than a single face type.");
732
733 // Get max number of vertices per face - in a dedicated scope to destroy dsi quickly
734 int max_som_face;
735 {
736 MCAuto<DataArrayIdType> dsi = cI->deltaShiftIndex();
737 max_som_face = static_cast<int>(dsi->getMaxValueInArray() - 1); // -1 because first slot in connectivity descr is for type
738 }
739
740 // Filling face connectivity:
741 Cerr << "Detecting " << nfaces << " faces (" << type_face_ << ")." << finl;
742 all_faces_bords.resize(nfaces, max_som_face);
743 all_faces_bords = -1;
744 fac_grp_id.resize_array(nfaces);
745 for (int_t i = 0; i < nfaces; i++)
746 {
747 int_t index = connIndex[i] + 1; // +1 to skip MEDCoupling type
748 int nb_som = static_cast<int>(connIndex[i + 1] - index);
749 for (int j = 0; j < nb_som; j++)
750 all_faces_bords(i, j) = conn[index + j] ;
751 }
752
753 Cerr << "Reading groups at level -1:" << finl;
754 auto grp_names = mfumesh_->getGroupsOnSpecifiedLev(-1);
755 int zeid = 0;
756 std::set<mcIdType> id_check;
757 for (const auto& gnam: grp_names)
758 {
759 if (exclude_grps_.search(Nom(gnam)) != -1)
760 {
761 Cerr << " group '" << gnam << "' is skipped, as requested." << finl;
762 continue;
763 }
764 noms_bords_.add(gnam);
765 MCAuto<DataArrayIdType> ids(mfumesh_->getGroupArr(-1, gnam, false));
766 long bef = (long)id_check.size(), nb_faces = (long)ids->getNumberOfTuples();
767 id_check.insert(ids->begin(), ids->begin()+nb_faces);
768 if ((long)id_check.size() - bef < nb_faces)
769 {
770 Cerr << "ERROR: group '" << gnam << "' contains faces which are also in one of the previously read groups." << finl;
771 Cerr << " Fix your mesh, or use the 'exclude_groups' option to prevent reading of this group." << finl;
772 Process::exit(-1);
773 }
774 Cerr << " group_name=" << gnam << " with " << nb_faces << " faces" << finl;
775 for(const auto& id: *ids)
776 {
777 int_t id2 = static_cast<int_t>(id);
778 fac_grp_id[id2] = zeid+1;
779 }
780 zeid++;
781 }
782
783 if (noms_bords_.size()==0)
784 {
785 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
786 Cerr << "Lire_MED: Warning: no boundary detected for the mesh." << finl;
787 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
788 }
789#endif
790}
791
792/*! @brief Fills in all the information relative to Joints, Raccords and Frontiere
793 */
794template <typename _SIZE_>
795void LireMED_32_64<_SIZE_>::fill_frontieres(const BigArrOfInt_& fac_grp_id, const IntTab_t& all_faces_bords)
796{
797 using SmallArrOfTID_t = SmallArrOfTID_T<_SIZE_>;
798
799 using Bord_t = Bord_32_64<_SIZE_>;
800 using Bords_t = Bords_32_64<_SIZE_>;
801 using Groupe_Faces_t = Groupe_Faces_32_64<_SIZE_>;
802 using Groupes_Faces_t = Groupes_Faces_32_64<_SIZE_>;
803 using Frontiere_t = Frontiere_32_64<_SIZE_>;
804 using Raccord_t = OWN_PTR(Raccord_base_32_64<_SIZE_>);
805 using Raccords_t = Raccords_32_64<_SIZE_>;
806 using Joint_t = Joint_32_64<_SIZE_>;
807 using Joints_t = Joints_32_64<_SIZE_>;
808 using Faces_t = Faces_32_64<_SIZE_>;
809
810 Domaine_t& dom = this->domaine();
811 std::vector<ArrOfInt_t> sommets_joints;
812 ArrOfInt tab_pe_voisin;
813
814 int nbord = noms_bords_.size();
815 SmallArrOfTID_t nb_face_per_bord(nbord);
816 Bords_t& faces_bord=dom.faces_bord();
817 faces_bord.vide();
818 Groupes_Faces_t& goupes_faces=dom.groupes_faces();
819 goupes_faces.vide();
820 Raccords_t& faces_raccord=dom.faces_raccord();
821 faces_raccord.vide();
822 Joints_t& faces_joint=dom.faces_joint();
823 faces_joint.vide();
824
825 Noms noms_des_joints;
826 recuperer_info_des_joints(noms_des_joints,nom_fichier_,nom_mesh_,sommets_joints,tab_pe_voisin);
827
828 int_t nfacebord=all_faces_bords.dimension(0);
829 for (int ib=nbord-1; ib>-1; ib--)
830 {
831 int indice_bord=ib+1;
832 if (noms_bords_[ib]=="elems") continue;
833 Bord_t bordprov_;
834 Groupe_Faces_t facesgrpprov;
835 Raccord_t raccprov;
836 Joint_t jointprov;
837 bool israccord=false, isjoint=false, isfacesint=false;
838 if (noms_bords_[ib].debute_par("type_raccord_"))
839 {
840 israccord=true;
841 noms_bords_[ib].suffix("type_raccord_");
842 raccprov.typer("Raccord_local_homogene");
843 }
844 if (internal_face_grps_.search(noms_bords_[ib]) != -1)
845 isfacesint=true;
846
847 int numero_joint=noms_des_joints.search(noms_bords_[ib]);
848 if (numero_joint>-1)
849 {
850 Cerr<<noms_bords_[ib]<<" is considered as a joint "<<finl;
851 isjoint=true;
852 }
853 // on recupere la frontiere .... que ce soit un Bord,Raccord,ou Joint
854 Frontiere_t& bordprov = (isjoint?jointprov:(israccord?ref_cast(Frontiere_t,raccprov.valeur()):(isfacesint?ref_cast(Frontiere_t,facesgrpprov):ref_cast(Frontiere_t,bordprov_))));
855
856 bordprov.nommer(noms_bords_[ib]);
857 bordprov.typer_faces(type_face_);
858 int_t nb_face_this_bord=0;
859 int nsomfa=all_faces_bords.dimension_int(1);
860 IntTab_t sommprov(nfacebord,nsomfa);
861 for (int_t j=0; j<nfacebord; j++)
862 {
863 if (fac_grp_id[j]==indice_bord)
864 {
865 for (int k=0; k<nsomfa; k++)
866 sommprov(nb_face_this_bord,k)=all_faces_bords(j,k);
867 nb_face_this_bord++;
868 }
869 }
870 Faces_t& facesi=bordprov.faces();
871 IntTab_t& sommetsfaces=facesi.les_sommets();
872 sommetsfaces.resize(nb_face_this_bord,nsomfa);
873 for (int_t jj=0; jj<nb_face_this_bord; jj++)
874 for (int k=0; k<nsomfa; k++)
875 sommetsfaces(jj,k)=sommprov(jj,k);
876 IntTab_t& facesv=facesi.voisins();
877 facesv.resize(nb_face_this_bord,2);
878 facesv=-1;
879
880 bool vide_0D_a_ecrire=false;
881 if (nb_face_this_bord == 0)
882 {
883 bordprov.typer_faces("vide_0D");
884 vide_0D_a_ecrire = true;
885 }
886 nb_face_per_bord[ib] = nb_face_this_bord;
887 // ne marche pas ajoute la famille elem
888 if (indice_bord != 0
889 && (nb_face_this_bord>0 || vide_0D_a_ecrire))
890 {
891 if (isjoint)
892 {
893 int PE_voisin=tab_pe_voisin[numero_joint];
894 int epaisseur=1;
895 ArrOfInt_t& sommets_joint=sommets_joints[numero_joint];
896 jointprov.affecte_PEvoisin(PE_voisin);
897 jointprov.affecte_epaisseur(epaisseur);
898 ArrOfInt_t& sommets_du_joint=jointprov.set_joint_item(JOINT_ITEM::SOMMET).set_items_communs();
899 sommets_du_joint=sommets_joint;
900 faces_joint.add(jointprov);
901 }
902 else if (israccord)
903 faces_raccord.add(raccprov);
904 else if (isfacesint)
905 goupes_faces.add(facesgrpprov);
906 else
907 faces_bord.add(bordprov_);
908 }
909 }
910 faces_bord.associer_domaine(dom);
911 faces_raccord.associer_domaine(dom);
912 faces_joint.associer_domaine(dom);
913 goupes_faces.associer_domaine(dom);
915 int nbfr=dom.nb_front_Cl();
916 for (int fr=0; fr<nbfr; fr++)
917 {
918 dom.frontiere(fr).faces().associer_domaine(dom);
919 if (dom.frontiere(fr).faces().type_face() != Type_Face::vide_0D)
920 dom.frontiere(fr).faces().reordonner();
921 }
922}
923
924template <typename _SIZE_>
926{
927#ifndef MED_
928 med_non_installe();
929#else
930#ifdef MEDCOUPLING_
931 Domaine_t& dom = this->domaine();
932 const Nom& nom_dom_trio = dom.le_nom();
933
934 axi1d_ = dom.axi1d();
935 // pour verif
936 if (Objet_U::dimension==0)
937 {
938 Cerr << "Dimension is not defined. Check your data file." << finl;
940 }
941 Cerr << "Trying to read the mesh " << nom_mesh_ << " from the file " << nom_fichier_ << " in order to affect to domain "
942 << nom_dom_trio << "..." << finl;
943
945
946 // Reading vertices and element descriptions:
947 DoubleTab_t sommets2;
948 IntTab_t les_elems2;
949 prepare_som_and_elem(sommets2, les_elems2);
950
951 // Detect and export sub-domains (based on group of volumes);
952 if (subDom)
954
955 // Detect boundary meshes:
956 BigArrOfInt_ fac_grp_id;
957 IntTab_t all_faces_bords;
958 std::vector<int> nel = mfumesh_->getNonEmptyLevels();
959 if (nel.size() > 1)
960 {
961 assert(nel[1] == -1);
962 read_boundaries(fac_grp_id, all_faces_bords);
963 }
964
965 // Converting from MED to TRUST connectivity
966 Nom type_elem_n = type_elem_->que_suis_je(); // prepare_som_and_elem() has performed the 'typer' operation on type_elem_
967 conn_trust_to_med(les_elems2,type_elem_n,false);
968 conn_trust_to_med(all_faces_bords,type_face_,false);
969
971
972 DoubleTab_t& sommets=dom.les_sommets();
973 finalize_sommets(sommets2, sommets);
974
975 // Typage des elts du domaine et remplissage des elts
976 // Avant de typer on regarde si il ne faut pas transormer les hexa en Hexa_vef
977 Nom type_elem_orig = type_elem_n;
978 verifier_modifier_type_elem(type_elem_n,les_elems2,sommets);
979
980 dom.type_elem() = type_elem_;
981 // si on a modifie type_elem
982 if (type_elem_orig != type_elem_n)
983 dom.typer(type_elem_n);
984 dom.type_elem()->associer_domaine(dom);
985 dom.les_elems() = les_elems2;
986
987 fill_frontieres(fac_grp_id, all_faces_bords);
988
989 // Fix connectivity to be compliant with TRUST connectivity conventions
990 // (see doc of Hexaedre/Rectangle for example)
991 if (type_elem_n == "Rectangle" || type_elem_n == "Hexaedre" || type_elem_n == "Rectangle_64" || type_elem_n == "Hexaedre_64"
992 || sub_type(Polyedre_32_64<_SIZE_>,dom.type_elem().valeur()))
993 dom.reordonner();
994
995 if (Process::nproc()==1)
996 {
997 Cerr << " Lire_MED called in sequential => applying NettoieNoeuds" << finl;
999 }
1000
1002
1003 // MCUMesh object will be rebuilt next time it is retreived:
1004 dom.set_mc_mesh_ready(false);
1005
1006 Cerr<<"Reading of the MED domain ended."<<finl;
1007#endif // MEDCOUPLING_
1008#endif // MED_
1009}
1010
1011
1012template class LireMED_32_64<int>;
1013#if INT_is_64_ == 2
1014template class LireMED_32_64<trustIdType>;
1015#endif
1016
1017
Classe Bord Cette classe represente un bord d'un domaine, c'est un type de frontiere.
Definition Bord.h:32
Classe Bords Cette classe represente une liste d'objets de 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:1102
void typer(const Nom &)
Type les elements du domaine avec le nom passe en parametre.
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
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Une entree dont la source est une chaine de caracteres.
Definition EChaine.h:31
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Classe Faces Faces decrit un ensemble de faces par leur type (point ,segment, triangle ou quadrangle)...
Definition Faces.h:50
void associer_domaine(const Domaine_t &z)
Definition Faces.h:94
void reordonner()
Reordonne les faces.
Definition Faces.cpp:889
Type_Face type_face() const
Definition Faces.h:65
Classe Frontiere.
Definition Frontiere.h:32
const Faces_t & faces() const
Definition Frontiere.h:54
Classe Groupe_Face La classe sert a representer une selection de faces lu dans le fichier med.
Class Groupes_Faces Cette classe represente une liste d'objets de type Groupe_Faces.
classe Interprete_geometrique_base .
La classe Joint est une Frontiere qui contient les faces et les sommets de joint avec le domaine PEvo...
Definition Joint.h:34
Classe Joints Cette classe represente une liste d'objet de type Joint.
Definition Joints.h:28
void lire_geom(bool subDom=true)
Definition LireMED.cpp:925
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:795
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
renvoie le type trio a partir du type medocoupling : http://docs.salome-platform.org/6/gui/MED/MEDLoa...
Definition LireMED.cpp:583
void read_boundaries(BigArrOfInt_ &familles, IntTab_t &all_faces_bords)
Handles the boundaries found in the MED file.
Definition LireMED.cpp:706
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:634
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 Une chaine de caractere pour nommer les objets de TRUST
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
Insere _prefix000n (n=me() ou nproc()) dans un nom de fichier (par ex:toto.
Definition Nom.cpp:387
Nom & prefix(const char *const)
Definition Nom.cpp:329
const std::string & getString() const
Definition Nom.h:92
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
int search(const Nom &t) const
Definition Noms.cpp:39
friend class Entree
Definition Objet_U.h:76
static int dimension
Definition Objet_U.h:99
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
static double precision_geom
Definition Objet_U.h:86
static const Nom & nom_du_cas()
Renvoie une reference constante vers le nom du cas.
Definition Objet_U.cpp:146
static int bidim_axi
Definition Objet_U.h:102
static int axi
Definition Objet_U.h:101
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
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
Classe Polyedre Cette represente l'element geometrique Polyedre.
Definition Polyedre.h:29
Classe Polygone Cette represente l'element geometrique Polygone.
Definition Polygone.h:29
static int nproc()
renvoie le nombre de processeurs dans le groupe courant Voir Comm_Group::nproc() et PE_Groups::curren...
Definition Process.cpp:104
static int me()
renvoie mon rang dans le groupe de communication courant.
Definition Process.cpp:125
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
Definition Process.cpp:86
Classe Raccord_base Cette classe est simplement une frontiere, c'est la classe de base de la.
Classe Raccords Cette represente une liste d'objets de type Raccord.
Definition Raccords.h:29
Cette classe est a la classe C++ ofstream ce que la classe Sortie est a la classe C++ ostream Elle re...
Definition SFichier.h:27
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:2742
static void uninit_sequential_domain(Domaine_32_64< _SIZE_ > &dom)
methode utilisee par les interpretes qui modifient le domaine (sequentiel), detruit les descripteurs ...
Definition Scatter.cpp:2757
Classe de base des flux de sortie.
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