14#include "arcane/impl/internal/LegacyMeshBuilder.h"
16#include "arcane/utils/PlatformUtils.h"
17#include "arcane/utils/StringBuilder.h"
19#include "arcane/core/MeshKind.h"
20#include "arcane/core/ISubDomain.h"
21#include "arcane/core/CaseNodeNames.h"
22#include "arcane/core/ICaseDocument.h"
23#include "arcane/core/IParallelMng.h"
24#include "arcane/core/ServiceBuilder.h"
25#include "arcane/core/IMainFactory.h"
26#include "arcane/core/IPrimaryMesh.h"
27#include "arcane/core/IGhostLayerMng.h"
28#include "arcane/core/IMeshReader.h"
29#include "arcane/core/IMeshMng.h"
30#include "arcane/core/IMeshUniqueIdMng.h"
45, m_default_mesh_handle(default_mesh_handle)
46, m_internal_partitioner_name(ARCANE_DEFAULT_PARTITIONER_STR)
53void LegacyMeshBuilder::
56 ISubDomain* sd = m_sub_domain;
57 Integer sub_domain_id = sd->subDomainId();
58 ICaseDocument* case_doc = sd->caseDocument();
59 CaseNodeNames* cnn = case_doc->caseNodeNames();
60 XmlNodeList mesh_elems(case_doc->meshElements());
61 bool has_mesh_file =
true;
62 if (mesh_elems.empty()){
63 info() <<
"No mesh in the input data";
64 has_mesh_file =
false;
66 Integer nb_mesh = mesh_elems.size();
67 m_meshes_build_info.resize(nb_mesh);
68 for( Integer i=0; i<nb_mesh; ++i ){
69 MeshBuildInfo& mbi = m_meshes_build_info[i];
71 mbi.m_xml_node = mesh_elems[i];
72 XmlNodeList partitioner_elems = mesh_elems[i].children(cnn->mesh_partitioner) ;
73 m_use_partitioner_tester =
false;
74 if(partitioner_elems.empty()) {
75 m_use_partitioner_tester =
true;
76 m_internal_partitioner_name = ARCANE_DEFAULT_PARTITIONER_STR;
79 m_internal_partitioner_name = partitioner_elems[0].value() ;
81 m_use_partitioner_tester = partitioner_elems[0].attr(
"need-basic-partition-first").valueAsBoolean();
84 XmlNode meshfile_elem = mesh_elems[i].child(cnn->mesh_file);
85 String smesh_file = meshfile_elem.value();
86 StringBuilder mesh_file = smesh_file;
87 mbi.m_orig_file_name = smesh_file;
88 if (smesh_file.null()){
89 info() <<
"No mesh in the input data";
90 has_mesh_file =
false;
93 String file_format = meshfile_elem.attrValue(
"format");
94 bool internal_cut = meshfile_elem.attr(
"internal-partition").valueAsBoolean();
95 String internal_partitioner = meshfile_elem.attr(
"partitioner").value();
99 String internal_partitioner_env = platform::getEnvironmentVariable(
"ARCANE_INTERNAL_PARTITIONER");
100 if (!internal_partitioner_env.null()){
101 info() <<
"Forcing internal partitioner from environment variable";
103 internal_partitioner = internal_partitioner_env;
105 IParallelMng* pm = sd->parallelMng();
107 if (pm->isParallel() && (pm->commSize()>1)){
108 m_use_internal_mesh_partitioner = internal_cut;
110 if (!internal_partitioner.empty())
111 m_internal_partitioner_name = internal_partitioner;
112 Integer nb_sub_domain = pm->commSize();
113 info() <<
"Subdomain number is " << sub_domain_id <<
'/' << nb_sub_domain;
116 bool use_unique_file = meshfile_elem.attr(
"unique").valueAsBoolean();
117 if (!use_unique_file){
119 StringBuilder cut_dir_str(
"cut_");
120 cut_dir_str += nb_sub_domain;
121 String mesh_cut_dir = meshfile_elem.attrValue(cut_dir_str);
122 debug() <<
"MESH CUT DIR " << mesh_cut_dir <<
' ' << cut_dir_str;
123 if (has_mesh_file && !internal_cut){
125 String file_format_str =
"mli2";
126 if (!file_format.null())
127 file_format_str = file_format;
128 sprintf(buf,
"CPU%05d.%s",(
int)sub_domain_id,file_format_str.localstr());
129 log() <<
"The original mesh file is " << mesh_file;
130 if (mesh_cut_dir.empty())
131 mesh_file = String(std::string_view(buf));
133 mbi.m_dir_name = mesh_cut_dir;
134 mesh_file = mesh_cut_dir;
141 log() <<
"The mesh file is " << mesh_file;
142 mbi.m_file_name = mesh_file;
151 _createMeshesHandle();
157void LegacyMeshBuilder::
162 ServiceBuilder<IMeshReader> builder(m_sub_domain);
163 UniqueArray<Ref<IMeshReader>> mesh_readers(builder.createAllInstances());
165 for(
const MeshBuildInfo& mbi : m_meshes_build_info ){
166 _readMesh(mesh_readers,mbi);
173void LegacyMeshBuilder::
176 ISubDomain* sd = m_sub_domain;
177 String mesh_name = m_default_mesh_handle.meshName();
178 ICaseDocument* case_doc = sd->caseDocument();
181 m_default_mesh_handle._setMesh(sd->mainFactory()->createMesh(sd,mesh_name));
185 CaseNodeNames* cnn = case_doc->caseNodeNames();
186 XmlNodeList mesh_elems(case_doc->meshElements());
187 if (mesh_elems.empty()){
188 info() <<
"No mesh in the input data";
190 Integer nb_mesh = mesh_elems.size();
191 for( Integer i=0; i<nb_mesh; ++i ){
192 XmlNode meshfile_elem = mesh_elems[i].child(cnn->mesh_file);
193 String mesh_file = meshfile_elem.value();
194 if (mesh_file.null()){
195 info() <<
"No mesh in the input data";
200 bool is_amr = mesh_elems[0].attr(
"amr").valueAsBoolean();
202 if(is_amr && amr_type == eMeshAMRKind::None) {
203 amr_type = eMeshAMRKind::Cell;
206 m_default_mesh_handle._setMesh(sd->mainFactory()->createMesh(sd,mesh_name, amr_type));
212void LegacyMeshBuilder::
215 IMeshMng* mesh_mng = m_sub_domain->meshMng();
218 Integer nb_build_mesh = m_meshes_build_info.size();
219 if (nb_build_mesh>0){
220 m_meshes_build_info[0].m_mesh_handle = m_default_mesh_handle;
224 for( Integer z=1; z<nb_build_mesh; ++z ){
226 if(m_meshes_build_info[z].m_xml_node.attr(
"dual").valueAsBoolean())
231 MeshHandle handle = mesh_mng->createMeshHandle(name);
232 m_meshes_build_info[z].m_mesh_handle = handle;
239void LegacyMeshBuilder::
242 ISubDomain* sd = m_sub_domain;
245 Integer nb_build_mesh = m_meshes_build_info.size();
246 if (nb_build_mesh>0){
247 m_meshes_build_info[0].m_mesh = m_default_mesh_handle.mesh()->toPrimaryMesh();
251 for( Integer z=1; z<nb_build_mesh; ++z ){
252 MeshHandle handle = m_meshes_build_info[z].m_mesh_handle;
254 ARCANE_FATAL(
"Invalid null MeshHandle for mesh index={0}",z);
257 bool is_amr = m_meshes_build_info[z].m_xml_node.attr(
"amr").valueAsBoolean();
258 eMeshAMRKind amr_type =
static_cast<eMeshAMRKind>(m_meshes_build_info[z].m_xml_node.attr(
"amr-type").valueAsInteger());
259 if(is_amr && amr_type == eMeshAMRKind::None) {
260 amr_type = eMeshAMRKind::Cell;
263 IPrimaryMesh* mesh = sd->mainFactory()->createMesh(sd,handle.meshName(),amr_type);
264 m_meshes_build_info[z].m_mesh = mesh;
271void LegacyMeshBuilder::
272initializeMeshVariablesFromCaseFile()
274 info() <<
"Initialization of the variable from the configuration file";
275 CaseNodeNames* cnn = m_sub_domain->caseDocument()->caseNodeNames();
276 for(
const LegacyMeshBuilder::MeshBuildInfo& mbi : m_meshes_build_info ){
277 IMesh* mesh = mbi.m_mesh;
278 XmlNode node = mbi.m_xml_node;
279 XmlNode init_node = node.child(cnn->mesh_initialisation);
280 if (!init_node.null())
281 mesh->initializeVariables(init_node);
288void LegacyMeshBuilder::
294 String mesh_file_name = mbi.m_file_name;
299 mesh_file_name = mbi.m_orig_file_name;
300 use_internal_partitioner =
true;
304 if (wanted_dimension!=0){
305 info() <<
"Force mesh dimension to " << wanted_dimension;
306 mesh->setDimension(wanted_dimension);
308 log() <<
"Mesh file: " << mesh_file_name;
311 XmlNode nbGhostLayerNode = mbi.m_xml_node.
attr(
"nb-ghostlayer");
312 if (!nbGhostLayerNode.
null()){
314 if (nb_ghost_layer>=0){
315 info() <<
"Set number of ghost layers to '" << nb_ghost_layer <<
"' from caseoption";
316 mesh->ghostLayerMng()->setNbGhostLayer(nb_ghost_layer);
321 if (nb_ghost_layer>=0 && builder_version>=0){
322 info() <<
"Set ghostlayer builder version to '" << builder_version <<
"' from caseoption";
323 mesh->ghostLayerMng()->setBuilderVersion(builder_version);
326 XmlNode face_numbering_version_node = mbi.m_xml_node.
attr(
"face-numbering-version");
327 if (!face_numbering_version_node.
null()) {
330 info() <<
"Set face numbering version to '" << v <<
"' from caseoption";
331 mesh->meshUniqueIdMng()->setFaceBuilderVersion(v);
339 debug() <<
" MF=" << fview;
340 std::size_t extension_pos = fview.find_last_of(
'.');
341 if (extension_pos!=std::string_view::npos){
342 fview.remove_prefix(extension_pos+1);
347 for(
auto& mesh_reader_ref : mesh_readers ){
356 use_internal_partitioner);
367 ARCANE_FATAL(
"Internal error: no mesh loaded or generated. \n",
368 "The mesh reader or generator required isn't available ",
369 "Recompile with the relevant options");
372 mesh->computeTiedInterfaces(mbi.m_xml_node);
377 IMeshWriter* writer = ServiceFinderT<IMeshWriter>::find(serviceMng(),
"VtkLegacyMeshWriter");
381 if (!parallelMng()->isParallel()){
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
void writeMeshConnectivity(IMesh *mesh, const String &file_name)
Ecrit sur le fichier file_name la connectivité du maillage mesh.
Vue constante d'un tableau de type T.
Interface du service gérant la lecture d'un maillage.
virtual bool allowExtension(const String &str)=0
Vérifie si le service supporte les fichiers avec l'extension str.
virtual eReturnType readMeshFromFile(IPrimaryMesh *mesh, const XmlNode &mesh_element, const String &file_name, const String &dir_name, bool use_internal_partition)=0
Lit un maillage à partir d'un fichier.
eReturnType
Types des codes de retour d'une lecture ou écriture.
@ 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 bool writeMeshToFile(IMesh *mesh, const String &file_name)=0
Ecrit un maillage sur un fichier.
Interface du gestionnaire d'un sous-domaine.
ScopedPtrT< IInitialPartitioner > m_initial_partitioner
Partitionneur initial.
bool m_use_internal_mesh_partitioner
true si partitionne le maillage en interne
Référence à une instance.
Chaîne de caractères unicode.
std::string_view toStdStringView() const
Retourne une vue de la STL sur la chaîne actuelle.
Classe d'accès aux traces.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage log() const
Flot pour un message de log.
TraceMessage info() const
Flot pour un message d'information.
XmlNode attr(const String &name, bool throw_exception=false) const
Retourne l'attribut de nom name.
bool null() const
Vrai si le noeud est nul.
Integer valueAsInteger(bool throw_exception=false) const
Valeur du noeud convertie en entier.
__host__ __device__ double log(double v)
Logarithme népérien de v.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.
eMeshAMRKind
Type de maillage AMR.
std::int32_t Int32
Type entier signé sur 32 bits.