14#include "arcane/utils/CommandLineArguments.h"
17#include "arcane/core/ServiceBuilder.h"
18#include "arcane/core/ICaseMeshService.h"
19#include "arcane/core/ICaseMeshReader.h"
20#include "arcane/core/IMeshBuilder.h"
21#include "arcane/core/IMeshBuilderCustomiser.h"
22#include "arcane/core/IPrimaryMesh.h"
23#include "arcane/core/IItemFamily.h"
24#include "arcane/core/IMeshPartitionerBase.h"
25#include "arcane/core/IVariableMng.h"
26#include "arcane/core/IMeshModifier.h"
27#include "arcane/core/IMeshUtilities.h"
28#include "arcane/core/IParallelMng.h"
29#include "arcane/core/MeshBuildInfo.h"
30#include "arcane/core/IMeshMng.h"
31#include "arcane/core/IMeshFactoryMng.h"
32#include "arcane/core/IGhostLayerMng.h"
33#include "arcane/core/MeshPartInfo.h"
34#include "arcane/core/IMeshSubdivider.h"
35#include "arcane/core/IMeshUniqueIdMng.h"
36#include "arcane/core/ParallelMngUtils.h"
37#include "arcane/core/internal/StringVariableReplace.h"
44#include "arcane/impl/ArcaneCaseMeshService_axl.h"
57class ArcaneCaseMeshService
82 bool m_is_allow_null_mesh =
false;
88 void _initializeVariables();
89 void _doInitialPartition();
90 void _doInitialPartition2(
const String& name);
91 void _setGhostLayerInfos();
92 void _checkMeshCreationAndAllocation(
bool is_check_allocated);
93 void _setUniqueIdNumberingVersion();
99ArcaneCaseMeshService::
102, m_sub_domain(sbi.subDomain())
113 ARCANE_FATAL(
"Mesh '{0}' has already been created", default_name);
115 m_mesh_name = default_name;
116 info() <<
"Creating mesh name='" << m_mesh_name <<
"' from ArcaneCaseMeshService";
118 m_is_allow_null_mesh = (default_name !=
"Mesh0");
123 bool has_generator =
options()->generator.isPresent();
126 if ((has_filename && has_generator) || (!has_filename && !has_generator))
127 ARCANE_FATAL(
"In '{0}': one and one only of <{1}> or <{2}> has to be specified",
128 options()->configList()->xpathFullName(),
129 options()->generator.rootTagName(),
132 m_mesh_file_name =
options()->filename();
133 if (m_mesh_file_name.empty())
135 m_mesh_file_name,
options()->filename.xpathFullName());
137 _fillReadInfo(read_info);
138 auto& specific_reader =
options()->specificReader;
139 if (specific_reader.isPresent()) {
140 m_mesh_builder_ref = specific_reader()->createBuilder(read_info);
141 if (m_mesh_builder_ref.isNull())
142 ARCANE_FATAL(
"No 'IMeshBuilder' created by specific reader");
145 m_mesh_builder_ref = _createBuilderFromFile(read_info);
147 m_mesh_builder = m_mesh_builder_ref.get();
149 else if (has_generator)
150 m_mesh_builder =
options()->generator();
158 if (mesh_dim_kind != build_info.
meshKind().meshDimensionKind()) {
160 mesh_kind.setMeshDimensionKind(mesh_dim_kind);
164 m_mesh_builder->fillMeshBuildInfo(build_info);
167 m_partitioner_name =
options()->partitioner();
186 else if (!m_is_allow_null_mesh)
196 _checkMeshCreationAndAllocation(
false);
202 _setGhostLayerInfos();
203 _setUniqueIdNumberingVersion();
205 m_mesh_builder->allocateMeshItems(m_mesh);
214 _checkMeshCreationAndAllocation(
true);
216 if (m_mesh && (m_mesh->meshPartInfo().nbPart() > 1))
217 if (!m_partitioner_name.empty())
218 _doInitialPartition();
227 _checkMeshCreationAndAllocation(
true);
233 _initializeVariables();
239void ArcaneCaseMeshService::
240_checkMeshCreationAndAllocation(
bool is_check_allocated)
243 ARCANE_FATAL(
"Mesh is not created. You should call createMesh() before");
246 ARCANE_FATAL(
"Mesh is not allocated. You should call initializeMesh() before");
252void ArcaneCaseMeshService::
253_fillReadInfo(CaseMeshReaderReadInfo& read_info)
256 String file_extension;
259 std::size_t extension_pos = fview.find_last_of(
'.');
260 if (extension_pos != std::string_view::npos) {
261 fview.remove_prefix(extension_pos + 1);
262 file_extension = fview;
264 read_info.setFormat(file_extension);
271 String mesh_file_name = m_mesh_file_name;
273 String partitioner_name =
options()->partitioner();
274 bool use_internal_partitioner = partitioner_name !=
"External";
275 if (use_internal_partitioner) {
276 m_partitioner_name = partitioner_name;
279 info() <<
"Using external partitioner";
280 int mesh_rank = m_sub_domain->parallelMng()->commRank();
282 sprintf(buf,
"CPU%05d.%s", mesh_rank, file_extension.localstr());
283 mesh_file_name = String(std::string_view(buf));
286 read_info.setFileName(mesh_file_name);
288 info() <<
"Mesh filename=" << mesh_file_name
289 <<
" extension=" << read_info.format() <<
" partitioner=" << partitioner_name;
291 read_info.setParallelRead(use_internal_partitioner);
305 ServiceBuilder<ICaseMeshReader> builder(m_sub_domain);
306 UniqueArray<Ref<ICaseMeshReader>> mesh_readers(builder.createAllInstances());
308 for (
auto& mesh_reader_ref : mesh_readers) {
309 ICaseMeshReader* mesh_reader = mesh_reader_ref.get();
310 Ref<IMeshBuilder> builder = mesh_reader->createBuilder(read_info);
311 if (!builder.isNull())
318 builder.getServicesNames(valid_names);
319 String available_readers = String::join(
", ", valid_names);
320 ARCANE_FATAL(
"The mesh reader required for format '{0}' is not available."
321 "The following reader services are available: {1}",
322 read_info.format(), available_readers);
328void ArcaneCaseMeshService::
336 const bool use_partitioner_tester =
false;
337 String test_service =
"MeshPartitionerTester";
338 if (use_partitioner_tester) {
339 Int64 nb_cell = m_mesh->nbCell();
341 info() <<
"Min nb cell=" << min_nb_cell;
342 if (min_nb_cell == 0)
343 _doInitialPartition2(test_service);
345 info() <<
"Mesh name=" << m_mesh->name() <<
" have cells. Do not use " << test_service;
348 info() <<
"No basic partition first needed";
349 _doInitialPartition2(m_partitioner_name);
355void ArcaneCaseMeshService::
356_doInitialPartition2(
const String& partitioner_name)
360 info() <<
"Doing initial partitioning service=" << partitioner_name;
364 ServiceBuilder<IMeshPartitionerBase> sbuilder(m_sub_domain);
365 auto mesh_partitioner = sbuilder.createReference(partitioner_name, m_mesh);
367 IMesh* mesh = m_mesh;
368 bool is_dynamic = mesh->isDynamic();
369 mesh->modifier()->setDynamic(
true);
370 mesh->utilities()->partitionAndExchangeMeshWithReplication(mesh_partitioner.get(),
true);
371 mesh->modifier()->setDynamic(is_dynamic);
377void ArcaneCaseMeshService::
378_initializeVariables()
383 IVariableMng* vm = m_sub_domain->variableMng();
384 const auto& vars_opt =
options()->initialization().variable;
385 UniqueArray<String> errors;
386 for (
Integer i = 0, n = vars_opt.size(); i < n; ++i) {
387 const auto& o = vars_opt[i];
388 String var_name = o.name;
389 String group_name = o.group;
390 String value = o.value;
391 info() <<
"Initialize variable=" << var_name <<
" group=" << group_name <<
" value=" << value;
392 IVariable* var = vm->findMeshVariable(m_mesh, var_name);
394 errors.add(String::format(
"No variable named '{0}' exists", var_name));
401 IItemFamily* var_family = var->itemFamily();
403 errors.add(String::format(
"Variable '{0}' has no family", var->fullName()));
407 ItemGroup group = var_family->findGroup(group_name);
409 errors.add(String::format(
"No group named '{0}' exists in family '{1}'",
410 group_name, var_family->name()));
414 bool ret = var->initialize(group, value);
416 errors.add(String::format(
"Bad value '{0}' for initializing variable '{1}'",
417 value, var->fullName()));
421 if (!errors.empty()) {
422 for (String s : errors)
423 pinfo() <<
"ERROR: " << s;
424 ARCANE_FATAL(
"Variable initialization failed for option '{0}'",
425 vars_opt.xpathFullName());
432void ArcaneCaseMeshService::
435 IGhostLayerMng* gm = m_mesh->ghostLayerMng();
443 if (nb_ghost_layer >= 0) {
444 info() <<
"Set number of ghost layers to '" << nb_ghost_layer <<
"' from caseoption";
445 gm->setNbGhostLayer(nb_ghost_layer);
449 if (builder_version >= 0) {
450 info() <<
"Set ghostlayer builder version to '" << builder_version <<
"' from caseoption";
451 gm->setBuilderVersion(builder_version);
458void ArcaneCaseMeshService::
459_setUniqueIdNumberingVersion()
464 if (
options()->faceNumberingVersion.isPresent()) {
466 info() <<
"Set face uniqueId numbering version to '" << v <<
"' from caseoption";
467 IMeshUniqueIdMng* mum = m_mesh->meshUniqueIdMng();
468 mum->setFaceBuilderVersion(v);
471 if (
options()->edgeNumberingVersion.isPresent()) {
473 info() <<
"Set edge uniqueId numbering version to '" << v <<
"' from caseoption";
474 IMeshUniqueIdMng* mum = m_mesh->meshUniqueIdMng();
475 mum->setEdgeBuilderVersion(v);
#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.
This file contains the various service factories and macros for registering services.
Generation de la classe de base du Service.
CaseOptionsArcaneCaseMeshService * options() const
Options du jeu de données du service.
ArcaneArcaneCaseMeshServiceObject(const Arcane::ServiceBuildInfo &sbi)
Constructeur.
Arcane Service for reading or generating a mesh from the case option file.
void createMesh(const String &default_name) override
Creates the mesh with the name name.
void allocateMeshItems() override
Allocates the mesh items.
void partitionMesh() override
Partitions the mesh.
bool m_has_created_mesh_called
True if createMesh() has already been called.
void applyAdditionalOperations() override
Applies operations after everything else.
Necessary information for reading a mesh file.
const Type & value() const
Returns the value of the option.
bool isPresent() const
Returns true if the option is present.
Interface of a mesh builder customisation service.
virtual void applyCustomisation(MeshBuildInfo &build_info)=0
Modify build_info to customise mesh creation.
Interface of a mesh creation/reading service.
virtual IPrimaryMesh * createMesh(const MeshBuildInfo &build_info)=0
Creates a mesh or a sub-mesh.
virtual IMeshFactoryMng * meshFactoryMng() const =0
Mesh factory associated with this manager.
virtual void subdivideMesh(IPrimaryMesh *mesh)=0
Subdivides the mesh mesh.
virtual bool isAllocated()=0
True if the mesh is allocated.
Interface of the parallelism manager for a subdomain.
Interface of the subdomain manager.
virtual IParallelMng * parallelMng()=0
Returns the parallelism manager.
virtual IMeshMng * meshMng() const =0
Returns the mesh manager.
Parameters necessary for building a mesh.
const MeshKind meshKind() const
Mesh characteristics.
MeshBuildInfo & addParallelMng(Ref< IParallelMng > pm)
Sets the parallelism manager to create the mesh.
bool isNeedPartitioning() const
Indicates if the reader/generator requires partitioning.
Ref< IParallelMng > parallelMngRef() const
Parallelism manager in the case of a new mesh.
const String & factoryName() const
Factory name to create the mesh (via IMeshFactory).
MeshBuildInfo & addMeshKind(const MeshKind &v)
Sets the mesh characteristics.
MeshBuildInfo & addFactoryName(const String &factory_name)
Sets the factory name to create this mesh.
Characteristics of a mesh.
Reference to an instance.
Structure containing the information to create a service.
Unicode character string.
bool empty() const
True if the string is empty (null or "").
std::string_view toStdStringView() const
Returns an STL view of the current string.
TraceMessage pinfo() const
Flow for a parallel information message.
TraceMessage info() const
Flow for an information message.
@ ReduceMin
Minimum of values.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
eMeshCellDimensionKind
Types of mesh dimension management.
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
UniqueArray< String > StringUniqueArray
Dynamic 1D array of strings.
std::int32_t Int32
Signed integer type of 32 bits.