TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Ecrire_MED.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 <Ecrire_MED.h>
17#include <Domaine.h>
18#include <med++.h>
19#include <Domaine_VF.h>
20#include <TRUSTTabs.h>
21#include <Char_ptr.h>
22#include <medcoupling++.h>
23#include <ctime>
24#include <TRUST_2_MED.h>
25#include <Sortie_Fichier_base.h>
26#include <Synonyme_info.h>
27#include <Domaine_dis_cache.h>
28#include <Domaine_VF.h>
29
30#ifdef MEDCOUPLING_
31#include <MEDLoader.hxx>
32#include <MEDFileMesh.hxx>
33#include <MEDCouplingFieldDouble.hxx>
34#pragma GCC diagnostic ignored "-Wreorder"
35#include <MEDFileField.hxx>
36using namespace MEDCoupling;
37#endif
38
39Implemente_instanciable_32_64(Ecrire_MED_32_64,"Write_MED",Interprete);
40Add_synonym(Ecrire_MED,"Ecrire_MED");
41
42// Anonymous namespace for local functions:
43namespace
44{
45
46/*! @brief Loop on bords,raccords,joints
47 */
48template <typename _SIZE_>
49const Frontiere_32_64<_SIZE_>& mes_faces_fr(const Domaine_32_64<_SIZE_>& domaine, int i)
50{
51 int nb_std = domaine.nb_front_Cl() + domaine.nb_groupes_faces();
52 return i<nb_std ? domaine.frontiere(i) : domaine.joint(i-nb_std);
53}
54
55} // namespace
56template <typename _SIZE_>
58{
59 return Interprete::printOn(os);
60}
61
62template <typename _SIZE_>
64{
65 return Interprete::readOn(is);
66}
67
68template <typename _SIZE_>
70 dom_(dom)
71#ifdef MEDCOUPLING_
72 , mcumesh_(nullptr)
73#endif
74{
76 if (nom_fichier_!="") nom_fichier_+="/";
77 nom_fichier_ += file_name;
78}
79
80template <typename _SIZE_>
81void Ecrire_MED_32_64<_SIZE_>::set_file_name_and_dom(const Nom& file_name, const Domaine_t& dom, const Domaine_dis_base* dom_dis)
82{
84 if (nom_fichier_!="") nom_fichier_+="/";
85 nom_fichier_ += file_name;
86 dom_ = dom;
87 if(dom_dis)
88 domaine_dis_ = ref_cast(Domaine_VF, *dom_dis);
89}
90
91// XD Ecrire_MED interprete Write_MED INHERITS_BRACE Write a domain to MED format into a file.
92// XD attr nom_dom ref_domaine nom_dom REQ Name of domain.
93// XD attr file chaine file REQ Name of file.
94template <typename _SIZE_>
96{
97 Cerr<<"syntax : Write_MED [ append ] nom_dom nom_fic "<<finl;
98 bool append=false;
99 Nom nom_dom;
100 is >> nom_dom ;
101 Motcle app("append");
102 if (app==nom_dom)
103 {
104 append=true;
105 is >> nom_dom;
106 Cerr<<" Adding "<<nom_dom<<finl;
107 }
108 is >> nom_fichier_;
109 if(! sub_type(Domaine_t, objet(nom_dom)))
110 {
111 Cerr << nom_dom << " type is " << objet(nom_dom).que_suis_je() << finl;
112 Cerr << "Only Domaine type objects can be meshed" << finl;
113 exit();
114 }
115 dom_ = ref_cast(Domaine_t, objet(nom_dom));
116 ecrire_domaine(append);
117 return is;
118}
119
120#ifndef MED_
121template <typename _SIZE_>
122void Ecrire_MED_32_64<_SIZE_>::ecrire_champ(const Nom& type,const Nom& nom_cha1,const DoubleTab& val,const Noms& unite, const Noms& noms_compo, const Nom& type_elem,double time)
123{
124 med_non_installe();
125}
126
127template <typename _SIZE_>
129{
130 med_non_installe();
131}
132
133template <typename _SIZE_>
135{
136 med_non_installe();
137}
138
139template <typename _SIZE_>
141{
142 med_non_installe();
143}
144#else
145
146/*! @brief For each bord get starting and ending index (by construction in TRUST, face indices at the
147 * boundary are grouped)
148 */
149template <typename _SIZE_>
150void Ecrire_MED_32_64<_SIZE_>::get_bords_infos(Noms& noms_bords_and_jnts, ArrOfInt_t& sz_bords_and_jnts) const
151{
152 const Domaine_t& dom = dom_.valeur();
153 int nb_bords = dom.nb_front_Cl(), nb_faces_int = dom.nb_groupes_faces();
154
155 // [ABN] TODO handle joints properly - they could be written too
156 int nb_jnts = dom.nb_joints();
157 nb_jnts = 0;
158
159 noms_bords_and_jnts.dimensionner(nb_bords+nb_jnts+nb_faces_int);
160 sz_bords_and_jnts.resize_array(nb_bords+nb_jnts+nb_faces_int);
161
162 // Get border names and nb of faces:
163 for(int i=0; i<nb_bords + nb_faces_int; i++)
164 {
165 const Frontiere_32_64<_SIZE_>& front = dom.frontiere(i);
166 if (sub_type(Raccord_base_32_64<_SIZE_>,front))
167 {
168 noms_bords_and_jnts[i] = "type_raccord_";
169 noms_bords_and_jnts[i] += front.le_nom();
170 }
171 else if (sub_type(Groupe_Faces_32_64<_SIZE_>,front))
172 {
173 noms_bords_and_jnts[i] = "groupes_faces_";
174 noms_bords_and_jnts[i] += front.le_nom();
175 }
176 else
177 noms_bords_and_jnts[i] = front.le_nom();
178 sz_bords_and_jnts[i] = front.nb_faces();
179 }
180// for(int i=0; i<nb_jnts; i++)
181// {
182// const Joint& jnt = dom.joint(i);
183// noms_bords_and_jnts[nb_bords+i] = jnt.le_nom();
184// sz_bords_and_jnts[nb_bords+i] = jnt.nb_faces();
185// }
186}
187
188template <typename _SIZE_>
190{
192 {
193 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
194 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
195 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
196 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
197 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
198 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
199 Cerr << finl;
200 Cerr << "*** WARNING *** The MED post-processing format will generate " << Process::nproc() << " files" << finl;
201 Cerr << "This will slow I/O performances since it exceeds the limit of " << Process::multiple_files << finl;
202 Cerr << "Use LATA format instead or contact TRUST support team." << finl;
203 Cerr << finl;
204 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
205 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
206 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
207 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
208 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
209 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
210 Cerr << finl;
211 }
212 ecrire_domaine_dis(append);
213}
214
215/*! @brief Write the dual of the domain in the file
216 *
217 * @param append = false new file, append = true append to existing file
218 */
219template <>
221{
222 if (Objet_U::dimension==0)
223 Process::exit("Dimension is not defined. Check your data file.");
224#ifndef MEDCOUPLING_
225 med_non_installe(); // actually MEDCoupling ... but will do.
226#else
227
228 // Retrieve (or build!) the **dual** mesh associated with the domain.
229 // This potentially means discretizing the domaine !
230 assert(domaine_dis_);
231 const Domaine_VF& dom_vf = ref_cast(Domaine_VF, domaine_dis_.valeur());
232 const auto& dual_m = dom_vf.get_mc_dual_mesh();
233 MEDCouplingUMesh *dual_no_const = const_cast<MEDCouplingUMesh *>(dual_m); // because of setCoords() and setMeshAtLevel()
234
235 // Prepare final MEDFileUMesh object:
236 MCAuto<MEDFileUMesh> mfu(MEDFileUMesh::New());
237 mfu->setName(dual_m->getName()); // name must be provided
238 mfu->setCoords(dual_no_const->getCoords()); // should be the same coord array for all levels (i.e. dom->les_sommets())
239 mfu->setMeshAtLevel(0, dual_no_const, false);
240
241 // Check the mesh
242#ifndef NDEBUG
243 dual_m->checkConsistency();
244#endif
245
246 // Write:
247 int option = (append ? 1 : 2); /* 2: reset file. 1: append, 0: overwrite objects */
248 Cerr<<"Writing file '" << nom_fichier_<<"' with mesh name '" << dual_m->getName() << "' (append=" << (append ? "true": "false") << ") ..."<<finl;
249 mfu->write(nom_fichier_.getString(), option);
250
251#endif
252}
253
254template <typename _SIZE_>
256{
257 // not coded for 64b domains ...
258 throw;
259}
260
261/*! @brief Fill face and groups in the MEDCoupling object
262 *
263 * Two cases:
264 * - either we want the full face mesh, in which case we guarantee that the face numbering will be identical to TRUST in the
265 * final MED file
266 * - or, we only write boundary faces. In this case we can still preserve face numbering for all 'classical' borders (i.e. not
267 * joints) since by construction TRUST places those faces first, but faces of **joints** are renumbered.
268 */
269template <typename _SIZE_>
271{
272 using Frontiere_t = Frontiere_32_64<_SIZE_>;
273
274 // Fill arrays all_faces_bords and noms_bords
275 Noms noms_bords_and_jnts;
276 ArrOfInt_t sz_bords_and_jnts;
277 get_bords_infos(noms_bords_and_jnts, sz_bords_and_jnts);
278
279 int_t nfaces = 0;
280 bool full_face_mesh = domaine_dis_ && ref_cast(Domaine_VF, domaine_dis_.valeur()).elem_faces().size()>0;
281 // If the domain has faces (eg:domain computation), we can create a face mesh (all faces, incl internal ones), else only a boundary mesh
282 if (full_face_mesh)
283 {
284 assert((std::is_same<_SIZE_, int>::value)); // we have a Domaine_dis, so we discretized already, so we are 32bits ...
285 // Faces mesh - by construction (see build_mc_face_mesh) it will have the same face numbering as in TRUST.
286 const Domaine_VF& dom_vf = ref_cast(Domaine_VF, domaine_dis_.valeur());
287 dom_vf.build_mc_face_mesh();
288 const MEDCouplingUMesh *faces_mesh = dom_vf.get_mc_face_mesh();
289 MCAuto<MEDCouplingUMesh> face_mesh2 = faces_mesh->clone(false); // perform a super light copy, no data array copied
290 face_mesh2->setName(mfumesh_->getName()); // names have to be aligned ...
291 mfumesh_->setMeshAtLevel(-1, face_mesh2, false);
292 nfaces = static_cast<int>(faces_mesh->getNumberOfCells());
293 }
294 else // Boundary mesh only
295 {
296 MCAuto<MEDCouplingUMesh> boundary_mesh(MEDCouplingUMesh::New(mcumesh_->getName(), mesh_dimension_ - 1));
297 boundary_mesh->setCoords(mcumesh_->getCoords());
298
299 for (int j = 0; j < noms_bords_and_jnts.size(); j++) nfaces += sz_bords_and_jnts(j);
300 boundary_mesh->allocateCells(nfaces);
301
302 for (int b=0; b < noms_bords_and_jnts.size(); b++)
303 {
304 const Frontiere_t& front = ::mes_faces_fr(dom_.valeur(),b);
305 const IntTab_t& som_fac = front.les_sommets_des_faces();
306 int_t nb_fac = som_fac.dimension(0);
307 int nb_som_fac = som_fac.dimension_int(1);
308 const Nom& typ_f_trust = front.faces().type(front.faces().type_face());
309
310 int boundary_mesh_dimension = -1;
311 INTERP_KERNEL::NormalizedCellType typ_fac_mc = type_geo_trio_to_type_medcoupling(typ_f_trust, boundary_mesh_dimension);
312 assert(boundary_mesh_dimension == mesh_dimension_ - 1);
313
314 // Convert connectivity from TRUST to MED:
315 IntTab_t som_fac_cpy = som_fac; // a deep copy since next method modify this in place:
316 conn_trust_to_med(som_fac_cpy, typ_f_trust, true);
317 // Insert it in the MC mesh, **always as a polygon/segment**:
318 for (int_t face_idx=0; face_idx < nb_fac; face_idx++)
319 {
320 int nvertices = nb_som_fac;
321 for (int k = 0; k < nb_som_fac; k++)
322 if (som_fac_cpy(face_idx, k) < 0) nvertices--; // Non constant number of vertices (polygons)
323 if(std::is_same<_SIZE_, mcIdType>::value)
324 {
325 // Wild cast just for compiler (when _SIZE_!=mcIdType) - the test above ensures pointer types are aligned:
326 const mcIdType* where = (mcIdType *)(som_fac_cpy.addr() + face_idx*nb_som_fac);
327 boundary_mesh->insertNextCell(typ_fac_mc, nvertices, where);
328 }
329 else
330 {
331 auto ptr = som_fac_cpy.addr() + face_idx*nb_som_fac;
332 std::vector<mcIdType> tmp(ptr, ptr+nvertices); // will copy and downcast
333 boundary_mesh->insertNextCell(typ_fac_mc, nvertices, tmp.data());
334 }
335 }
336 }
337 mfumesh_->setMeshAtLevel(-1, boundary_mesh, false);
338 }
339
340 // Register groups
341 std::vector<const DataArrayIdType *> grps;
342 std::vector<MCAuto<DataArrayIdType>> grps_mem; // just for memory management -> will ensure proper array deletion when destroyed
343
344 int_t face_idx = 0, start, end;
345 int nb_bords = dom_->nb_front_Cl() + dom_->nb_groupes_faces();
346 for (int b=0; b < nb_bords; b++, face_idx=end) // not joints
347 {
348 MCAuto<DataArrayIdType> g(DataArrayIdType::New());
349 start=face_idx, end=start+sz_bords_and_jnts[b];
350 Cerr << " grp " << noms_bords_and_jnts[b] << " " << start << " " << end << finl;
351
352 g->alloc(end-start);
353 g->iota(start);
354 g->setName(noms_bords_and_jnts[b].getChar());
355 grps_mem.push_back(g);
356 grps.push_back(g);
357 }
358
359// [ABN] TODO handle joints properly - they could be written too.
360// // Joint do not necessary have consecutive face numbers and must be handled separately
361// for (int j=0; j < dom_->nb_joints(); j++)
362// {
363// const Joint& jnt = dom_->joint(j);
364// const ArrOfInt& ric = jnt.joint_item(JOINT_ITEM::FACE).items_communs();
365// assert(ric.size_array() == jnt.nb_faces());
366// MCAuto<DataArrayIdType> g(DataArrayIdType::New());
367// g->alloc(ric.size_array());
368// mcIdType* gP = g->getPointer();
369// if (full_face_mesh) // we can preserve original TRUST numbers
370// for (int k=0; k<jnt.nb_faces(); k++) gP[k] = ric(k);
371// else // otherwise just take next available ids:
372// for (int k=0; k<jnt.nb_faces(); k++) gP[k] = face_idx++;
373// g->setName(jnt.le_nom().getChar());
374// grps_mem.push_back(g);
375// grps.push_back(g);
376// }
377 // Save all this:
378 mfumesh_->setGroupsAtLevel(-1, grps);
379}
380
381/*! @brief Ecrit le domaine dom dans le fichier nom_fichier_
382 *
383 * @param append = false nouveau fichier, append = true ajout du domaine dans le fichier
384 */
385template <typename _SIZE_>
387{
388 if (Objet_U::dimension==0)
389 Process::exit("Dimension is not defined. Check your data file.");
390#ifndef MEDCOUPLING_
391 med_non_installe(); // actually MEDCoupling ... but will do.
392#else
393
394 // Retrieve (or build!) the MEDCouplingUMesh associated with the domain:
395 mcumesh_ = dom_->get_mc_mesh();
396 mesh_dimension_ = mcumesh_->getMeshDimension();
397 MEDCouplingUMesh *mc_no_const = const_cast<MEDCouplingUMesh *>(mcumesh_); // because of setCoords() and setMeshAtLevel()
398
399 // Prepare final MEDFileUMesh object:
400 mfumesh_ = MEDFileUMesh::New();
401 mfumesh_->setName(mcumesh_->getName()); // name must be provided
402 mfumesh_->setCoords(mc_no_const->getCoords()); // should be the same coord array for all levels (i.e. dom->les_sommets())
403 mfumesh_->setMeshAtLevel(0, mc_no_const, false);
404
405 // Check the mesh
406#ifndef NDEBUG
407 mcumesh_->checkConsistency();
408#endif
409
410 // Faces and group of faces representing boundaries:
411 fill_faces_and_boundaries();
412
413 // Write:
414 int option = (append ? 1 : 2); /* 2: reset file. 1: append, 0: overwrite objects */
415 Cerr<<"Writing file '" << nom_fichier_<<"' with mesh name '" << mfumesh_->getName() << "' (append=" << (append ? "true": "false") << ") ..."<<finl;
416 mfumesh_->write(nom_fichier_.getString(), option);
417#endif
418}
419
420#if INT_is_64_ == 2
421template <>
423{
424 Process::exit("Ecrire_MED_32_64<trustIdType>::ecrire_domaine_dis() -- Not allowed with a 64b object!");
425}
426#endif
427
428/*! @brief Permet d'ecrire le tableau de valeurs val comme un champ dans le fichier med de nom nom_fichier_, avec pour support le domaine de nom nom_dom.
429 *
430 * @param type: CHAMPPOINT,CHAMPMAILLE,CHAMPFACES
431 * @param nom_cha1 le nom du champ
432 * @param unite : les unites
433 * @param type_elem le type des elems du domaine
434 * @param time le temps
435 */
436template <typename _SIZE_>
437void Ecrire_MED_32_64<_SIZE_>::ecrire_champ(const Nom& type, const Nom& nom_cha1, const DoubleTab& val, const Noms& unite,
438 const Noms& noms_compo, const Nom& type_elem, double time)
439{
441 {
442 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
443 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
444 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
445 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
446 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
447 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
448 Cerr << finl;
449 Cerr << "*** WARNING *** The MED post-processing format will generate " << Process::nproc() << " files" << finl;
450 Cerr << "This will slow I/O performances since it exceeds the limit of " << Process::multiple_files << finl;
451 Cerr << "Use LATA format instead or contact TRUST support team." << finl;
452 Cerr << finl;
453 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
454 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
455 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
456 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
457 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
458 Cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << finl;
459 Cerr << finl;
460 }
461 const Nom& nom_dom = dom_->le_nom();
462#ifdef MEDCOUPLING_
463 // Create MEDCouplingField
464 MEDCoupling::TypeOfField field_type;
465 if (type == "CHAMPMAILLE")
466 field_type = MEDCoupling::ON_CELLS;
467 else if (type == "CHAMPPOINT")
468 field_type = MEDCoupling::ON_NODES;
469 else if (type == "CHAMPFACES")
470 field_type = MEDCoupling::ON_CELLS;
471 else
472 {
473 Cerr << "Field type " << type << " is not supported yet." << finl;
475 return;
476 }
477 std::string file_name = nom_fichier_.getString();
478 std::string field_name = nom_cha1.getString();
479 // Get the previous timestep:
480 if (timestep_.find(field_name)==timestep_.end())
481 {
482 int timestep = 0;
483 std::vector<std::string> field_names = GetAllFieldNames(file_name);
484 if (std::find(field_names.begin(), field_names.end(), field_name) != field_names.end())
485 {
486 std::vector<std::pair<std::pair<int, int>, double> > ts = GetAllFieldIterations(file_name, field_name);
487 timestep = ts[ts.size() - 1].first.first + 1;
488 }
489 timestep_.insert({field_name,timestep});
490 }
491 else
492 timestep_.at(field_name)++;
493 MCAuto<MEDCouplingFieldDouble> field(MEDCouplingFieldDouble::New(field_type, MEDCoupling::ONE_TIME));
494 field->setName(field_name);
495 field->setTime(time, timestep_.at(field_name), -1);
496 field->setTimeUnit("s");
497
498 // Get directly the U-mesh from the domain, except in some weird cases:
499 if (nom_dom == "PARTICULES")
500 {
501 MEDCoupling::CheckFileForRead(file_name);
502 std::string mesh_name = nom_dom.getString();
503 MCAuto<MEDFileMesh> mm(MEDFileMesh::New(file_name,mesh_name));
504 MEDFileMesh *mmPtr(mm);
505 MEDFileUMesh *mmuPtr=dynamic_cast<MEDFileUMesh *>(mmPtr);
506 if(!mmuPtr)
507 {
508 std::ostringstream oss;
509 oss << "ReadUMeshFromFile : With fileName=\""<< file_name << "\", meshName=\""<< mesh_name << "\" exists but it is not an unstructured mesh !";
510 throw INTERP_KERNEL::Exception(oss.str());
511 }
512 const MCAuto<MEDCouplingUMesh> umesh_particles = mmuPtr->getMeshAtLevel(1);
513 field->setMesh(umesh_particles);
514 }
515 else
516 {
517 if (type == "CHAMPFACES")
518 field->setMesh(domaine_dis_->get_mc_face_mesh());
519 else
520 field->setMesh(dom_->get_mc_mesh());
521 }
522
523 // Fill array:
524 int size = val.dimension(0);
525 if (size>0)
526 {
527 int nb_comp = val.nb_dim() == 1 ? 1 : val.dimension(1);
528 MCAuto<DataArrayDouble> array(DataArrayDouble::New());
529 array->useArray(val.addr(), false, MEDCoupling::DeallocType::CPP_DEALLOC, size, nb_comp);
530 // Units:
531
532 if (nb_comp > 1)
533 for (int i = 0; i < nb_comp; i++)
534 array->setInfoOnComponent(i, "[" + unite[i].getString() + "]");
535 else
536 array->setInfoOnComponent(0, "[" + unite[0].getString() + "]");
537 field->setArray(array);
538 // Write
539 MCAuto<MEDFileField1TS> file(MEDFileField1TS::New());
540 file->setFieldNoProfileSBT(field);
541 file->write(file_name, 0);
542 }
543#else
544 med_non_installe();
545#endif
546}
547
548#if INT_is_64_ == 2
549template <>
550void Ecrire_MED_32_64<trustIdType>::ecrire_champ(const Nom& type, const Nom& nom_cha1, const DoubleTab& val, const Noms& unite,
551 const Noms& noms_compo, const Nom& type_elem, double time)
552{
553 Process::exit("Ecrire_MED_32_64<trustIdType>::ecrire_champ() -- Not allowed with a 64b object!");
554}
555#endif
556
557
558#endif
559
560
561template class Ecrire_MED_32_64<int>;
562#if INT_is_64_ == 2
563template class Ecrire_MED_32_64<trustIdType>;
564#endif
565
566
classe Domaine_32_64 un Domaine est un maillage compose d'un ensemble d'elements geometriques de meme...
Definition Domaine.h:62
class Domaine_VF
Definition Domaine_VF.h:44
void build_mc_face_mesh() const
Build the MEDCoupling face mesh. It is always made of polygons (in 3D) for simplicity purposes....
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
Classe Ecrire_MED Ecrit un fichier MED.
Definition Ecrire_MED.h:45
void ecrire_domaine_dis(bool append=true)
void ecrire_champ(const Nom &type, const Nom &nom_cha1, const DoubleTab &val, const Noms &unite, const Noms &noms_compo, const Nom &type_elem, double time)
Nom nom_fichier_
Name of the MED file to write.
Definition Ecrire_MED.h:78
Ecrire_MED_32_64(const Nom &file_name, const Domaine_t &dom)
void get_bords_infos(Noms &noms_bords_and_jnts, ArrOfInt_t &sz_bords_and_jnts) const
void ecrire_domaine_dual(bool append=true)
Domaine_32_64< _SIZE_ > Domaine_t
Definition Ecrire_MED.h:52
void set_file_name_and_dom(const Nom &file_name, const Domaine_t &dom, const Domaine_dis_base *dom_dis=nullptr)
void fill_faces_and_boundaries()
Entree & interpreter(Entree &) override
void ecrire_domaine(bool append=true)
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Classe Frontiere.
Definition Frontiere.h:32
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Frontiere.h:49
int_t nb_faces() const
Renvoie le nombre de faces de la frontiere.
Definition Frontiere.h:59
Classe Groupe_Face La classe sert a representer une selection de faces lu dans le fichier med.
Classe de base des objets "interprete".
Definition Interprete.h:38
static Objet_U & objet(const Nom &)
Voir Interprete_bloc::objet_global() BM: la classe Interprete n'est pas le meilleur endroit pour cett...
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
const std::string & getString() const
Definition Nom.h:92
const Nom & le_nom() const override
Renvoie *this;.
Definition Nom.cpp:563
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
friend class Entree
Definition Objet_U.h:76
static int dimension
Definition Objet_U.h:99
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
static int multiple_files
Definition Process.h:164
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 void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe Raccord_base Cette classe est simplement une frontiere, c'est la classe de base de la.
static std::string root
Classe de base des flux de sortie.
Definition Sortie.h:52
_TYPE_ * addr()
int nb_dim() const
Definition TRUSTTab.h:199
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133