14#include "arcane/utils/Iostream.h"
15#include "arcane/utils/StdHeader.h"
16#include "arcane/utils/HashTableMap.h"
17#include "arcane/utils/ValueConvert.h"
18#include "arcane/utils/ScopedPtr.h"
19#include "arcane/utils/ArcanePrecomp.h"
20#include "arcane/utils/ITraceMng.h"
21#include "arcane/utils/Collection.h"
22#include "arcane/utils/Enumerator.h"
23#include "arcane/utils/PlatformUtils.h"
24#include "arcane/utils/Real3.h"
25#include "arcane/utils/OStringStream.h"
26#include "arcane/utils/CheckedConvert.h"
27#include "arcane/utils/StringBuilder.h"
29#include "arcane/core/IMeshReader.h"
30#include "arcane/core/IGhostLayerMng.h"
31#include "arcane/core/ISubDomain.h"
32#include "arcane/core/IIOMng.h"
33#include "arcane/core/IParallelMng.h"
34#include "arcane/core/IPrimaryMesh.h"
35#include "arcane/core/Item.h"
36#include "arcane/core/ItemTypeMng.h"
37#include "arcane/core/ItemGroup.h"
38#include "arcane/core/ArcaneException.h"
39#include "arcane/core/Service.h"
40#include "arcane/core/Timer.h"
42#include "arcane/core/ServiceInfo.h"
43#include "arcane/core/CaseOptionsMain.h"
46#include "arcane/core/VariableTypes.h"
47#include "arcane/core/ServiceBuildInfo.h"
48#include "arcane/core/XmlNodeList.h"
49#include "arcane/core/IXmlDocumentHolder.h"
50#include "arcane/core/IItemFamily.h"
51#include "arcane/core/FactoryService.h"
52#include "arcane/core/IMeshWriter.h"
53#include "arcane/core/AbstractService.h"
54#include "arcane/core/ICaseDocument.h"
55#include "arcane/core/ICaseMeshReader.h"
56#include "arcane/core/IMeshBuilder.h"
58#include "arcane/lima/LimaCutInfosReader.h"
59#include "arcane/lima/internal/LimaUtils.h"
61#include <Lima/lima++.h>
84 std::mutex global_lima_mutex;
89 explicit GlobalLimaMutex(
bool is_active)
90 : m_is_active(is_active)
93 global_lima_mutex.lock();
98 global_lima_mutex.unlock();
103 bool m_is_active =
false;
120 , m_sub_domain(sub_domain)
122 virtual ~LimaMeshBase() {}
127 const String& dir_name,
bool use_internal_partition,
Real length_multiplier) = 0;
129 ISubDomain* subDomain()
const {
return m_sub_domain; }
147template <
typename ReaderWrapper>
154 : LimaMeshBase(sub_domain)
160 delete m_cut_infos_reader;
166 const String& dir_name,
bool use_internal_partition,
Real length_multiplier);
171 ReaderWrapper m_wrapper;
174 const String& dir_name,
bool use_internal_partition,
Real length_multiplier);
186 void setLima(
const Lima::Maillage& lima_mesh)
188 m_lima_mesh = lima_mesh;
193 Lima::Maillage m_lima_mesh;
204 typedef Lima::Surface LimaCellGroup;
205 typedef Lima::Polygone LimaCell;
206 typedef Lima::Ligne LimaFaceGroup;
207 typedef Lima::Bras LimaFace;
213 return CheckedConvert::toInteger(m_lima_mesh.nb_surfaces());
217 return CheckedConvert::toInteger(m_lima_mesh.nb_lignes());
219 LimaCellGroup cellGroup(
Integer i)
221 return m_lima_mesh.surface(i);
223 LimaFaceGroup faceGroup(
Integer i)
225 return m_lima_mesh.ligne(i);
227 Integer faceGroupNbFace(
const LimaFaceGroup& group)
229 return CheckedConvert::toInteger(group.nb_bras());
231 LimaFace faceFaceGroup(
const LimaFaceGroup& group,
Integer i)
233 return group.bras(i);
235 Integer cellGroupNbCell(
const LimaCellGroup& group)
237 return CheckedConvert::toInteger(group.nb_polygones());
239 LimaCell cellCellGroup(
const LimaCellGroup& group,
Integer i)
241 return group.polygone(i);
245 return m_lima_mesh.polygone(i);
249 return m_lima_mesh.bras(i);
253 return CheckedConvert::toInteger(m_lima_mesh.nb_polygones());
257 return CheckedConvert::toInteger(m_lima_mesh.nb_bras());
263 const char* strDimension()
293 typedef Lima::Volume LimaCellGroup;
294 typedef Lima::Polyedre LimaCell;
295 typedef Lima::Surface LimaFaceGroup;
296 typedef Lima::Polygone LimaFace;
300 return CheckedConvert::toInteger(m_lima_mesh.nb_volumes());
304 return CheckedConvert::toInteger(m_lima_mesh.nb_surfaces());
306 LimaCellGroup cellGroup(
Integer i)
308 return m_lima_mesh.volume(i);
310 LimaFaceGroup faceGroup(
Integer i)
312 return m_lima_mesh.surface(i);
314 Integer faceGroupNbFace(
const LimaFaceGroup& group)
316 return CheckedConvert::toInteger(group.nb_polygones());
318 LimaFace faceFaceGroup(
const LimaFaceGroup& group,
Integer i)
320 return group.polygone(i);
322 Integer cellGroupNbCell(
const LimaCellGroup& group)
324 return CheckedConvert::toInteger(group.nb_polyedres());
326 LimaCell cellCellGroup(
const LimaCellGroup& group,
Integer i)
328 return group.polyedre(i);
332 return m_lima_mesh.polyedre(i);
336 return m_lima_mesh.polygone(i);
340 return CheckedConvert::toInteger(m_lima_mesh.nb_polyedres());
344 return CheckedConvert::toInteger(m_lima_mesh.nb_polygones());
350 const char* strDimension()
358 return IT_Tetraedron4;
362 return IT_Pentaedron6;
364 return IT_Hexaedron8;
366 return IT_Heptaedron10;
368 return IT_Octaedron12;
394 const String& dir_name,
bool use_internal_partition,
407class LimaMeshReaderService
423 return str ==
"unf" || str ==
"mli" || str ==
"mli2" || str ==
"ice" || str ==
"uns" || str ==
"unv";
428 const String& dir_name,
bool use_internal_partition)
override;
429 ISubDomain* subDomain() {
return m_sub_domain; }
433 ISubDomain* m_sub_domain;
448LimaMeshReaderService::
451, m_sub_domain(sbi.subDomain())
461 bool use_internal_partition)
465 String case_doc_lang =
"en";
468 case_doc_lang = case_doc->
language();
471 String use_unit_attr_name =
"utilise-unite";
473 if (case_doc_lang ==
"en") {
476 if (!use_unit_str.
empty()) {
477 warning() <<
"'utilise-unite' should only be used for French datasets."
478 <<
"Use 'use-unit' instead";
480 use_unit_attr_name =
"use-unit";
486 if (use_unit_str.
null()) {
487 info() <<
"Attribute '" << use_unit_attr_name <<
"' is not found. Trying with 'use-unit'";
488 use_unit_attr_name =
"use-unit";
494 bool use_length_unit =
true;
496 use_length_unit =
false;
497 info() <<
"Default value for unit usage: " << use_length_unit;
499 if (use_unit_str.
empty())
500 use_unit_str = mesh_node.
attrValue(use_unit_attr_name);
501 info() <<
"Checking for attribute '" << use_unit_attr_name <<
"' value='" << use_unit_str <<
"'";
502 if (!use_unit_str.
empty()) {
503 if (use_unit_str ==
"1" || use_unit_str ==
"true")
504 use_length_unit =
true;
505 else if (use_unit_str ==
"0" || use_unit_str ==
"false")
506 use_length_unit =
false;
508 ARCANE_FATAL(
"Invalid value boolean value '{0}' for '{1}' attribute."
509 " Valid values are '0', '1' 'true' or 'false'",
510 use_unit_str, use_unit_attr_name);
513 info() <<
"Uses Lima's length unit: " << use_length_unit <<
" (lang=" << case_doc_lang <<
")";
516 return reader.readMesh(
mesh, filename, dir_name, use_internal_partition, use_length_unit);
524 bool use_internal_partition,
bool use_length_unit)
534 info() <<
"Lima: use_length_unit=" << use_length_unit
535 <<
" use_internal_partition=" << use_internal_partition;
536 Real length_multiplier = 0.0;
537 if (use_length_unit) {
541 if (code_system.
null() || code_system.
empty()) {
542 info() <<
"No unit system configured. Use MKS unit system.";
543 length_multiplier = 1.0;
545 else if (code_system ==
"CGS") {
546 length_multiplier = 100.0;
548 else if (code_system ==
"MKS") {
549 length_multiplier = 1.0;
552 ARCANE_FATAL(
"Unknown unit system '{0}' (valid values are: 'CGS' or 'MKS'", code_system);
556 std::string loc_file_name = filename.
localstr();
557 size_t rpos = loc_file_name.rfind(
".mli");
558 size_t rpos2 = loc_file_name.rfind(
".mli2");
559 const bool need_mutex = rpos2 != std::string::npos;
560 info() <<
" FILE_NAME=" << loc_file_name;
561 info() <<
" RPOS MLI=" << rpos <<
" s=" << loc_file_name.length();
562 info() <<
" RPOS MLI2=" << rpos2 <<
" s=" << loc_file_name.length();
574 if (!has_thread && use_internal_partition && ((rpos + 4) == loc_file_name.length())) {
575 info() <<
"Use direct partitioning with mli";
576#ifdef ARCANE_LIMA_HAS_MLI
577 return LimaUtils::_directLimaPartitionMalipp(timer_mng, mesh, filename, length_multiplier);
579 ARCANE_FATAL(
"Can not use 'mli' files because Lima is not compiled with 'mli' support");
582 else if (!has_thread && use_internal_partition && ((rpos2 + 5) == loc_file_name.length())) {
583 info() <<
"Use direct partitioning with mli2";
584#ifdef ARCANE_LIMA_HAS_MLI2
585 return LimaUtils::_directLimaPartitionMalipp2(timer_mng, mesh, filename, length_multiplier);
587 ARCANE_FATAL(
"Can not use 'mli2' files because Lima is not compiled with 'mli2' support");
591 info() <<
"Loading Lima file '" << filename <<
"'";
593 const char* version = Lima::lima_version();
594 info() <<
"Using version " << version <<
" of Lima";
599 LM_TYPEMASQUE preparation = LM_ORIENTATION | LM_COMPACTE;
601 log() <<
"Starting file read " << filename;
603 Lima::Maillage lima(filename.
localstr());
607 Timer::Sentry sentry(&time_to_read);
608 Timer::Phase t_action(sd, TP_InputOutput);
609 GlobalLimaMutex sc(need_mutex);
610 lima.lire(filename.
localstr(), Lima::SUFFIXE,
true);
612 lima.preparation_parametrable(preparation);
615 catch (
const Lima::erreur& ex) {
616 ARCANE_FATAL(
"Can not read lima file '{0}' error is '{1}'", filename, ex.what());
622 info() <<
"Mesh read and preparation time (unit: seconds): "
623 << time_to_read.lastActivationTime();
627 if (lima.dimension() == Lima::D3) {
631 else if (lima.dimension() == Lima::D2) {
638 lm =
new LimaWrapper<Lima3DReaderWrapper>(sd);
641 lm =
new LimaWrapper<Lima2DReaderWrapper>(sd);
644 log() <<
"Mesh dimension not recognized by lima";
648 bool ret = lm->readMesh(lima, mesh, filename, dir_name, use_internal_partition, length_multiplier);
655 if (nb_ghost_layer > 1)
670 const String& dir_name,
bool use_internal_partition,
Real length_multiplier)
672 return _readMesh(lima,
mesh, filename, dir_name, use_internal_partition, length_multiplier);
680 const String& dir_name,
bool use_internal_partition,
Real length_multiplier)
682 ARCANE_UNUSED(file_name);
688 bool is_parallel = pm->isParallel();
696 m_wrapper.setLima(lima);
698 mesh_nb_node = CheckedConvert::toInteger(lima.nb_noeuds());
699 mesh_nb_cell = m_wrapper.nbCell();
700 lima_nb_face = m_wrapper.nbFace();
703 info() <<
"-- Mesh Information (Internal):";
704 info() <<
"Number of nodes " << mesh_nb_node;
705 info() <<
"Number of edges " << nb_edge;
706 info() <<
"Number of faces " << lima_nb_face;
707 info() <<
"Number of cells " << mesh_nb_cell;
708 info() <<
"-- Mesh Information (Lima):";
709 info() <<
"Number of nodes " << lima.nb_noeuds();
710 info() <<
"Number of edges " << lima.nb_bras();
711 info() <<
"Number of polygons " << lima.nb_polygones();
712 info() <<
"Number of polyhedra " << lima.nb_polyedres();
713 info() <<
"Number of surfaces " << lima.nb_surfaces();
714 info() <<
"Number of volumes " << lima.nb_volumes();
716 info() <<
"File length unit: " << lima.unite_longueur();
719 if (length_multiplier == 0.0)
720 length_multiplier = 1.0;
722 length_multiplier *= lima.unite_longueur();
724 if (mesh_nb_node == 0) {
735 if (is_parallel && !use_internal_partition && pm->commSize() > 1) {
736 m_cut_infos_reader->readItemsUniqueId(nodes_unique_id, cells_unique_id, dir_name);
739 for (
Integer i = 0; i < mesh_nb_node; ++i)
740 nodes_unique_id[i] = i;
741 for (
Integer i = 0; i < mesh_nb_cell; ++i)
742 cells_unique_id[i] = i;
747 bool first_uid_is_one =
false;
749 first_uid_is_one =
true;
750 info() <<
"WARNING: UniqueId begin at 1";
752 if (first_uid_is_one) {
753 for (
Integer i = 0; i < mesh_nb_node; ++i)
754 ++nodes_unique_id[i];
755 for (
Integer i = 0; i < mesh_nb_cell; ++i)
756 ++cells_unique_id[i];
761 info() <<
"Using length multiplier v=" << length_multiplier;
762 for (
Integer i = 0; i < mesh_nb_node; ++i) {
763 const Lima::Noeud& node = lima.noeud(i);
764 Real3 coord(node.x(), node.y(), node.z());
765 coord *= length_multiplier;
766 nodes_coords.nocheckAdd(nodes_unique_id[i], coord);
770 for (
Integer i = 0; i < mesh_nb_node; ++i) {
771 const Lima::Noeud& node = lima.noeud(i);
772 Real3 coord(node.x(), node.y(), node.z());
773 nodes_coords.nocheckAdd(nodes_unique_id[i], coord);
781 bool use_own_mesh =
false;
783 if (is_parallel && pm->commSize() > 1) {
785 if (use_internal_partition)
786 use_own_mesh =
false;
789 typedef typename ReaderWrapper::LimaCellGroup LimaCellGroup;
790 typedef typename ReaderWrapper::LimaCell LimaCell;
791 typedef typename ReaderWrapper::LimaFaceGroup LimaFaceGroup;
792 typedef typename ReaderWrapper::LimaFace LimaFace;
795 Integer nb = m_wrapper.nbCellGroup();
796 for (
Integer i = 0; i < nb; ++i) {
797 const LimaCellGroup& lima_group = m_wrapper.cellGroup(i);
798 std::string group_name = lima_group.nom();
799 if (group_name ==
"LOCAL" || group_name ==
"local") {
800 Integer nb_own_cell = m_wrapper.cellGroupNbCell(lima_group);
801 cells_filter.resize(nb_own_cell);
802 for (
Integer z = 0; z < nb_own_cell; ++z) {
803 cells_filter[z] = CheckedConvert::toInteger(m_wrapper.cellCellGroup(lima_group, z).id() - 1);
809 if (use_internal_partition && sid != 0) {
814 cells_filter.resize(mesh_nb_cell);
815 for (
Integer i = 0; i < mesh_nb_cell; ++i)
821 for (
Integer j = 0, js = cells_filter.size(); j < js; ++j) {
822 mesh_nb_cell_node += CheckedConvert::toInteger(m_wrapper.cell(cells_filter[j]).nb_noeuds());
829 for (
Integer i_cell = 0, s_cell = cells_filter.size(); i_cell < s_cell; ++i_cell) {
831 Integer cell_indirect_id = cells_filter[i_cell];
832 LimaCell lima_cell = m_wrapper.cell(cell_indirect_id);
833 Integer n = CheckedConvert::toInteger(lima_cell.nb_noeuds());
835 Integer ct = ReaderWrapper::cellToType(n);
836 if (ct == IT_NullType)
839 cells_infos[cells_infos_index] = ct;
842 cells_infos[cells_infos_index] = cells_unique_id[cell_indirect_id];
846 for (
Integer z = 0, sz = n; z < sz; ++z) {
847 Int64 node_uid = nodes_unique_id[CheckedConvert::toInteger(lima_cell.noeud(z).id() - 1)];
848 cells_infos[cells_infos_index + z] = node_uid;
852 cout <<
"CELL LIMA1 " << cells_unique_id[cell_indirect_id] <<
" ";
854 cout <<
" " << cells_infos[cells_infos_index+z];
858 cells_infos_index += n;
861 logdate() <<
"Début allocation du maillage nb_cell=" << cells_filter.size();
862 mesh->allocateCells(cells_filter.size(), cells_infos,
false);
863 logdate() <<
"Fin allocation du maillage";
866 if (use_internal_partition) {
868 for (
Integer i = 0, is = nodes.size(); i < is; ++i)
869 nodes[i]->setOwner(sid, sid);
871 for (
Integer i = 0, is = cells.size(); i < is; ++i)
872 cells[i]->setOwner(sid, sid);
877 Integer sub_domain_id = subDomain()->subDomainId();
878 Integer nb = CheckedConvert::toInteger(lima.nb_nuages());
879 for (
Integer i = 0; i < nb; ++i) {
880 const Lima::Nuage& lima_group = lima.nuage(i);
881 Integer nb_item_in_group = CheckedConvert::toInteger(lima_group.nb_noeuds());
882 std::string group_name = lima_group.nom();
883 unique_ids.resize(nb_item_in_group);
884 local_ids.resize(nb_item_in_group);
885 for (
Integer z = 0; z < nb_item_in_group; ++z) {
886 unique_ids[z] = nodes_unique_id[CheckedConvert::toInteger(lima_group.noeud(z).id() - 1)];
888 mesh->nodeFamily()->itemsUniqueIdToLocalId(local_ids, unique_ids,
false);
889 bool remove_group =
false;
890 if (group_name ==
"LOCALN" || group_name ==
"localn") {
891 info() <<
"Utilisation du groupe 'LOCALN' pour indiquer que les "
892 <<
"noeuds appartiennent au sous-domaine";
894 for (
Integer z = 0, sz = nb_item_in_group; z < sz; ++z) {
895 Integer local_id = local_ids[z];
896 if (local_id != NULL_ITEM_ID)
897 nodes[local_id]->setOwner(sub_domain_id, sub_domain_id);
901 debug() <<
"Vérification du groupe '" << group_name <<
"'";
902 if (group_name.length() > 3 && !remove_group) {
904 if (grp.startsWith(
"NF_")) {
905 grp = grp.substring(3);
906 Int32 ghost_sub_domain_id = 0;
907 bool is_bad = builtInGetValue(ghost_sub_domain_id, grp);
908 debug() <<
"Vérification du groupe '" << group_name <<
"' (3) " << is_bad;
910 info() <<
"Utilisation du groupe " << group_name <<
" pour indiquer que le "
911 <<
"sous-domaine " << ghost_sub_domain_id <<
" est propriétaire de ses noeuds";
913 for (
Integer z = 0, sz = nb_item_in_group; z < sz; ++z) {
914 Integer local_id = local_ids[z];
915 if (local_id != NULL_ITEM_ID)
916 nodes[local_ids[z]]->setOwner(ghost_sub_domain_id, sub_domain_id);
934 for (
Integer i_face = 0; i_face < lima_nb_face; ++i_face) {
935 const LimaFace& lima_face = m_wrapper.face(i_face);
936 face_nb_node += CheckedConvert::toInteger(lima_face.nb_noeuds());
942 Integer faces_nodes_unique_id_index = 0;
952 for (
Integer i_face = 0; i_face < lima_nb_face; ++i_face) {
953 const LimaFace& lima_face = m_wrapper.face(i_face);
954 Integer n = CheckedConvert::toInteger(lima_face.nb_noeuds());
955 orig_nodes_id.resize(n);
956 face_nodes_index.resize(n);
957 for (
Integer z = 0; z < n; ++z)
958 orig_nodes_id[z] = nodes_unique_id[CheckedConvert::toInteger(lima_face.noeud(z).id() - 1)];
962 cout <<
"FACE LIMA1 " << lima_face.id()-1 <<
" ";
964 cout <<
" " << orig_nodes_id[z];
969 for (
Integer z = 0; z < n; ++z)
970 faces_nodes_unique_id[faces_nodes_unique_id_index + z] = orig_nodes_id[face_nodes_index[z]];
971 faces_first_node_unique_id[i_face] = orig_nodes_id[face_nodes_index[0]];
972 faces_nodes_unique_id_index += n;
975 mesh->nodeFamily()->itemsUniqueIdToLocalId(faces_first_node_local_id, faces_first_node_unique_id);
977 faces_nodes_unique_id_index = 0;
978 for (
Integer i_face = 0; i_face < lima_nb_face; ++i_face) {
979 const LimaFace& lima_face = m_wrapper.face(i_face);
980 Integer n = CheckedConvert::toInteger(lima_face.nb_noeuds());
982 Node current_node(mesh_nodes[faces_first_node_local_id[i_face]]);
983 Face face = mesh_utils::getFaceFromNodesUnique(current_node, face_nodes_id);
988 for (
Integer z = 0; z < n; ++z)
989 ostr() <<
' ' << face_nodes_id[z];
990 ostr() <<
" - " << current_node.localId() <<
")";
991 ARCANE_FATAL(
"INTERNAL: Lima face index={0} with nodes '{1}' is not in node/face connectivity",
994 faces_id[i_face] = face.localId();
996 faces_nodes_unique_id_index += n;
1005 if (use_internal_partition && sid != 0) {
1007 Integer nb = CheckedConvert::toInteger(lima.nb_nuages());
1008 for (
Integer i = 0; i < nb; ++i) {
1009 const Lima::Nuage& lima_group = lima.nuage(i);
1010 std::string group_name = lima_group.nom();
1015 Integer nb = m_wrapper.nbFaceGroup();
1016 for (
Integer i = 0; i < nb; ++i) {
1017 const LimaFaceGroup& lima_group = m_wrapper.faceGroup(i);
1018 std::string group_name = lima_group.nom();
1023 Integer nb = m_wrapper.nbCellGroup();
1024 for (
Integer i = 0; i < nb; ++i) {
1025 const LimaCellGroup& lima_group = m_wrapper.cellGroup(i);
1026 std::string group_name = lima_group.nom();
1034 Integer sub_domain_id = subDomain()->subDomainId();
1037 Integer nb = CheckedConvert::toInteger(lima.nb_nuages());
1038 for (
Integer i = 0; i < nb; ++i) {
1039 const Lima::Nuage& lima_group = lima.nuage(i);
1040 Integer nb_item_in_group = CheckedConvert::toInteger(lima_group.nb_noeuds());
1041 std::string group_name = lima_group.nom();
1042 unique_ids.resize(nb_item_in_group);
1043 local_ids.resize(nb_item_in_group);
1044 for (
Integer z = 0; z < nb_item_in_group; ++z) {
1045 Integer lima_node_id = CheckedConvert::toInteger(lima_group.noeud(z).id());
1046 unique_ids[z] = nodes_unique_id[lima_node_id - 1];
1048 mesh->nodeFamily()->itemsUniqueIdToLocalId(local_ids, unique_ids);
1049 bool remove_group =
false;
1050 if (group_name ==
"LOCALN" || group_name ==
"localn") {
1051 remove_group =
true;
1053 debug() <<
"Vérification du groupe '" << group_name <<
"'";
1054 if (group_name.length() > 3 && !remove_group) {
1055 String grp = group_name.c_str();
1057 debug() <<
"Vérification du groupe '" << group_name <<
"' (2) '" << grp <<
"'";
1058 if (grp.startsWith(
"NF_")) {
1061 grp = grp.substring(3);
1062 Integer ghost_sub_domain_id = 0;
1063 bool is_bad = builtInGetValue(ghost_sub_domain_id, grp);
1064 debug() <<
"Vérification du groupe '" << group_name <<
"' (3) " << is_bad;
1066 remove_group =
true;
1070 if (!remove_group) {
1071 log() <<
"NodeGroup Name <" << group_name <<
"> (" << nb_item_in_group <<
" elements)";
1078 Integer nb = m_wrapper.nbFaceGroup();
1079 for (
Integer i = 0; i < nb; ++i) {
1080 const LimaFaceGroup& lima_group = m_wrapper.faceGroup(i);
1081 Integer nb_item_in_group = m_wrapper.faceGroupNbFace(lima_group);
1082 local_ids.resize(nb_item_in_group);
1085 for (
Integer z = 0; z < nb_item_in_group; ++z) {
1086 local_ids[z] = faces_id[CheckedConvert::toInteger(m_wrapper.faceFaceGroup(lima_group, z).id() - 1)];
1088 std::string group_name = lima_group.nom();
1089 log() <<
"FaceGroup Name <" << group_name <<
"> (" << nb_item_in_group <<
" elements)";
1095 Integer nb = m_wrapper.nbCellGroup();
1096 for (
Integer i = 0; i < nb; ++i) {
1097 const LimaCellGroup& lima_group = m_wrapper.cellGroup(i);
1098 Integer nb_item_in_group = m_wrapper.cellGroupNbCell(lima_group);
1099 std::string group_name = lima_group.nom();
1100 unique_ids.resize(nb_item_in_group);
1101 local_ids.resize(nb_item_in_group);
1102 for (
Integer z = 0; z < nb_item_in_group; ++z) {
1103 unique_ids[z] = cells_unique_id[CheckedConvert::toInteger(m_wrapper.cellCellGroup(lima_group, z).id() - 1)];
1105 mesh->cellFamily()->itemsUniqueIdToLocalId(local_ids, unique_ids);
1106 bool remove_group =
false;
1107 if (group_name ==
"LOCAL" || group_name ==
"local") {
1109 for (
Integer z = 0, sz = nb_item_in_group; z < sz; ++z)
1110 cells[local_ids[z]]->setOwner(sub_domain_id, sub_domain_id);
1111 remove_group =
true;
1113 if (!remove_group) {
1114 String grp(group_name.c_str());
1115 if (grp.startsWith(
"MF_")) {
1116 info() <<
"Le groupe de mailles " << group_name <<
" n'est pas utilisé";
1117 remove_group =
true;
1120 if (!remove_group) {
1121 log() <<
"CellGroup Name <" << group_name <<
"> (" << nb_item_in_group <<
" elements)";
1138 Integer nb_ghost_layer =
mesh->ghostLayerMng()->nbGhostLayer();
1139 if (nb_ghost_layer > 1)
1140 nodes =
mesh->ownNodes();
1142 const Node& node = *i;
1143 nodes_coord_var[node] = nodes_coords.lookupValue(node.uniqueId());
1146 if (nb_ghost_layer > 1)
1147 nodes_coord_var.synchronize();
1151 info() <<
"Nombre de nuages " << lima.nb_nuages();
1152 info() <<
"Nombre de lignes " << lima.nb_lignes();
1153 info() <<
"Nombre de surfaces " << lima.nb_surfaces();
1154 info() <<
"Nombre de volumes " << lima.nb_volumes();
1160 logdate() <<
"Fin de lecture du fichier";
1172 if (!dir_name.empty()) {
1173 comm_file_nameb += dir_name;
1174 comm_file_nameb +=
"/";
1176 comm_file_nameb +=
"Communications";
1177 String comm_file_name = comm_file_nameb.toString();
1181 if (!doc_holder.get())
1188 String ustr_buf = String::fromNumber(sd->subDomainId());
1190 for (
Integer i = 0, s = cpu_list.size(); i < s; ++i) {
1191 String id_str = cpu_list[i].attrValue(ustr_id);
1192 if (id_str == ustr_buf) {
1193 cpu_elem = cpu_list[i];
1197 if (cpu_elem.null())
1198 ARCANE_FATAL(
"No element <cpus/cpu-from[@id=\"{0}\"]>", sd->subDomainId());
1200 cpu_list = cpu_elem.children(
String(
"cpu-to"));
1201 debug() <<
"Nb procs " << cpu_list.size();
1202 for (
Integer i = 0; i < cpu_list.size(); ++i) {
1203 Integer v = cpu_list[i].valueAsInteger();
1205 debug() <<
"Read proc " << v;
1213class LimaCaseMeshReader
1227 , m_read_info(read_info)
1234 ARCANE_UNUSED(build_info);
1239 String fname = m_read_info.fileName();
1240 m_trace_mng->info() <<
"Lima Reader (ICaseMeshReader) file_name=" << fname;
1241 bool use_length_unit =
true;
1242 String directory_name = m_read_info.directoryName();
1243 IMeshReader::eReturnType ret = reader.readMesh(pm, fname, directory_name, m_read_info.isParallelRead(), use_length_unit);
1259 , m_sub_domain(sbi.subDomain())
1267 String str = read_info.format();
1268 if (str ==
"unf" || str ==
"mli" || str ==
"mli2" || str ==
"ice" || str ==
"uns" || str ==
"unv")
1269 builder =
new Builder(m_sub_domain, read_info);
1324void LimaMeshWriter::
1325_writeItem(Lima::Maillage& m, ConstArrayView<Lima::Noeud> nodes, ItemWithNodes c)
1328 case IT_Octaedron12:
1329 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()], nodes[c.node(1).localId()],
1330 nodes[c.node(2).localId()], nodes[c.node(3).localId()],
1331 nodes[c.node(4).localId()], nodes[c.node(5).localId()],
1332 nodes[c.node(6).localId()], nodes[c.node(7).localId()],
1333 nodes[c.node(8).localId()], nodes[c.node(9).localId()],
1334 nodes[c.node(10).localId()], nodes[c.node(11).localId()]));
1336 case IT_Heptaedron10:
1337 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()], nodes[c.node(1).localId()],
1338 nodes[c.node(2).localId()], nodes[c.node(3).localId()],
1339 nodes[c.node(4).localId()], nodes[c.node(5).localId()],
1340 nodes[c.node(6).localId()], nodes[c.node(7).localId()],
1341 nodes[c.node(8).localId()], nodes[c.node(9).localId()]));
1344 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()], nodes[c.node(1).localId()],
1345 nodes[c.node(2).localId()], nodes[c.node(3).localId()],
1346 nodes[c.node(4).localId()], nodes[c.node(5).localId()],
1347 nodes[c.node(6).localId()], nodes[c.node(7).localId()]));
1349 case IT_Pentaedron6:
1350 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()], nodes[c.node(1).localId()],
1351 nodes[c.node(2).localId()], nodes[c.node(3).localId()],
1352 nodes[c.node(4).localId()], nodes[c.node(5).localId()]));
1355 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()], nodes[c.node(1).localId()],
1356 nodes[c.node(2).localId()], nodes[c.node(3).localId()],
1357 nodes[c.node(4).localId()]));
1359 case IT_Tetraedron4:
1360 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()], nodes[c.node(1).localId()],
1361 nodes[c.node(2).localId()], nodes[c.node(3).localId()]));
1364 m.ajouter(Lima::Polygone(nodes[c.node(0).localId()], nodes[c.node(1).localId()],
1365 nodes[c.node(2).localId()], nodes[c.node(3).localId()],
1366 nodes[c.node(4).localId()], nodes[c.node(5).localId()]));
1369 m.ajouter(Lima::Polygone(nodes[c.node(0).localId()], nodes[c.node(1).localId()],
1370 nodes[c.node(2).localId()], nodes[c.node(3).localId()],
1371 nodes[c.node(4).localId()]));
1374 m.ajouter(Lima::Polygone(nodes[c.node(0).localId()], nodes[c.node(1).localId()],
1375 nodes[c.node(2).localId()], nodes[c.node(3).localId()]));
1378 m.ajouter(Lima::Polygone(nodes[c.node(0).localId()], nodes[c.node(1).localId()],
1379 nodes[c.node(2).localId()]));
1382 m.ajouter(Lima::Bras(nodes[c.node(0).localId()], nodes[c.node(1).localId()]));
1398 int dimension =
mesh->dimension();
1400 std::string std_file_name = file_name.
localstr();
1404 const size_t rpos2 = std_file_name.rfind(
".mli2");
1405 std::string::size_type std_end = std::string::npos;
1406 bool need_mutex = rpos2 != std_end;
1407 if (rpos2 == std_end && std_file_name.rfind(
".mli") == std_end && std_file_name.rfind(
".unf") == std_end) {
1408 std_file_name +=
".mli2";
1411 info() <<
"FINAL_FILE_NAME=" << std_file_name;
1412 Lima::Maillage lima(std_file_name);
1415 lima.dimension(Lima::D3);
1416 else if (dimension == 2)
1417 lima.dimension(Lima::D2);
1439 for (
Integer i = 0; i < mesh_nb_node; ++i) {
1440 Node node = nodes[i];
1441 Real3 coord = nodes_coords[node];
1445 lima.ajouter(lm_nodes[i]);
1449 for (
Integer i = 0; i < mesh_nb_edge; ++i) {
1450 _writeItem(lima, lm_nodes, edges[i]);
1454 for (
Integer i = 0; i < mesh_nb_face; ++i) {
1455 _writeItem(lima, lm_nodes, faces[i]);
1459 for (
Integer i = 0; i < mesh_nb_cell; ++i) {
1460 _writeItem(lima, lm_nodes, cells[i]);
1471 lima.ajouter(lm_group);
1473 lm_group.ajouter(lima.noeud(iitem.localId()));
1483 lima.ajouter(lm_group);
1485 lm_group.ajouter(lima.bras(iitem.localId()));
1494 if (dimension == 3) {
1496 lima.ajouter(lm_group);
1498 lm_group.ajouter(lima.polygone(iitem.localId()));
1501 else if (dimension == 2) {
1503 lima.ajouter(lm_group);
1505 lm_group.ajouter(lima.bras(iitem.localId()));
1515 if (dimension == 3) {
1517 lima.ajouter(lm_group);
1519 lm_group.ajouter(lima.polyedre(iitem.localId()));
1522 else if (dimension == 2) {
1524 lima.ajouter(lm_group);
1526 lm_group.ajouter(lima.polygone(iitem.localId()));
1530 info(4) <<
"Writing file '" << std_file_name <<
"'";
1533 GlobalLimaMutex sc(need_mutex);
1534 lima.ecrire(std_file_name);
1537 catch (
const std::exception& ex) {
1538 trace->
warning() <<
"Exception (std::exception) in LIMA: Can not write file <" << std_file_name <<
">"
1539 <<
" Exception: " << ex.what() <<
'\n';
1543 trace->
warning() <<
"Exception (unknown) in LIMA: Can not write file <" << std_file_name <<
">";
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Utility functions for the mesh.
bool reorderNodesOfFace2(Int64ConstArrayView nodes_unique_id, Int32ArrayView new_index)
Reorders the nodes of a face.
This file contains the various service factories and macros for registering services.
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro to declare an interface when registering a service.
AbstractService(const ServiceBuildInfo &)
Constructor from a ServiceBuildInfo.
void reserve(Int64 new_capacity)
Reserves memory for new_capacity elements.
Necessary information for reading a mesh file.
View of cell information.
EnumeratorT< ItemGroup > Enumerator
Constant view of an array of type T.
View of edge information.
View of face information.
Hash table for associative arrays.
virtual ITraceMng * traceMng() const =0
Trace manager.
virtual String language() const =0
Language used in the dataset.
Interface of a class managing an XML document of the dataset.
virtual String codeUnitSystem() const =0
Name of the document's unit system.
Interface for the mesh reading service from the dataset.
virtual Integer nbGhostLayer() const =0
Number of ghost layers.
Interface of an entity family.
virtual ItemGroupCollection groups() const =0
Collection of groups in this family.
virtual Integer nbItem() const =0
Number of entities.
virtual Integer dimension()=0
Mesh dimension (1D, 2D, or 3D).
Interface of a mesh creation/reading service.
Interface of the service managing the reading of a mesh.
eReturnType
Types of return codes for a read or write operation.
@ RTIrrelevant
Not relevant to the operation. This means that the file format does not match this reader or that the...
@ RTError
Error during the operation.
@ RTOk
Operation successfully performed.
Interface of a mesh writing service.
virtual IParallelMng * parallelMng()=0
Parallelism manager.
virtual void synchronizeGroupsAndVariables()=0
Synchronizes all mesh groups and variables.
virtual IGhostLayerMng * ghostLayerMng() const =0
Associated ghost layer manager.
Interface of the parallelism manager for a subdomain.
virtual bool isThreadImplementation() const =0
Indicates if the implementation uses threads.
virtual void setDimension(Integer dim)=0
Positions the mesh dimension (1D, 2D, or 3D).
Interface of the subdomain manager.
virtual ICaseDocument * caseDocument()=0
Case XML document.
virtual IParallelMng * parallelMng()=0
Returns the parallelism manager.
virtual ITimerMng * timerMng() const =0
Returns the timer manager.
Interface of a timer manager.
virtual TraceMessage warning()=0
Stream for a warning message.
const String & name() const
Group name.
bool isAllItems() const
Indicates if the group is that of all entities.
Mesh element based on nodes (Edge,Face,Cell).
void fillMeshBuildInfo(MeshBuildInfo &build_info) override
Fills build_info with the necessary information to create the mesh.
void allocateMeshItems(IPrimaryMesh *pm) override
Allocates the mesh entities managed by this service.
Ref< IMeshBuilder > createBuilder(const CaseMeshReaderReadInfo &read_info) const override
Returns a builder to create and read the mesh whose information is specified in read_info.
Construction of a 3D mesh.
Mesh file reader via the LIMA library.
Mesh file reader via the LIMA library.
eReturnType readMeshFromFile(IPrimaryMesh *mesh, const XmlNode &mesh_node, const String &file_name, const String &dir_name, bool use_internal_partition) override
Reads a mesh from a file.
void build()
Build-level construction of the service.
bool allowExtension(const String &str) override
Checks if the service supports files with the extension str.
Mesh file reader via the LIMA library.
virtual bool writeMeshToFile(IMesh *mesh, const String &file_name)
Writing the mesh in Lima format.
virtual void build()
Build-level construction of the service.
static void createGroup(IItemFamily *family, const String &name, Int32ArrayView local_ids)
Creates a group of entities.
Mesh file reader via the LIMA library.
Parameters necessary for building a mesh.
View of node information.
Output stream linked to a String.
Class managing a 3-dimensional real vector.
Reference to an instance.
Encapsulation of an automatically destructing pointer.
ISubDomain * subDomain() const
Access to the associated ISubDomain.
Structure containing the information to create a service.
Service creation properties.
Unicode character string constructor.
Unicode character string.
bool null() const
Returns true if the string is null.
const char * localstr() const
Returns the conversion of the instance into UTF-8 encoding.
bool empty() const
True if the string is empty (null or "").
@ TimerReal
Timer using real time.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage log() const
Flow for a log message.
TraceMessage info() const
Flow for an information message.
TraceMessage warning() const
Flow for a warning message.
1D data vector with value semantics (STL style).
Exception when a mesh entity is not of a known type.
List of nodes of a DOM tree.
XmlNode documentElement() const
Returns the document element.
String attrValue(const String &name, bool throw_exception=false) const
Value of attribute name.
ItemGroupT< Node > NodeGroup
Group of nodes.
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro for registering a service.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Coordinate type quantity at node.
ItemVariableScalarRefT< Real3 > VariableItemReal3
3D coordinate type quantity
double toDouble(Real r)
Converts a Real to double.
__host__ __device__ double log(double v)
Natural logarithm of v.
constexpr __host__ __device__ bool isEqual(const _Type &a, const _Type &b)
Tests the bit-by-bit equality between two values.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
UniqueArray< Int64 > Int64UniqueArray
Dynamic 1D array of 64-bit integers.
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
ConstArrayView< ItemInternal * > ItemInternalList
Type of the internal list of entities.
@ ST_SubDomain
The service is used at the subdomain level.
ConstArrayView< Int64 > Int64ConstArrayView
C equivalent of a 1D array of 64-bit integers.
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
ArrayView< Int32 > Int32ArrayView
C equivalent of a 1D array of 32-bit integers.
@ IK_Node
Node mesh entity.
@ IK_Cell
Cell mesh entity.
double Real
Type representing a real number.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
std::int32_t Int32
Signed integer type of 32 bits.
Real y
second component of the triplet
Real z
third component of the triplet
Real x
first component of the triplet