701 {
703
704 moab::Interface &moab = m_field.
get_moab();
705
708 << "WRITE_MED IS EXPERIMENTAL, MAY CONTAIN BUGS, ALWAYS CHECK THE OUTPUT "
709 "FILE";
710
711 med_idt fid =
712 MEDfileVersionOpen((
char *)
file.c_str(), MED_ACC_CREAT, MED_MAJOR_NUM,
713 MED_MINOR_NUM, MED_RELEASE_NUM);
714
715 if (fid < 0) {
717 "Cannot create MED file");
718 return 0;
719 }
720
721
722 CHKERR MEDfichDesEcr(fid, (
char *)
"MED file generated by MoFEM");
723
724
725 char dtUnit[MED_SNAME_SIZE + 1] = "";
726 char axisName[3 * MED_SNAME_SIZE + 1] = "";
727 char axisUnit[3 * MED_SNAME_SIZE + 1] = "";
728
729 PetscBool is_cubit_meshset = PETSC_TRUE;
730 int med_mesh_name_id = 0;
731
732
733 char mesh_name_char[255];
734 std::string mesh_name = "Mesh";
735
736
737 PetscOptionsBegin(PETSC_COMM_WORLD, "", "MED mesh options", "");
738 CHKERR PetscOptionsString(
"-med_mesh_name",
"get med mesh name",
"",
739 mesh_name.c_str(), mesh_name_char, 255, PETSC_NULLPTR);
740 PetscOptionsEnd();
741
742 mesh_name = mesh_name_char;
743
744
745 for (
auto &
m : *meshsets_ptr) {
746 if (
m->getName() == mesh_name) {
747 med_mesh_name_id =
m->getMeshsetId();
748 is_cubit_meshset = PETSC_FALSE;
749 break;
750 }
751 }
752
753
754 int max_id = 0;
755 for (
auto &
m : *meshsets_ptr) {
756 if (
m->getMeshsetId() == med_mesh_name_id)
757 mesh_name =
m->getName();
758 max_id = (max_id <
m->getMeshsetId()) ?
m->getMeshsetId() : max_id;
759 }
760
761
762 CHKERR MEDmeshCr(fid, mesh_name.c_str(), 3, 3, MED_UNSTRUCTURED_MESH,
763 "Mesh created", dtUnit, MED_SORT_DTIT, MED_CARTESIAN,
764 axisName, axisUnit);
765
766
767 med_int family_id = 0;
768 std::map<std::vector<std::string>, std::tuple<med_int, std::vector<int>>>
769 shared_meshsets_map;
770 std::map<EntityHandle, med_int> entityHandle_family_map;
771
772
773 shared_meshsets_map[std::vector<string>()] =
774 std::make_tuple(family_id, std::vector<int>());
775
776
777 auto get_set_name = [&](const CubitMeshSets *iit) {
778 std::string bc_type_name;
779 if (iit->getBcTypeULong() &
BLOCKSET) {
780
781 bc_type_name = iit->getName();
782 if (bc_type_name == "NoNameSet") {
783 bc_type_name = "BLOCKSET_";
784 bc_type_name += std::to_string(iit->getMeshsetId());
785 }
786 return bc_type_name;
787 }
else if (iit->getBcTypeULong() &
SIDESET ||
788 iit->getBcTypeULong() &
NODESET) {
789
791
792 unsigned jj = 0;
795 if ((iit->getBcType() & jj_bc_type).any()) {
796
797 std::string temp_bc_type_name = string(
CubitBCNames[jj + 1]);
798 if (temp_bc_type_name.length() > 10) {
799 temp_bc_type_name = temp_bc_type_name.substr(0, 4);
800 }
801 bc_type_name += temp_bc_type_name;
802 bc_type_name += "_";
803 }
804 ++jj;
805 }
806 bc_type_name += std::to_string(iit->getMeshsetId());
807 } else {
808 bc_type_name = "UnknownSet";
809 }
810 return bc_type_name;
811 };
812
813
814
815
816
817
818 for (auto &entity : *write_range_ptr) {
819
820 std::vector<int> shared_meshsets;
821 std::vector<string> shared_names;
822
823
824 auto add_shared_meshset = [&](auto &other_meshset) {
825 std::string other_name = get_set_name(other_meshset);
826 if (std::find(shared_names.begin(), shared_names.end(), other_name) ==
827 shared_names.end()) {
828 shared_meshsets.push_back(other_meshset->getMeshsetId());
829 shared_names.push_back(other_name);
830 }
831 };
832
833
834 for (auto &other_meshset : *meshsets_ptr) {
835
836 if (med_mesh_name_id == other_meshset->getMeshsetId())
837 continue;
838
839 Range other_entities;
841 moab.get_entities_by_handle(other_set, other_entities);
842 if (other_entities.empty())
843 continue;
844
845 bool is_in_meshset = moab.contains_entities(other_set, &entity, 1);
846 if (is_in_meshset) {
847
848 add_shared_meshset(other_meshset);
849 }
850 }
851
852
853 auto it = shared_meshsets_map.find(shared_names);
854 if (it == shared_meshsets_map.end()) {
855
856 family_id++;
857
858 it = shared_meshsets_map
859 .insert(
860 {shared_names, std::make_tuple(family_id, shared_meshsets)})
861 .first;
862 }
863
864 entityHandle_family_map[entity] = std::get<0>(it->second);
865 }
866
867
868 for (const auto &it : shared_meshsets_map) {
869
870 std::string family_name = "F_";
871 const auto &[family_id, shared_meshsets] = it.second;
872 family_name += std::to_string(family_id);
873
874 const auto &shared_meshset_names = it.first;
875 std::string group_name;
876 for (const auto &name : shared_meshset_names) {
877
878 std::string meshset_name = name;
879 meshset_name.resize(MED_LNAME_SIZE, ' ');
880 group_name += meshset_name;
881 }
882
883
884 CHKERR MEDfamilyCr(fid, mesh_name.c_str(), family_name.c_str(), family_id,
885 shared_meshset_names.size(), group_name.c_str());
886
888 << "Creating family " << family_name << " with id " << family_id
889 << " and " << shared_meshset_names.size() << " groups " << std::endl;
890 }
891
892
894 verts = write_range_ptr->subset_by_type(MBVERTEX);
895
896
897 std::vector<med_float> coord_med(3 * verts.size());
898 std::vector<med_int> fam;
899 std::vector<med_int> tags;
900 std::map<EntityHandle, med_int> entityHandle_tag_map;
901 med_int med_node_num = 1;
902
903
904 for (Range::iterator it = verts.begin(); it != verts.end(); ++it) {
905 double coords[3];
906 moab.get_coords(&(*it), 1, coords);
907 coord_med[3 * (it - verts.begin())] = coords[0];
908 coord_med[3 * (it - verts.begin()) + 1] = coords[1];
909 coord_med[3 * (it - verts.begin()) + 2] = coords[2];
910 fam.push_back(entityHandle_family_map[*it]);
911 tags.push_back(*it);
912
913 entityHandle_tag_map[*it] = med_node_num;
914 med_node_num++;
915 }
916
917 CHKERR MEDmeshNodeWr(fid, mesh_name.c_str(), MED_NO_DT, MED_NO_IT,
918 MED_UNDEF_DT, MED_FULL_INTERLACE, verts.size(),
919 &coord_med[0], MED_FALSE, "", MED_TRUE, &tags[0],
920 MED_TRUE, &fam[0]);
921
922
923 double last_tag = tags.back();
924
925 for (EntityType ent_type = MBVERTEX; ent_type < MBMAXTYPE; ent_type++) {
926
928 moab.get_entities_by_type(0, ent_type, entities, true);
930 ents_to_write = intersect(entities, *write_range_ptr);
931
932 if (ents_to_write.empty())
933 continue;
934
935
936 std::vector<med_int> tag_number;
937 std::vector<med_int> family_number;
938 std::vector<med_int> connectivity;
939
940
941 for (auto &entity : ents_to_write) {
942 if (ent_type != MBVERTEX) {
943 last_tag++;
944
945 family_number.push_back(entityHandle_family_map[entity]);
946
947 tag_number.push_back(last_tag);
948
949 std::vector<EntityHandle> conn;
950 moab.get_connectivity(&entity, 1, conn);
951
952 for (
auto &
c : conn) {
953 connectivity.push_back(entityHandle_tag_map[
c]);
954 }
955 } else {
956 continue;
957 }
958 }
959
960 auto get_med_element_type = [](EntityType ent_type) {
961 med_geometrie_element
type;
962 switch (ent_type) {
963 case MBHEX:
965 break;
966 case MBTET:
968 break;
969 case MBQUAD:
971 break;
972 case MBTRI:
974 break;
975 case MBEDGE:
977 break;
978 case MBPRISM:
980 break;
981 default:
983 break;
984 }
986 };
987
988 med_geometrie_element med_type = get_med_element_type(ent_type);
989 if (ent_type == MBENTITYSET) {
990 continue;
991 }
992 CHKERR MEDmeshElementWr(fid, mesh_name.c_str(), MED_NO_DT, MED_NO_IT, 0.,
993 MED_CELL, med_type, MED_NODAL, MED_FULL_INTERLACE,
994 family_number.size(), &connectivity[0], MED_FALSE,
995 nullptr, MED_TRUE, &tag_number[0], MED_TRUE,
996 &family_number[0]);
997
998 MOFEM_LOG_C(
"MEDWORLD", Sev::inform,
"Writing %zu elements of type %i (%s) ",
999 family_number.size(), med_type,
1000 moab::CN::EntityTypeName(ent_type));
1001 }
1002
1003
1006}
static const char *const CubitBCNames[]
Names of types of sets and boundary conditions.
const double c
speed of light (cm/ns)
moab::Interface & get_moab()