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"
57#include "arcane/core/LimaCutInfosReader.h"
58#include "arcane/core/internal/LimaUtils.h"
60#include <Lima/lima++.h>
83std::mutex global_lima_mutex;
88 explicit GlobalLimaMutex(
bool is_active)
89 : m_is_active(is_active)
92 global_lima_mutex.lock();
97 global_lima_mutex.unlock();
102 bool m_is_active =
false;
119 virtual ~LimaMeshBase() {}
124 const String& dir_name,
bool use_internal_partition,
Real length_multiplier) =0;
126 ISubDomain* subDomain()
const {
return m_sub_domain; }
145template<
typename ReaderWrapper>
156 delete m_cut_infos_reader;
162 const String& dir_name,
bool use_internal_partition,
Real length_multiplier);
167 ReaderWrapper m_wrapper;
170 const String& dir_name,
bool use_internal_partition,
Real length_multiplier);
182 void setLima(
const Lima::Maillage& lima_mesh)
184 m_lima_mesh = lima_mesh;
189 Lima::Maillage m_lima_mesh;
199 typedef Lima::Surface LimaCellGroup;
200 typedef Lima::Polygone LimaCell;
201 typedef Lima::Ligne LimaFaceGroup;
202 typedef Lima::Bras LimaFace;
206 return CheckedConvert::toInteger(m_lima_mesh.nb_surfaces());
210 return CheckedConvert::toInteger(m_lima_mesh.nb_lignes());
212 LimaCellGroup cellGroup(
Integer i)
214 return m_lima_mesh.surface(i);
216 LimaFaceGroup faceGroup(
Integer i)
218 return m_lima_mesh.ligne(i);
220 Integer faceGroupNbFace(
const LimaFaceGroup& group)
222 return CheckedConvert::toInteger(group.nb_bras());
224 LimaFace faceFaceGroup(
const LimaFaceGroup& group,
Integer i)
226 return group.bras(i);
228 Integer cellGroupNbCell(
const LimaCellGroup& group)
230 return CheckedConvert::toInteger(group.nb_polygones());
232 LimaCell cellCellGroup(
const LimaCellGroup& group,
Integer i)
234 return group.polygone(i);
238 return m_lima_mesh.polygone(i);
242 return m_lima_mesh.bras(i);
246 return CheckedConvert::toInteger(m_lima_mesh.nb_polygones());
250 return CheckedConvert::toInteger(m_lima_mesh.nb_bras());
256 const char* strDimension()
263 case 3:
return IT_Triangle3;
264 case 4:
return IT_Quad4;
265 case 5:
return IT_Pentagon5;
266 case 6:
return IT_Hexagon6;
281 typedef Lima::Volume LimaCellGroup;
282 typedef Lima::Polyedre LimaCell;
283 typedef Lima::Surface LimaFaceGroup;
284 typedef Lima::Polygone LimaFace;
288 return CheckedConvert::toInteger(m_lima_mesh.nb_volumes());
292 return CheckedConvert::toInteger(m_lima_mesh.nb_surfaces());
294 LimaCellGroup cellGroup(
Integer i)
296 return m_lima_mesh.volume(i);
298 LimaFaceGroup faceGroup(
Integer i)
300 return m_lima_mesh.surface(i);
302 Integer faceGroupNbFace(
const LimaFaceGroup& group)
304 return CheckedConvert::toInteger(group.nb_polygones());
306 LimaFace faceFaceGroup(
const LimaFaceGroup& group,
Integer i)
308 return group.polygone(i);
310 Integer cellGroupNbCell(
const LimaCellGroup& group)
312 return CheckedConvert::toInteger(group.nb_polyedres());
314 LimaCell cellCellGroup(
const LimaCellGroup& group,
Integer i)
316 return group.polyedre(i);
320 return m_lima_mesh.polyedre(i);
324 return m_lima_mesh.polygone(i);
328 return CheckedConvert::toInteger(m_lima_mesh.nb_polyedres());
332 return CheckedConvert::toInteger(m_lima_mesh.nb_polygones());
338 const char* strDimension()
345 case 4:
return IT_Tetraedron4;
346 case 5:
return IT_Pyramid5;
347 case 6:
return IT_Pentaedron6;
348 case 8:
return IT_Hexaedron8;
349 case 10:
return IT_Heptaedron10;
350 case 12:
return IT_Octaedron12;
374 const String& dir_name,
bool use_internal_partition,
387class LimaMeshReaderService
403 return str==
"unf" || str==
"mli" || str==
"mli2" || str==
"ice" || str==
"uns" || str==
"unv";
408 const String& dir_name,
bool use_internal_partition)
override;
409 ISubDomain* subDomain() {
return m_sub_domain; }
413 ISubDomain* m_sub_domain;
428LimaMeshReaderService::
431, m_sub_domain(sbi.subDomain())
441 bool use_internal_partition)
445 String case_doc_lang =
"en";
448 case_doc_lang = case_doc->
language();
451 String use_unit_attr_name =
"utilise-unite";
453 if (case_doc_lang==
"en"){
456 if (!use_unit_str.
empty()){
457 warning() <<
"'utilise-unite' ne doit être utilisé que pour les JDD en francais."
458 <<
"Utilisez 'use-unit' à la place";
460 use_unit_attr_name =
"use-unit";
466 if (use_unit_str.
null()){
467 info() <<
"Attribute '" << use_unit_attr_name <<
"' is not found. Trying with 'use-unit'";
468 use_unit_attr_name =
"use-unit";
474 bool use_length_unit =
true;
476 use_length_unit =
false;
477 info() <<
"Default value for unit usage: " << use_length_unit;
479 if (use_unit_str.
empty())
480 use_unit_str = mesh_node.
attrValue(use_unit_attr_name);
481 info() <<
"Checking for attribute '" << use_unit_attr_name <<
"' value='" << use_unit_str <<
"'";
482 if (!use_unit_str.
empty()){
483 if (use_unit_str==
"1" || use_unit_str==
"true")
484 use_length_unit =
true;
485 else if (use_unit_str==
"0" || use_unit_str==
"false")
486 use_length_unit =
false;
488 ARCANE_FATAL(
"Invalid value boolean value '{0}' for '{1}' attribute."
489 " Valid values are '0', '1' 'true' or 'false'",
490 use_unit_str,use_unit_attr_name);
493 info() <<
"Utilise l'unité de longueur de Lima: " << use_length_unit <<
" (lang=" << case_doc_lang <<
")";
496 return reader.readMesh(
mesh,filename,dir_name,use_internal_partition,use_length_unit);
504 bool use_internal_partition,
bool use_length_unit)
514 info() <<
"Lima: use_length_unit=" << use_length_unit
515 <<
" use_internal_partition=" << use_internal_partition;
516 Real length_multiplier = 0.0;
517 if (use_length_unit){
521 if (code_system.
null() || code_system.
empty()){
522 info() <<
"No unit system configured. Use MKS unit system.";
523 length_multiplier = 1.0;
525 else if (code_system==
"CGS"){
526 length_multiplier = 100.0;
528 else if (code_system==
"MKS"){
529 length_multiplier = 1.0;
532 ARCANE_FATAL(
"Unknown unit system '{0}' (valid values are: 'CGS' ou 'MKS'",code_system);
536 std::string loc_file_name = filename.
localstr();
537 size_t rpos = loc_file_name.rfind(
".mli");
538 size_t rpos2 = loc_file_name.rfind(
".mli2");
539 const bool need_mutex = rpos2 != std::string::npos;
540 info() <<
" FILE_NAME=" << loc_file_name;
541 info() <<
" RPOS MLI=" << rpos <<
" s=" << loc_file_name.length();
542 info() <<
" RPOS MLI2=" << rpos2 <<
" s=" << loc_file_name.length();
554 if (!has_thread && use_internal_partition && ((rpos+4)==loc_file_name.length())){
555 info() <<
"Use direct partitioning with mli";
556#ifdef ARCANE_LIMA_HAS_MLI
557 return LimaUtils::_directLimaPartitionMalipp(timer_mng, mesh, filename, length_multiplier);
559 ARCANE_FATAL(
"Can not use 'mli' files because Lima is not compiled with 'mli' support");
562 else if (!has_thread && use_internal_partition && ((rpos2+5)==loc_file_name.length())){
563 info() <<
"Use direct partitioning with mli2";
564#ifdef ARCANE_LIMA_HAS_MLI2
565 return LimaUtils::_directLimaPartitionMalipp2(timer_mng, mesh, filename, length_multiplier);
567 ARCANE_FATAL(
"Can not use 'mli2' files because Lima is not compiled with 'mli2' support");
571 info() <<
"Chargement Lima du fichier '" << filename <<
"'";
573 const char* version = Lima::lima_version();
574 info() <<
"Utilisation de la version " << version <<
" de Lima";
579 LM_TYPEMASQUE preparation = LM_ORIENTATION | LM_COMPACTE;
581 log() <<
"Début lecture fichier " << filename;
583 Lima::Maillage lima(filename.
localstr());
587 Timer::Sentry sentry(&time_to_read);
588 Timer::Phase t_action(sd, TP_InputOutput);
589 GlobalLimaMutex sc(need_mutex);
590 lima.lire(filename.
localstr(),Lima::SUFFIXE,
true);
592 lima.preparation_parametrable(preparation);
595 catch(
const Lima::erreur& ex){
596 ARCANE_FATAL(
"Can not read lima file '{0}' error is '{1}'",filename,ex.what());
602 info() <<
"Temps de lecture et préparation du maillage (unité: seconde): "
603 << time_to_read.lastActivationTime();
607 if (lima.dimension()==Lima::D3){
609 info() <<
"Maillage 3D";
611 else if (lima.dimension()==Lima::D2){
613 info() <<
"Maillage 2D";
618 lm =
new LimaWrapper<Lima3DReaderWrapper>(sd);
621 lm =
new LimaWrapper<Lima2DReaderWrapper>(sd);
624 log() <<
"Dimension du maillage non reconnue par lima";
628 bool ret = lm->readMesh(lima,mesh,filename,dir_name,use_internal_partition,length_multiplier);
635 if (nb_ghost_layer>1)
650 const String& dir_name,
bool use_internal_partition,
Real length_multiplier)
652 return _readMesh(lima,
mesh,filename,dir_name,use_internal_partition,length_multiplier);
660 const String& dir_name,
bool use_internal_partition,
Real length_multiplier)
662 ARCANE_UNUSED(file_name);
668 bool is_parallel = pm->isParallel();
676 m_wrapper.setLima(lima);
678 mesh_nb_node = CheckedConvert::toInteger(lima.nb_noeuds());
679 mesh_nb_cell = m_wrapper.nbCell();
680 lima_nb_face = m_wrapper.nbFace();
683 info() <<
"-- Informations sur le maillage (Interne):";
684 info() <<
"Nombre de noeuds " << mesh_nb_node;
685 info() <<
"Nombre d'arêtes " << nb_edge;
686 info() <<
"Nombre de faces " << lima_nb_face;
687 info() <<
"Nombre de mailles " << mesh_nb_cell;
688 info() <<
"-- Informations sur le maillage (Lima):";
689 info() <<
"Nombre de noeuds " << lima.nb_noeuds();
690 info() <<
"Nombre d'arêtes " << lima.nb_bras();
691 info() <<
"Nombre de polygones " << lima.nb_polygones();
692 info() <<
"Nombre de polyedres " << lima.nb_polyedres();
693 info() <<
"Nombre de surfaces " << lima.nb_surfaces();
694 info() <<
"Nombre de volumes " << lima.nb_volumes();
696 info() <<
"Unité de longueur du fichier: " << lima.unite_longueur();
699 if (length_multiplier==0.0)
700 length_multiplier = 1.0;
702 length_multiplier *= lima.unite_longueur();
704 if (mesh_nb_node==0){
716 if (is_parallel && !use_internal_partition && pm->commSize()>1){
717 m_cut_infos_reader->readItemsUniqueId(nodes_unique_id,cells_unique_id,dir_name);
720 for(
Integer i=0; i<mesh_nb_node; ++i )
721 nodes_unique_id[i] = i;
722 for(
Integer i=0; i<mesh_nb_cell; ++i )
723 cells_unique_id[i] = i;
728 bool first_uid_is_one =
false;
730 first_uid_is_one =
true;
731 info() <<
"WARNING: UniqueId begin at 1";
733 if (first_uid_is_one){
734 for(
Integer i=0; i<mesh_nb_node; ++i )
735 ++nodes_unique_id[i];
736 for(
Integer i=0; i<mesh_nb_cell; ++i )
737 ++cells_unique_id[i];
742 info() <<
"Using length multiplier v=" << length_multiplier;
743 for(
Integer i=0; i<mesh_nb_node; ++i ){
744 const Lima::Noeud& node = lima.noeud(i);
745 Real3 coord(node.x(),node.y(),node.z());
746 coord *= length_multiplier;
747 nodes_coords.nocheckAdd(nodes_unique_id[i],coord);
751 for(
Integer i=0; i<mesh_nb_node; ++i ){
752 const Lima::Noeud& node = lima.noeud(i);
753 Real3 coord(node.x(),node.y(),node.z());
754 nodes_coords.nocheckAdd(nodes_unique_id[i],coord);
762 bool use_own_mesh =
false;
764 if (is_parallel && pm->commSize()>1){
766 if (use_internal_partition)
767 use_own_mesh =
false;
770 typedef typename ReaderWrapper::LimaCellGroup LimaCellGroup;
771 typedef typename ReaderWrapper::LimaCell LimaCell;
772 typedef typename ReaderWrapper::LimaFaceGroup LimaFaceGroup;
773 typedef typename ReaderWrapper::LimaFace LimaFace;
776 Integer nb = m_wrapper.nbCellGroup();
778 const LimaCellGroup& lima_group = m_wrapper.cellGroup(i);
779 std::string group_name = lima_group.nom();
780 if (group_name==
"LOCAL" || group_name==
"local"){
781 Integer nb_own_cell = m_wrapper.cellGroupNbCell(lima_group);
782 cells_filter.resize(nb_own_cell);
783 for(
Integer z=0; z<nb_own_cell; ++z ){
784 cells_filter[z] = CheckedConvert::toInteger(m_wrapper.cellCellGroup(lima_group,z).id() - 1);
790 if (use_internal_partition && sid!=0){
795 cells_filter.resize(mesh_nb_cell);
796 for(
Integer i=0; i<mesh_nb_cell; ++i )
802 for(
Integer j=0, js=cells_filter.size(); j<js; ++j ){
803 mesh_nb_cell_node += CheckedConvert::toInteger(m_wrapper.cell(cells_filter[j]).nb_noeuds());
810 for(
Integer i_cell=0, s_cell=cells_filter.size(); i_cell<s_cell; ++i_cell ){
812 Integer cell_indirect_id = cells_filter[i_cell];
813 LimaCell lima_cell = m_wrapper.cell(cell_indirect_id);
814 Integer n = CheckedConvert::toInteger(lima_cell.nb_noeuds());
816 Integer ct = ReaderWrapper::cellToType(n);
820 cells_infos[cells_infos_index] = ct;
823 cells_infos[cells_infos_index] = cells_unique_id[cell_indirect_id];
827 for(
Integer z=0, sz=n; z<sz; ++z ){
828 Int64 node_uid = nodes_unique_id[CheckedConvert::toInteger(lima_cell.noeud(z).id()-1)];
829 cells_infos[cells_infos_index+z] = node_uid;
833 cout <<
"CELL LIMA1 " << cells_unique_id[cell_indirect_id] <<
" ";
835 cout <<
" " << cells_infos[cells_infos_index+z];
839 cells_infos_index += n;
842 logdate() <<
"Début allocation du maillage nb_cell=" << cells_filter.size();
843 mesh->allocateCells(cells_filter.size(),cells_infos,
false);
844 logdate() <<
"Fin allocation du maillage";
847 if (use_internal_partition){
849 for(
Integer i=0, is=nodes.size(); i<is; ++i )
850 nodes[i]->setOwner(sid,sid);
852 for(
Integer i=0, is=cells.size(); i<is; ++i )
853 cells[i]->setOwner(sid,sid);
858 Integer sub_domain_id = subDomain()->subDomainId();
859 Integer nb = CheckedConvert::toInteger(lima.nb_nuages());
861 const Lima::Nuage& lima_group = lima.nuage(i);
862 Integer nb_item_in_group = CheckedConvert::toInteger(lima_group.nb_noeuds());
863 std::string group_name = lima_group.nom();
864 unique_ids.resize(nb_item_in_group);
865 local_ids.resize(nb_item_in_group);
866 for(
Integer z=0; z<nb_item_in_group; ++z ){
867 unique_ids[z] = nodes_unique_id[CheckedConvert::toInteger(lima_group.noeud(z).id() - 1)];
869 mesh->nodeFamily()->itemsUniqueIdToLocalId(local_ids,unique_ids,
false);
870 bool remove_group =
false;
871 if (group_name==
"LOCALN" || group_name==
"localn"){
872 info() <<
"Utilisation du groupe 'LOCALN' pour indiquer que les "
873 <<
"noeuds appartiennent au sous-domaine";
875 for(
Integer z=0, sz=nb_item_in_group; z<sz; ++z ){
876 Integer local_id = local_ids[z];
877 if (local_id!=NULL_ITEM_ID)
878 nodes[local_id]->setOwner(sub_domain_id,sub_domain_id);
882 debug() <<
"Vérification du groupe '" << group_name <<
"'";
883 if (group_name.length()>3 && !remove_group){
885 if (grp.startsWith(
"NF_")){
886 grp = grp.substring(3);
887 Int32 ghost_sub_domain_id = 0;
888 bool is_bad = builtInGetValue(ghost_sub_domain_id,grp);
889 debug() <<
"Vérification du groupe '" << group_name <<
"' (3) " << is_bad;
891 info() <<
"Utilisation du groupe " << group_name <<
" pour indiquer que le "
892 <<
"sous-domaine " << ghost_sub_domain_id <<
" est propriétaire de ses noeuds";
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_ids[z]]->setOwner(ghost_sub_domain_id,sub_domain_id);
915 for(
Integer i_face=0; i_face<lima_nb_face; ++i_face ){
916 const LimaFace& lima_face = m_wrapper.face(i_face);
917 face_nb_node += CheckedConvert::toInteger(lima_face.nb_noeuds());
923 Integer faces_nodes_unique_id_index = 0;
933 for(
Integer i_face=0; i_face<lima_nb_face; ++i_face ){
934 const LimaFace& lima_face = m_wrapper.face(i_face);
935 Integer n = CheckedConvert::toInteger(lima_face.nb_noeuds());
936 orig_nodes_id.resize(n);
937 face_nodes_index.resize(n);
939 orig_nodes_id[z] = nodes_unique_id[CheckedConvert::toInteger(lima_face.noeud(z).id() - 1)];
943 cout <<
"FACE LIMA1 " << lima_face.id()-1 <<
" ";
945 cout <<
" " << orig_nodes_id[z];
951 faces_nodes_unique_id[faces_nodes_unique_id_index+z] = orig_nodes_id[face_nodes_index[z]];
952 faces_first_node_unique_id[i_face] = orig_nodes_id[face_nodes_index[0]];
953 faces_nodes_unique_id_index += n;
956 mesh->nodeFamily()->itemsUniqueIdToLocalId(faces_first_node_local_id,faces_first_node_unique_id);
958 faces_nodes_unique_id_index = 0;
959 for(
Integer i_face=0; i_face<lima_nb_face; ++i_face ){
960 const LimaFace& lima_face = m_wrapper.face(i_face);
961 Integer n = CheckedConvert::toInteger(lima_face.nb_noeuds());
963 Node current_node(mesh_nodes[faces_first_node_local_id[i_face]]);
964 Face face = mesh_utils::getFaceFromNodesUnique(current_node,face_nodes_id);
970 ostr() <<
' ' << face_nodes_id[z];
971 ostr() <<
" - " << current_node.localId() <<
")";
972 ARCANE_FATAL(
"INTERNAL: Lima face index={0} with nodes '{1}' is not in node/face connectivity",
975 faces_id[i_face] = face.localId();
977 faces_nodes_unique_id_index += n;
986 if (use_internal_partition && sid!=0){
988 Integer nb = CheckedConvert::toInteger(lima.nb_nuages());
990 const Lima::Nuage& lima_group = lima.nuage(i);
991 std::string group_name = lima_group.nom();
996 Integer nb = m_wrapper.nbFaceGroup();
998 const LimaFaceGroup& lima_group = m_wrapper.faceGroup(i);
999 std::string group_name = lima_group.nom();
1004 Integer nb = m_wrapper.nbCellGroup();
1005 for(
Integer i=0; i<nb; ++i ){
1006 const LimaCellGroup& lima_group = m_wrapper.cellGroup(i);
1007 std::string group_name = lima_group.nom();
1015 Integer sub_domain_id = subDomain()->subDomainId();
1018 Integer nb = CheckedConvert::toInteger(lima.nb_nuages());
1019 for(
Integer i=0; i<nb; ++i ){
1020 const Lima::Nuage& lima_group = lima.nuage(i);
1021 Integer nb_item_in_group = CheckedConvert::toInteger(lima_group.nb_noeuds());
1022 std::string group_name = lima_group.nom();
1023 unique_ids.resize(nb_item_in_group);
1024 local_ids.resize(nb_item_in_group);
1025 for(
Integer z=0; z<nb_item_in_group; ++z ){
1026 Integer lima_node_id = CheckedConvert::toInteger(lima_group.noeud(z).id());
1027 unique_ids[z] = nodes_unique_id[lima_node_id - 1];
1029 mesh->nodeFamily()->itemsUniqueIdToLocalId(local_ids,unique_ids);
1030 bool remove_group =
false;
1031 if (group_name==
"LOCALN" || group_name==
"localn"){
1032 remove_group =
true;
1034 debug() <<
"Vérification du groupe '" << group_name <<
"'";
1035 if (group_name.length()>3 && !remove_group){
1036 String grp = group_name.c_str();
1038 debug() <<
"Vérification du groupe '" << group_name <<
"' (2) '" << grp <<
"'";
1039 if (grp.startsWith(
"NF_")){
1042 grp = grp.substring(3);
1043 Integer ghost_sub_domain_id = 0;
1044 bool is_bad = builtInGetValue(ghost_sub_domain_id,grp);
1045 debug() <<
"Vérification du groupe '" << group_name <<
"' (3) " << is_bad;
1047 remove_group =
true;
1052 log() <<
"NodeGroup Name <" << group_name <<
"> (" << nb_item_in_group <<
" elements)";
1059 Integer nb = m_wrapper.nbFaceGroup();
1060 for(
Integer i=0; i<nb; ++i ){
1061 const LimaFaceGroup& lima_group = m_wrapper.faceGroup(i);
1062 Integer nb_item_in_group = m_wrapper.faceGroupNbFace(lima_group);
1063 local_ids.resize(nb_item_in_group);
1066 for(
Integer z=0; z<nb_item_in_group; ++z ){
1067 local_ids[z] = faces_id[CheckedConvert::toInteger(m_wrapper.faceFaceGroup(lima_group,z).id() - 1)];
1069 std::string group_name = lima_group.nom();
1070 log() <<
"FaceGroup Name <" << group_name <<
"> (" << nb_item_in_group <<
" elements)";
1076 Integer nb = m_wrapper.nbCellGroup();
1077 for(
Integer i=0; i<nb; ++i ){
1078 const LimaCellGroup& lima_group = m_wrapper.cellGroup(i);
1079 Integer nb_item_in_group = m_wrapper.cellGroupNbCell(lima_group);
1080 std::string group_name = lima_group.nom();
1081 unique_ids.resize(nb_item_in_group);
1082 local_ids.resize(nb_item_in_group);
1083 for(
Integer z=0; z<nb_item_in_group; ++z ){
1084 unique_ids[z] = cells_unique_id[CheckedConvert::toInteger(m_wrapper.cellCellGroup(lima_group,z).id() - 1)];
1086 mesh->cellFamily()->itemsUniqueIdToLocalId(local_ids,unique_ids);
1087 bool remove_group =
false;
1088 if (group_name==
"LOCAL" || group_name==
"local"){
1090 for(
Integer z=0, sz=nb_item_in_group; z<sz; ++z )
1091 cells[local_ids[z]]->setOwner(sub_domain_id,sub_domain_id);
1092 remove_group =
true;
1095 String grp(group_name.c_str());
1096 if (grp.startsWith(
"MF_")){
1097 info() <<
"Le groupe de mailles " << group_name <<
" n'est pas utilisé";
1098 remove_group =
true;
1102 log() <<
"CellGroup Name <" << group_name <<
"> (" << nb_item_in_group <<
" elements)";
1120 Integer nb_ghost_layer =
mesh->ghostLayerMng()->nbGhostLayer();
1121 if (nb_ghost_layer>1)
1122 nodes =
mesh->ownNodes();
1124 const Node& node = *i;
1125 nodes_coord_var[node] = nodes_coords.lookupValue(node.uniqueId());
1128 if (nb_ghost_layer>1)
1129 nodes_coord_var.synchronize();
1134 info() <<
"Nombre de nuages " << lima.nb_nuages();
1135 info() <<
"Nombre de lignes " << lima.nb_lignes();
1136 info() <<
"Nombre de surfaces " << lima.nb_surfaces();
1137 info() <<
"Nombre de volumes " << lima.nb_volumes();
1143 logdate() <<
"Fin de lecture du fichier";
1155 if (!dir_name.empty()){
1156 comm_file_nameb += dir_name;
1157 comm_file_nameb +=
"/";
1159 comm_file_nameb +=
"Communications";
1160 String comm_file_name = comm_file_nameb.toString();
1164 if (!doc_holder.get())
1171 String ustr_buf = String::fromNumber(sd->subDomainId());
1173 for(
Integer i=0, s=cpu_list.size(); i<s; ++i ){
1174 String id_str = cpu_list[i].attrValue(ustr_id);
1175 if (id_str==ustr_buf){
1176 cpu_elem = cpu_list[i];
1180 if (cpu_elem.null())
1181 ARCANE_FATAL(
"No element <cpus/cpu-from[@id=\"{0}\"]>",sd->subDomainId());
1183 cpu_list = cpu_elem.children(
String(
"cpu-to"));
1184 debug() <<
"Nb procs " << cpu_list.size();
1185 for(
Integer i=0; i<cpu_list.size(); ++i ){
1186 Integer v = cpu_list[i].valueAsInteger();
1188 debug() <<
"Read proc " << v;
1196class LimaCaseMeshReader
1210 , m_read_info(read_info)
1217 ARCANE_UNUSED(build_info);
1222 String fname = m_read_info.fileName();
1223 m_trace_mng->info() <<
"Lima Reader (ICaseMeshReader) file_name=" << fname;
1224 bool use_length_unit =
true;
1225 String directory_name = m_read_info.directoryName();
1226 IMeshReader::eReturnType ret = reader.readMesh(pm, fname, directory_name, m_read_info.isParallelRead(), use_length_unit);
1249 String str = read_info.format();
1250 if (str==
"unf" || str==
"mli" || str==
"mli2" || str==
"ice" || str==
"uns" || str==
"unv")
1251 builder =
new Builder(m_sub_domain, read_info);
1300void LimaMeshWriter::
1301_writeItem(Lima::Maillage& m,ConstArrayView<Lima::Noeud> nodes,ItemWithNodes c)
1304 case IT_Octaedron12:
1305 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1306 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1307 nodes[c.node(4).localId()],nodes[c.node(5).localId()],
1308 nodes[c.node(6).localId()],nodes[c.node(7).localId()],
1309 nodes[c.node(8).localId()],nodes[c.node(9).localId()],
1310 nodes[c.node(10).localId()],nodes[c.node(11).localId()]));
1312 case IT_Heptaedron10:
1313 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1314 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1315 nodes[c.node(4).localId()],nodes[c.node(5).localId()],
1316 nodes[c.node(6).localId()],nodes[c.node(7).localId()],
1317 nodes[c.node(8).localId()],nodes[c.node(9).localId()]));
1320 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1321 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1322 nodes[c.node(4).localId()],nodes[c.node(5).localId()],
1323 nodes[c.node(6).localId()],nodes[c.node(7).localId()]));
1325 case IT_Pentaedron6:
1326 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1327 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1328 nodes[c.node(4).localId()],nodes[c.node(5).localId()]));
1331 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1332 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1333 nodes[c.node(4).localId()]));
1335 case IT_Tetraedron4:
1336 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1337 nodes[c.node(2).localId()],nodes[c.node(3).localId()]));
1340 m.ajouter(Lima::Polygone(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1341 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1342 nodes[c.node(4).localId()],nodes[c.node(5).localId()]));
1345 m.ajouter(Lima::Polygone(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1346 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1347 nodes[c.node(4).localId()]));
1350 m.ajouter(Lima::Polygone(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1351 nodes[c.node(2).localId()],nodes[c.node(3).localId()]));
1354 m.ajouter(Lima::Polygone(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1355 nodes[c.node(2).localId()]));
1358 m.ajouter(Lima::Bras(nodes[c.node(0).localId()],nodes[c.node(1).localId()]));
1374 int dimension =
mesh->dimension();
1376 std::string std_file_name = file_name.
localstr();
1380 const size_t rpos2 = std_file_name.rfind(
".mli2");
1381 std::string::size_type std_end = std::string::npos;
1382 bool need_mutex = rpos2!=std_end;
1383 if (rpos2==std_end && std_file_name.rfind(
".mli")==std_end && std_file_name.rfind(
".unf")==std_end){
1384 std_file_name +=
".mli2";
1387 info() <<
"FINAL_FILE_NAME=" << std_file_name;
1388 Lima::Maillage lima(std_file_name);
1391 lima.dimension(Lima::D3);
1392 else if (dimension==2)
1393 lima.dimension(Lima::D2);
1415 for(
Integer i=0; i<mesh_nb_node; ++i ){
1416 Node node = nodes[i];
1417 Real3 coord = nodes_coords[node];
1421 lima.ajouter(lm_nodes[i]);
1425 for(
Integer i=0; i<mesh_nb_edge; ++i ){
1426 _writeItem(lima,lm_nodes,edges[i]);
1430 for(
Integer i=0; i<mesh_nb_face; ++i ){
1431 _writeItem(lima,lm_nodes,faces[i]);
1435 for(
Integer i=0; i<mesh_nb_cell; ++i ){
1436 _writeItem(lima,lm_nodes,cells[i]);
1447 lima.ajouter(lm_group);
1449 lm_group.ajouter(lima.noeud(iitem.localId()));
1459 lima.ajouter(lm_group);
1461 lm_group.ajouter(lima.bras(iitem.localId()));
1472 lima.ajouter(lm_group);
1474 lm_group.ajouter(lima.polygone(iitem.localId()));
1477 else if (dimension==2){
1479 lima.ajouter(lm_group);
1481 lm_group.ajouter(lima.bras(iitem.localId()));
1493 lima.ajouter(lm_group);
1495 lm_group.ajouter(lima.polyedre(iitem.localId()));
1498 else if (dimension==2){
1500 lima.ajouter(lm_group);
1502 lm_group.ajouter(lima.polygone(iitem.localId()));
1506 info(4) <<
"Writing file '" << std_file_name <<
"'";
1509 GlobalLimaMutex sc(need_mutex);
1510 lima.ecrire(std_file_name);
1513 catch(
const std::exception& ex){
1514 trace->
warning() <<
"Exception (std::exception) in LIMA: Can not write file <" << std_file_name <<
">"
1515 <<
" Exception: " << ex.what() <<
'\n';
1519 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