14#include "arcane/utils/ApplicationInfo.h"
15#include "arcane/utils/CommandLineArguments.h"
18#include "arcane/core/ServiceBuilder.h"
19#include "arcane/core/ICaseMeshService.h"
20#include "arcane/core/ICaseMeshReader.h"
21#include "arcane/core/IMeshBuilder.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/internal/StringVariableReplace.h"
38#include "arcane/impl/ArcaneCaseMeshService_axl.h"
52class ArcaneCaseMeshService
79 void _initializeVariables();
80 void _doInitialPartition();
81 void _doInitialPartition2(
const String& name);
82 void _setGhostLayerInfos();
83 void _checkMeshCreationAndAllocation(
bool is_check_allocated);
84 void _setUniqueIdNumberingVersion();
90ArcaneCaseMeshService::
93, m_sub_domain(sbi.subDomain())
106 info() <<
"Creating mesh from 'ArcaneCaseMeshService'";
111 bool has_generator =
options()->generator.isPresent();
114 if ((has_filename && has_generator) || (!has_filename && !has_generator))
115 ARCANE_FATAL(
"In '{0}': one and one only of <{1}> or <{2}> has to be specified",
116 options()->configList()->xpathFullName(),
117 options()->generator.rootTagName(),
120 m_mesh_file_name =
options()->filename();
121 if (m_mesh_file_name.empty())
123 m_mesh_file_name,
options()->filename.xpathFullName());
125 _fillReadInfo(read_info);
126 auto& specific_reader =
options()->specificReader;
127 if (specific_reader.isPresent()) {
128 m_mesh_builder_ref = specific_reader()->createBuilder(read_info);
129 if (m_mesh_builder_ref.isNull())
130 ARCANE_FATAL(
"No 'IMeshBuilder' created by specific reader");
133 m_mesh_builder_ref = _createBuilderFromFile(read_info);
135 m_mesh_builder = m_mesh_builder_ref.get();
137 else if (has_generator)
138 m_mesh_builder =
options()->generator();
146 if (mesh_dim_kind != build_info.
meshKind().meshDimensionKind()) {
148 mesh_kind.setMeshDimensionKind(mesh_dim_kind);
152 m_mesh_builder->fillMeshBuildInfo(build_info);
155 m_partitioner_name =
options()->partitioner();
172 _checkMeshCreationAndAllocation(
false);
176 _setGhostLayerInfos();
177 _setUniqueIdNumberingVersion();
179 m_mesh_builder->allocateMeshItems(m_mesh);
188 _checkMeshCreationAndAllocation(
true);
190 if (m_mesh->meshPartInfo().nbPart() > 1)
191 if (!m_partitioner_name.empty())
192 _doInitialPartition();
201 _checkMeshCreationAndAllocation(
true);
207 _initializeVariables();
213void ArcaneCaseMeshService::
214_checkMeshCreationAndAllocation(
bool is_check_allocated)
217 ARCANE_FATAL(
"Mesh is not created. You should call createMesh() before");
219 ARCANE_FATAL(
"Mesh is not allocated. You should call initializeMesh() before");
225void ArcaneCaseMeshService::
226_fillReadInfo(CaseMeshReaderReadInfo& read_info)
229 String file_extension;
232 std::size_t extension_pos = fview.find_last_of(
'.');
233 if (extension_pos != std::string_view::npos) {
234 fview.remove_prefix(extension_pos + 1);
235 file_extension = fview;
237 read_info.setFormat(file_extension);
244 String mesh_file_name = m_mesh_file_name;
246 String partitioner_name =
options()->partitioner();
247 bool use_internal_partitioner = partitioner_name !=
"External";
248 if (use_internal_partitioner) {
249 m_partitioner_name = partitioner_name;
252 info() <<
"Using external partitioner";
253 int mesh_rank = m_sub_domain->parallelMng()->commRank();
255 sprintf(buf,
"CPU%05d.%s", mesh_rank, file_extension.localstr());
256 mesh_file_name = String(std::string_view(buf));
259 read_info.setFileName(mesh_file_name);
261 info() <<
"Mesh filename=" << mesh_file_name
262 <<
" extension=" << read_info.format() <<
" partitioner=" << partitioner_name;
264 read_info.setParallelRead(use_internal_partitioner);
278 ServiceBuilder<ICaseMeshReader> builder(m_sub_domain);
279 UniqueArray<Ref<ICaseMeshReader>> mesh_readers(builder.createAllInstances());
281 for (
auto& mesh_reader_ref : mesh_readers) {
282 ICaseMeshReader* mesh_reader = mesh_reader_ref.get();
283 Ref<IMeshBuilder> builder = mesh_reader->createBuilder(read_info);
284 if (!builder.isNull())
291 builder.getServicesNames(valid_names);
292 String available_readers = String::join(
", ", valid_names);
293 ARCANE_FATAL(
"The mesh reader required for format '{0}' is not available."
294 "The following reader services are available: {1}",
295 read_info.format(), available_readers);
301void ArcaneCaseMeshService::
307 const bool use_partitioner_tester =
false;
308 String test_service =
"MeshPartitionerTester";
309 if (use_partitioner_tester) {
310 Int64 nb_cell = m_mesh->nbCell();
312 info() <<
"Min nb cell=" << min_nb_cell;
313 if (min_nb_cell == 0)
314 _doInitialPartition2(test_service);
316 info() <<
"Mesh name=" << m_mesh->name() <<
" have cells. Do not use " << test_service;
319 info() <<
"No basic partition first needed";
320 _doInitialPartition2(m_partitioner_name);
326void ArcaneCaseMeshService::
327_doInitialPartition2(
const String& partitioner_name)
329 info() <<
"Doing initial partitioning service=" << partitioner_name;
333 ServiceBuilder<IMeshPartitionerBase> sbuilder(m_sub_domain);
334 auto mesh_partitioner = sbuilder.createReference(partitioner_name, m_mesh);
336 IMesh* mesh = m_mesh;
337 bool is_dynamic = mesh->isDynamic();
338 mesh->modifier()->setDynamic(
true);
339 mesh->utilities()->partitionAndExchangeMeshWithReplication(mesh_partitioner.get(),
true);
340 mesh->modifier()->setDynamic(is_dynamic);
346void ArcaneCaseMeshService::
347_initializeVariables()
349 IVariableMng* vm = m_sub_domain->variableMng();
350 const auto& vars_opt =
options()->initialization().variable;
351 UniqueArray<String> errors;
352 for (
Integer i = 0, n = vars_opt.size(); i < n; ++i) {
353 const auto& o = vars_opt[i];
354 String var_name = o.name;
355 String group_name = o.group;
356 String value = o.value;
357 info() <<
"Initialize variable=" << var_name <<
" group=" << group_name <<
" value=" << value;
358 IVariable* var = vm->findMeshVariable(m_mesh, var_name);
360 errors.add(String::format(
"No variable named '{0}' exists", var_name));
367 IItemFamily* var_family = var->itemFamily();
369 errors.add(String::format(
"Variable '{0}' has no family", var->fullName()));
373 ItemGroup group = var_family->findGroup(group_name);
375 errors.add(String::format(
"No group named '{0}' exists in family '{1}'",
376 group_name, var_family->name()));
380 bool ret = var->initialize(group, value);
382 errors.add(String::format(
"Bad value '{0}' for initializing variable '{1}'",
383 value, var->fullName()));
387 if (!errors.empty()) {
388 for (String s : errors)
389 pinfo() <<
"ERROR: " << s;
390 ARCANE_FATAL(
"Variable initialization failed for option '{0}'",
391 vars_opt.xpathFullName());
398void ArcaneCaseMeshService::
401 IGhostLayerMng* gm = m_mesh->ghostLayerMng();
409 if (nb_ghost_layer >= 0) {
410 info() <<
"Set number of ghost layers to '" << nb_ghost_layer <<
"' from caseoption";
411 gm->setNbGhostLayer(nb_ghost_layer);
415 if (builder_version >= 0) {
416 info() <<
"Set ghostlayer builder version to '" << builder_version <<
"' from caseoption";
417 gm->setBuilderVersion(builder_version);
424void ArcaneCaseMeshService::
425_setUniqueIdNumberingVersion()
430 if (
options()->faceNumberingVersion.isPresent()) {
432 info() <<
"Set face uniqueId numbering version to '" << v <<
"' from caseoption";
433 IMeshUniqueIdMng* mum = m_mesh->meshUniqueIdMng();
434 mum->setFaceBuilderVersion(v);
437 if (
options()->edgeNumberingVersion.isPresent()) {
439 info() <<
"Set edge uniqueId numbering version to '" << v <<
"' from caseoption";
440 IMeshUniqueIdMng* mum = m_mesh->meshUniqueIdMng();
441 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 meshing the dataset.
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.
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 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 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.