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/IMeshReader.h"
30#include "arcane/IGhostLayerMng.h"
31#include "arcane/ISubDomain.h"
32#include "arcane/IIOMng.h"
33#include "arcane/IParallelMng.h"
34#include "arcane/IPrimaryMesh.h"
35#include "arcane/Item.h"
36#include "arcane/ItemTypeMng.h"
37#include "arcane/ItemGroup.h"
38#include "arcane/ArcaneException.h"
39#include "arcane/Service.h"
40#include "arcane/Timer.h"
41#include "arcane/ServiceFactory.h"
42#include "arcane/ServiceInfo.h"
43#include "arcane/CaseOptionsMain.h"
44#include "arcane/MeshUtils.h"
45#include "arcane/ItemEnumerator.h"
46#include "arcane/VariableTypes.h"
47#include "arcane/ServiceBuildInfo.h"
48#include "arcane/XmlNodeList.h"
49#include "arcane/IXmlDocumentHolder.h"
50#include "arcane/IItemFamily.h"
51#include "arcane/FactoryService.h"
52#include "arcane/IMeshWriter.h"
53#include "arcane/AbstractService.h"
54#include "arcane/ICaseDocument.h"
55#include "arcane/ICaseMeshReader.h"
56#include "arcane/IMeshBuilder.h"
58#include "arcane/cea/LimaCutInfosReader.h"
60#include <Lima/lima++.h>
76void createGroup(IItemFamily* family,
const String& name,
Int32ArrayView local_ids);
96 const String& dir_name,
bool use_internal_partition,Real length_multiplier) =0;
98 ISubDomain* subDomain()
const {
return m_sub_domain; }
117template<
typename ReaderWrapper>
128 delete m_cut_infos_reader;
134 const String& dir_name,
bool use_internal_partition,Real length_multiplier);
139 ReaderWrapper m_wrapper;
142 const String& dir_name,
bool use_internal_partition,Real length_multiplier);
154 void setLima(
const Lima::Maillage& lima_mesh)
156 m_lima_mesh = lima_mesh;
161 Lima::Maillage m_lima_mesh;
171 typedef Lima::Surface LimaCellGroup;
172 typedef Lima::Polygone LimaCell;
173 typedef Lima::Ligne LimaFaceGroup;
174 typedef Lima::Bras LimaFace;
176 Integer nbCellGroup()
180 Integer nbFaceGroup()
184 LimaCellGroup cellGroup(Integer i)
186 return m_lima_mesh.surface(i);
188 LimaFaceGroup faceGroup(Integer i)
190 return m_lima_mesh.ligne(i);
192 Integer faceGroupNbFace(
const LimaFaceGroup& group)
196 LimaFace faceFaceGroup(
const LimaFaceGroup& group,Integer i)
198 return group.bras(i);
200 Integer cellGroupNbCell(
const LimaCellGroup& group)
204 LimaCell cellCellGroup(
const LimaCellGroup& group,Integer i)
206 return group.polygone(i);
208 LimaCell cell(Integer i)
210 return m_lima_mesh.polygone(i);
212 LimaFace face(Integer i)
214 return m_lima_mesh.bras(i);
228 const char* strDimension()
232 static Integer cellToType(Integer nb_node)
235 case 3:
return IT_Triangle3;
236 case 4:
return IT_Quad4;
237 case 5:
return IT_Pentagon5;
238 case 6:
return IT_Hexagon6;
253 typedef Lima::Volume LimaCellGroup;
254 typedef Lima::Polyedre LimaCell;
255 typedef Lima::Surface LimaFaceGroup;
256 typedef Lima::Polygone LimaFace;
258 Integer nbCellGroup()
262 Integer nbFaceGroup()
266 LimaCellGroup cellGroup(Integer i)
268 return m_lima_mesh.volume(i);
270 LimaFaceGroup faceGroup(Integer i)
272 return m_lima_mesh.surface(i);
274 Integer faceGroupNbFace(
const LimaFaceGroup& group)
278 LimaFace faceFaceGroup(
const LimaFaceGroup& group,Integer i)
280 return group.polygone(i);
282 Integer cellGroupNbCell(
const LimaCellGroup& group)
286 LimaCell cellCellGroup(
const LimaCellGroup& group,Integer i)
288 return group.polyedre(i);
290 LimaCell cell(Integer i)
292 return m_lima_mesh.polyedre(i);
294 LimaFace face(Integer i)
296 return m_lima_mesh.polygone(i);
310 const char* strDimension()
314 static Integer cellToType(Integer nb_node)
317 case 4:
return IT_Tetraedron4;
318 case 5:
return IT_Pyramid5;
319 case 6:
return IT_Pentaedron6;
320 case 8:
return IT_Hexaedron8;
321 case 10:
return IT_Heptaedron10;
322 case 12:
return IT_Octaedron12;
346 const String& dir_name,
bool use_internal_partition,
375 return str==
"unf" || str==
"mli" || str==
"mli2" || str==
"ice" || str==
"uns" || str==
"unv";
380 const String& dir_name,
bool use_internal_partition)
override;
381 ISubDomain* subDomain() {
return m_sub_domain; }
385 ISubDomain* m_sub_domain;
400LimaMeshReaderService::
401LimaMeshReaderService(
const ServiceBuildInfo& sbi)
402: AbstractService(sbi)
403, m_sub_domain(sbi.subDomain())
410#ifdef ARCANE_LIMA_HAS_MLI
412_directLimaPartitionMalipp(ITimerMng* timer_mng,IPrimaryMesh* mesh,
413 const String& filename,Real length_multiplier);
416#ifdef ARCANE_LIMA_HAS_MLI2
418_directLimaPartitionMalipp2(ITimerMng* timer_mng,IPrimaryMesh* mesh,
419 const String& filename,Real length_multiplier);
428 bool use_internal_partition)
432 String case_doc_lang =
"en";
435 case_doc_lang = case_doc->
language();
438 String use_unit_attr_name =
"utilise-unite";
440 if (case_doc_lang==
"en"){
443 if (!use_unit_str.
empty()){
444 warning() <<
"'utilise-unite' ne doit être utilisé que pour les JDD en francais."
445 <<
"Utilisez 'use-unit' à la place";
447 use_unit_attr_name =
"use-unit";
453 if (use_unit_str.
null()){
454 info() <<
"Attribute '" << use_unit_attr_name <<
"' is not found. Trying with 'use-unit'";
455 use_unit_attr_name =
"use-unit";
461 bool use_length_unit =
true;
462 if (!platform::getEnvironmentVariable(
"ARCANE_LIMA_DEFAULT_NO_UNIT").null())
463 use_length_unit =
false;
464 info() <<
"Default value for unit usage: " << use_length_unit;
466 if (use_unit_str.
empty())
467 use_unit_str = mesh_node.
attrValue(use_unit_attr_name);
468 info() <<
"Checking for attribute '" << use_unit_attr_name <<
"' value='" << use_unit_str <<
"'";
469 if (!use_unit_str.
empty()){
470 if (use_unit_str==
"1" || use_unit_str==
"true")
471 use_length_unit =
true;
472 else if (use_unit_str==
"0" || use_unit_str==
"false")
473 use_length_unit =
false;
475 ARCANE_FATAL(
"Invalid value boolean value '{0}' for '{1}' attribute."
476 " Valid values are '0', '1' 'true' or 'false'",
477 use_unit_str,use_unit_attr_name);
480 info() <<
"Utilise l'unité de longueur de Lima: " << use_length_unit <<
" (lang=" << case_doc_lang <<
")";
483 return reader.readMesh(mesh,filename,dir_name,use_internal_partition,use_length_unit);
491 bool use_internal_partition,
bool use_length_unit)
501 info() <<
"Lima: use_length_unit=" << use_length_unit
502 <<
" use_internal_partition=" << use_internal_partition;
503 Real length_multiplier = 0.0;
504 if (use_length_unit){
508 if (code_system.
null() || code_system.
empty()){
509 info() <<
"No unit system configured. Use MKS unit system.";
510 length_multiplier = 1.0;
512 else if (code_system==
"CGS"){
513 length_multiplier = 100.0;
515 else if (code_system==
"MKS"){
516 length_multiplier = 1.0;
519 ARCANE_FATAL(
"Unknown unit system '{0}' (valid values are: 'CGS' ou 'MKS'",code_system);
523 std::string loc_file_name = filename.
localstr();
524 size_t rpos = loc_file_name.rfind(
".mli");
525 size_t rpos2 = loc_file_name.rfind(
".mli2");
526 info() <<
" FILE_NAME=" << loc_file_name;
527 info() <<
" RPOS MLI=" << rpos <<
" s=" << loc_file_name.length();
528 info() <<
" RPOS MLI2=" << rpos2 <<
" s=" << loc_file_name.length();
531 bool has_thread =
false;
533 if (!has_thread && use_internal_partition && ((rpos+4)==loc_file_name.length())){
534 info() <<
"Use direct partitioning with mli";
535#ifdef ARCANE_LIMA_HAS_MLI
536 return _directLimaPartitionMalipp(timer_mng,mesh,filename,length_multiplier);
538 ARCANE_FATAL(
"Can not use 'mli' files because Lima is not compiled with 'mli' support");
541 else if (!has_thread && use_internal_partition && ((rpos2+5)==loc_file_name.length())){
542 info() <<
"Use direct partitioning with mli2";
543#ifdef ARCANE_LIMA_HAS_MLI2
544 return _directLimaPartitionMalipp2(timer_mng,mesh,filename,length_multiplier);
546 ARCANE_FATAL(
"Can not use 'mli2' files because Lima is not compiled with 'mli2' support");
550 info() <<
"Chargement Lima du fichier '" << filename <<
"'";
552 const char* version = Lima::lima_version();
553 info() <<
"Utilisation de la version " << version <<
" de Lima";
558 LM_TYPEMASQUE preparation = LM_ORIENTATION | LM_COMPACTE;
560 log() <<
"Début lecture fichier " << filename;
562 Lima::Maillage lima(filename.
localstr());
566 Timer::Sentry sentry(&time_to_read);
567 Timer::Phase t_action(sd,TP_InputOutput);
568 lima.lire(filename.
localstr(),Lima::SUFFIXE,
true);
570 lima.preparation_parametrable(preparation);
573 catch(
const Lima::erreur& ex){
574 ARCANE_FATAL(
"Can not read lima file '{0}' error is '{1}'",filename,ex.what());
580 info() <<
"Temps de lecture et préparation du maillage (unité: seconde): "
581 << time_to_read.lastActivationTime();
585 if (lima.dimension()==Lima::D3){
587 info() <<
"Maillage 3D";
589 else if (lima.dimension()==Lima::D2){
591 info() <<
"Maillage 2D";
596 lm =
new LimaWrapper<Lima3DReaderWrapper>(sd);
599 lm =
new LimaWrapper<Lima2DReaderWrapper>(sd);
602 log() <<
"Dimension du maillage non reconnue par lima";
606 bool ret = lm->readMesh(lima,mesh,filename,dir_name,use_internal_partition,length_multiplier);
613 if (nb_ghost_layer>1)
626template<
typename ReaderWrapper>
bool LimaWrapper<ReaderWrapper>::
627readMesh(Lima::Maillage& lima,IPrimaryMesh* mesh,
const String& filename,
628 const String& dir_name,
bool use_internal_partition,Real length_multiplier)
630 return _readMesh(lima,mesh,filename,dir_name,use_internal_partition,length_multiplier);
636template<
typename ReaderWrapper>
bool LimaWrapper<ReaderWrapper>::
637_readMesh(Lima::Maillage& lima,IPrimaryMesh* mesh,
const String& file_name,
638 const String& dir_name,
bool use_internal_partition,Real length_multiplier)
640 ARCANE_UNUSED(file_name);
644 IParallelMng* pm = mesh->parallelMng();
646 bool is_parallel = pm->isParallel();
654 m_wrapper.setLima(lima);
657 mesh_nb_cell = m_wrapper.nbCell();
658 lima_nb_face = m_wrapper.nbFace();
661 info() <<
"-- Informations sur le maillage (Interne):";
662 info() <<
"Nombre de noeuds " << mesh_nb_node;
663 info() <<
"Nombre d'arêtes " << nb_edge;
664 info() <<
"Nombre de faces " << lima_nb_face;
665 info() <<
"Nombre de mailles " << mesh_nb_cell;
666 info() <<
"-- Informations sur le maillage (Lima):";
667 info() <<
"Nombre de noeuds " << lima.nb_noeuds();
668 info() <<
"Nombre d'arêtes " << lima.nb_bras();
669 info() <<
"Nombre de polygones " << lima.nb_polygones();
670 info() <<
"Nombre de polyedres " << lima.nb_polyedres();
671 info() <<
"Nombre de surfaces " << lima.nb_surfaces();
672 info() <<
"Nombre de volumes " << lima.nb_volumes();
674 info() <<
"Unité de longueur du fichier: " << lima.unite_longueur();
677 if (length_multiplier==0.0)
678 length_multiplier = 1.0;
680 length_multiplier *= lima.unite_longueur();
682 if (mesh_nb_node==0){
692 UniqueArray<Int64> nodes_unique_id(mesh_nb_node);
693 UniqueArray<Int64> cells_unique_id(mesh_nb_cell);
694 if (is_parallel && !use_internal_partition && pm->commSize()>1){
695 m_cut_infos_reader->readItemsUniqueId(nodes_unique_id,cells_unique_id,dir_name);
698 for( Integer i=0; i<mesh_nb_node; ++i )
699 nodes_unique_id[i] = i;
700 for( Integer i=0; i<mesh_nb_cell; ++i )
701 cells_unique_id[i] = i;
706 bool first_uid_is_one =
false;
707 if (!platform::getEnvironmentVariable(
"ARCANE_LIMA_UNIQUE_ID").null()){
708 first_uid_is_one =
true;
709 info() <<
"WARNING: UniqueId begin at 1";
711 if (first_uid_is_one){
712 for( Integer i=0; i<mesh_nb_node; ++i )
713 ++nodes_unique_id[i];
714 for( Integer i=0; i<mesh_nb_cell; ++i )
715 ++cells_unique_id[i];
718 HashTableMapT<Int64,Real3> nodes_coords(mesh_nb_node,
true);
720 info() <<
"Using length multiplier v=" << length_multiplier;
721 for( Integer i=0; i<mesh_nb_node; ++i ){
722 const Lima::Noeud& node = lima.noeud(i);
723 Real3 coord(node.x(),node.y(),node.z());
724 coord *= length_multiplier;
725 nodes_coords.nocheckAdd(nodes_unique_id[i],coord);
729 for( Integer i=0; i<mesh_nb_node; ++i ){
730 const Lima::Noeud& node = lima.noeud(i);
731 Real3 coord(node.x(),node.y(),node.z());
732 nodes_coords.nocheckAdd(nodes_unique_id[i],coord);
738 UniqueArray<Integer> cells_filter;
740 bool use_own_mesh =
false;
742 if (is_parallel && pm->commSize()>1){
744 if (use_internal_partition)
745 use_own_mesh =
false;
748 typedef typename ReaderWrapper::LimaCellGroup LimaCellGroup;
749 typedef typename ReaderWrapper::LimaCell LimaCell;
750 typedef typename ReaderWrapper::LimaFaceGroup LimaFaceGroup;
751 typedef typename ReaderWrapper::LimaFace LimaFace;
754 Integer nb = m_wrapper.nbCellGroup();
755 for( Integer i=0; i<nb; ++i ){
756 const LimaCellGroup& lima_group = m_wrapper.cellGroup(i);
757 std::string group_name = lima_group.nom();
758 if (group_name==
"LOCAL" || group_name==
"local"){
759 Integer nb_own_cell = m_wrapper.cellGroupNbCell(lima_group);
760 cells_filter.resize(nb_own_cell);
761 for( Integer z=0; z<nb_own_cell; ++z ){
768 if (use_internal_partition && sid!=0){
773 cells_filter.resize(mesh_nb_cell);
774 for( Integer i=0; i<mesh_nb_cell; ++i )
780 for( Integer j=0, js=cells_filter.size(); j<js; ++j ){
785 UniqueArray<Int64> cells_infos(mesh_nb_cell_node+cells_filter.size()*2);
788 for( Integer i_cell=0, s_cell=cells_filter.size(); i_cell<s_cell; ++i_cell ){
790 Integer cell_indirect_id = cells_filter[i_cell];
791 LimaCell lima_cell = m_wrapper.cell(cell_indirect_id);
794 Integer ct = ReaderWrapper::cellToType(n);
796 throw UnknownItemTypeException(
"Lima::readFile: Cell",n,cell_indirect_id);
798 cells_infos[cells_infos_index] = ct;
801 cells_infos[cells_infos_index] = cells_unique_id[cell_indirect_id];
805 for( Integer z=0, sz=n; z<sz; ++z ){
807 cells_infos[cells_infos_index+z] = node_uid;
811 cout <<
"CELL LIMA1 " << cells_unique_id[cell_indirect_id] <<
" ";
812 for( Integer z=0; z<n; ++z )
813 cout <<
" " << cells_infos[cells_infos_index+z];
817 cells_infos_index += n;
820 logdate() <<
"Début allocation du maillage nb_cell=" << cells_filter.size();
821 mesh->allocateCells(cells_filter.size(),cells_infos,
false);
822 logdate() <<
"Fin allocation du maillage";
825 if (use_internal_partition){
827 for( Integer i=0, is=nodes.size(); i<is; ++i )
828 nodes[i]->setOwner(sid,sid);
830 for( Integer i=0, is=cells.size(); i<is; ++i )
831 cells[i]->setOwner(sid,sid);
836 Integer sub_domain_id = subDomain()->subDomainId();
838 for( Integer i=0; i<nb; ++i ){
839 const Lima::Nuage& lima_group = lima.nuage(i);
841 std::string group_name = lima_group.nom();
842 unique_ids.resize(nb_item_in_group);
843 local_ids.resize(nb_item_in_group);
844 for( Integer z=0; z<nb_item_in_group; ++z ){
847 mesh->nodeFamily()->itemsUniqueIdToLocalId(local_ids,unique_ids,
false);
848 bool remove_group =
false;
849 if (group_name==
"LOCALN" || group_name==
"localn"){
850 info() <<
"Utilisation du groupe 'LOCALN' pour indiquer que les "
851 <<
"noeuds appartiennent au sous-domaine";
853 for( Integer z=0, sz=nb_item_in_group; z<sz; ++z ){
854 Integer local_id = local_ids[z];
855 if (local_id!=NULL_ITEM_ID)
856 nodes[local_id]->setOwner(sub_domain_id,sub_domain_id);
860 debug() <<
"Vérification du groupe '" << group_name <<
"'";
861 if (group_name.length()>3 && !remove_group){
862 String grp = group_name;
863 if (grp.startsWith(
"NF_")){
864 grp = grp.substring(3);
865 Int32 ghost_sub_domain_id = 0;
866 bool is_bad = builtInGetValue(ghost_sub_domain_id,grp);
867 debug() <<
"Vérification du groupe '" << group_name <<
"' (3) " << is_bad;
869 info() <<
"Utilisation du groupe " << group_name <<
" pour indiquer que le "
870 <<
"sous-domaine " << ghost_sub_domain_id <<
" est propriétaire de ses noeuds";
872 for( Integer z=0, sz=nb_item_in_group; z<sz; ++z ){
873 Integer local_id = local_ids[z];
874 if (local_id!=NULL_ITEM_ID)
875 nodes[local_ids[z]]->setOwner(ghost_sub_domain_id,sub_domain_id);
889 UniqueArray<Integer> faces_id(lima_nb_face);
893 for( Integer i_face=0; i_face<lima_nb_face; ++i_face ){
894 const LimaFace& lima_face = m_wrapper.face(i_face);
898 UniqueArray<Int64> faces_first_node_unique_id(lima_nb_face);
899 UniqueArray<Int32> faces_first_node_local_id(lima_nb_face);
900 UniqueArray<Int64> faces_nodes_unique_id(face_nb_node);
901 Integer faces_nodes_unique_id_index = 0;
903 UniqueArray<Int64> orig_nodes_id;
904 orig_nodes_id.reserve(100);
906 UniqueArray<Integer> face_nodes_index;
907 face_nodes_index.reserve(100);
911 for( Integer i_face=0; i_face<lima_nb_face; ++i_face ){
912 const LimaFace& lima_face = m_wrapper.face(i_face);
914 orig_nodes_id.resize(n);
915 face_nodes_index.resize(n);
916 for( Integer z=0; z<n; ++z )
921 cout <<
"FACE LIMA1 " << lima_face.id()-1 <<
" ";
922 for( Integer z=0; z<n; ++z )
923 cout <<
" " << orig_nodes_id[z];
927 mesh_utils::reorderNodesOfFace2(orig_nodes_id,face_nodes_index);
928 for( Integer z=0; z<n; ++z )
929 faces_nodes_unique_id[faces_nodes_unique_id_index+z] = orig_nodes_id[face_nodes_index[z]];
930 faces_first_node_unique_id[i_face] = orig_nodes_id[face_nodes_index[0]];
931 faces_nodes_unique_id_index += n;
934 mesh->nodeFamily()->itemsUniqueIdToLocalId(faces_first_node_local_id,faces_first_node_unique_id);
936 faces_nodes_unique_id_index = 0;
937 for( Integer i_face=0; i_face<lima_nb_face; ++i_face ){
938 const LimaFace& lima_face = m_wrapper.face(i_face);
941 Node current_node(mesh_nodes[faces_first_node_local_id[i_face]]);
942 Face face = mesh_utils::getFaceFromNodesUnique(current_node,face_nodes_id);
947 for( Integer z=0; z<n; ++z )
948 ostr() <<
' ' << face_nodes_id[z];
949 ostr() <<
" - " << current_node.localId() <<
")";
950 ARCANE_FATAL(
"INTERNAL: Lima face index={0} with nodes '{1}' is not in node/face connectivity",
953 faces_id[i_face] = face.localId();
955 faces_nodes_unique_id_index += n;
959 IItemFamily* node_family = mesh->nodeFamily();
960 IItemFamily* face_family = mesh->faceFamily();
961 IItemFamily* cell_family = mesh->cellFamily();
964 if (use_internal_partition && sid!=0){
967 for( Integer i=0; i<nb; ++i ){
968 const Lima::Nuage& lima_group = lima.nuage(i);
969 std::string group_name = lima_group.nom();
974 Integer nb = m_wrapper.nbFaceGroup();
975 for( Integer i=0; i<nb; ++i ){
976 const LimaFaceGroup& lima_group = m_wrapper.faceGroup(i);
977 std::string group_name = lima_group.nom();
982 Integer nb = m_wrapper.nbCellGroup();
983 for( Integer i=0; i<nb; ++i ){
984 const LimaCellGroup& lima_group = m_wrapper.cellGroup(i);
985 std::string group_name = lima_group.nom();
991 UniqueArray<Int64> unique_ids;
992 UniqueArray<Int32> local_ids;
993 Integer sub_domain_id = subDomain()->subDomainId();
997 for( Integer i=0; i<nb; ++i ){
998 const Lima::Nuage& lima_group = lima.nuage(i);
1000 std::string group_name = lima_group.nom();
1001 unique_ids.resize(nb_item_in_group);
1002 local_ids.resize(nb_item_in_group);
1003 for( Integer z=0; z<nb_item_in_group; ++z ){
1005 unique_ids[z] = nodes_unique_id[lima_node_id - 1];
1007 mesh->nodeFamily()->itemsUniqueIdToLocalId(local_ids,unique_ids);
1008 bool remove_group =
false;
1009 if (group_name==
"LOCALN" || group_name==
"localn"){
1010 remove_group =
true;
1012 debug() <<
"Vérification du groupe '" << group_name <<
"'";
1013 if (group_name.length()>3 && !remove_group){
1014 String grp = group_name.c_str();
1016 debug() <<
"Vérification du groupe '" << group_name <<
"' (2) '" << grp <<
"'";
1017 if (grp.startsWith(
"NF_")){
1020 grp = grp.substring(3);
1021 Integer ghost_sub_domain_id = 0;
1022 bool is_bad = builtInGetValue(ghost_sub_domain_id,grp);
1023 debug() <<
"Vérification du groupe '" << group_name <<
"' (3) " << is_bad;
1025 remove_group =
true;
1030 log() <<
"NodeGroup Name <" << group_name <<
"> (" << nb_item_in_group <<
" elements)";
1031 LimaUtils::createGroup(node_family,group_name,local_ids);
1037 Integer nb = m_wrapper.nbFaceGroup();
1038 for( Integer i=0; i<nb; ++i ){
1039 const LimaFaceGroup& lima_group = m_wrapper.faceGroup(i);
1040 Integer nb_item_in_group = m_wrapper.faceGroupNbFace(lima_group);
1041 local_ids.resize(nb_item_in_group);
1044 for( Integer z=0; z<nb_item_in_group; ++z ){
1047 std::string group_name = lima_group.nom();
1048 log() <<
"FaceGroup Name <" << group_name <<
"> (" << nb_item_in_group <<
" elements)";
1049 LimaUtils::createGroup(face_family,group_name,local_ids);
1054 Integer nb = m_wrapper.nbCellGroup();
1055 for( Integer i=0; i<nb; ++i ){
1056 const LimaCellGroup& lima_group = m_wrapper.cellGroup(i);
1057 Integer nb_item_in_group = m_wrapper.cellGroupNbCell(lima_group);
1058 std::string group_name = lima_group.nom();
1059 unique_ids.resize(nb_item_in_group);
1060 local_ids.resize(nb_item_in_group);
1061 for( Integer z=0; z<nb_item_in_group; ++z ){
1064 mesh->cellFamily()->itemsUniqueIdToLocalId(local_ids,unique_ids);
1065 bool remove_group =
false;
1066 if (group_name==
"LOCAL" || group_name==
"local"){
1068 for( Integer z=0, sz=nb_item_in_group; z<sz; ++z )
1069 cells[local_ids[z]]->setOwner(sub_domain_id,sub_domain_id);
1070 remove_group =
true;
1073 String grp(group_name.c_str());
1074 if (grp.startsWith(
"MF_")){
1075 info() <<
"Le groupe de mailles " << group_name <<
" n'est pas utilisé";
1076 remove_group =
true;
1080 log() <<
"CellGroup Name <" << group_name <<
"> (" << nb_item_in_group <<
" elements)";
1081 LimaUtils::createGroup(cell_family,group_name,local_ids);
1098 Integer nb_ghost_layer = mesh->ghostLayerMng()->nbGhostLayer();
1099 if (nb_ghost_layer>1)
1100 nodes = mesh->ownNodes();
1102 const Node& node = *i;
1103 nodes_coord_var[node] = nodes_coords.lookupValue(node.uniqueId());
1106 if (nb_ghost_layer>1)
1107 nodes_coord_var.synchronize();
1112 info() <<
"Nombre de nuages " << lima.nb_nuages();
1113 info() <<
"Nombre de lignes " << lima.nb_lignes();
1114 info() <<
"Nombre de surfaces " << lima.nb_surfaces();
1115 info() <<
"Nombre de volumes " << lima.nb_volumes();
1121 logdate() <<
"Fin de lecture du fichier";
1128template<
typename ReaderWrapper>
void LimaWrapper<ReaderWrapper>::
1129_getProcList(UniqueArray<Integer>& proc_list,
const String& dir_name)
1131 ISubDomain* sd = subDomain();
1132 StringBuilder comm_file_nameb;
1133 if (!dir_name.empty()){
1134 comm_file_nameb += dir_name;
1135 comm_file_nameb +=
"/";
1137 comm_file_nameb +=
"Communications";
1138 String comm_file_name = comm_file_nameb.toString();
1141 ScopedPtrT<IXmlDocumentHolder> doc_holder(sd->ioMng()->parseXmlFile(comm_file_name));
1142 if (!doc_holder.get())
1145 XmlNode root_elem = doc_holder->documentNode().documentElement();
1147 XmlNodeList cpu_list = root_elem.child(String(
"cpus")).children(String(
"cpu-from"));
1149 String ustr_buf = String::fromNumber(sd->subDomainId());
1150 String ustr_id(String(
"id"));
1151 for( Integer i=0, s=cpu_list.size(); i<s; ++i ){
1152 String id_str = cpu_list[i].attrValue(ustr_id);
1153 if (id_str==ustr_buf){
1154 cpu_elem = cpu_list[i];
1158 if (cpu_elem.null())
1159 ARCANE_FATAL(
"No element <cpus/cpu-from[@id=\"{0}\"]>",sd->subDomainId());
1161 cpu_list = cpu_elem.children(String(
"cpu-to"));
1162 debug() <<
"Nb procs " << cpu_list.size();
1163 for( Integer i=0; i<cpu_list.size(); ++i ){
1164 Integer v = cpu_list[i].valueAsInteger();
1166 debug() <<
"Read proc " << v;
1188 , m_read_info(read_info)
1195 ARCANE_UNUSED(build_info);
1200 String fname = m_read_info.fileName();
1201 m_trace_mng->
info() <<
"Lima Reader (ICaseMeshReader) file_name=" << fname;
1202 bool use_length_unit =
true;
1203 String directory_name = m_read_info.directoryName();
1204 IMeshReader::eReturnType ret = reader.readMesh(pm, fname, directory_name, m_read_info.isParallelRead(), use_length_unit);
1227 String str = read_info.format();
1228 if (str==
"unf" || str==
"mli" || str==
"mli2" || str==
"ice" || str==
"uns" || str==
"unv")
1229 builder =
new Builder(m_sub_domain, read_info);
1230 return makeRef(builder);
1278void LimaMeshWriter::
1279_writeItem(Lima::Maillage& m,ConstArrayView<Lima::Noeud> nodes,ItemWithNodes c)
1282 case IT_Octaedron12:
1283 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1284 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1285 nodes[c.node(4).localId()],nodes[c.node(5).localId()],
1286 nodes[c.node(6).localId()],nodes[c.node(7).localId()],
1287 nodes[c.node(8).localId()],nodes[c.node(9).localId()],
1288 nodes[c.node(10).localId()],nodes[c.node(11).localId()]));
1290 case IT_Heptaedron10:
1291 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1292 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1293 nodes[c.node(4).localId()],nodes[c.node(5).localId()],
1294 nodes[c.node(6).localId()],nodes[c.node(7).localId()],
1295 nodes[c.node(8).localId()],nodes[c.node(9).localId()]));
1298 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1299 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1300 nodes[c.node(4).localId()],nodes[c.node(5).localId()],
1301 nodes[c.node(6).localId()],nodes[c.node(7).localId()]));
1303 case IT_Pentaedron6:
1304 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1305 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1306 nodes[c.node(4).localId()],nodes[c.node(5).localId()]));
1309 m.ajouter(Lima::Polyedre(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1310 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1311 nodes[c.node(4).localId()]));
1313 case IT_Tetraedron4:
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()]));
1318 m.ajouter(Lima::Polygone(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1319 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1320 nodes[c.node(4).localId()],nodes[c.node(5).localId()]));
1323 m.ajouter(Lima::Polygone(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1324 nodes[c.node(2).localId()],nodes[c.node(3).localId()],
1325 nodes[c.node(4).localId()]));
1328 m.ajouter(Lima::Polygone(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1329 nodes[c.node(2).localId()],nodes[c.node(3).localId()]));
1332 m.ajouter(Lima::Polygone(nodes[c.node(0).localId()],nodes[c.node(1).localId()],
1333 nodes[c.node(2).localId()]));
1336 m.ajouter(Lima::Bras(nodes[c.node(0).localId()],nodes[c.node(1).localId()]));
1354 std::string std_file_name = file_name.
localstr();
1358 std::string::size_type std_end = std::string::npos;
1359 if (std_file_name.rfind(
".mli")==std_end && std_file_name.rfind(
".unf")==std_end){
1360 std_file_name +=
".mli";
1362 info() <<
"FINAL_FILE_NAME=" << std_file_name;
1363 Lima::Maillage lima(std_file_name);
1366 lima.dimension(Lima::D3);
1367 else if (dimension==2)
1368 lima.dimension(Lima::D2);
1375 Integer mesh_nb_node = node_family->
nbItem();
1376 Integer mesh_nb_edge = edge_family->
nbItem();
1377 Integer mesh_nb_face = face_family->
nbItem();
1378 Integer mesh_nb_cell = cell_family->
nbItem();
1390 for( Integer i=0; i<mesh_nb_node; ++i ){
1391 Node node = nodes[i];
1392 Real3 coord = nodes_coords[node];
1396 lima.ajouter(lm_nodes[i]);
1400 for( Integer i=0; i<mesh_nb_edge; ++i ){
1401 _writeItem(lima,lm_nodes,edges[i]);
1405 for( Integer i=0; i<mesh_nb_face; ++i ){
1406 _writeItem(lima,lm_nodes,faces[i]);
1410 for( Integer i=0; i<mesh_nb_cell; ++i ){
1411 _writeItem(lima,lm_nodes,cells[i]);
1422 lima.ajouter(lm_group);
1424 lm_group.ajouter(lima.noeud(iitem.localId()));
1434 lima.ajouter(lm_group);
1436 lm_group.ajouter(lima.bras(iitem.localId()));
1447 lima.ajouter(lm_group);
1449 lm_group.ajouter(lima.polygone(iitem.localId()));
1452 else if (dimension==2){
1454 lima.ajouter(lm_group);
1456 lm_group.ajouter(lima.bras(iitem.localId()));
1468 lima.ajouter(lm_group);
1470 lm_group.ajouter(lima.polyedre(iitem.localId()));
1473 else if (dimension==2){
1475 lima.ajouter(lm_group);
1477 lm_group.ajouter(lima.polygone(iitem.localId()));
1481 info(4) <<
"Writing file '" << std_file_name <<
"'";
1483 lima.ecrire(std_file_name);
1485 catch(
const std::exception& ex){
1486 trace->
warning() <<
"Exception (std::exception) in LIMA: Can not write file <" << std_file_name <<
">"
1487 <<
" Exception: " << ex.what() <<
'\n';
1491 trace->
warning() <<
"Exception (unknown) in LIMA: Can not write file <" << std_file_name <<
">";
1511 if (!local_ids.
empty())
1512 std::sort(std::begin(local_ids),std::end(local_ids));
1513 Integer nb_item = local_ids.
size();
1514 Integer nb_duplicated = 0;
1516 for( Integer i=1; i<nb_item; ++i )
1517 if (local_ids[i]==local_ids[i-1]){
1520 if (nb_duplicated!=0){
1521 tm->
warning() <<
"Duplicated items in group name=" << name
1522 <<
" nb_duplicated=" << nb_duplicated;
1523 auto xbegin = std::begin(local_ids);
1524 auto xend = std::end(local_ids);
1526 tm->
info() <<
"NEW_SIZE=" << new_size <<
" old=" << nb_item;
1527 local_ids = local_ids.
subView(0,new_size);
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro pour déclarer une interface lors de l'enregistrement d'un service.
Classe de base d'un service.
Informations nécessaires pour la lecture d'un fichier de maillage.
Vue sur les informations des mailles.
Vue sur les informations des arêtes.
Vue sur les informations des faces.
virtual ITraceMng * traceMng() const =0
Gestionnaire de traces.
virtual String language() const =0
Langage utilisé dans le 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 ItemGroup createGroup(const String &name, Int32ConstArrayView local_ids, bool do_override=false)=0
Créé un groupe d'entités de nom name contenant les entités local_ids.
virtual ITraceMng * traceMng() const =0
Gestionnaire de trace associé
virtual Integer nbItem() const =0
Nombre d'entités.
virtual ITraceMng * traceMng()=0
Gestionnaire de message associé
virtual IItemFamily * nodeFamily()=0
Retourne la famille des noeuds.
virtual IItemFamily * edgeFamily()=0
Retourne la famille des arêtes.
virtual Integer dimension()=0
Dimension du maillage (1D, 2D ou 3D).
virtual IItemFamily * faceFamily()=0
Retourne la famille des faces.
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
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 VariableNodeReal3 & nodesCoordinates()=0
Coordonnées des noeuds.
virtual void synchronizeGroupsAndVariables()=0
Synchronise tous les groupes et les variables du maillage.
virtual IGhostLayerMng * ghostLayerMng() const =0
Gestionnare de couche fantômes associé
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.
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.
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.
Classe gérant un vecteur de réel de dimension 3.
ISubDomain * subDomain() const
Accès au ISubDomain associé.
Structure contenant les informations pour créer un service.
@ TimerReal
Timer utilisant le temps réel.
String attrValue(const String &name, bool throw_exception=false) const
Valeur de l'attribut name.
Vue modifiable d'un tableau d'un type T.
constexpr ArrayView< T > subView(Integer abegin, Integer asize) noexcept
Sous-vue à partir de l'élément abegin et contenant asize éléments.
constexpr Integer size() const noexcept
Retourne la taille du tableau.
constexpr bool empty() const noexcept
Retourne true si le tableau est vide (dimension nulle)
Vue constante d'un tableau de type T.
Interface du gestionnaire de traces.
virtual TraceMessage warning()=0
Flot pour un message d'avertissement.
virtual TraceMessage info()=0
Flot pour un message d'information.
Chaîne de caractères unicode.
bool empty() const
Vrai si la chaîne est vide (nulle ou "")
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
bool null() const
Retourne true si la chaîne est nulle.
Classe d'accès aux traces.
TraceMessage warning() const
Flot pour un message d'avertissement.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage log() const
Flot pour un message de log.
Vecteur 1D de données avec sémantique par valeur (style STL).
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.
Integer toInteger(Real r)
Converti un Int64 en un Integer.
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.
ConstArrayView< ItemInternal * > ItemInternalList
Type de la liste interne des entités.
@ ST_SubDomain
Le service s'utilise au niveau du sous-domaine.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
@ IK_Node
Entité de maillage de genre noeud.
@ IK_Cell
Entité de maillage de genre maille.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
ArrayView< Int32 > Int32ArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Int32 Integer
Type représentant un entier.
Real y
deuxième composante du triplet
Real z
troisième composante du triplet
Real x
première composante du triplet