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"
58class ArcaneCaseMeshService
83 bool m_is_allow_null_mesh =
false;
89 void _initializeVariables();
90 void _doInitialPartition();
91 void _doInitialPartition2(
const String& name);
92 void _setGhostLayerInfos();
93 void _checkMeshCreationAndAllocation(
bool is_check_allocated);
94 void _setUniqueIdNumberingVersion();
100ArcaneCaseMeshService::
103, m_sub_domain(sbi.subDomain())
114 ARCANE_FATAL(
"Mesh '{0}' has already been created", default_name);
116 m_mesh_name = default_name;
117 info() <<
"Creating mesh name='" << m_mesh_name <<
"' from ArcaneCaseMeshService";
119 m_is_allow_null_mesh = (default_name !=
"Mesh0");
124 bool has_generator =
options()->generator.isPresent();
127 if ((has_filename && has_generator) || (!has_filename && !has_generator))
128 ARCANE_FATAL(
"In '{0}': one and one only of <{1}> or <{2}> has to be specified",
129 options()->configList()->xpathFullName(),
130 options()->generator.rootTagName(),
133 m_mesh_file_name =
options()->filename();
134 if (m_mesh_file_name.empty())
136 m_mesh_file_name,
options()->filename.xpathFullName());
138 _fillReadInfo(read_info);
139 auto& specific_reader =
options()->specificReader;
140 if (specific_reader.isPresent()){
141 m_mesh_builder_ref = specific_reader()->createBuilder(read_info);
142 if (m_mesh_builder_ref.isNull())
143 ARCANE_FATAL(
"No 'IMeshBuilder' created by specific reader");
146 m_mesh_builder_ref = _createBuilderFromFile(read_info);
148 m_mesh_builder = m_mesh_builder_ref.get();
150 else if (has_generator)
151 m_mesh_builder =
options()->generator();
159 if (mesh_dim_kind != build_info.
meshKind().meshDimensionKind()) {
161 mesh_kind.setMeshDimensionKind(mesh_dim_kind);
165 m_mesh_builder->fillMeshBuildInfo(build_info);
168 m_partitioner_name =
options()->partitioner();
187 else if (!m_is_allow_null_mesh)
197 _checkMeshCreationAndAllocation(
false);
203 _setGhostLayerInfos();
204 _setUniqueIdNumberingVersion();
206 m_mesh_builder->allocateMeshItems(m_mesh);
215 _checkMeshCreationAndAllocation(
true);
217 if (m_mesh && (m_mesh->meshPartInfo().nbPart() > 1))
218 if (!m_partitioner_name.empty())
219 _doInitialPartition();
228 _checkMeshCreationAndAllocation(
true);
234 _initializeVariables();
240void ArcaneCaseMeshService::
241_checkMeshCreationAndAllocation(
bool is_check_allocated)
244 ARCANE_FATAL(
"Mesh is not created. You should call createMesh() before");
247 ARCANE_FATAL(
"Mesh is not allocated. You should call initializeMesh() before");
253void ArcaneCaseMeshService::
254_fillReadInfo(CaseMeshReaderReadInfo& read_info)
257 String file_extension;
260 std::size_t extension_pos = fview.find_last_of(
'.');
261 if (extension_pos!=std::string_view::npos){
262 fview.remove_prefix(extension_pos+1);
263 file_extension = fview;
265 read_info.setFormat(file_extension);
272 String mesh_file_name = m_mesh_file_name;
274 String partitioner_name =
options()->partitioner();
275 bool use_internal_partitioner = partitioner_name !=
"External";
276 if (use_internal_partitioner){
277 m_partitioner_name = partitioner_name;
280 info() <<
"Using external partitioner";
281 int mesh_rank = m_sub_domain->parallelMng()->commRank();
283 sprintf(buf,
"CPU%05d.%s",mesh_rank,file_extension.localstr());
284 mesh_file_name = String(std::string_view(buf));
287 read_info.setFileName(mesh_file_name);
289 info() <<
"Mesh filename=" << mesh_file_name
290 <<
" extension=" << read_info.format() <<
" partitioner=" << partitioner_name;
292 read_info.setParallelRead(use_internal_partitioner);
306 ServiceBuilder<ICaseMeshReader> builder(m_sub_domain);
307 UniqueArray<Ref<ICaseMeshReader>> mesh_readers(builder.createAllInstances());
309 for(
auto& mesh_reader_ref : mesh_readers ){
310 ICaseMeshReader* mesh_reader = mesh_reader_ref.get();
311 Ref<IMeshBuilder> builder = mesh_reader->createBuilder(read_info);
312 if (!builder.isNull())
319 builder.getServicesNames(valid_names);
320 String available_readers = String::join(
", ",valid_names);
321 ARCANE_FATAL(
"The mesh reader required for format '{0}' is not available."
322 "The following reader services are available: {1}",
323 read_info.format(),available_readers);
329void ArcaneCaseMeshService::
337 const bool use_partitioner_tester =
false;
338 String test_service =
"MeshPartitionerTester";
339 if (use_partitioner_tester) {
340 Int64 nb_cell = m_mesh->nbCell();
342 info() <<
"Min nb cell=" << min_nb_cell;
344 _doInitialPartition2(test_service);
346 info() <<
"Mesh name=" << m_mesh->name() <<
" have cells. Do not use " << test_service;
349 info() <<
"No basic partition first needed";
350 _doInitialPartition2(m_partitioner_name);
356void ArcaneCaseMeshService::
357_doInitialPartition2(
const String& partitioner_name)
361 info() <<
"Doing initial partitioning service=" << partitioner_name;
365 ServiceBuilder<IMeshPartitionerBase> sbuilder(m_sub_domain);
366 auto mesh_partitioner = sbuilder.createReference(partitioner_name,m_mesh);
368 IMesh* mesh = m_mesh;
369 bool is_dynamic = mesh->isDynamic();
370 mesh->modifier()->setDynamic(
true);
371 mesh->utilities()->partitionAndExchangeMeshWithReplication(mesh_partitioner.get(),
true);
372 mesh->modifier()->setDynamic(is_dynamic);
378void ArcaneCaseMeshService::
379_initializeVariables()
384 IVariableMng* vm = m_sub_domain->variableMng();
385 const auto& vars_opt =
options()->initialization().variable;
386 UniqueArray<String> errors;
387 for(
Integer i=0, n=vars_opt.size(); i<n; ++i ){
388 const auto& o = vars_opt[i];
389 String var_name = o.name;
390 String group_name = o.group;
391 String value = o.value;
392 info() <<
"Initialize variable=" << var_name <<
" group=" << group_name <<
" value=" << value;
393 IVariable* var = vm->findMeshVariable(m_mesh,var_name);
395 errors.add(String::format(
"No variable named '{0}' exists",var_name));
402 IItemFamily* var_family = var->itemFamily();
404 errors.add(String::format(
"Variable '{0}' has no family",var->fullName()));
408 ItemGroup group = var_family->findGroup(group_name);
410 errors.add(String::format(
"No group named '{0}' exists in family '{1}'",
411 group_name,var_family->name()));
415 bool ret = var->initialize(group,value);
417 errors.add(String::format(
"Bad value '{0}' for initializing variable '{1}'",
418 value,var->fullName()));
422 if (!errors.empty()){
423 for( String s : errors )
424 pinfo() <<
"ERROR: " << s;
425 ARCANE_FATAL(
"Variable initialization failed for option '{0}'",
426 vars_opt.xpathFullName());
433void ArcaneCaseMeshService::
436 IGhostLayerMng* gm = m_mesh->ghostLayerMng();
444 if (nb_ghost_layer >= 0) {
445 info() <<
"Set number of ghost layers to '" << nb_ghost_layer <<
"' from caseoption";
446 gm->setNbGhostLayer(nb_ghost_layer);
450 if (builder_version >= 0) {
451 info() <<
"Set ghostlayer builder version to '" << builder_version <<
"' from caseoption";
452 gm->setBuilderVersion(builder_version);
459void ArcaneCaseMeshService::
460_setUniqueIdNumberingVersion()
465 if (
options()->faceNumberingVersion.isPresent()) {
467 info() <<
"Set face uniqueId numbering version to '" << v <<
"' from caseoption";
468 IMeshUniqueIdMng* mum = m_mesh->meshUniqueIdMng();
469 mum->setFaceBuilderVersion(v);
472 if (
options()->edgeNumberingVersion.isPresent()) {
474 info() <<
"Set edge uniqueId numbering version to '" << v <<
"' from caseoption";
475 IMeshUniqueIdMng* mum = m_mesh->meshUniqueIdMng();
476 mum->setEdgeBuilderVersion(v);
#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.
Ce fichier contient les différentes fabriques de services et macro pour enregistrer les 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.
Service Arcane de lecture ou de génération d'un maillage à partir du fichier d'options du jeu de donn...
void createMesh(const String &default_name) override
Créé le maillage avec le nom name.
void allocateMeshItems() override
Alloue les éléments du maillage.
void partitionMesh() override
Partitionne le maillage.
bool m_has_created_mesh_called
True if createMesh() has already been called.
void applyAdditionalOperations() override
Applique les opérations après tout le reste.
Informations nécessaires pour la lecture d'un fichier de maillage.
const Type & value() const
Retourne la valeur de l'option.
bool isPresent() const
Retourne true si l'option est présente.
Interface d'un service de personnalisation de constructeur de maillage.
virtual void applyCustomisation(MeshBuildInfo &build_info)=0
Modifie build_info pour personnaliser la création du maillage.
Interface d'un service de création/lecture du maillage.
virtual IPrimaryMesh * createMesh(const MeshBuildInfo &build_info)=0
Créé un maillage ou un sous-maillage.
virtual IMeshFactoryMng * meshFactoryMng() const =0
Fabrique de maillages associée à ce gestionnaire.
virtual void subdivideMesh(IPrimaryMesh *mesh)=0
Subdivise le maillage mesh.
virtual bool isAllocated()=0
Vrai si le maillage est allouée.
Interface du gestionnaire de parallélisme pour un sous-domaine.
Interface du gestionnaire d'un sous-domaine.
virtual IParallelMng * parallelMng()=0
Retourne le gestionnaire de parallélisme.
virtual IMeshMng * meshMng() const =0
Retourne le gestionnaire de maillage.
Paramètres nécessaires à la construction d'un maillage.
const MeshKind meshKind() const
Caractéristiques du maillage.
MeshBuildInfo & addParallelMng(Ref< IParallelMng > pm)
Positionne le gestionnaire de parallélisme pour créér la maillage.
bool isNeedPartitioning() const
Indique si le lecteur/générateur nécessite un partitionnement.
Ref< IParallelMng > parallelMngRef() const
Gestionnaire de parallélisme dans le cas d'un nouveau maillage.
const String & factoryName() const
Nom de la fabrique pour créer le maillage (via IMeshFactory).
MeshBuildInfo & addMeshKind(const MeshKind &v)
Positionne les caractéristiques du maillage.
MeshBuildInfo & addFactoryName(const String &factory_name)
Positionne le nom de la fabrique pour créer ce maillage.
Caractéristiques d'un maillage.
Référence à une instance.
Structure contenant les informations pour créer un service.
Chaîne de caractères unicode.
bool empty() const
Vrai si la chaîne est vide (nulle ou "").
std::string_view toStdStringView() const
Retourne une vue de la STL sur la chaîne actuelle.
TraceMessage pinfo() const
Flot pour un message d'information en parallèle.
TraceMessage info() const
Flot pour un message d'information.
@ ReduceMin
Minimum des valeurs.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
eMeshCellDimensionKind
Types de gestion de la dimension du maillage.
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
UniqueArray< String > StringUniqueArray
Tableau dynamique à une dimension de chaînes de caractères.
std::int32_t Int32
Type entier signé sur 32 bits.