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"
32#include "arcane_internal_config.h"
47, m_default_mesh_handle(default_mesh_handle)
48, m_internal_partitioner_name(ARCANE_DEFAULT_PARTITIONER_STR)
55void LegacyMeshBuilder::
58 ISubDomain* sd = m_sub_domain;
59 Integer sub_domain_id = sd->subDomainId();
60 ICaseDocument* case_doc = sd->caseDocument();
61 CaseNodeNames* cnn = case_doc->caseNodeNames();
62 XmlNodeList mesh_elems(case_doc->meshElements());
63 bool has_mesh_file =
true;
64 if (mesh_elems.empty()) {
65 info() <<
"No mesh in the input data";
66 has_mesh_file =
false;
68 Integer nb_mesh = mesh_elems.size();
69 m_meshes_build_info.resize(nb_mesh);
70 for (Integer i = 0; i < nb_mesh; ++i) {
71 MeshBuildInfo& mbi = m_meshes_build_info[i];
73 mbi.m_xml_node = mesh_elems[i];
74 XmlNodeList partitioner_elems = mesh_elems[i].children(cnn->mesh_partitioner);
75 m_use_partitioner_tester =
false;
76 if (partitioner_elems.empty()) {
77 m_use_partitioner_tester =
true;
78 m_internal_partitioner_name = ARCANE_DEFAULT_PARTITIONER_STR;
81 m_internal_partitioner_name = partitioner_elems[0].value();
83 m_use_partitioner_tester = partitioner_elems[0].attr(
"need-basic-partition-first").valueAsBoolean();
86 XmlNode meshfile_elem = mesh_elems[i].child(cnn->mesh_file);
87 String smesh_file = meshfile_elem.value();
88 StringBuilder mesh_file = smesh_file;
89 mbi.m_orig_file_name = smesh_file;
90 if (smesh_file.null()) {
91 info() <<
"No mesh in the input data";
92 has_mesh_file =
false;
95 String file_format = meshfile_elem.attrValue(
"format");
96 bool internal_cut = meshfile_elem.attr(
"internal-partition").valueAsBoolean();
97 String internal_partitioner = meshfile_elem.attr(
"partitioner").value();
101 String internal_partitioner_env = platform::getEnvironmentVariable(
"ARCANE_INTERNAL_PARTITIONER");
102 if (!internal_partitioner_env.null()) {
103 info() <<
"Forcing internal partitioner from environment variable";
105 internal_partitioner = internal_partitioner_env;
107 IParallelMng* pm = sd->parallelMng();
109 if (pm->isParallel() && (pm->commSize() > 1)) {
110 m_use_internal_mesh_partitioner = internal_cut;
112 if (!internal_partitioner.empty())
113 m_internal_partitioner_name = internal_partitioner;
114 Integer nb_sub_domain = pm->commSize();
115 info() <<
"Subdomain number is " << sub_domain_id <<
'/' << nb_sub_domain;
118 bool use_unique_file = meshfile_elem.attr(
"unique").valueAsBoolean();
119 if (!use_unique_file) {
121 StringBuilder cut_dir_str(
"cut_");
122 cut_dir_str += nb_sub_domain;
123 String mesh_cut_dir = meshfile_elem.attrValue(cut_dir_str);
124 debug() <<
"MESH CUT DIR " << mesh_cut_dir <<
' ' << cut_dir_str;
125 if (has_mesh_file && !internal_cut) {
127 String file_format_str =
"mli2";
128 if (!file_format.null())
129 file_format_str = file_format;
130 sprintf(buf,
"CPU%05d.%s", (
int)sub_domain_id, file_format_str.localstr());
131 log() <<
"The original mesh file is " << mesh_file;
132 if (mesh_cut_dir.empty())
133 mesh_file = String(std::string_view(buf));
135 mbi.m_dir_name = mesh_cut_dir;
136 mesh_file = mesh_cut_dir;
143 log() <<
"The mesh file is " << mesh_file;
144 mbi.m_file_name = mesh_file;
153 _createMeshesHandle();
159void LegacyMeshBuilder::
164 ServiceBuilder<IMeshReader> builder(m_sub_domain);
165 UniqueArray<Ref<IMeshReader>> mesh_readers(builder.createAllInstances());
167 for (
const MeshBuildInfo& mbi : m_meshes_build_info) {
168 _readMesh(mesh_readers, mbi);
175void LegacyMeshBuilder::
178 ISubDomain* sd = m_sub_domain;
179 String mesh_name = m_default_mesh_handle.meshName();
180 ICaseDocument* case_doc = sd->caseDocument();
183 m_default_mesh_handle._setMesh(sd->mainFactory()->createMesh(sd, mesh_name));
187 CaseNodeNames* cnn = case_doc->caseNodeNames();
188 XmlNodeList mesh_elems(case_doc->meshElements());
189 if (mesh_elems.empty()) {
190 info() <<
"No mesh in the input data";
192 Integer nb_mesh = mesh_elems.size();
193 for (Integer i = 0; i < nb_mesh; ++i) {
194 XmlNode meshfile_elem = mesh_elems[i].child(cnn->mesh_file);
195 String mesh_file = meshfile_elem.value();
196 if (mesh_file.null()) {
197 info() <<
"No mesh in the input data";
202 bool is_amr = mesh_elems[0].attr(
"amr").valueAsBoolean();
204 if (is_amr && amr_type == eMeshAMRKind::None) {
205 amr_type = eMeshAMRKind::Cell;
208 m_default_mesh_handle._setMesh(sd->mainFactory()->createMesh(sd, mesh_name, amr_type));
214void LegacyMeshBuilder::
217 IMeshMng* mesh_mng = m_sub_domain->meshMng();
220 Integer nb_build_mesh = m_meshes_build_info.size();
221 if (nb_build_mesh > 0) {
222 m_meshes_build_info[0].m_mesh_handle = m_default_mesh_handle;
226 for (Integer z = 1; z < nb_build_mesh; ++z) {
228 if (m_meshes_build_info[z].m_xml_node.attr(
"dual").valueAsBoolean())
233 MeshHandle handle = mesh_mng->createMeshHandle(name);
234 m_meshes_build_info[z].m_mesh_handle = handle;
241void LegacyMeshBuilder::
244 ISubDomain* sd = m_sub_domain;
247 Integer nb_build_mesh = m_meshes_build_info.size();
248 if (nb_build_mesh > 0) {
249 m_meshes_build_info[0].m_mesh = m_default_mesh_handle.mesh()->toPrimaryMesh();
253 for (Integer z = 1; z < nb_build_mesh; ++z) {
254 MeshHandle handle = m_meshes_build_info[z].m_mesh_handle;
256 ARCANE_FATAL(
"Invalid null MeshHandle for mesh index={0}", z);
259 bool is_amr = m_meshes_build_info[z].m_xml_node.attr(
"amr").valueAsBoolean();
260 eMeshAMRKind amr_type =
static_cast<eMeshAMRKind>(m_meshes_build_info[z].m_xml_node.attr(
"amr-type").valueAsInteger());
261 if (is_amr && amr_type == eMeshAMRKind::None) {
262 amr_type = eMeshAMRKind::Cell;
265 IPrimaryMesh* mesh = sd->mainFactory()->createMesh(sd, handle.meshName(), amr_type);
266 m_meshes_build_info[z].m_mesh = mesh;
273void LegacyMeshBuilder::
274initializeMeshVariablesFromCaseFile()
276 info() <<
"Initialization of the variable from the configuration file";
277 CaseNodeNames* cnn = m_sub_domain->caseDocument()->caseNodeNames();
278 for (
const LegacyMeshBuilder::MeshBuildInfo& mbi : m_meshes_build_info) {
279 IMesh* mesh = mbi.m_mesh;
280 XmlNode node = mbi.m_xml_node;
281 XmlNode init_node = node.child(cnn->mesh_initialisation);
282 if (!init_node.null())
283 mesh->initializeVariables(init_node);
290void LegacyMeshBuilder::
296 String mesh_file_name = mbi.m_file_name;
301 mesh_file_name = mbi.m_orig_file_name;
302 use_internal_partitioner =
true;
306 if (wanted_dimension != 0) {
307 info() <<
"Force mesh dimension to " << wanted_dimension;
308 mesh->setDimension(wanted_dimension);
310 log() <<
"Mesh file: " << mesh_file_name;
313 XmlNode nbGhostLayerNode = mbi.m_xml_node.
attr(
"nb-ghostlayer");
314 if (!nbGhostLayerNode.
null()) {
316 if (nb_ghost_layer >= 0) {
317 info() <<
"Set number of ghost layers to '" << nb_ghost_layer <<
"' from caseoption";
318 mesh->ghostLayerMng()->setNbGhostLayer(nb_ghost_layer);
323 if (nb_ghost_layer >= 0 && builder_version >= 0) {
324 info() <<
"Set ghostlayer builder version to '" << builder_version <<
"' from caseoption";
325 mesh->ghostLayerMng()->setBuilderVersion(builder_version);
328 XmlNode face_numbering_version_node = mbi.m_xml_node.
attr(
"face-numbering-version");
329 if (!face_numbering_version_node.
null()) {
332 info() <<
"Set face numbering version to '" << v <<
"' from caseoption";
333 mesh->meshUniqueIdMng()->setFaceBuilderVersion(v);
341 debug() <<
" MF=" << fview;
342 std::size_t extension_pos = fview.find_last_of(
'.');
343 if (extension_pos != std::string_view::npos) {
344 fview.remove_prefix(extension_pos + 1);
349 for (
auto& mesh_reader_ref : mesh_readers) {
358 use_internal_partitioner);
369 ARCANE_FATAL(
"Internal error: no mesh loaded or generated. \n",
370 "The mesh reader or generator required isn't available ",
371 "Recompile with the relevant options");
374 mesh->computeTiedInterfaces(mbi.m_xml_node);
379 IMeshWriter* writer = ServiceFinderT<IMeshWriter>::find(serviceMng(),
"VtkLegacyMeshWriter");
383 if (!parallelMng()->isParallel()){
#define ARCANE_CHECK_POINTER(ptr)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
void writeMeshConnectivity(IMesh *mesh, const String &file_name)
Writes the connectivity of the mesh mesh to the file file_name.
Constant view of an array of type T.
Interface of the service managing the reading of a mesh.
virtual bool allowExtension(const String &str)=0
Checks if the service supports files with the extension str.
virtual eReturnType readMeshFromFile(IPrimaryMesh *mesh, const XmlNode &mesh_element, const String &file_name, const String &dir_name, bool use_internal_partition)=0
Reads a mesh from a file.
eReturnType
Types of return codes for a read or write operation.
@ RTError
Error during the operation.
@ RTOk
Operation successfully performed.
Interface of a mesh writing service.
virtual bool writeMeshToFile(IMesh *mesh, const String &file_name)=0
Writes a mesh to a file.
Interface of the subdomain manager.
ScopedPtrT< IInitialPartitioner > m_initial_partitioner
Initial partitioner.
bool m_use_internal_mesh_partitioner
true if it partitions the mesh internally
Reference to an instance.
Unicode character string.
std::string_view toStdStringView() const
Returns an STL view of the current string.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
TraceMessage log() const
Flow for a log message.
TraceMessage info() const
Flow for an information message.
XmlNode attr(const String &name, bool throw_exception=false) const
Returns the attribute of name name.
bool null() const
True if the node is null.
Integer valueAsInteger(bool throw_exception=false) const
Node value converted to integer.
__host__ __device__ double log(double v)
Natural logarithm of v.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
eMeshAMRKind
AMR mesh type.
std::int32_t Int32
Signed integer type of 32 bits.