v0.15.0
Loading...
Searching...
No Matches
MedInterface.cpp
Go to the documentation of this file.
1/** \file MedInterface.cpp
2 * \brief Med file interface interface
3 *
4 * Interface loading mesh and data on mesh directly to mofem & moab
5 *
6 */
7
8#ifdef WITH_MED
9
10extern "C" {
11#include <med.h>
12}
13
14#if (MED_MAJOR_NUM >= 3)
15// To avoid too many ifdefs below we use defines for the bits of the
16// API that did not change too much between MED2 and MED3. If we
17// remove MED2 support at some point, please remove these defines and
18// replace the symbols accordingly.
19#define med_geometrie_element med_geometry_type
20#define med_entite_maillage med_entity_type
21#define med_type_champ med_field_type
22#define MED_LECTURE MED_ACC_RDONLY
23#define MED_LECTURE_AJOUT MED_ACC_RDEXT
24#define MED_NOEUD MED_NODE
25#define MED_MAILLE MED_CELL
26#define MED_NOEUD_MAILLE MED_NODE_ELEMENT
27#define MED_NOPFL MED_NO_PROFILE
28#define MEDouvrir MEDfileOpen
29#define MEDfermer MEDfileClose
30#define MEDnChamp MEDfieldnComponent
31#define MEDnValProfil MEDprofileSizeByName
32#define MEDfichDesEcr MEDfileCommentWr
33#define MED_ARETE MED_EDGE
34#define MED_FACETTE MED_FACE
35#else
36#error "MED file is not MED_MAJOR_NUM == 3"
37#endif
38
39#include <MedInterface.hpp>
40#include <unordered_set>
41
42namespace MoFEM {
43
45MedInterface::query_interface(boost::typeindex::type_index type_index,
46 UnknownInterface **iface) const {
47 *iface = const_cast<MedInterface *>(this);
48 return 0;
49}
50
52 : cOre(const_cast<Core &>(core)), flgFile(PETSC_FALSE) {
53
54 if (!LogManager::checkIfChannelExist("MEDWORLD")) {
55 auto core_log = logging::core::get();
56 core_log->add_sink(
58 LogManager::setLog("MEDWORLD");
59 MOFEM_LOG_TAG("MEDWORLD", "MED");
60 }
61
62 MOFEM_LOG("MEDWORLD", Sev::noisy) << "Mashset manager created";
63}
64
66 Interface &m_field = cOre;
67 char mesh_file_name[255];
69 PetscOptionsBegin(m_field.get_comm(), "", "MED Interface", "none");
70 ierr = PetscOptionsString("-med_file", "med file name", "", "mesh.med",
71 mesh_file_name, 255, &flgFile);
73 PetscOptionsEnd();
74 if (flgFile == PETSC_TRUE) {
75 medFileName = std::string(mesh_file_name);
76 } else {
77 medFileName = std::string("mesh.med");
78 }
80}
81
82MoFEMErrorCode MedInterface::medGetFieldNames(const string &file, int verb) {
83 Interface &m_field = cOre;
85 med_idt fid = MEDfileOpen(file.c_str(), MED_ACC_RDONLY);
86 if (fid < 0) {
87 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
88 "Unable to open file '%s'", file.c_str());
89 }
90 med_int num_fields = MEDnField(fid);
91 for (int index = 0; index < num_fields; index++) {
92
93 med_int num_comp = MEDfieldnComponent(fid, index + 1);
94 if (num_comp <= 0) {
95 SETERRQ(m_field.get_comm(), MOFEM_IMPOSSIBLE_CASE,
96 "Could not get number of components for MED field");
97 }
98
99 char name[MED_NAME_SIZE + 1], mesh_name[MED_NAME_SIZE + 1];
100 char dt_unit[MED_SNAME_SIZE + 1];
101 std::vector<char> comp_name(num_comp * MED_SNAME_SIZE + 1);
102 std::vector<char> comp_unit(num_comp * MED_SNAME_SIZE + 1);
103 med_int num_steps = 0;
104 med_type_champ type;
105 med_bool local_mesh;
106 if (MEDfieldInfo(fid, index + 1, name, mesh_name, &local_mesh, &type,
107 &comp_name[0], &comp_unit[0], dt_unit, &num_steps) < 0) {
108 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
109 "Could not get MED field info");
110 }
111
112 std::string field_name = std::string(name);
114 fieldNames[field_name].fieldName = field_name;
115 fieldNames[field_name].meshName = std::string(mesh_name);
116 fieldNames[field_name].localMesh = (local_mesh == MED_TRUE);
117 for (int ff = 0; ff != num_comp; ff++) {
118 fieldNames[field_name].componentNames.push_back(
119 std::string(&comp_name[ff * MED_SNAME_SIZE], MED_SNAME_SIZE));
120 fieldNames[field_name].componentUnits.push_back(
121 std::string(&comp_unit[ff * MED_SNAME_SIZE], MED_SNAME_SIZE));
122 }
123 fieldNames[field_name].dtUnit = std::string(&dt_unit[0]);
124 fieldNames[field_name].ncSteps = num_steps;
125
126 if (verb > 0)
127 MOFEM_LOG("MEDWORLD", Sev::inform) << fieldNames[name];
128 }
129 if (MEDfileClose(fid) < 0) {
130 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
131 "Unable to close file '%s'", file.c_str());
132 }
134}
135
144
145MoFEMErrorCode MedInterface::readMed(const string &file, int verb) {
146 Interface &m_field = cOre;
148
149 med_idt fid = MEDfileOpen(file.c_str(), MED_ACC_RDONLY);
150 if (fid < 0) {
151 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
152 "Unable to open file '%s'", file.c_str());
153 }
154
155 med_int v[3], vf[3];
156 MEDlibraryNumVersion(&v[0], &v[1], &v[2]);
157 MEDfileNumVersionRd(fid, &vf[0], &vf[1], &vf[2]);
158
159 if (verb > 0)
160 MOFEM_LOG_C("MEDWORLD", Sev::inform,
161 "Reading MED file V%d.%d.%d using MED library V%d.%d.%d", vf[0],
162 vf[1], vf[2], v[0], v[1], v[2]);
163
164 if (vf[0] < 2 || (vf[0] == 2 && vf[1] < 2)) {
165 SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
166 "Cannot read MED file older than V2.2");
167 }
168
169 for (int i = 0; i < MEDnMesh(fid); i++) {
170 char mesh_name[MED_NAME_SIZE + 1], mesh_desc[MED_COMMENT_SIZE + 1];
171 bzero(mesh_name, MED_NAME_SIZE);
172 bzero(mesh_desc, MED_COMMENT_SIZE);
173 med_int space_dim;
174 med_mesh_type mesh_type;
175 med_int mesh_dim, n_step;
176 char dt_unit[MED_SNAME_SIZE + 1];
177 char axis_name[3 * MED_SNAME_SIZE + 1], axis_unit[3 * MED_SNAME_SIZE + 1];
178 med_sorting_type sorting_type;
179 med_axis_type axis_type;
180 if (MEDmeshInfo(fid, i + 1, mesh_name, &space_dim, &mesh_dim, &mesh_type,
181 mesh_desc, dt_unit, &sorting_type, &n_step, &axis_type,
182 axis_name, axis_unit) < 0) {
183 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
184 "Unable to read mesh information");
185 }
186 meshNames.push_back(std::string(mesh_name));
187 if (verb > 0) {
188 MOFEM_LOG_C("MEDWORLD", Sev::inform, "Check mesh %s nsteps %d", mesh_name,
189 n_step);
190 }
191 }
192
193 std::map<int, Range> family_elem_map;
194 std::map<string, Range> group_elem_map;
195
196 for (unsigned int ii = 0; ii != meshNames.size(); ii++) {
197 CHKERR readMesh(file, ii, family_elem_map, verb);
198 CHKERR readFamily(file, ii, family_elem_map, group_elem_map, verb);
199 CHKERR makeBlockSets(group_elem_map, verb);
200 }
201
202 if (MEDfileClose(fid) < 0) {
203 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
204 "Unable to close file '%s'", file.c_str());
205 }
206
208}
209
210static std::vector<med_geometrie_element>
211moab2med_element_type(const EntityType type) {
212
213 std::vector<med_geometrie_element> types;
214
215 switch (type) {
216 case MBEDGE:
217 types.push_back(MED_SEG2);
218 types.push_back(MED_SEG3);
219 break;
220 case MBTRI:
221 types.push_back(MED_TRIA3);
222 types.push_back(MED_TRIA6);
223 break;
224 case MBQUAD:
225 types.push_back(MED_QUAD4);
226 break;
227 case MBTET:
228 types.push_back(MED_TETRA4);
229 types.push_back(MED_TETRA10);
230 break;
231 case MBHEX:
232 types.push_back(MED_HEXA8);
233 break;
234 case MBPRISM:
235 types.push_back(MED_PENTA6);
236 break;
237 case MBPYRAMID:
238 types.push_back(MED_PYRA5);
239 break;
240 case MBVERTEX:
241 // Not Currently Used
242 //types.push_back(MED_POINT1);
243 break;
244 default:
245 break;
246 }
247
248 return types;
249}
250
251MoFEMErrorCode MedInterface::readMesh(const string &file, const int index,
252 std::map<int, Range> &family_elem_map,
253 int verb) {
254
255 Interface &m_field = cOre;
257
258 med_idt fid = MEDfileOpen(file.c_str(), MED_ACC_RDONLY);
259 if (fid < 0) {
260 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
261 "Unable to open file '%s'", file.c_str());
262 }
263 med_int v[3], vf[3];
264 MEDlibraryNumVersion(&v[0], &v[1], &v[2]);
265 MEDfileNumVersionRd(fid, &vf[0], &vf[1], &vf[2]);
266 if (verb > 1)
267 MOFEM_LOG_C("MEDWORLD", Sev::noisy,
268 "Reading MED file V%d.%d.%d using MED library V%d.%d.%d", vf[0],
269 vf[1], vf[2], v[0], v[1], v[2]);
270
271 if (vf[0] < 2 || (vf[0] == 2 && vf[1] < 2)) {
272 SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
273 "Cannot read MED file older than V2.2");
274 }
275
276 char mesh_name[MED_NAME_SIZE + 1], mesh_desc[MED_COMMENT_SIZE + 1];
277 bzero(mesh_name, MED_NAME_SIZE + 1);
278 bzero(mesh_desc, MED_COMMENT_SIZE + 1);
279 med_int space_dim;
280 med_mesh_type mesh_type;
281 med_int mesh_dim, n_step;
282 char dt_unit[MED_SNAME_SIZE + 1];
283 char axis_name[3 * MED_SNAME_SIZE + 1], axis_unit[3 * MED_SNAME_SIZE + 1];
284 med_sorting_type sorting_type;
285 med_axis_type axis_type;
286 if (MEDmeshInfo(fid, index + 1, mesh_name, &space_dim, &mesh_dim, &mesh_type,
287 mesh_desc, dt_unit, &sorting_type, &n_step, &axis_type,
288 axis_name, axis_unit) < 0) {
289 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
290 "Unable to read mesh information");
291 }
292 if (verb > 0)
293 MOFEM_LOG_C("MEDWORLD", Sev::inform, "Reading mesh %s nsteps %d", mesh_name,
294 n_step);
295
296 switch (axis_type) {
297 case MED_CARTESIAN:
298 break;
299 case MED_SPHERICAL:
300 case MED_CYLINDRICAL:
301 default:
302 SETERRQ(m_field.get_comm(), MOFEM_NOT_IMPLEMENTED,
303 "Curvilinear coordinate system implemented");
304 }
305 if (space_dim < 2) {
306 SETERRQ(m_field.get_comm(), MOFEM_NOT_IMPLEMENTED,
307 "Not implemented for space dim %d", space_dim);
308 }
309
310 EntityHandle mesh_meshset;
311 {
312 MeshsetsManager *meshsets_manager_ptr;
313 CHKERR m_field.getInterface(meshsets_manager_ptr);
314 int max_id = 0;
316 max_id = (max_id < cit->getMeshsetId()) ? cit->getMeshsetId() : max_id;
317 }
318 max_id++;
319 CHKERR meshsets_manager_ptr->addMeshset(BLOCKSET, max_id,
320 std::string(mesh_name));
321 CubitMeshSet_multiIndex::index<
323 cit =
324 meshsets_manager_ptr->getMeshsetsMultindex()
326 .find(boost::make_tuple(max_id, CubitBCType(BLOCKSET).to_ulong()));
327 max_id++;
328 mesh_meshset = cit->getMeshset();
329 meshMeshsets.push_back(mesh_meshset);
330 }
331
332 med_bool change_of_coord, geo_transform;
333 med_int num_nodes = MEDmeshnEntity(
334 fid, mesh_name, MED_NO_DT, MED_NO_IT, MED_NODE, MED_NO_GEOTYPE,
335 MED_COORDINATE, MED_NO_CMODE, &change_of_coord, &geo_transform);
336 if (num_nodes < 0) {
337 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
338 "Could not read number of MED nodes");
339 }
340 if (num_nodes == 0) {
341 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
342 "No nodes in MED mesh");
343 }
344 if (verb > 0)
345 MOFEM_LOG_C("MEDWORLD", Sev::inform, "Read number of nodes %d", num_nodes);
346
347 std::vector<med_float> coord_med(space_dim * num_nodes);
348 if (MEDmeshNodeCoordinateRd(fid, mesh_name, MED_NO_DT, MED_NO_IT,
349 MED_NO_INTERLACE, &coord_med[0]) < 0) {
350 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
351 "Could not read MED node coordinates");
352 }
353
354 // Add vertices to moab
355 ReadUtilIface *iface;
356 vector<double *> arrays_coord;
357 EntityHandle startv;
358 CHKERR m_field.get_moab().query_interface(iface);
359 CHKERR iface->get_node_coords(3, num_nodes, 0, startv, arrays_coord);
360 Range verts(startv, startv + num_nodes - 1);
361 std::copy(&coord_med[0 * num_nodes], &coord_med[1 * num_nodes],
362 arrays_coord[0]);
363 std::copy(&coord_med[1 * num_nodes], &coord_med[2 * num_nodes],
364 arrays_coord[1]);
365 if (space_dim == 2) {
366 std::fill(arrays_coord[2], &arrays_coord[2][num_nodes], 0.);
367 } else {
368 std::copy(&coord_med[2 * num_nodes], &coord_med[3 * num_nodes],
369 arrays_coord[2]);
370 }
371 CHKERR m_field.get_moab().add_entities(mesh_meshset, verts);
372 family_elem_map.clear();
373
374 // get family for vertices
375 {
376 std::vector<med_int> nodes_tags(num_nodes, 0);
377 if (MEDmeshEntityFamilyNumberRd(fid, mesh_name, MED_NO_DT, MED_NO_IT,
378 MED_NODE, MED_NO_GEOTYPE,
379 &nodes_tags[0]) < 0) {
380 nodes_tags.clear();
381 }
382 for (int i = 0; i < num_nodes; i++) {
383 family_elem_map[nodes_tags.empty() ? i : nodes_tags[i]].insert(verts[i]);
384 }
385 }
386
387 // read elements (loop over all possible MSH element types)
388 for (EntityType ent_type = MBVERTEX; ent_type < MBMAXTYPE; ent_type++) {
389
390 auto types = moab2med_element_type(ent_type);
391
392 for (auto type : types) {
393
394 // get number of cells
395 med_bool change_of_coord;
396 med_bool geo_transform;
397 med_int num_ele = MEDmeshnEntity(
398 fid, mesh_name, MED_NO_DT, MED_NO_IT, MED_CELL, type,
399 MED_CONNECTIVITY, MED_NODAL, &change_of_coord, &geo_transform);
400
401 // get connectivity
402 if (num_ele <= 0)
403 continue;
404
405 int num_nod_per_ele = type % 100;
406 if (verb > 0)
407 MOFEM_LOG("MEDWORLD", Sev::inform)
408 << "Reading elements " << num_ele << " of type "
409 << moab::CN::EntityTypeName(ent_type) << " number of nodes "
410 << num_nod_per_ele;
411
412 std::vector<med_int> conn_med(num_ele * num_nod_per_ele);
413 if (MEDmeshElementConnectivityRd(fid, mesh_name, MED_NO_DT, MED_NO_IT,
414 MED_CELL, type, MED_NODAL,
415 MED_FULL_INTERLACE, &conn_med[0]) < 0) {
416 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
417 "Could not read MED elements");
418 }
419
420 Range ents;
421
422 if (ent_type != MBVERTEX) {
423 EntityHandle *conn_moab;
424 EntityHandle starte;
425 CHKERR iface->get_element_connect(num_ele, num_nod_per_ele, ent_type, 0,
426 starte, conn_moab);
427 switch (ent_type) {
428 // FIXME: Some connectivity could not work, need to run and test
429 case MBTET: {
430 int ii = 0;
431 for (int ee = 0; ee != num_ele; ee++) {
432 std::vector<EntityHandle> n(num_nod_per_ele);
433 for (int nn = 0; nn != num_nod_per_ele; nn++) {
434 n[nn] = verts[conn_med[ii + nn] - 1];
435 }
436
437 std::array<int, 10> nodes_map{
438
439 1, 0, 2, 3,
440
441 4, 6, 5, 8,
442 7, 9
443
444 };
445
446 for (int nn = 0; nn != num_nod_per_ele; nn++, ii++) {
447 conn_moab[ii] = n[nodes_map[nn]];
448 }
449 }
450 } break;
451 default: {
452 int ii = 0;
453 for (int ee = 0; ee != num_ele; ee++) {
454 for (int nn = 0; nn != num_nod_per_ele; nn++, ii++) {
455 conn_moab[ii] = verts[conn_med[ii] - 1];
456 }
457 }
458 }
459 }
460 CHKERR iface->update_adjacencies(starte, num_ele, num_nod_per_ele,
461 conn_moab);
462 ents = Range(starte, starte + num_ele - 1);
463 } else {
464 // This is special case when in med vertices are defined as elements
465 int ii = 0;
466 std::vector<EntityHandle> conn_moab(num_ele * num_nod_per_ele);
467 for (int ee = 0; ee != num_ele; ++ee)
468 for (int nn = 0; nn != num_nod_per_ele; ++nn, ++ii)
469 conn_moab[ii] = verts[conn_med[ii] - 1];
470 ents.insert_list(conn_moab.begin(), conn_moab.end());
471 }
472
473 // Add elements to family meshset
474 CHKERR m_field.get_moab().add_entities(mesh_meshset, ents);
475
476 // get family for cells
477 {
478 std::vector<med_int> fam(num_ele, 0);
479 if (MEDmeshEntityFamilyNumberRd(fid, mesh_name, MED_NO_DT, MED_NO_IT,
480 MED_CELL, type, &fam[0]) < 0) {
481 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
482 "No family number for elements: using 0 as default family "
483 "number");
484 }
485 for (int j = 0; j < num_ele; j++) {
486 family_elem_map[fam[j]].insert(ents[j]);
487 }
488 }
489 }
490 }
491
492 if (MEDfileClose(fid) < 0) {
493 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
494 "Unable to close file '%s'", file.c_str());
495 }
496
498}
499
501MedInterface::readFamily(const string &file, const int index,
502 const std::map<int, Range> &family_elem_map,
503 std::map<string, Range> &group_elem_map, int verb) {
504 Interface &m_field = cOre;
506
507 med_idt fid = MEDfileOpen(file.c_str(), MED_ACC_RDONLY);
508 if (fid < 0) {
509 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
510 "Unable to open file '%s'", file.c_str());
511 }
512 med_int v[3], vf[3];
513 MEDlibraryNumVersion(&v[0], &v[1], &v[2]);
514 MEDfileNumVersionRd(fid, &vf[0], &vf[1], &vf[2]);
515
516 if (verb > 1) {
517 MOFEM_LOG_C("MEDWORLD", Sev::noisy,
518 "Reading MED file V%d.%d.%d using MED library V%d.%d.%d", vf[0],
519 vf[1], vf[2], v[0], v[1], v[2]);
520 }
521 if (vf[0] < 2 || (vf[0] == 2 && vf[1] < 2)) {
522 SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
523 "Cannot read MED file older than V2.2");
524 }
525
526 // clear groups
527 group_elem_map.clear();
528
529 med_int num_families = MEDnFamily(fid, meshNames[index].c_str());
530 if (num_families < 0) {
531 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
532 "Could not read MED families");
533 }
534 for (int i = 0; i < num_families; i++) {
535 med_int num_attrib =
536 (vf[0] == 2)
537 ? MEDnFamily23Attribute(fid, meshNames[index].c_str(), i + 1)
538 : 0;
539 med_int num_groups = MEDnFamilyGroup(fid, meshNames[index].c_str(), i + 1);
540 if (num_attrib < 0 || num_groups < 0) {
541 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
542 "Could not read MED groups or attributes");
543 }
544
545 std::vector<med_int> attribId(num_attrib + 1);
546 std::vector<med_int> attrib_val(num_attrib + 1);
547 std::vector<char> attrib_des(MED_COMMENT_SIZE * num_attrib + 1);
548 std::vector<char> group_names(MED_LNAME_SIZE * num_groups + 1);
549 char family_name[MED_NAME_SIZE + 1];
550 med_int family_num;
551
552 if (vf[0] == 2) { // MED2 file
553 if (MEDfamily23Info(fid, meshNames[index].c_str(), i + 1, family_name,
554 &attribId[0], &attrib_val[0], &attrib_des[0],
555 &family_num, &group_names[0]) < 0) {
556 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
557 "Could not read info for MED2 family %d", i + 1);
558 }
559 } else {
560 if (MEDfamilyInfo(fid, meshNames[index].c_str(), i + 1, family_name,
561 &family_num, &group_names[0]) < 0) {
562 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
563 "Could not read info for MED3 family %d", i + 1);
564 }
565 }
566
567 for (int g = 0; g != num_groups; g++) {
568 std::string name =
569 std::string(&group_names[MED_LNAME_SIZE * g], MED_LNAME_SIZE - 1);
570 name.resize(NAME_TAG_SIZE - 1);
571 if (family_elem_map.find(family_num) == family_elem_map.end()) {
573 "MEDWORLD", Sev::warning,
574 "Family %d not read, likely type of element is not added "
575 "to moab database. Currently only triangle, quad, tetrahedral and "
576 "hexahedral elements are read to moab database",
577 family_num);
578 } else {
579 group_elem_map[name].merge(family_elem_map.at(family_num));
580 }
581 }
582 }
583
584 if (MEDfileClose(fid) < 0) {
585 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
586 "Unable to close file '%s'", file.c_str());
587 }
588
590}
591
593MedInterface::makeBlockSets(const std::map<string, Range> &group_elem_map,
594 int verb) {
595
596 Interface &m_field = cOre;
598 MeshsetsManager *meshsets_manager_ptr;
599 CHKERR m_field.getInterface(meshsets_manager_ptr);
600
601 int max_id = 0;
603 max_id = (max_id < cit->getMeshsetId()) ? cit->getMeshsetId() : max_id;
604 }
605 max_id++;
606
607 for (std::map<string, Range>::const_iterator git = group_elem_map.begin();
608 git != group_elem_map.end(); git++) {
609 CHKERR meshsets_manager_ptr->addMeshset(BLOCKSET, max_id, git->first);
610 CubitMeshSet_multiIndex::index<
612 cit =
613 meshsets_manager_ptr->getMeshsetsMultindex()
615 .find(boost::make_tuple(max_id, CubitBCType(BLOCKSET).to_ulong()));
616 EntityHandle meshsets = cit->getMeshset();
617 if (!git->second.empty()) {
618 CHKERR m_field.get_moab().add_entities(meshsets, git->second);
619 }
620 max_id++;
621 }
622
624 MOFEM_LOG("MEDWORLD", Sev::verbose) << *cit;
625
627}
628
637
639 boost::shared_ptr<std::vector<const CubitMeshSets *>> &meshsets_ptr) {
640 Interface &m_field = cOre;
642
643 auto &meshsets_idx =
644 m_field.getInterface<MeshsetsManager>()->getMeshsetsMultindex();
645 std::vector<const CubitMeshSets *> meshsets;
646
647 for (auto &m : meshsets_idx) {
648 meshsets.push_back(&m);
649 }
650 // Sort meshsets based on meshsetId
651 std::sort(meshsets.begin(), meshsets.end(),
652 [](const CubitMeshSets *a, const CubitMeshSets *b) {
653 return a->getMeshsetId() < b->getMeshsetId();
654 });
655
656 meshsets_ptr =
657 boost::make_shared<std::vector<const CubitMeshSets *>>(meshsets);
659}
660
661MoFEMErrorCode MedInterface::writeMed(boost::shared_ptr<Range> range_ptr,
662 int verb) {
664 if (medFileName.empty()) {
666 }
667
668 // Get all meshsets
669 boost::shared_ptr<std::vector<const CubitMeshSets *>> meshsets_ptr;
670 getMeshsets(meshsets_ptr);
671
672 CHKERR writeMed(medFileName, meshsets_ptr, range_ptr, verb);
674}
675
677 const string &file,
678 boost::shared_ptr<std::vector<const CubitMeshSets *>> meshsets_ptr,
679 boost::shared_ptr<Range> write_range_ptr, int verb) {
680 Interface &m_field = cOre;
681 // Get the MOAB instance from the field
682 moab::Interface &moab = m_field.get_moab();
683
685 MOFEM_LOG("MEDWORLD", Sev::warning)
686 << "WRITE_MED IS EXPERIMENTAL, MAY CONTAIN BUGS, ALWAYS CHECK THE OUTPUT "
687 "FILE";
688 // Open a med file with the specified version
689 med_idt fid =
690 MEDfileVersionOpen((char *)file.c_str(), MED_ACC_CREAT, MED_MAJOR_NUM,
691 MED_MINOR_NUM, MED_RELEASE_NUM);
692 // Throw an error if the file could not be opened
693 if (fid < 0) {
694 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
695 "Cannot create MED file");
696 return 0;
697 }
698
699 // Write appropriate header
700 CHKERR MEDfichDesEcr(fid, (char *)"MED file generated by MoFEM");
701
702 // Generate empty mesh
703 char dtUnit[MED_SNAME_SIZE + 1] = ""; // time unit
704 char axisName[3 * MED_SNAME_SIZE + 1] = ""; // axis name
705 char axisUnit[3 * MED_SNAME_SIZE + 1] = ""; // axis unit
706
707 PetscBool is_cubit_meshset = PETSC_TRUE;
708 int med_mesh_name_id = 0;
709
710 // Create the mesh
711 char mesh_name_char[255];
712 std::string mesh_name = "Mesh";
713
714 // Get mesh_name from command line
715 PetscOptionsBegin(PETSC_COMM_WORLD, "", "MED mesh options", "");
716 CHKERR PetscOptionsString("-med_mesh_name", "get med mesh name", "",
717 mesh_name.c_str(), mesh_name_char, 255, PETSC_NULLPTR);
718 PetscOptionsEnd();
719
720 mesh_name = mesh_name_char;
721
722 // check if mesh_name is a meshset
723 for (auto &m : *meshsets_ptr) {
724 if (m->getName() == mesh_name) {
725 med_mesh_name_id = m->getMeshsetId();
726 is_cubit_meshset = PETSC_FALSE;
727 break;
728 }
729 }
730
731 // Get the maximum meshset id
732 int max_id = 0;
733 for (auto &m : *meshsets_ptr) {
734 if (m->getMeshsetId() == med_mesh_name_id)
735 mesh_name = m->getName();
736 max_id = (max_id < m->getMeshsetId()) ? m->getMeshsetId() : max_id;
737 }
738
739 // Create a mesh
740 CHKERR MEDmeshCr(fid, mesh_name.c_str(), 3, 3, MED_UNSTRUCTURED_MESH,
741 "Mesh created", dtUnit, MED_SORT_DTIT, MED_CARTESIAN,
742 axisName, axisUnit);
743
744 // Create a map of meshset names to family ids and shared meshsets
745 med_int family_id = 0;
746 std::map<std::vector<std::string>, std::tuple<med_int, std::vector<int>>>
747 shared_meshsets_map;
748 std::map<EntityHandle, med_int> entityHandle_family_map;
749
750 // initialise zero family id
751 shared_meshsets_map[std::vector<string>()] =
752 std::make_tuple(family_id, std::vector<int>());
753
754 // function to get meshset names
755 auto get_set_name = [&](const CubitMeshSets *iit) {
756 std::string bc_type_name;
757 if (iit->getBcTypeULong() & BLOCKSET) {
758
759 bc_type_name = iit->getName();
760 if (bc_type_name == "NoNameSet") {
761 bc_type_name = "BLOCKSET_";
762 bc_type_name += std::to_string(iit->getMeshsetId());
763 }
764 return bc_type_name;
765 } else if (iit->getBcTypeULong() & SIDESET ||
766 iit->getBcTypeULong() & NODESET) {
767
768 CubitBCType cubitBcType(iit->getBcTypeULong());
769
770 unsigned jj = 0;
771 while (1 << jj != LASTSET_BC) {
772 const CubitBCType jj_bc_type = 1 << jj;
773 if ((iit->getBcType() & jj_bc_type).any()) {
774
775 std::string temp_bc_type_name = string(CubitBCNames[jj + 1]);
776 if (temp_bc_type_name.length() > 10) {
777 temp_bc_type_name = temp_bc_type_name.substr(0, 4);
778 }
779 bc_type_name += temp_bc_type_name;
780 bc_type_name += "_";
781 }
782 ++jj;
783 }
784 bc_type_name += std::to_string(iit->getMeshsetId());
785 } else {
786 bc_type_name = "UnknownSet";
787 }
788 return bc_type_name;
789 };
790
791 // loop over all entities in the write range
792 // FIXME: This is a very slow implementation
793 // We should use a binary search tree
794 // instead of looping each entity in
795 // write_range_ptr to find shared meshsets
796 for (auto &entity : *write_range_ptr) {
797 // check if entity is shared with other meshsets
798 std::vector<int> shared_meshsets;
799 std::vector<string> shared_names;
800
801 // function to add shared meshsets to vectors
802 auto add_shared_meshset = [&](auto &other_meshset) {
803 std::string other_name = get_set_name(other_meshset);
804 if (std::find(shared_names.begin(), shared_names.end(), other_name) ==
805 shared_names.end()) {
806 shared_meshsets.push_back(other_meshset->getMeshsetId());
807 shared_names.push_back(other_name);
808 }
809 };
810
811 // loop over all meshsets provided
812 for (auto &other_meshset : *meshsets_ptr) {
813 // skip if meshset is the global meshset given by user
814 if (med_mesh_name_id == other_meshset->getMeshsetId())
815 continue;
816
817 Range other_entities;
818 EntityHandle other_set = other_meshset->getMeshset();
819 moab.get_entities_by_handle(other_set, other_entities);
820 if (other_entities.empty())
821 continue;
822
823 bool is_in_meshset = moab.contains_entities(other_set, &entity, 1);
824 if (is_in_meshset) {
825 // add shared meshset id to list
826 add_shared_meshset(other_meshset);
827 }
828 }
829
830 // check if shared meshset is already in map
831 auto it = shared_meshsets_map.find(shared_names);
832 if (it == shared_meshsets_map.end()) {
833 // create new family id
834 family_id++;
835 // create and insert new tuple into the map
836 it = shared_meshsets_map
837 .insert(
838 {shared_names, std::make_tuple(family_id, shared_meshsets)})
839 .first;
840 }
841 // assign family id to entity
842 entityHandle_family_map[entity] = std::get<0>(it->second);
843 }
844
845 // loop to create families based on shared meshsets map
846 for (const auto &it : shared_meshsets_map) {
847 // create family
848 std::string family_name = "F_";
849 const auto &[family_id, shared_meshsets] = it.second;
850 family_name += std::to_string(family_id);
851
852 const auto &shared_meshset_names = it.first;
853 std::string group_name;
854 for (const auto &name : shared_meshset_names) {
855 // get meshset name
856 std::string meshset_name = name;
857 meshset_name.resize(MED_LNAME_SIZE, ' ');
858 group_name += meshset_name;
859 }
860
861 // create family
862 CHKERR MEDfamilyCr(fid, mesh_name.c_str(), family_name.c_str(), family_id,
863 shared_meshset_names.size(), group_name.c_str());
864
865 MOFEM_LOG("MEDWORLD", Sev::inform)
866 << "Creating family " << family_name << " with id " << family_id
867 << " and " << shared_meshset_names.size() << " groups " << std::endl;
868 }
869
870 // write nodes from range
871 Range verts;
872 verts = write_range_ptr->subset_by_type(MBVERTEX);
873
874 // Prepare arrays to hold the coordinates
875 std::vector<med_float> coord_med(3 * verts.size());
876 std::vector<med_int> fam;
877 std::vector<med_int> tags;
878 std::map<EntityHandle, med_int> entityHandle_tag_map;
879 med_int med_node_num = 1;
880
881 // For each vertex, get its coordinates
882 for (Range::iterator it = verts.begin(); it != verts.end(); ++it) {
883 double coords[3];
884 moab.get_coords(&(*it), 1, coords);
885 coord_med[3 * (it - verts.begin())] = coords[0];
886 coord_med[3 * (it - verts.begin()) + 1] = coords[1];
887 coord_med[3 * (it - verts.begin()) + 2] = coords[2];
888 fam.push_back(entityHandle_family_map[*it]);
889 tags.push_back(*it);
890 // map entityHandle to new tag (node) number
891 entityHandle_tag_map[*it] = med_node_num;
892 med_node_num++;
893 }
894 // Write the coordinates to the MED file
895 CHKERR MEDmeshNodeWr(fid, mesh_name.c_str(), MED_NO_DT, MED_NO_IT,
896 MED_UNDEF_DT, MED_FULL_INTERLACE, verts.size(),
897 &coord_med[0], MED_FALSE, "", MED_TRUE, &tags[0],
898 MED_TRUE, &fam[0]);
899
900 // get last vertex id
901 double last_tag = tags.back();
902 // loop to write elements to families
903 for (EntityType ent_type = MBVERTEX; ent_type < MBMAXTYPE; ent_type++) {
904 // get all entities of type ent_type
905 Range entities;
906 moab.get_entities_by_type(0, ent_type, entities, true);
907 Range ents_to_write;
908 ents_to_write = intersect(entities, *write_range_ptr);
909
910 if (ents_to_write.empty())
911 continue;
912
913 // vectors to write
914 std::vector<med_int> tag_number;
915 std::vector<med_int> family_number;
916 std::vector<med_int> connectivity;
917
918 // loop over all entities
919 for (auto &entity : ents_to_write) {
920 if (ent_type != MBVERTEX) {
921 last_tag++;
922 // get family id for entity
923 family_number.push_back(entityHandle_family_map[entity]);
924 // get tag number for entity
925 tag_number.push_back(last_tag);
926 // get connectivity for entity
927 std::vector<EntityHandle> conn;
928 moab.get_connectivity(&entity, 1, conn);
929 // add connectivity to vector from map of entityHandle to new tag number
930 for (auto &c : conn) {
931 connectivity.push_back(entityHandle_tag_map[c]);
932 }
933 } else {
934 continue;
935 }
936 }
937
938 auto get_med_element_type = [](EntityType ent_type) {
939 med_geometrie_element type;
940 switch (ent_type) {
941 case MBHEX:
942 type = MED_HEXA8;
943 break;
944 case MBTET:
945 type = MED_TETRA4;
946 break;
947 case MBQUAD:
948 type = MED_QUAD4;
949 break;
950 case MBTRI:
951 type = MED_TRIA3;
952 break;
953 case MBEDGE:
954 type = MED_SEG2;
955 break;
956 case MBPRISM:
957 type = MED_PENTA6;
958 break;
959 default:
960 type = MED_POINT1;
961 break;
962 }
963 return type;
964 };
965
966 med_geometrie_element med_type = get_med_element_type(ent_type);
967 if (ent_type == MBENTITYSET) {
968 continue;
969 }
970 CHKERR MEDmeshElementWr(fid, mesh_name.c_str(), MED_NO_DT, MED_NO_IT, 0.,
971 MED_CELL, med_type, MED_NODAL, MED_FULL_INTERLACE,
972 family_number.size(), &connectivity[0], MED_FALSE,
973 nullptr, MED_TRUE, &tag_number[0], MED_TRUE,
974 &family_number[0]);
975
976 MOFEM_LOG_C("MEDWORLD", Sev::inform, "Writing %i elements of type %i (%s) ",
977 family_number.size(), med_type,
978 moab::CN::EntityTypeName(ent_type));
979 }
980
981 // Close the MED file
982 CHKERR MEDfermer(fid);
984}
985
986MoFEMErrorCode MedInterface::readFields(const std::string &file_name,
987 const std::string &field_name,
988 const bool load_series,
989 const int only_step, int verb) {
990
991 Interface &m_field = cOre;
993 med_idt fid = MEDfileOpen((char *)file_name.c_str(), MED_LECTURE);
994 if (fid < 0) {
995 SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
996 "Unable to open file '%s'", file_name.c_str());
997 }
998
999 med_int num_comp = MEDfieldnComponentByName(fid, field_name.c_str());
1000 if (num_comp <= 0) {
1001 SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1002 "Could not get number of components for MED field");
1003 }
1004
1005 char meshName[MED_NAME_SIZE + 1];
1006 char dtUnit[MED_SNAME_SIZE + 1];
1007 std::vector<char> compName(num_comp * MED_SNAME_SIZE + 1);
1008 std::vector<char> compUnit(num_comp * MED_SNAME_SIZE + 1);
1009 med_int numSteps = 0;
1010 med_type_champ type;
1011 med_bool localMesh;
1012 if (MEDfieldInfoByName(fid, field_name.c_str(), meshName, &localMesh, &type,
1013 &compName[0], &compUnit[0], dtUnit, &numSteps) < 0) {
1014 SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1015 "Could not get MED field info");
1016 }
1017
1018 // Get meshset
1019 MeshsetsManager *meshsets_manager_ptr;
1020 CHKERR m_field.getInterface(meshsets_manager_ptr);
1021 const CubitMeshSets *cubit_meshset_ptr;
1022 CHKERR meshsets_manager_ptr->getCubitMeshsetPtr(meshName, &cubit_meshset_ptr);
1023 EntityHandle meshset = cubit_meshset_ptr->getMeshset();
1024
1025 // Paraview can only plot field which have 1, 3, or 9 components. If field has
1026 // more that 9 comonents, it is stored on MOAB mesh but not viable in
1027 // ParaView.
1028 int num_comp_msh = (num_comp <= 1) ? 1
1029 : (num_comp <= 3) ? 3
1030 : (num_comp <= 9) ? 9
1031 : num_comp;
1032
1033 // Create tag to store nodal or cell values read form med file. Note that tag
1034 // has prefix MED to avoid collision with other tags.
1035 Tag th;
1036 std::string tag_name = "MED_" + field_name;
1037 {
1038 std::vector<double> def_val(num_comp_msh, 0);
1039 CHKERR m_field.get_moab().tag_get_handle(
1040 tag_name.c_str(), num_comp_msh, MB_TYPE_DOUBLE, th,
1041 MB_TAG_CREAT | MB_TAG_SPARSE, &def_val[0]);
1042 }
1043
1044 // Warning! The ordering of the elements in the last two lists is
1045 // important: it should match the ordering of the MSH element types
1046 // (when elements are saved without tags, this governs the order
1047 // with which we implicitly index them in GModel::readMED)
1048 const med_entity_type entType[] = {MED_NODE, MED_CELL, MED_NODE_ELEMENT};
1049 const med_geometrie_element eleType[] = {
1050 MED_NONE, MED_SEG2, MED_TRIA3, MED_QUAD4, MED_TETRA4, MED_HEXA8,
1051 MED_PENTA6, MED_PYRA5, MED_SEG3, MED_TRIA6, MED_QUAD9, MED_TETRA10,
1052 MED_HEXA27, MED_POINT1, MED_QUAD8, MED_HEXA20, MED_PENTA15, MED_PYRA13};
1053 // const int nodesPerEle[] = {0, 2, 3, 4, 4, 8, 6, 5, 3, 6, 9, 10, 27, 1, 8,
1054 // 20, 15, 13};
1055
1056 std::vector<std::pair<int, int>> pairs;
1057 for (unsigned int i = 0; i < sizeof(entType) / sizeof(entType[0]); i++) {
1058 for (unsigned int j = 0; j < sizeof(eleType) / sizeof(eleType[0]); j++) {
1059 if ((!i && !j) || j) {
1060 med_int n = numSteps;
1061 if (n > 0) {
1062 pairs.push_back(std::pair<int, int>(i, j));
1063 numSteps = std::max(numSteps, n);
1064 }
1065 if (!i && !j)
1066 break; // MED_NOEUD does not care about eleType
1067 }
1068 }
1069 }
1070
1071 if (numSteps < 1 || pairs.empty()) {
1072 SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1073 "Nothing to import from MED file");
1074 }
1075
1076 if (load_series) {
1077 SETERRQ(m_field.get_comm(), MOFEM_NOT_IMPLEMENTED, "Not yet implemented");
1078 }
1079
1080 for (int step = (only_step == -1) ? 0 : only_step; step < numSteps; step++) {
1081
1082 if (!load_series && only_step != step)
1083 continue;
1084
1085 // FIXME: in MED3 we might want to loop over all profiles instead
1086 // of relying of the default one
1087
1088 // FIXME: MED3 allows to store multi-step meshes; we should
1089
1090 for (unsigned int pair = 0; pair < pairs.size(); pair++) {
1091
1092 // get step info
1093 med_entite_maillage ent = entType[pairs[pair].first];
1094 med_geometrie_element ele = eleType[pairs[pair].second];
1095 med_int numdt, numit, ngauss;
1096 med_float dt;
1097 if (MEDfieldComputingStepInfo(fid, field_name.c_str(), step + 1, &numdt,
1098 &numit, &dt) < 0) {
1099 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
1100 "Could not read step info");
1101 }
1102
1103 char locName[MED_NAME_SIZE + 1], profileName[MED_NAME_SIZE + 1];
1104
1105 // get number of values in the field (numVal takes the number of
1106 // Gauss points or the number of nodes per element into account,
1107 // but not the number of components)
1108 med_int profileSize;
1109 med_int numVal = MEDfieldnValueWithProfile(
1110 fid, field_name.c_str(), numdt, numit, ent, ele, 1,
1111 MED_COMPACT_STMODE, profileName, &profileSize, locName, &ngauss);
1112 numVal *= ngauss;
1113
1114 if (numVal <= 0)
1115 continue;
1116
1117 // read field data
1118 std::vector<double> val(numVal * num_comp);
1119 if (MEDfieldValueWithProfileRd(fid, field_name.c_str(), numdt, numit, ent,
1120 ele, MED_COMPACT_STMODE, profileName,
1121 MED_FULL_INTERLACE, MED_ALL_CONSTITUENT,
1122 (unsigned char *)&val[0]) < 0) {
1123 SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
1124 "Could not read field values");
1125 }
1126
1127 switch (ent) {
1128 case MED_CELL: {
1129 EntityType ent_type = MBMAXTYPE;
1130 switch (ele) {
1131 case MED_TETRA4:
1132 case MED_TETRA10:
1133 ent_type = MBTET;
1134 break;
1135 case MED_HEXA8:
1136 ent_type = MBHEX;
1137 break;
1138 default:
1139 MOFEM_LOG_C("MEDWORLD", Sev::warning,
1140 "Not yet implemented for this cell %d", ele);
1141 }
1142 if (ent_type != MBMAXTYPE) {
1143 if (ngauss == 1) {
1144 Range ents;
1145 CHKERR m_field.get_moab().get_entities_by_type(meshset, ent_type,
1146 ents, true);
1147 double e_vals[num_comp_msh];
1148 bzero(e_vals, sizeof(double) * num_comp_msh);
1149 std::vector<double>::iterator vit = val.begin();
1150 for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
1151 for (int ii = 0; ii != num_comp; ii++, vit++) {
1152 e_vals[ii] = *vit;
1153 }
1154 CHKERR m_field.get_moab().tag_set_data(th, &*eit, 1, e_vals);
1155 }
1156 } else {
1157 Range ents;
1158 CHKERR m_field.get_moab().get_entities_by_type(meshset, ent_type,
1159 ents, true);
1160 if (ents.size() * ngauss * num_comp != val.size()) {
1161 SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1162 "data inconsistency");
1163 }
1164 // FIXME simply average gauss values, far from perfect need fix
1165 double e_vals[num_comp_msh];
1166 std::vector<double>::iterator vit = val.begin();
1167 for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
1168 bzero(e_vals, sizeof(double) * num_comp_msh);
1169 for (int gg = 0; gg != ngauss; gg++) {
1170 for (int ii = 0; ii != num_comp; ii++, vit++) {
1171 e_vals[ii] += *vit / ngauss;
1172 }
1173 }
1174 CHKERR m_field.get_moab().tag_set_data(th, &*eit, 1, e_vals);
1175 }
1176 }
1177 }
1178 } break;
1179 case MED_NODE:
1180 case MED_NODE_ELEMENT: {
1181 EntityType ent_type = MBVERTEX;
1182 Range ents;
1183 CHKERR m_field.get_moab().get_entities_by_type(meshset, ent_type, ents,
1184 true);
1185 double e_vals[num_comp_msh];
1186 bzero(e_vals, sizeof(double) * num_comp_msh);
1187 std::vector<double>::iterator vit = val.begin();
1188 for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
1189 for (int ii = 0; ii != num_comp; ii++, vit++) {
1190 e_vals[ii] = *vit;
1191 }
1192 CHKERR m_field.get_moab().tag_set_data(th, &*eit, 1, e_vals);
1193 }
1194 } break;
1195 default:
1196 MOFEM_LOG_C("MEDWORLD", Sev::inform, "Entity type %d not implemented",
1197 ent);
1198 }
1199 }
1200 }
1201
1203}
1204
1205std::ostream &operator<<(std::ostream &os,
1206 const MedInterface::FieldData &field_data) {
1207 os << "field name: " << field_data.fieldName;
1208 os << " mesh name: " << field_data.meshName;
1209 os << " local mesh: " << ((field_data.localMesh) ? "true" : "false");
1210 os << std::endl;
1211 os << " componentNames:";
1212 for (unsigned int ff = 0; ff != field_data.componentNames.size(); ff++) {
1213 os << " " << field_data.componentNames[ff];
1214 }
1215 os << std::endl;
1216 os << " componentUnits:";
1217 for (unsigned int ff = 0; ff != field_data.componentUnits.size(); ff++) {
1218 os << " " << field_data.componentUnits[ff];
1219 }
1220 os << std::endl;
1221 os << " dtUnit: " << field_data.dtUnit << endl;
1222 os << " number of steps: " << field_data.ncSteps;
1223 return os;
1224}
1225
1226 } // namespace MoFEM
1227
1228#endif // WITH_MED
#define MOFEM_LOG_C(channel, severity, format,...)
Med file interface interface.
constexpr double a
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define CHKERRG(n)
Check error code of MoFEM/MOAB/PETSc function.
@ NODESET
@ SIDESET
@ LASTSET_BC
@ BLOCKSET
@ MOFEM_IMPOSSIBLE_CASE
Definition definitions.h:35
@ MOFEM_OPERATION_UNSUCCESSFUL
Definition definitions.h:34
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
static const char *const CubitBCNames[]
Names of types of sets and boundary conditions.
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
MoFEMErrorCode addMeshset(const CubitBCType cubit_bc_type, const int ms_id, const std::string name="")
add cubit meshset
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
#define _IT_CUBITMESHSETS_BY_SET_TYPE_FOR_LOOP_(MESHSET_MANAGER, CUBITBCTYPE, IT)
Iterator that loops over a specific Cubit MeshSet having a particular BC meshset in a moFEM field.
FTensor::Index< 'i', SPACE_DIM > i
double dt
const double c
speed of light (cm/ns)
const double v
phase velocity of light in medium (cm/ns)
const double n
refractive index of diffusive medium
FTensor::Index< 'j', 3 > j
char mesh_file_name[255]
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
std::bitset< 32 > CubitBCType
Definition Types.hpp:52
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
std::ostream & operator<<(std::ostream &os, const EntitiesFieldData::EntData &e)
static std::vector< med_geometrie_element > moab2med_element_type(const EntityType type)
constexpr auto field_name
constexpr double g
FTensor::Index< 'm', 3 > m
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
Core (interface) class.
Definition Core.hpp:82
this struct keeps basic methods for moab meshset about material and boundary conditions
EntityHandle getMeshset() const
get bc meshset
Deprecated interface functions.
static boost::shared_ptr< SinkType > createSink(boost::shared_ptr< std::ostream > stream_ptr, std::string comm_filter)
Create a sink object.
static boost::shared_ptr< std::ostream > getStrmWorld()
Get the strm world object.
static bool checkIfChannelExist(const std::string channel)
Check if channel exist.
std::vector< std::string > componentNames
std::vector< std::string > componentUnits
Interface for load MED files.
MoFEMErrorCode readMed(const string &file, int verb=1)
read MED file
MoFEMErrorCode writeMed(boost::shared_ptr< Range > range_ptr=nullptr, int verb=1)
write MED file
std::vector< EntityHandle > meshMeshsets
meshset for each mesh
MoFEMErrorCode readFamily(const string &file, const int index, const std::map< int, Range > &family_elem_mapint, std::map< string, Range > &group_elem_map, int verb=1)
read family and groups
MoFEMErrorCode makeBlockSets(const std::map< string, Range > &group_elem_map, int verb=1)
make from groups meshsets
std::map< std::string, FieldData > fieldNames
std::string medFileName
MED file name.
MoFEMErrorCode getMeshsets(boost::shared_ptr< std::vector< const CubitMeshSets * > > &meshsets_ptr)
MoFEMErrorCode getFileNameFromCommandLine(int verb=1)
Get MED file name from command line.
MedInterface(const MoFEM::Core &core)
std::vector< std::string > meshNames
list of meshes in MED file
MoFEM::Core & cOre
core database
MoFEMErrorCode readFields(const std::string &file_name, const std::string &field_name, const bool load_series=false, const int only_step=-1, int verb=1)
MoFEMErrorCode readMesh(const string &file, const int index, std::map< int, Range > &family_elem_map, int verb=1)
read mesh from MED file
PetscBool flgFile
true if file name given in command line
MoFEMErrorCode medGetFieldNames(const string &file, int verb=1)
Get field names in MED file.
MoFEMErrorCode query_interface(boost::typeindex::type_index type_index, UnknownInterface **iface) const
Interface for managing meshsets containing materials and boundary conditions.
CubitMeshSet_multiIndex & getMeshsetsMultindex()
base class for all interface classes
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.