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"
51class ArcaneCaseMeshService
78 void _initializeVariables();
79 void _doInitialPartition();
80 void _doInitialPartition2(
const String& name);
81 void _setGhostLayerInfos();
82 void _checkMeshCreationAndAllocation(
bool is_check_allocated);
83 void _setUniqueIdNumberingVersion();
89ArcaneCaseMeshService::
92, m_sub_domain(sbi.subDomain())
105 info() <<
"Creating mesh from 'ArcaneCaseMeshService'";
110 bool has_generator =
options()->generator.isPresent();
113 if ((has_filename && has_generator) || (!has_filename && !has_generator))
114 ARCANE_FATAL(
"In '{0}': one and one only of <{1}> or <{2}> has to be specified",
115 options()->configList()->xpathFullName(),
116 options()->generator.rootTagName(),
119 m_mesh_file_name =
options()->filename();
120 if (m_mesh_file_name.empty())
122 m_mesh_file_name,
options()->filename.xpathFullName());
124 _fillReadInfo(read_info);
125 auto& specific_reader =
options()->specificReader;
126 if (specific_reader.isPresent()){
127 m_mesh_builder_ref = specific_reader()->createBuilder(read_info);
128 if (m_mesh_builder_ref.isNull())
129 ARCANE_FATAL(
"No 'IMeshBuilder' created by specific reader");
132 m_mesh_builder_ref = _createBuilderFromFile(read_info);
134 m_mesh_builder = m_mesh_builder_ref.get();
136 else if (has_generator)
137 m_mesh_builder =
options()->generator();
144 bool is_non_manifold =
options()->nonManifoldMesh;
145 if (is_non_manifold) {
147 mesh_kind.setIsNonManifold(
true);
151 m_mesh_builder->fillMeshBuildInfo(build_info);
154 m_partitioner_name =
options()->partitioner();
171 _checkMeshCreationAndAllocation(
false);
175 _setGhostLayerInfos();
176 _setUniqueIdNumberingVersion();
178 m_mesh_builder->allocateMeshItems(m_mesh);
187 _checkMeshCreationAndAllocation(
true);
189 if (m_mesh->meshPartInfo().nbPart() > 1)
190 if (!m_partitioner_name.empty())
191 _doInitialPartition();
200 _checkMeshCreationAndAllocation(
true);
206 _initializeVariables();
212void ArcaneCaseMeshService::
213_checkMeshCreationAndAllocation(
bool is_check_allocated)
216 ARCANE_FATAL(
"Mesh is not created. You should call createMesh() before");
218 ARCANE_FATAL(
"Mesh is not allocated. You should call initializeMesh() before");
224void ArcaneCaseMeshService::
225_fillReadInfo(CaseMeshReaderReadInfo& read_info)
228 String file_extension;
231 std::size_t extension_pos = fview.find_last_of(
'.');
232 if (extension_pos!=std::string_view::npos){
233 fview.remove_prefix(extension_pos+1);
234 file_extension = fview;
236 read_info.setFormat(file_extension);
243 String mesh_file_name = m_mesh_file_name;
245 String partitioner_name =
options()->partitioner();
246 bool use_internal_partitioner = partitioner_name !=
"External";
247 if (use_internal_partitioner){
248 m_partitioner_name = partitioner_name;
251 info() <<
"Using external partitioner";
252 int mesh_rank = m_sub_domain->parallelMng()->commRank();
254 sprintf(buf,
"CPU%05d.%s",mesh_rank,file_extension.localstr());
255 mesh_file_name = String(std::string_view(buf));
258 read_info.setFileName(mesh_file_name);
260 info() <<
"Mesh filename=" << mesh_file_name
261 <<
" extension=" << read_info.format() <<
" partitioner=" << partitioner_name;
263 read_info.setParallelRead(use_internal_partitioner);
277 ServiceBuilder<ICaseMeshReader> builder(m_sub_domain);
278 UniqueArray<Ref<ICaseMeshReader>> mesh_readers(builder.createAllInstances());
280 for(
auto& mesh_reader_ref : mesh_readers ){
281 ICaseMeshReader* mesh_reader = mesh_reader_ref.get();
282 Ref<IMeshBuilder> builder = mesh_reader->createBuilder(read_info);
283 if (!builder.isNull())
290 builder.getServicesNames(valid_names);
291 String available_readers = String::join(
", ",valid_names);
292 ARCANE_FATAL(
"The mesh reader required for format '{0}' is not available."
293 "The following reader services are available: {1}",
294 read_info.format(),available_readers);
300void ArcaneCaseMeshService::
306 const bool use_partitioner_tester =
false;
307 String test_service =
"MeshPartitionerTester";
308 if (use_partitioner_tester) {
309 Int64 nb_cell = m_mesh->nbCell();
311 info() <<
"Min nb cell=" << min_nb_cell;
313 _doInitialPartition2(test_service);
315 info() <<
"Mesh name=" << m_mesh->name() <<
" have cells. Do not use " << test_service;
318 info() <<
"No basic partition first needed";
319 _doInitialPartition2(m_partitioner_name);
325void ArcaneCaseMeshService::
326_doInitialPartition2(
const String& partitioner_name)
328 info() <<
"Doing initial partitioning service=" << partitioner_name;
332 ServiceBuilder<IMeshPartitionerBase> sbuilder(m_sub_domain);
333 auto mesh_partitioner = sbuilder.createReference(partitioner_name,m_mesh);
335 IMesh* mesh = m_mesh;
336 bool is_dynamic = mesh->isDynamic();
337 mesh->modifier()->setDynamic(
true);
338 mesh->utilities()->partitionAndExchangeMeshWithReplication(mesh_partitioner.get(),
true);
339 mesh->modifier()->setDynamic(is_dynamic);
345void ArcaneCaseMeshService::
346_initializeVariables()
348 IVariableMng* vm = m_sub_domain->variableMng();
349 const auto& vars_opt =
options()->initialization().variable;
350 UniqueArray<String> errors;
351 for(
Integer i=0, n=vars_opt.size(); i<n; ++i ){
352 const auto& o = vars_opt[i];
353 String var_name = o.name;
354 String group_name = o.group;
355 String value = o.value;
356 info() <<
"Initialize variable=" << var_name <<
" group=" << group_name <<
" value=" << value;
357 IVariable* var = vm->findMeshVariable(m_mesh,var_name);
359 errors.add(String::format(
"No variable named '{0}' exists",var_name));
366 IItemFamily* var_family = var->itemFamily();
368 errors.add(String::format(
"Variable '{0}' has no family",var->fullName()));
372 ItemGroup group = var_family->findGroup(group_name);
374 errors.add(String::format(
"No group named '{0}' exists in family '{1}'",
375 group_name,var_family->name()));
379 bool ret = var->initialize(group,value);
381 errors.add(String::format(
"Bad value '{0}' for initializing variable '{1}'",
382 value,var->fullName()));
386 if (!errors.empty()){
387 for( String s : errors )
388 pinfo() <<
"ERROR: " << s;
389 ARCANE_FATAL(
"Variable initialization failed for option '{0}'",
390 vars_opt.xpathFullName());
397void ArcaneCaseMeshService::
400 IGhostLayerMng* gm = m_mesh->ghostLayerMng();
408 if (nb_ghost_layer >= 0) {
409 info() <<
"Set number of ghost layers to '" << nb_ghost_layer <<
"' from caseoption";
410 gm->setNbGhostLayer(nb_ghost_layer);
414 if (builder_version >= 0) {
415 info() <<
"Set ghostlayer builder version to '" << builder_version <<
"' from caseoption";
416 gm->setBuilderVersion(builder_version);
423void ArcaneCaseMeshService::
424_setUniqueIdNumberingVersion()
429 if (
options()->faceNumberingVersion.isPresent()) {
431 info() <<
"Set face uniqueId numbering version to '" << v <<
"' from caseoption";
432 IMeshUniqueIdMng* mum = m_mesh->meshUniqueIdMng();
433 mum->setFaceBuilderVersion(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.
ArcaneArcaneCaseMeshServiceObject(const Arcane::ServiceBuildInfo &sbi)
Constructeur.
CaseOptionsArcaneCaseMeshService * options() const
Options du jeu de données du service.
Service Arcane un maillage du jeu de données.
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.
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 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 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 -*-
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.