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>
84std::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 virtual ~LimaMeshBase() {}
125 const String& dir_name,
bool use_internal_partition,
Real length_multiplier) =0;
127 ISubDomain* subDomain()
const {
return m_sub_domain; }
146template<
typename ReaderWrapper>
157 delete m_cut_infos_reader;
163 const String& dir_name,
bool use_internal_partition,
Real length_multiplier);
168 ReaderWrapper m_wrapper;
171 const String& dir_name,
bool use_internal_partition,
Real length_multiplier);
183 void setLima(
const Lima::Maillage& lima_mesh)
185 m_lima_mesh = lima_mesh;
190 Lima::Maillage m_lima_mesh;
200 typedef Lima::Surface LimaCellGroup;
201 typedef Lima::Polygone LimaCell;
202 typedef Lima::Ligne LimaFaceGroup;
203 typedef Lima::Bras LimaFace;
207 return CheckedConvert::toInteger(m_lima_mesh.nb_surfaces());
211 return CheckedConvert::toInteger(m_lima_mesh.nb_lignes());
213 LimaCellGroup cellGroup(
Integer i)
215 return m_lima_mesh.surface(i);
217 LimaFaceGroup faceGroup(
Integer i)
219 return m_lima_mesh.ligne(i);
221 Integer faceGroupNbFace(
const LimaFaceGroup& group)
223 return CheckedConvert::toInteger(group.nb_bras());
225 LimaFace faceFaceGroup(
const LimaFaceGroup& group,
Integer i)
227 return group.bras(i);
229 Integer cellGroupNbCell(
const LimaCellGroup& group)
231 return CheckedConvert::toInteger(group.nb_polygones());
233 LimaCell cellCellGroup(
const LimaCellGroup& group,
Integer i)
235 return group.polygone(i);
239 return m_lima_mesh.polygone(i);
243 return m_lima_mesh.bras(i);
247 return CheckedConvert::toInteger(m_lima_mesh.nb_polygones());
251 return CheckedConvert::toInteger(m_lima_mesh.nb_bras());
257 const char* strDimension()
264 case 3:
return IT_Triangle3;
265 case 4:
return IT_Quad4;
266 case 5:
return IT_Pentagon5;
267 case 6:
return IT_Hexagon6;
282 typedef Lima::Volume LimaCellGroup;
283 typedef Lima::Polyedre LimaCell;
284 typedef Lima::Surface LimaFaceGroup;
285 typedef Lima::Polygone LimaFace;
289 return CheckedConvert::toInteger(m_lima_mesh.nb_volumes());
293 return CheckedConvert::toInteger(m_lima_mesh.nb_surfaces());
295 LimaCellGroup cellGroup(
Integer i)
297 return m_lima_mesh.volume(i);
299 LimaFaceGroup faceGroup(
Integer i)
301 return m_lima_mesh.surface(i);
303 Integer faceGroupNbFace(
const LimaFaceGroup& group)
305 return CheckedConvert::toInteger(group.nb_polygones());
307 LimaFace faceFaceGroup(
const LimaFaceGroup& group,
Integer i)
309 return group.polygone(i);
311 Integer cellGroupNbCell(
const LimaCellGroup& group)
313 return CheckedConvert::toInteger(group.nb_polyedres());
315 LimaCell cellCellGroup(
const LimaCellGroup& group,
Integer i)
317 return group.polyedre(i);
321 return m_lima_mesh.polyedre(i);
325 return m_lima_mesh.polygone(i);
329 return CheckedConvert::toInteger(m_lima_mesh.nb_polyedres());
333 return CheckedConvert::toInteger(m_lima_mesh.nb_polygones());
339 const char* strDimension()
346 case 4:
return IT_Tetraedron4;
347 case 5:
return IT_Pyramid5;
348 case 6:
return IT_Pentaedron6;
349 case 8:
return IT_Hexaedron8;
350 case 10:
return IT_Heptaedron10;
351 case 12:
return IT_Octaedron12;
375 const String& dir_name,
bool use_internal_partition,
388class LimaMeshReaderService
404 return str==
"unf" || str==
"mli" || str==
"mli2" || str==
"ice" || str==
"uns" || str==
"unv";
409 const String& dir_name,
bool use_internal_partition)
override;
410 ISubDomain* subDomain() {
return m_sub_domain; }
414 ISubDomain* m_sub_domain;
429LimaMeshReaderService::
432, m_sub_domain(sbi.subDomain())
442 bool use_internal_partition)
446 String case_doc_lang =
"en";
449 case_doc_lang = case_doc->
language();
452 String use_unit_attr_name =
"utilise-unite";
454 if (case_doc_lang==
"en"){
457 if (!use_unit_str.
empty()){
458 warning() <<
"'utilise-unite' ne doit être utilisé que pour les JDD en francais."
459 <<
"Utilisez 'use-unit' à la place";
461 use_unit_attr_name =
"use-unit";
467 if (use_unit_str.
null()){
468 info() <<
"Attribute '" << use_unit_attr_name <<
"' is not found. Trying with 'use-unit'";
469 use_unit_attr_name =
"use-unit";
475 bool use_length_unit =
true;
477 use_length_unit =
false;
478 info() <<
"Default value for unit usage: " << use_length_unit;
480 if (use_unit_str.
empty())
481 use_unit_str = mesh_node.
attrValue(use_unit_attr_name);
482 info() <<
"Checking for attribute '" << use_unit_attr_name <<
"' value='" << use_unit_str <<
"'";
483 if (!use_unit_str.
empty()){
484 if (use_unit_str==
"1" || use_unit_str==
"true")
485 use_length_unit =
true;
486 else if (use_unit_str==
"0" || use_unit_str==
"false")
487 use_length_unit =
false;
489 ARCANE_FATAL(
"Invalid value boolean value '{0}' for '{1}' attribute."
490 " Valid values are '0', '1' 'true' or 'false'",
491 use_unit_str,use_unit_attr_name);
494 info() <<
"Utilise l'unité de longueur de Lima: " << use_length_unit <<
" (lang=" << case_doc_lang <<
")";
497 return reader.readMesh(
mesh,filename,dir_name,use_internal_partition,use_length_unit);
505 bool use_internal_partition,
bool use_length_unit)
515 info() <<
"Lima: use_length_unit=" << use_length_unit
516 <<
" use_internal_partition=" << use_internal_partition;
517 Real length_multiplier = 0.0;
518 if (use_length_unit){
522 if (code_system.
null() || code_system.
empty()){
523 info() <<
"No unit system configured. Use MKS unit system.";
524 length_multiplier = 1.0;
526 else if (code_system==
"CGS"){
527 length_multiplier = 100.0;
529 else if (code_system==
"MKS"){
530 length_multiplier = 1.0;
533 ARCANE_FATAL(
"Unknown unit system '{0}' (valid values are: 'CGS' ou 'MKS'",code_system);
537 std::string loc_file_name = filename.
localstr();
538 size_t rpos = loc_file_name.rfind(
".mli");
539 size_t rpos2 = loc_file_name.rfind(
".mli2");
540 const bool need_mutex = rpos2 != std::string::npos;
541 info() <<
" FILE_NAME=" << loc_file_name;
542 info() <<
" RPOS MLI=" << rpos <<
" s=" << loc_file_name.length();
543 info() <<
" RPOS MLI2=" << rpos2 <<
" s=" << loc_file_name.length();
555 if (!has_thread && use_internal_partition && ((rpos+4)==loc_file_name.length())){
556 info() <<
"Use direct partitioning with mli";
557#ifdef ARCANE_LIMA_HAS_MLI
558 return LimaUtils::_directLimaPartitionMalipp(timer_mng, mesh, filename, length_multiplier);
560 ARCANE_FATAL(
"Can not use 'mli' files because Lima is not compiled with 'mli' support");
563 else if (!has_thread && use_internal_partition && ((rpos2+5)==loc_file_name.length())){
564 info() <<
"Use direct partitioning with mli2";
565#ifdef ARCANE_LIMA_HAS_MLI2
566 return LimaUtils::_directLimaPartitionMalipp2(timer_mng, mesh, filename, length_multiplier);
568 ARCANE_FATAL(
"Can not use 'mli2' files because Lima is not compiled with 'mli2' support");
572 info() <<
"Chargement Lima du fichier '" << filename <<
"'";
574 const char* version = Lima::lima_version();
575 info() <<
"Utilisation de la version " << version <<
" de Lima";
580 LM_TYPEMASQUE preparation = LM_ORIENTATION | LM_COMPACTE;
582 log() <<
"Début lecture fichier " << filename;
584 Lima::Maillage lima(filename.
localstr());
588 Timer::Sentry sentry(&time_to_read);
589 Timer::Phase t_action(sd, TP_InputOutput);
590 GlobalLimaMutex sc(need_mutex);
591 lima.lire(filename.
localstr(),Lima::SUFFIXE,
true);
593 lima.preparation_parametrable(preparation);
596 catch(
const Lima::erreur& ex){
597 ARCANE_FATAL(
"Can not read lima file '{0}' error is '{1}'",filename,ex.what());
603 info() <<
"Temps de lecture et préparation du maillage (unité: seconde): "
604 << time_to_read.lastActivationTime();
608 if (lima.dimension()==Lima::D3){
610 info() <<
"Maillage 3D";
612 else if (lima.dimension()==Lima::D2){
614 info() <<
"Maillage 2D";
619 lm =
new LimaWrapper<Lima3DReaderWrapper>(sd);
622 lm =
new LimaWrapper<Lima2DReaderWrapper>(sd);
625 log() <<
"Dimension du maillage non reconnue par lima";
629 bool ret = lm->readMesh(lima,mesh,filename,dir_name,use_internal_partition,length_multiplier);
636 if (nb_ghost_layer>1)
651 const String& dir_name,
bool use_internal_partition,
Real length_multiplier)
653 return _readMesh(lima,
mesh,filename,dir_name,use_internal_partition,length_multiplier);
661 const String& dir_name,
bool use_internal_partition,
Real length_multiplier)
663 ARCANE_UNUSED(file_name);
669 bool is_parallel = pm->isParallel();
677 m_wrapper.setLima(lima);
679 mesh_nb_node = CheckedConvert::toInteger(lima.nb_noeuds());
680 mesh_nb_cell = m_wrapper.nbCell();
681 lima_nb_face = m_wrapper.nbFace();
684 info() <<
"-- Informations sur le maillage (Interne):";
685 info() <<
"Nombre de noeuds " << mesh_nb_node;
686 info() <<
"Nombre d'arêtes " << nb_edge;
687 info() <<
"Nombre de faces " << lima_nb_face;
688 info() <<
"Nombre de mailles " << mesh_nb_cell;
689 info() <<
"-- Informations sur le maillage (Lima):";
690 info() <<
"Nombre de noeuds " << lima.nb_noeuds();
691 info() <<
"Nombre d'arêtes " << lima.nb_bras();
692 info() <<
"Nombre de polygones " << lima.nb_polygones();
693 info() <<
"Nombre de polyedres " << lima.nb_polyedres();
694 info() <<
"Nombre de surfaces " << lima.nb_surfaces();
695 info() <<
"Nombre de volumes " << lima.nb_volumes();
697 info() <<
"Unité de longueur du fichier: " << lima.unite_longueur();
700 if (length_multiplier==0.0)
701 length_multiplier = 1.0;
703 length_multiplier *= lima.unite_longueur();
705 if (mesh_nb_node==0){
717 if (is_parallel && !use_internal_partition && pm->commSize()>1){
718 m_cut_infos_reader->readItemsUniqueId(nodes_unique_id,cells_unique_id,dir_name);
721 for(
Integer i=0; i<mesh_nb_node; ++i )
722 nodes_unique_id[i] = i;
723 for(
Integer i=0; i<mesh_nb_cell; ++i )
724 cells_unique_id[i] = i;
729 bool first_uid_is_one =
false;
731 first_uid_is_one =
true;
732 info() <<
"WARNING: UniqueId begin at 1";
734 if (first_uid_is_one){
735 for(
Integer i=0; i<mesh_nb_node; ++i )
736 ++nodes_unique_id[i];
737 for(
Integer i=0; i<mesh_nb_cell; ++i )
738 ++cells_unique_id[i];
743 info() <<
"Using length multiplier v=" << length_multiplier;
744 for(
Integer i=0; i<mesh_nb_node; ++i ){
745 const Lima::Noeud& node = lima.noeud(i);
746 Real3 coord(node.x(),node.y(),node.z());
747 coord *= length_multiplier;
748 nodes_coords.nocheckAdd(nodes_unique_id[i],coord);
752 for(
Integer i=0; i<mesh_nb_node; ++i ){
753 const Lima::Noeud& node = lima.noeud(i);
754 Real3 coord(node.x(),node.y(),node.z());
755 nodes_coords.nocheckAdd(nodes_unique_id[i],coord);
763 bool use_own_mesh =
false;
765 if (is_parallel && pm->commSize()>1){
767 if (use_internal_partition)
768 use_own_mesh =
false;
771 typedef typename ReaderWrapper::LimaCellGroup LimaCellGroup;
772 typedef typename ReaderWrapper::LimaCell LimaCell;
773 typedef typename ReaderWrapper::LimaFaceGroup LimaFaceGroup;
774 typedef typename ReaderWrapper::LimaFace LimaFace;
777 Integer nb = m_wrapper.nbCellGroup();
779 const LimaCellGroup& lima_group = m_wrapper.cellGroup(i);
780 std::string group_name = lima_group.nom();
781 if (group_name==
"LOCAL" || group_name==
"local"){
782 Integer nb_own_cell = m_wrapper.cellGroupNbCell(lima_group);
783 cells_filter.resize(nb_own_cell);
784 for(
Integer z=0; z<nb_own_cell; ++z ){
785 cells_filter[z] = CheckedConvert::toInteger(m_wrapper.cellCellGroup(lima_group,z).id() - 1);
791 if (use_internal_partition && sid!=0){
796 cells_filter.resize(mesh_nb_cell);
797 for(
Integer i=0; i<mesh_nb_cell; ++i )
803 for(
Integer j=0, js=cells_filter.size(); j<js; ++j ){
804 mesh_nb_cell_node += CheckedConvert::toInteger(m_wrapper.cell(cells_filter[j]).nb_noeuds());
811 for(
Integer i_cell=0, s_cell=cells_filter.size(); i_cell<s_cell; ++i_cell ){
813 Integer cell_indirect_id = cells_filter[i_cell];
814 LimaCell lima_cell = m_wrapper.cell(cell_indirect_id);
815 Integer n = CheckedConvert::toInteger(lima_cell.nb_noeuds());
817 Integer ct = ReaderWrapper::cellToType(n);
821 cells_infos[cells_infos_index] = ct;
824 cells_infos[cells_infos_index] = cells_unique_id[cell_indirect_id];
828 for(
Integer z=0, sz=n; z<sz; ++z ){
829 Int64 node_uid = nodes_unique_id[CheckedConvert::toInteger(lima_cell.noeud(z).id()-1)];
830 cells_infos[cells_infos_index+z] = node_uid;
834 cout <<
"CELL LIMA1 " << cells_unique_id[cell_indirect_id] <<
" ";
836 cout <<
" " << cells_infos[cells_infos_index+z];
840 cells_infos_index += n;
843 logdate() <<
"Début allocation du maillage nb_cell=" << cells_filter.size();
844 mesh->allocateCells(cells_filter.size(),cells_infos,
false);
845 logdate() <<
"Fin allocation du maillage";
848 if (use_internal_partition){
850 for(
Integer i=0, is=nodes.size(); i<is; ++i )
851 nodes[i]->setOwner(sid,sid);
853 for(
Integer i=0, is=cells.size(); i<is; ++i )
854 cells[i]->setOwner(sid,sid);
859 Integer sub_domain_id = subDomain()->subDomainId();
860 Integer nb = CheckedConvert::toInteger(lima.nb_nuages());
862 const Lima::Nuage& lima_group = lima.nuage(i);
863 Integer nb_item_in_group = CheckedConvert::toInteger(lima_group.nb_noeuds());
864 std::string group_name = lima_group.nom();
865 unique_ids.resize(nb_item_in_group);
866 local_ids.resize(nb_item_in_group);
867 for(
Integer z=0; z<nb_item_in_group; ++z ){
868 unique_ids[z] = nodes_unique_id[CheckedConvert::toInteger(lima_group.noeud(z).id() - 1)];
870 mesh->nodeFamily()->itemsUniqueIdToLocalId(local_ids,unique_ids,
false);
871 bool remove_group =
false;
872 if (group_name==
"LOCALN" || group_name==
"localn"){
873 info() <<
"Utilisation du groupe 'LOCALN' pour indiquer que les "
874 <<
"noeuds appartiennent au sous-domaine";
876 for(
Integer z=0, sz=nb_item_in_group; z<sz; ++z ){
877 Integer local_id = local_ids[z];
878 if (local_id!=NULL_ITEM_ID)
879 nodes[local_id]->setOwner(sub_domain_id,sub_domain_id);
883 debug() <<
"Vérification du groupe '" << group_name <<
"'";
884 if (group_name.length()>3 && !remove_group){
886 if (grp.startsWith(
"NF_")){
887 grp = grp.substring(3);
888 Int32 ghost_sub_domain_id = 0;
889 bool is_bad = builtInGetValue(ghost_sub_domain_id,grp);
890 debug() <<
"Vérification du groupe '" << group_name <<
"' (3) " << is_bad;
892 info() <<
"Utilisation du groupe " << group_name <<
" pour indiquer que le "
893 <<
"sous-domaine " << ghost_sub_domain_id <<
" est propriétaire de ses noeuds";
895 for(
Integer z=0, sz=nb_item_in_group; z<sz; ++z ){
896 Integer local_id = local_ids[z];
897 if (local_id!=NULL_ITEM_ID)
898 nodes[local_ids[z]]->setOwner(ghost_sub_domain_id,sub_domain_id);
916 for(
Integer i_face=0; i_face<lima_nb_face; ++i_face ){
917 const LimaFace& lima_face = m_wrapper.face(i_face);
918 face_nb_node += CheckedConvert::toInteger(lima_face.nb_noeuds());
924 Integer faces_nodes_unique_id_index = 0;
934 for(
Integer i_face=0; i_face<lima_nb_face; ++i_face ){
935 const LimaFace& lima_face = m_wrapper.face(i_face);
936 Integer n = CheckedConvert::toInteger(lima_face.nb_noeuds());
937 orig_nodes_id.resize(n);
938 face_nodes_index.resize(n);
940 orig_nodes_id[z] = nodes_unique_id[CheckedConvert::toInteger(lima_face.noeud(z).id() - 1)];
944 cout <<
"FACE LIMA1 " << lima_face.id()-1 <<
" ";
946 cout <<
" " << orig_nodes_id[z];
952 faces_nodes_unique_id[faces_nodes_unique_id_index+z] = orig_nodes_id[face_nodes_index[z]];
953 faces_first_node_unique_id[i_face] = orig_nodes_id[face_nodes_index[0]];
954 faces_nodes_unique_id_index += n;
957 mesh->nodeFamily()->itemsUniqueIdToLocalId(faces_first_node_local_id,faces_first_node_unique_id);
959 faces_nodes_unique_id_index = 0;
960 for(
Integer i_face=0; i_face<lima_nb_face; ++i_face ){
961 const LimaFace& lima_face = m_wrapper.face(i_face);
962 Integer n = CheckedConvert::toInteger(lima_face.nb_noeuds());
964 Node current_node(mesh_nodes[faces_first_node_local_id[i_face]]);
965 Face face = mesh_utils::getFaceFromNodesUnique(current_node,face_nodes_id);
971 ostr() <<
' ' << face_nodes_id[z];
972 ostr() <<
" - " << current_node.localId() <<
")";
973 ARCANE_FATAL(
"INTERNAL: Lima face index={0} with nodes '{1}' is not in node/face connectivity",
976 faces_id[i_face] = face.localId();
978 faces_nodes_unique_id_index += n;
987 if (use_internal_partition && sid!=0){
989 Integer nb = CheckedConvert::toInteger(lima.nb_nuages());
991 const Lima::Nuage& lima_group = lima.nuage(i);
992 std::string group_name = lima_group.nom();
997 Integer nb = m_wrapper.nbFaceGroup();
999 const LimaFaceGroup& lima_group = m_wrapper.faceGroup(i);
1000 std::string group_name = lima_group.nom();
1005 Integer nb = m_wrapper.nbCellGroup();
1006 for(
Integer i=0; i<nb; ++i ){
1007 const LimaCellGroup& lima_group = m_wrapper.cellGroup(i);
1008 std::string group_name = lima_group.nom();
1016 Integer sub_domain_id = subDomain()->subDomainId();
1019 Integer nb = CheckedConvert::toInteger(lima.nb_nuages());
1020 for(
Integer i=0; i<nb; ++i ){
1021 const Lima::Nuage& lima_group = lima.nuage(i);
1022 Integer nb_item_in_group = CheckedConvert::toInteger(lima_group.nb_noeuds());
1023 std::string group_name = lima_group.nom();
1024 unique_ids.resize(nb_item_in_group);
1025 local_ids.resize(nb_item_in_group);
1026 for(
Integer z=0; z<nb_item_in_group; ++z ){
1027 Integer lima_node_id = CheckedConvert::toInteger(lima_group.noeud(z).id());
1028 unique_ids[z] = nodes_unique_id[lima_node_id - 1];
1030 mesh->nodeFamily()->itemsUniqueIdToLocalId(local_ids,unique_ids);
1031 bool remove_group =
false;
1032 if (group_name==
"LOCALN" || group_name==
"localn"){
1033 remove_group =
true;
1035 debug() <<
"Vérification du groupe '" << group_name <<
"'";
1036 if (group_name.length()>3 && !remove_group){
1037 String grp = group_name.c_str();
1039 debug() <<
"Vérification du groupe '" << group_name <<
"' (2) '" << grp <<
"'";
1040 if (grp.startsWith(
"NF_")){
1043 grp = grp.substring(3);
1044 Integer ghost_sub_domain_id = 0;
1045 bool is_bad = builtInGetValue(ghost_sub_domain_id,grp);
1046 debug() <<
"Vérification du groupe '" << group_name <<
"' (3) " << is_bad;
1048 remove_group =
true;
1053 log() <<
"NodeGroup Name <" << group_name <<
"> (" << nb_item_in_group <<
" elements)";
1060 Integer nb = m_wrapper.nbFaceGroup();
1061 for(
Integer i=0; i<nb; ++i ){
1062 const LimaFaceGroup& lima_group = m_wrapper.faceGroup(i);
1063 Integer nb_item_in_group = m_wrapper.faceGroupNbFace(lima_group);
1064 local_ids.resize(nb_item_in_group);
1067 for(
Integer z=0; z<nb_item_in_group; ++z ){
1068 local_ids[z] = faces_id[CheckedConvert::toInteger(m_wrapper.faceFaceGroup(lima_group,z).id() - 1)];
1070 std::string group_name = lima_group.nom();
1071 log() <<
"FaceGroup Name <" << group_name <<
"> (" << nb_item_in_group <<
" elements)";
1077 Integer nb = m_wrapper.nbCellGroup();
1078 for(
Integer i=0; i<nb; ++i ){
1079 const LimaCellGroup& lima_group = m_wrapper.cellGroup(i);
1080 Integer nb_item_in_group = m_wrapper.cellGroupNbCell(lima_group);
1081 std::string group_name = lima_group.nom();
1082 unique_ids.resize(nb_item_in_group);
1083 local_ids.resize(nb_item_in_group);
1084 for(
Integer z=0; z<nb_item_in_group; ++z ){
1085 unique_ids[z] = cells_unique_id[CheckedConvert::toInteger(m_wrapper.cellCellGroup(lima_group,z).id() - 1)];
1087 mesh->cellFamily()->itemsUniqueIdToLocalId(local_ids,unique_ids);
1088 bool remove_group =
false;
1089 if (group_name==
"LOCAL" || group_name==
"local"){
1091 for(
Integer z=0, sz=nb_item_in_group; z<sz; ++z )
1092 cells[local_ids[z]]->setOwner(sub_domain_id,sub_domain_id);
1093 remove_group =
true;
1096 String grp(group_name.c_str());
1097 if (grp.startsWith(
"MF_")){
1098 info() <<
"Le groupe de mailles " << group_name <<
" n'est pas utilisé";
1099 remove_group =
true;
1103 log() <<
"CellGroup Name <" << group_name <<
"> (" << nb_item_in_group <<
" elements)";
1121 Integer nb_ghost_layer =
mesh->ghostLayerMng()->nbGhostLayer();
1122 if (nb_ghost_layer>1)
1123 nodes =
mesh->ownNodes();
1125 const Node& node = *i;
1126 nodes_coord_var[node] = nodes_coords.lookupValue(node.uniqueId());
1129 if (nb_ghost_layer>1)
1130 nodes_coord_var.synchronize();
1135 info() <<
"Nombre de nuages " << lima.nb_nuages();
1136 info() <<
"Nombre de lignes " << lima.nb_lignes();
1137 info() <<
"Nombre de surfaces " << lima.nb_surfaces();
1138 info() <<
"Nombre de volumes " << lima.nb_volumes();
1144 logdate() <<
"Fin de lecture du fichier";
1156 if (!dir_name.empty()){
1157 comm_file_nameb += dir_name;
1158 comm_file_nameb +=
"/";
1160 comm_file_nameb +=
"Communications";
1161 String comm_file_name = comm_file_nameb.toString();
1165 if (!doc_holder.get())
1172 String ustr_buf = String::fromNumber(sd->subDomainId());
1174 for(
Integer i=0, s=cpu_list.size(); i<s; ++i ){
1175 String id_str = cpu_list[i].attrValue(ustr_id);
1176 if (id_str==ustr_buf){
1177 cpu_elem = cpu_list[i];
1181 if (cpu_elem.null())
1182 ARCANE_FATAL(
"No element <cpus/cpu-from[@id=\"{0}\"]>",sd->subDomainId());
1184 cpu_list = cpu_elem.children(
String(
"cpu-to"));
1185 debug() <<
"Nb procs " << cpu_list.size();
1186 for(
Integer i=0; i<cpu_list.size(); ++i ){
1187 Integer v = cpu_list[i].valueAsInteger();
1189 debug() <<
"Read proc " << v;
1197class LimaCaseMeshReader
1211 , m_read_info(read_info)
1218 ARCANE_UNUSED(build_info);
1223 String fname = m_read_info.fileName();
1224 m_trace_mng->info() <<
"Lima Reader (ICaseMeshReader) file_name=" << fname;
1225 bool use_length_unit =
true;
1226 String directory_name = m_read_info.directoryName();
1227 IMeshReader::eReturnType ret = reader.readMesh(pm, fname, directory_name, m_read_info.isParallelRead(), use_length_unit);
1250 String str = read_info.format();
1251 if (str==
"unf" || str==
"mli" || str==
"mli2" || str==
"ice" || str==
"uns" || str==
"unv")
1252 builder =
new Builder(m_sub_domain, read_info);
1301void LimaMeshWriter::
1302_writeItem(Lima::Maillage& m,ConstArrayView<Lima::Noeud> nodes,ItemWithNodes c)
1305 case IT_Octaedron12:
1306 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1307 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1308 nodes[c.node(4).localId()],nodes[c.node(5).localId()],
1309 nodes[c.node(6).localId()],nodes[c.node(7).localId()],
1310 nodes[c.node(8).localId()],nodes[c.node(9).localId()],
1311 nodes[c.node(10).localId()],nodes[c.node(11).localId()]));
1313 case IT_Heptaedron10:
1314 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1315 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1316 nodes[c.node(4).localId()],nodes[c.node(5).localId()],
1317 nodes[c.node(6).localId()],nodes[c.node(7).localId()],
1318 nodes[c.node(8).localId()],nodes[c.node(9).localId()]));
1321 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1322 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1323 nodes[c.node(4).localId()],nodes[c.node(5).localId()],
1324 nodes[c.node(6).localId()],nodes[c.node(7).localId()]));
1326 case IT_Pentaedron6:
1327 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1328 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1329 nodes[c.node(4).localId()],nodes[c.node(5).localId()]));
1332 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1333 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1334 nodes[c.node(4).localId()]));
1336 case IT_Tetraedron4:
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()]));
1341 m.ajouter(Lima::Polygone(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1342 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1343 nodes[c.node(4).localId()],nodes[c.node(5).localId()]));
1346 m.ajouter(Lima::Polygone(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1347 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1348 nodes[c.node(4).localId()]));
1351 m.ajouter(Lima::Polygone(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1352 nodes[c.node(2).localId()],nodes[c.node(3).localId()]));
1355 m.ajouter(Lima::Polygone(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1356 nodes[c.node(2).localId()]));
1359 m.ajouter(Lima::Bras(nodes[c.node(0).localId()],nodes[c.node(1).localId()]));
1375 int dimension =
mesh->dimension();
1377 std::string std_file_name = file_name.
localstr();
1381 const size_t rpos2 = std_file_name.rfind(
".mli2");
1382 std::string::size_type std_end = std::string::npos;
1383 bool need_mutex = rpos2!=std_end;
1384 if (rpos2==std_end && std_file_name.rfind(
".mli")==std_end && std_file_name.rfind(
".unf")==std_end){
1385 std_file_name +=
".mli2";
1388 info() <<
"FINAL_FILE_NAME=" << std_file_name;
1389 Lima::Maillage lima(std_file_name);
1392 lima.dimension(Lima::D3);
1393 else if (dimension==2)
1394 lima.dimension(Lima::D2);
1416 for(
Integer i=0; i<mesh_nb_node; ++i ){
1417 Node node = nodes[i];
1418 Real3 coord = nodes_coords[node];
1422 lima.ajouter(lm_nodes[i]);
1426 for(
Integer i=0; i<mesh_nb_edge; ++i ){
1427 _writeItem(lima,lm_nodes,edges[i]);
1431 for(
Integer i=0; i<mesh_nb_face; ++i ){
1432 _writeItem(lima,lm_nodes,faces[i]);
1436 for(
Integer i=0; i<mesh_nb_cell; ++i ){
1437 _writeItem(lima,lm_nodes,cells[i]);
1448 lima.ajouter(lm_group);
1450 lm_group.ajouter(lima.noeud(iitem.localId()));
1460 lima.ajouter(lm_group);
1462 lm_group.ajouter(lima.bras(iitem.localId()));
1473 lima.ajouter(lm_group);
1475 lm_group.ajouter(lima.polygone(iitem.localId()));
1478 else if (dimension==2){
1480 lima.ajouter(lm_group);
1482 lm_group.ajouter(lima.bras(iitem.localId()));
1494 lima.ajouter(lm_group);
1496 lm_group.ajouter(lima.polyedre(iitem.localId()));
1499 else if (dimension==2){
1501 lima.ajouter(lm_group);
1503 lm_group.ajouter(lima.polygone(iitem.localId()));
1507 info(4) <<
"Writing file '" << std_file_name <<
"'";
1510 GlobalLimaMutex sc(need_mutex);
1511 lima.ecrire(std_file_name);
1514 catch(
const std::exception& ex){
1515 trace->
warning() <<
"Exception (std::exception) in LIMA: Can not write file <" << std_file_name <<
">"
1516 <<
" Exception: " << ex.what() <<
'\n';
1520 trace->
warning() <<
"Exception (unknown) in LIMA: Can not write file <" << std_file_name <<
">";
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fonctions utilitaires sur le maillage.
bool reorderNodesOfFace2(Int64ConstArrayView nodes_unique_id, Int32ArrayView new_index)
Réordonne les noeuds d'une face.
Ce fichier contient les différentes fabriques de services et macro pour enregistrer les services.
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro pour déclarer une interface lors de l'enregistrement d'un service.
Classe de base d'un service.
AbstractService(const ServiceBuildInfo &)
Constructeur à partir d'un ServiceBuildInfo.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
Informations nécessaires pour la lecture d'un fichier de maillage.
Vue sur les informations des mailles.
EnumeratorT< ItemGroup > Enumerator
Vue constante d'un tableau de type T.
Vue sur les informations des arêtes.
Vue sur les informations des faces.
Table de hachage pour tableaux associatifs.
virtual ITraceMng * traceMng() const =0
Gestionnaire de traces.
virtual String language() const =0
Langage utilisé dans le jeu de données.
Interface d'une classe gérant un document XML du jeu de données.
virtual String codeUnitSystem() const =0
Nom du système d'unité du document.
Interface du service de lecture du maillage à partir du jeu de données.
virtual Integer nbGhostLayer() const =0
Nombre de couches fantômes.
Interface d'une famille d'entités.
virtual ItemGroupCollection groups() const =0
Liste des groupes de cette famille.
virtual Integer nbItem() const =0
Nombre d'entités.
virtual Integer dimension()=0
Dimension du maillage (1D, 2D ou 3D).
Interface d'un service de création/lecture du maillage.
Interface du service gérant la lecture d'un maillage.
eReturnType
Types des codes de retour d'une lecture ou écriture.
@ RTIrrelevant
Non concerné par l'opération. Cela signifie que le format de fichier ne correspond pas à ce lecteur o...
@ RTError
Erreur lors de l'opération.
@ RTOk
Opération effectuée avec succès.
Interface d'un service d'écriture d'un maillage.
virtual IParallelMng * parallelMng()=0
Gestionnaire de parallèlisme.
virtual void synchronizeGroupsAndVariables()=0
Synchronise tous les groupes et les variables du maillage.
virtual IGhostLayerMng * ghostLayerMng() const =0
Gestionnare de couche fantômes associé
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual bool isThreadImplementation() const =0
Indique si l'implémentation utilise les threads.
virtual void setDimension(Integer dim)=0
Positionne la dimension du maillage (1D, 2D ou 3D).
Interface du gestionnaire d'un sous-domaine.
virtual ICaseDocument * caseDocument()=0
Document XML du cas.
virtual IParallelMng * parallelMng()=0
Retourne le gestionnaire de parallélisme.
virtual ITimerMng * timerMng() const =0
Retourne le gestionnaire de timers.
Interface d'un gestionnaire de timer.
Interface du gestionnaire de traces.
virtual TraceMessage warning()=0
Flot pour un message d'avertissement.
Groupe d'entités de maillage.
const String & name() const
Nom du groupe.
bool isAllItems() const
Indique si le groupe est celui de toutes les entités.
Elément de maillage s'appuyant sur des noeuds (Edge,Face,Cell).
void fillMeshBuildInfo(MeshBuildInfo &build_info) override
Remplit build_info avec les informations nécessaires pour créer le maillage.
void allocateMeshItems(IPrimaryMesh *pm) override
Alloue les entités du maillage géré par ce service.
Ref< IMeshBuilder > createBuilder(const CaseMeshReaderReadInfo &read_info) const override
Retourne un builder pour créer et lire le maillage dont les informations sont spécifiées dans read_in...
Construction d'un maillage 3D.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
eReturnType readMeshFromFile(IPrimaryMesh *mesh, const XmlNode &mesh_node, const String &file_name, const String &dir_name, bool use_internal_partition) override
Lit un maillage à partir d'un fichier.
void build()
Construction de niveau build du service.
bool allowExtension(const String &str) override
Vérifie si le service supporte les fichiers avec l'extension str.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
virtual bool writeMeshToFile(IMesh *mesh, const String &file_name)
Ecriture du maillage au format Lima.
virtual void build()
Construction de niveau build du service.
static void createGroup(IItemFamily *family, const String &name, Int32ArrayView local_ids)
Créé un groupe d'entités.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Paramètres nécessaires à la construction d'un maillage.
Vue sur les informations des noeuds.
Flot de sortie lié à une String.
Classe gérant un vecteur de réel de dimension 3.
Référence à une instance.
Encapsulation d'un pointeur qui se détruit automatiquement.
ISubDomain * subDomain() const
Accès au ISubDomain associé.
Structure contenant les informations pour créer un service.
Propriétés de création d'un service.
Constructeur de chaîne de caractère unicode.
Chaîne de caractères unicode.
bool null() const
Retourne true si la chaîne est nulle.
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
bool empty() const
Vrai si la chaîne est vide (nulle ou "")
@ TimerReal
Timer utilisant le temps réel.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessage log() const
Flot pour un message de log.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage warning() const
Flot pour un message d'avertissement.
Vecteur 1D de données avec sémantique par valeur (style STL).
Exception lorsqu'une entité du maillage n'est pas d'un type connu.
Liste de noeuds d'un arbre DOM.
XmlNode documentElement() const
Retourne le noeud élément du document.
String attrValue(const String &name, bool throw_exception=false) const
Valeur de l'attribut name.
ItemGroupT< Node > NodeGroup
Groupe de noeuds.
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro pour enregistrer un service.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
ItemVariableScalarRefT< Real3 > VariableItemReal3
Grandeur de type coordonn?es 3D.
double toDouble(Real r)
Converti un Real en double.
__host__ __device__ double log(double v)
Logarithme népérien de v.
constexpr __host__ __device__ bool isEqual(const _Type &a, const _Type &b)
Teste l'égalité bit à bit entre deux valeurs.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
ConstArrayView< ItemInternal * > ItemInternalList
Type de la liste interne des entités.
@ ST_SubDomain
Le service s'utilise au niveau du sous-domaine.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
ArrayView< Int32 > Int32ArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
@ IK_Node
Entité de maillage de genre noeud.
@ IK_Cell
Entité de maillage de genre maille.
double Real
Type représentant un réel.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
std::int32_t Int32
Type entier signé sur 32 bits.
Real y
deuxième composante du triplet
Real z
troisième composante du triplet
Real x
première composante du triplet