Arcane  4.2.1.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
MeshMaterialMng.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* MeshMaterialMng.cc (C) 2000-2026 */
9/* */
10/* Gestionnaire des matériaux et milieux d'un maillage. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/materials/internal/MeshMaterialMng.h"
15
16#include "arcane/utils/TraceAccessor.h"
17#include "arcane/utils/NotImplementedException.h"
18#include "arcane/utils/AutoDestroyUserData.h"
19#include "arcane/utils/IUserDataList.h"
20#include "arcane/utils/OStringStream.h"
21#include "arcane/utils/PlatformUtils.h"
22#include "arcane/utils/ValueConvert.h"
23#include "arcane/utils/CheckedConvert.h"
25
26#include "arcane/core/IMesh.h"
27#include "arcane/core/IItemFamily.h"
28#include "arcane/core/VariableTypes.h"
29#include "arcane/core/ItemPrinter.h"
30#include "arcane/core/IVariableMng.h"
31#include "arcane/core/Properties.h"
32#include "arcane/core/ObserverPool.h"
33#include "arcane/core/materials/IMeshMaterialVariableFactoryMng.h"
34#include "arcane/core/materials/IMeshMaterialVariable.h"
36#include "arcane/core/materials/internal/IMeshMaterialVariableInternal.h"
37#include "arcane/core/internal/IVariableMngInternal.h"
38
39#include "arcane/accelerator/core/IAcceleratorMng.h"
40
41#include "arcane/materials/MeshMaterialInfo.h"
42#include "arcane/materials/MeshEnvironmentBuildInfo.h"
43#include "arcane/materials/CellToAllEnvCellConverter.h"
44#include "arcane/materials/MeshMaterialExchangeMng.h"
45#include "arcane/materials/EnumeratorTracer.h"
46#include "arcane/materials/MeshMaterialVariableFactoryRegisterer.h"
47#include "arcane/materials/internal/AllEnvData.h"
48#include "arcane/materials/internal/MeshMaterialModifierImpl.h"
49#include "arcane/materials/internal/MeshMaterialSynchronizer.h"
50#include "arcane/materials/internal/MeshMaterialVariableSynchronizer.h"
51#include "arcane/materials/internal/ConstituentConnectivityList.h"
52#include "arcane/materials/internal/AllCellToAllEnvCellContainer.h"
53
54/*---------------------------------------------------------------------------*/
55/*---------------------------------------------------------------------------*/
56
57/*!
58 * \file MaterialsGlobal.h
59 *
60 * Liste des déclarations globales pour les matériaux.
61 */
62
63/*---------------------------------------------------------------------------*/
64/*---------------------------------------------------------------------------*/
65
66/*
67 * TODO:
68 * - Vérifier qu'on ne créé qu'une seule instance de MeshModifier.
69 * - Vérifier par exemple dans synchronizeMaterialsInCells()
70 * qu'on n'est pas en train de modifier le maillage.
71 */
72
73/*---------------------------------------------------------------------------*/
74/*---------------------------------------------------------------------------*/
75
76namespace Arcane::Materials
77{
78
80arcaneCreateMeshMaterialVariableFactoryMng(IMeshMaterialMng* mm);
81
82/*---------------------------------------------------------------------------*/
83/*---------------------------------------------------------------------------*/
84
85namespace
86{
88 arcaneCreateMeshMaterialMng(const MeshHandle& mesh_handle, const String& name)
89 {
90 MeshMaterialMng* mmm = new MeshMaterialMng(mesh_handle, name);
91 //std::cout << "CREATE MESH_MATERIAL_MNG mesh_name=" << mesh_handle.meshName()
92 // << " ref=" << mesh_handle.reference() << " this=" << mmm << "\n";
93 mmm->build();
94 return mmm;
95 }
96} // namespace
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100
101MeshMaterialMng::RunnerInfo::
102RunnerInfo(Runner& runner)
103: m_runner(runner)
104, m_run_queue(makeQueue(m_runner))
105, m_sequential_runner(Accelerator::eExecutionPolicy::Sequential)
106, m_sequential_run_queue(makeQueue(m_sequential_runner))
107, m_multi_thread_runner(Accelerator::eExecutionPolicy::Thread)
108, m_multi_thread_run_queue(makeQueue(m_multi_thread_runner))
109{
110}
111
112/*---------------------------------------------------------------------------*/
113/*---------------------------------------------------------------------------*/
114
115void MeshMaterialMng::RunnerInfo::
116initializeAsyncPool(Int32 nb_queue)
117{
118 // Si on utilise une politique accélérateur, créé des RunQueue asynchrones
119 // pour les opérations indépendantes. Cela permettra d'en exécuter plusieurs
120 // à la fois.
121 bool is_accelerator = isAcceleratorPolicy(m_runner.executionPolicy());
122 m_async_queue_pool.initialize(m_runner, nb_queue);
123 if (is_accelerator)
124 m_async_queue_pool.setAsync(true);
125}
126
127/*---------------------------------------------------------------------------*/
128/*---------------------------------------------------------------------------*/
129
130RunQueue MeshMaterialMng::RunnerInfo::
131runQueue(Accelerator::eExecutionPolicy policy) const
132{
133 if (policy == Accelerator::eExecutionPolicy::None)
134 return m_run_queue;
135 if (policy == Accelerator::eExecutionPolicy::Sequential)
136 return m_sequential_run_queue;
137 if (policy == Accelerator::eExecutionPolicy::Thread)
138 return m_multi_thread_run_queue;
139 ARCANE_FATAL("Invalid value '{0}' for execution policy. Valid values are None, Sequential or Thread", policy);
140}
141
142/*---------------------------------------------------------------------------*/
143/*---------------------------------------------------------------------------*/
144
145/*---------------------------------------------------------------------------*/
146/*---------------------------------------------------------------------------*/
147
148MeshMaterialMng::
149MeshMaterialMng(const MeshHandle& mesh_handle, const String& name)
150// TODO: utiliser le ITraceMng du maillage. Le faire lors de l'init
151: TraceAccessor(mesh_handle.traceMng())
152, m_mesh_handle(mesh_handle)
153, m_internal_api(std::make_unique<InternalApi>(this))
154, m_variable_mng(mesh_handle.variableMng())
155, m_name(name)
156, m_indexed_selection_identity(MemoryUtils::getDefaultDataAllocator())
157{
158 m_all_env_data = std::make_unique<AllEnvData>(this);
159 m_exchange_mng = std::make_unique<MeshMaterialExchangeMng>(this);
160 m_variable_factory_mng = arcaneCreateMeshMaterialVariableFactoryMng(this);
161 m_observer_pool = std::make_unique<ObserverPool>();
162 m_observer_pool->addObserver(this, &MeshMaterialMng::_onMeshDestroyed, mesh_handle.onDestroyObservable());
163
164 String s = platform::getEnvironmentVariable("ARCANE_ALLENVCELL_FOR_RUNCOMMAND");
165 if (!s.null())
166 m_is_use_accelerator_envcell_container = true;
167 m_mms = new MeshMaterialSynchronizer(this);
168}
169
170/*---------------------------------------------------------------------------*/
171/*---------------------------------------------------------------------------*/
172
173MeshMaterialMng::
174~MeshMaterialMng()
175{
176 //std::cout << "DESTROY MESH MATERIAL MNG this=" << this << '\n';
177 _dumpStats();
178
179 delete m_mms;
180 delete m_variable_factory_mng;
181 m_exchange_mng.reset();
182 m_all_cells_env_only_synchronizer.reset();
183 m_all_cells_mat_env_synchronizer.reset();
184 m_all_env_data.reset();
185 m_properties.reset();
186
187 for (MeshMaterial* m : m_true_materials)
188 delete m;
189 m_true_materials.clear();
190
191 for (MeshEnvironment* e : m_true_environments)
192 delete e;
193 m_true_environments.clear();
194
195 for (IMeshBlock* b : m_true_blocks)
196 delete b;
197
198 for (MeshMaterialInfo* mmi : m_materials_info)
199 delete mmi;
200
201 for (MeshMaterialVariableIndexer* mvi : m_variables_indexer_to_destroy)
202 delete mvi;
203
204 m_modifier.reset();
205 m_internal_api.reset();
206
207 m_accelerator_envcell_container.reset();
208
209 // On détruit le Runner à la fin pour être sur qu'il n'y a plus de
210 // références dessus dans les autres instances.
211 m_runner_info.reset();
212}
213
214/*---------------------------------------------------------------------------*/
215/*---------------------------------------------------------------------------*/
216
217/*---------------------------------------------------------------------------*/
218/*---------------------------------------------------------------------------*/
219
220void MeshMaterialMng::
221build()
222{
223 // Enregistre les fabriques des variables
224 {
225 auto* x = MeshMaterialVariableFactoryRegisterer::firstRegisterer();
226 while (x) {
227 m_variable_factory_mng->registerFactory(x->createFactory());
228 x = x->nextRegisterer();
229 }
230 }
231
232 // Indique si on utilise l'API accélérateur pour le calcul des entités
233 // de ConstituentItemVectorImpl
234 {
235 bool force_enable = false;
236 if (const auto v = Convert::Type<Real>::tryParseFromEnvironment("ARCANE_MATERIALMNG_USE_ACCELERATOR_FOR_CONSTITUENTITEMVECTOR", true)) {
237 m_is_use_accelerator_for_constituent_item_vector = (v.value() != 0);
238 force_enable = m_is_use_accelerator_for_constituent_item_vector;
239 }
240 // N'active pas l'utilisation des RunQueue pour le calcul
241 // des 'ComponentItemVector' si le multi-threading est actif. Actuellement
242 // l'utilisation d'une même RunQueue n'est pas multi-thread (et donc
243 // on ne peut pas créer des ComponentItemVector en concurrence)
244 if (!force_enable && TaskFactory::isActive())
245 m_is_use_accelerator_for_constituent_item_vector = false;
246 info() << "Use accelerator API for 'ConstituentItemVectorImpl' = " << m_is_use_accelerator_for_constituent_item_vector;
247 }
248
249 // Positionne le runner par défaut
250 {
251 IAcceleratorMng* acc_mng = m_variable_mng->_internalApi()->acceleratorMng();
252 Runner runner;
253 if (acc_mng) {
254 Runner* default_runner = acc_mng->defaultRunner();
255 // Indique si on active la file accélérateur
256 bool use_accelerator_runner = true;
257 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_MATERIALMNG_USE_QUEUE", true))
258 use_accelerator_runner = (v.value() != 0);
259 if (use_accelerator_runner && default_runner)
260 runner = *default_runner;
261 }
262 // Si pas de runner enregistré, utiliser un runner séquentiel.
263 if (!runner.isInitialized())
264 runner.initialize(Accelerator::eExecutionPolicy::Sequential);
265 m_runner_info = std::make_unique<RunnerInfo>(runner);
266 Int32 nb_queue = isAcceleratorPolicy(runner.executionPolicy()) ? 8 : 1;
267 info() << "Use runner '" << this->runner().executionPolicy() << "' for MeshMaterialMng name=" << name()
268 << " async_queue_size=" << nb_queue;
269 m_runner_info->initializeAsyncPool(nb_queue);
270
271 // En mode release et si on utilise un accélérateur alors on alloue par
272 // défaut sur accélérateur. C'est important surtout pour les tableaux
273 // temporaires.
274 // En mode 'check' il faut laisser la mémoire unifiée car les tests sont faits
275 // sur le CPU.
276 RunQueue& q = runQueue();
277 if (!arcaneIsCheck() && q.isAcceleratorPolicy())
278 q.setMemoryRessource(eMemoryRessource::Device);
279 }
280
281 // Choix des optimisations.
282 {
283 int default_flags = 0;
284
285 // Ne met pas encore par défaut ces flags car cela ne fonctionne pas
286 // pour tous les codes
287 // default_flags = (int)eModificationFlags::GenericOptimize | (int)eModificationFlags::OptimizeMultiAddRemove;
288
289 int opt_flag_value = 0;
290 String env_name = "ARCANE_MATERIAL_MODIFICATION_FLAGS";
291 String opt_flag_str = platform::getEnvironmentVariable(env_name);
292 if (!opt_flag_str.null()) {
293 if (builtInGetValue(opt_flag_value, opt_flag_str)) {
294 pwarning() << "Invalid value '" << opt_flag_str
295 << " 'for environment variable '" << env_name
296 << "'";
297 opt_flag_value = default_flags;
298 }
299 }
300 else {
301 opt_flag_value = default_flags;
302 }
303 m_modification_flags = opt_flag_value;
304 }
305
306 // Choix de la version de l'implémentation des synchronisations
307 {
308 String env_name = "ARCANE_MATSYNCHRONIZE_VERSION";
309 String env_value = platform::getEnvironmentVariable(env_name);
310 info() << "ENV_VALUE=" << env_value;
311 Integer version = m_synchronize_variable_version;
312 if (!env_value.null()) {
313 if (builtInGetValue(version, env_value)) {
314 pwarning() << "Invalid value '" << env_value
315 << " 'for environment variable '" << env_name
316 << "'";
317 }
318 else
319 m_synchronize_variable_version = version;
320 }
321 info() << "Set material variable synchronize version to "
322 << "'" << m_synchronize_variable_version << "'";
323 }
324
325 // Choix du service de compression
326 {
327 String env_name = "ARCANE_MATERIAL_DATA_COMPRESSOR_NAME";
328 String env_value = platform::getEnvironmentVariable(env_name);
329 if (!env_value.null()) {
330 info() << "Use service '" << env_value << "' for material data compression";
331 m_data_compressor_service_name = env_value;
332 }
333 }
334
335 // Choix du ratio de capacité additionelle
336 {
337 if (auto v = Convert::Type<Real>::tryParseFromEnvironment("ARCANE_MATERIALMNG_ADDITIONAL_CAPACITY_RATIO", true)) {
338 if (v >= 0.0) {
339 m_additional_capacity_ratio = v.value();
340 info() << "Set additional capacity ratio to " << m_additional_capacity_ratio;
341 }
342 }
343 }
344
345 m_exchange_mng->build();
346 // Si les traces des énumérateurs sur les entités sont actives, active celles
347 // sur les matériaux.
348 // TODO: rendre ce code thread-safe en cas d'utilisation de IParallelMng via les threads
349 // et ne l'appeler qu'une fois.
350 IItemEnumeratorTracer* item_tracer = IItemEnumeratorTracer::singleton();
351 if (item_tracer) {
352 info() << "Adding material enumerator tracing";
353 EnumeratorTracer::_setSingleton(new EnumeratorTracer(traceMng(), item_tracer->perfCounterRef()));
354 }
355}
356
357/*---------------------------------------------------------------------------*/
358/*---------------------------------------------------------------------------*/
359
360void MeshMaterialMng::
361_addVariableIndexer(MeshMaterialVariableIndexer* var_idx)
362{
363 var_idx->setIndex(m_variables_indexer.size());
364 m_variables_indexer.add(var_idx);
365}
366
367/*---------------------------------------------------------------------------*/
368/*---------------------------------------------------------------------------*/
369
370/*!
371 * \brief Création d'un matériau.
372 *
373 * Créé un matériau de nom \a name, dans le milieu \a env, avec les
374 * infos \a infos.
375 */
376MeshMaterial* MeshMaterialMng::
377_createMaterial(MeshEnvironment* env, MeshMaterialInfo* infos, const String& name)
378{
379 _checkEndCreate();
380 if (infos->materialMng() != this)
381 ARCANE_FATAL("Invalid materialMng() for material info");
382 if (env->materialMng() != this)
383 ARCANE_FATAL("Invalid materialMng() for environment");
384 Integer var_index = m_variables_indexer.size();
385 Int16 mat_id = CheckedConvert::toInt16(m_materials.size());
386 MeshMaterial* mat = new MeshMaterial(infos, env, name, mat_id);
387 info() << "Create material name=" << name << "mat_id=" << mat_id << " var_index=" << var_index;
388 mat->build();
389 m_materials.add(mat);
390 m_materials_as_components.add(mat);
391 m_true_materials.add(mat);
392
393 _addVariableIndexer(mat->variableIndexer());
394 return mat;
395}
396
397/*---------------------------------------------------------------------------*/
398/*---------------------------------------------------------------------------*/
399
400MeshMaterialInfo* MeshMaterialMng::
401registerMaterialInfo(const String& name)
402{
403 _checkEndCreate();
404 // Vérifie que le matériau n'est pas déjà enregistré.
405 MeshMaterialInfo* old_mmi = _findMaterialInfo(name);
406 if (old_mmi)
407 ARCANE_FATAL("Un matériau de nom '{0}' est déjà enregistré", name);
408
409 MeshMaterialInfo* mmi = new MeshMaterialInfo(this, name);
410 m_materials_info.add(mmi);
411 return mmi;
412}
413
414/*---------------------------------------------------------------------------*/
415/*---------------------------------------------------------------------------*/
416
417/*!
418 * \brief Création d'un milieu.
419 *
420 * Les infos du milieu sont données par la structure \a infos.
421 * En même temps que le milieu sont créés tous les matériaux
422 * le constituant.
423 */
424IMeshEnvironment* MeshMaterialMng::
425createEnvironment(const MeshEnvironmentBuildInfo& infos)
426{
427 _checkEndCreate();
428 Int16 env_index = CheckedConvert::toInt16(m_environments.size());
429 // Vérifie qu'un milieu de même nom n'existe pas.
430 const String& env_name = infos.name();
431 MeshEnvironment* old_me = _findEnvironment(env_name);
432 if (old_me)
433 ARCANE_FATAL("Un milieu de nom '{0}' est déjà enregistré", env_name);
434
435 info() << "Creating environment name=" << env_name << " index=" << env_index;
436 // Créé le milieu
437 MeshEnvironment* me = new MeshEnvironment(this, env_name, env_index);
438 me->build();
439 m_true_environments.add(me);
440 m_environments.add(me);
441 m_environments_as_components.add(me);
442
443 // Créé et ajoute les matériaux
444 Integer nb_mat = infos.materials().size();
445 ConstArrayView<MeshEnvironmentBuildInfo::MatInfo> mat_build_infos = infos.materials();
446 for (Integer i = 0; i < nb_mat; ++i) {
447 const MeshEnvironmentBuildInfo::MatInfo& buildinfo = mat_build_infos[i];
448 const String& mat_name = buildinfo.m_name;
449 String new_mat_name = env_name + "_" + mat_name;
450 MeshMaterialInfo* mat_info = _findMaterialInfo(mat_name);
451 if (!mat_info) {
452 ARCANE_FATAL("Aucun matériau de nom '{0}' n'est défini", mat_name);
453 }
454 MeshMaterial* mm = _createMaterial(me, mat_info, new_mat_name);
455 me->addMaterial(mm);
456 mat_info->_addEnvironment(env_name);
457 }
458 // Si le milieu contient plusieurs matériaux, il faut lui allouer
459 // des valeurs partielles. Sinon, ses valeurs partielles sont celles
460 // de son unique matériau.
461 {
462 MeshMaterialVariableIndexer* var_idx = nullptr;
463 if (nb_mat == 1) {
464 var_idx = me->materials()[0]->_internalApi()->variableIndexer();
465 }
466 else {
467 var_idx = new MeshMaterialVariableIndexer(traceMng(), me->name());
468 _addVariableIndexer(var_idx);
469 m_variables_indexer_to_destroy.add(var_idx);
470 }
471 me->setVariableIndexer(var_idx);
472 }
473 return me;
474}
475
476/*---------------------------------------------------------------------------*/
477/*---------------------------------------------------------------------------*/
478
479IMeshBlock* MeshMaterialMng::
480createBlock(const MeshBlockBuildInfo& infos)
481{
482 _checkEndCreate();
483
484 Int32 block_index = m_blocks.size();
485 // Vérifie qu'un bloc de même nom n'existe pas.
486 const String& name = infos.name();
487 const MeshBlock* old_mb = _findBlock(name);
488 if (old_mb)
489 ARCANE_FATAL("Un bloc de nom '{0}' est déjà enregistré", name);
490
491 info() << "Creating block name=" << name << " index=" << block_index
492 << " nb_env=" << infos.environments().size();
493 Integer nb_env = infos.environments().size();
494 for (Integer i = 0; i < nb_env; ++i)
495 info() << " Adding environment name=" << infos.environments()[i]->name() << " to block";
496
497 // Créé le bloc
498 MeshBlock* mb = new MeshBlock(this, block_index, infos);
499 mb->build();
500 m_true_blocks.add(mb);
501 m_blocks.add(mb);
502
503 return mb;
504}
505
506/*---------------------------------------------------------------------------*/
507/*---------------------------------------------------------------------------*/
508
509void MeshMaterialMng::
510addEnvironmentToBlock(IMeshBlock* block, IMeshEnvironment* env)
511{
512 MeshBlock* mb = ARCANE_CHECK_POINTER(dynamic_cast<MeshBlock*>(block));
513 mb->addEnvironment(env);
514}
515
516/*---------------------------------------------------------------------------*/
517/*---------------------------------------------------------------------------*/
518
519void MeshMaterialMng::
520removeEnvironmentToBlock(IMeshBlock* block, IMeshEnvironment* env)
521{
522 MeshBlock* mb = ARCANE_CHECK_POINTER(dynamic_cast<MeshBlock*>(block));
523 mb->removeEnvironment(env);
524}
525
526/*---------------------------------------------------------------------------*/
527/*---------------------------------------------------------------------------*/
528
529void MeshMaterialMng::
530endCreate(bool is_continue)
531{
532 if (m_is_end_create)
533 return;
534
535 _saveInfosInProperties();
536
537 info() << "END CREATE MATERIAL_MNG is_continue=" << is_continue;
538
539 m_modifier = std::make_unique<MeshMaterialModifierImpl>(this);
540 m_modifier->initOptimizationFlags();
541
542 m_all_env_data->endCreate(is_continue);
543
544 auto synchronizer = mesh()->cellFamily()->allItemsSynchronizer();
545 m_all_cells_mat_env_synchronizer = std::make_unique<MeshMaterialVariableSynchronizer>(this, synchronizer, MatVarSpace::MaterialAndEnvironment);
546 m_all_cells_env_only_synchronizer = std::make_unique<MeshMaterialVariableSynchronizer>(this, synchronizer, MatVarSpace::Environment);
547
548 // Détermine la liste de tous les composants.
549 {
550 Integer nb_component = m_environments_as_components.size() + m_materials_as_components.size();
551 m_components.reserve(nb_component);
552 m_components.addRange(m_environments_as_components);
553 m_components.addRange(m_materials_as_components);
554 }
555
556 // Il faut construire et initialiser les variables qui ont été
557 // créées avant cette allocation.
558 for (const auto& i : m_full_name_variable_map) {
559 IMeshMaterialVariable* mv = i.second;
560 info(4) << "BUILD FROM MANAGER name=" << mv->name() << " this=" << this;
561 mv->buildFromManager(is_continue);
562 }
563 if (is_continue)
564 _endUpdate();
565 m_is_end_create = true;
566
567 // Vérifie que les milieux sont valides.
568 // NOTE: on ne peut pas toujours appeler checkValid()
569 // (notamment au démarrage) car les groupes d'entités existent,
570 // mais les infos matériaux associées ne sont pas
571 // forcément encore créés.
572 // (Il faudra regarder une si cela est dû au mode compatible ou pas).
573 for (IMeshEnvironment* env : m_environments) {
574 env->checkValid();
575 }
576
577 // Maintenant que tout est créé, il est valide d'enregistrer les mécanismes
578 // d'échange.
579 m_exchange_mng->registerFactory();
580}
581
582/*---------------------------------------------------------------------------*/
583/*---------------------------------------------------------------------------*/
584
585void MeshMaterialMng::
586setModificationFlags(int v)
587{
588 _checkEndCreate();
589 m_modification_flags = v;
590 info() << "Setting ModificationFlags to v=" << v;
591}
592
593/*---------------------------------------------------------------------------*/
594/*---------------------------------------------------------------------------*/
595
596void MeshMaterialMng::
597setAllocateScalarEnvironmentVariableAsMaterial(bool v)
598{
599 _checkEndCreate();
600 m_is_allocate_scalar_environment_variable_as_material = v;
601 info() << "Setting AllocateScalarEnvironmentVariableAsMaterial to v=" << v;
602}
603
604/*---------------------------------------------------------------------------*/
605/*---------------------------------------------------------------------------*/
606
607void MeshMaterialMng::
608setDataCompressorServiceName(const String& name)
609{
610 m_data_compressor_service_name = name;
611}
612
613/*---------------------------------------------------------------------------*/
614/*---------------------------------------------------------------------------*/
615
616MeshMaterialModifierImpl* MeshMaterialMng::
617_modifier()
618{
619 return m_modifier.get();
620}
621
622/*---------------------------------------------------------------------------*/
623/*---------------------------------------------------------------------------*/
624
625MeshMaterialInfo* MeshMaterialMng::
626_findMaterialInfo(const String& name)
627{
628 for (MeshMaterialInfo* mmi : m_materials_info)
629 if (mmi->name() == name)
630 return mmi;
631 return nullptr;
632}
633
634/*---------------------------------------------------------------------------*/
635/*---------------------------------------------------------------------------*/
636
637IMeshEnvironment* MeshMaterialMng::
638findEnvironment(const String& name, bool throw_exception)
639{
640 IMeshEnvironment* env = _findEnvironment(name);
641 if (env)
642 return env;
643 if (throw_exception)
644 ARCANE_FATAL("No environment named '{0}'", name);
645 return nullptr;
646}
647
648/*---------------------------------------------------------------------------*/
649/*---------------------------------------------------------------------------*/
650
651MeshEnvironment* MeshMaterialMng::
652_findEnvironment(const String& name)
653{
654 for (MeshEnvironment* env : m_true_environments)
655 if (env->name() == name)
656 return env;
657 return nullptr;
658}
659
660/*---------------------------------------------------------------------------*/
661/*---------------------------------------------------------------------------*/
662
663IMeshBlock* MeshMaterialMng::
664findBlock(const String& name, bool throw_exception)
665{
666 IMeshBlock* block = _findBlock(name);
667 if (block)
668 return block;
669 if (throw_exception)
670 ARCANE_FATAL("No block named '{0}'", name);
671 return nullptr;
672}
673
674/*---------------------------------------------------------------------------*/
675/*---------------------------------------------------------------------------*/
676
677MeshBlock* MeshMaterialMng::
678_findBlock(const String& name)
679{
680 for (MeshBlock* b : m_true_blocks)
681 if (b->name() == name)
682 return b;
683 return nullptr;
684}
685
686/*---------------------------------------------------------------------------*/
687/*---------------------------------------------------------------------------*/
688
689void MeshMaterialMng::
690forceRecompute()
691{
692 _endUpdate();
693}
694
695/*---------------------------------------------------------------------------*/
696/*---------------------------------------------------------------------------*/
697
698/*!
699 * \brief Remise à jour des structures suite à une modification des mailles
700 * de matériaux ou de milieux.
701 */
702void MeshMaterialMng::
703_endUpdate()
704{
705 m_all_env_data->forceRecompute(true);
706}
707
708/*---------------------------------------------------------------------------*/
709/*---------------------------------------------------------------------------*/
710
711/*!
712 * \brief Met à jour les références des variables.
713 *
714 * Cela doit être fait lorsque le nombre d'éléments par matériau ou milieu
715 * change car les tableaux contenant les variables associées peuvent être
716 * modifiés lors de l'opération.
717 */
718void MeshMaterialMng::
719syncVariablesReferences(bool check_resize)
720{
721 for (const auto& i : m_full_name_variable_map) {
722 IMeshMaterialVariable* mv = i.second;
723 info(4) << "SYNC REFERENCES FROM MANAGER name=" << mv->name();
724 mv->_internalApi()->syncReferences(check_resize);
725 }
726}
727
728/*---------------------------------------------------------------------------*/
729/*---------------------------------------------------------------------------*/
730
731void MeshMaterialMng::
732visitVariables(IFunctorWithArgumentT<IMeshMaterialVariable*>* functor)
733{
734 if (!functor)
735 return;
736 for (const auto& i : m_full_name_variable_map) {
737 IMeshMaterialVariable* mv = i.second;
738 functor->executeFunctor(mv);
739 }
740}
741
742/*---------------------------------------------------------------------------*/
743/*---------------------------------------------------------------------------*/
744
745void MeshMaterialMng::
746checkValid()
747{
748 const IItemFamily* cell_family = mesh()->cellFamily();
749 ItemGroup all_cells = cell_family->allItems();
750 ConstArrayView<Int16> nb_env_per_cell = m_all_env_data->componentConnectivityList()->cellsNbEnvironment();
751 ENUMERATE_ALLENVCELL (iallenvcell, view(all_cells.view().localIds())) {
752 AllEnvCell all_env_cell = *iallenvcell;
753 Integer cell_nb_env = all_env_cell.nbEnvironment();
754 Cell cell = all_env_cell.globalCell();
755 Int64 cell_uid = cell.uniqueId();
756 if (all_env_cell.level() != LEVEL_ALLENVIRONMENT)
757 ARCANE_FATAL("Bad level for all_env_item");
758
759 if (all_env_cell.globalCell() != cell)
760 ARCANE_FATAL("Bad corresponding globalCell() in all_env_item");
761 if (cell_nb_env != nb_env_per_cell[cell.localId()])
762 ARCANE_FATAL("Bad value for nb_env direct='{0}' var='{1}'",
763 cell_nb_env, nb_env_per_cell[cell.localId()]);
764 for (Integer z = 0; z < cell_nb_env; ++z) {
765 EnvCell ec = all_env_cell.cell(z);
766 Integer cell_nb_mat = ec.nbMaterial();
767 matimpl::ConstituentItemBase eii = ec.constituentItemBase();
768 if (all_env_cell.constituentItemBase() != eii._superItemBase())
769 ARCANE_FATAL("Bad corresponding allEnvItem() in env_item uid={0}", cell_uid);
770 if (eii.globalItemBase() != cell)
771 ARCANE_FATAL("Bad corresponding globalItem() in env_item");
772 if (eii.level() != LEVEL_ENVIRONMENT)
773 ARCANE_FATAL("Bad level '{0}' for in env_item", eii.level());
774 // Si la maille n'est pas pure, la variable milieu ne peut être équivalente à
775 // la variable globale.
776 if (cell_nb_env > 1 && ec._varIndex().arrayIndex() == 0)
777 ARCANE_FATAL("Global index for a partial cell env_item={0}", ec);
778
779 for (Integer k = 0; k < cell_nb_mat; ++k) {
780 MatCell mc = ec.cell(k);
781 matimpl::ConstituentItemBase mci = mc.constituentItemBase();
782 if (eii != mci._superItemBase())
783 ARCANE_FATAL("Bad corresponding env_item in mat_item k={0} mc={1}", k, mc);
784 if (mci.globalItemBase() != cell)
785 ARCANE_FATAL("Bad corresponding globalItem() in mat_item");
786 if (mci.level() != LEVEL_MATERIAL)
787 ARCANE_FATAL("Bad level '{0}' for in mat_item", mci.level());
788 // Si la maille n'est pas pure, la variable matériau ne peut être équivalente à
789 // la variable globale.
790 if ((cell_nb_env > 1 || cell_nb_mat > 1) && mc._varIndex().arrayIndex() == 0) {
791 ARCANE_FATAL("Global index for a partial cell matitem={0} name={1} nb_mat={2} nb_env={3}",
792 mc, mc.material()->name(), cell_nb_mat, cell_nb_env);
793 }
794 }
795 }
796 }
797
798 for (IMeshEnvironment* env : m_environments) {
799 env->checkValid();
800 }
801}
802
803/*---------------------------------------------------------------------------*/
804/*---------------------------------------------------------------------------*/
805
806IMeshMaterialVariable* MeshMaterialMng::
807findVariable(const String& name)
808{
809 IMeshMaterialVariable* v = _findVariableFullyQualified(name);
810 if (v)
811 return v;
812
813 // Recherche la variable globale de nom \a name
814 // et si on la trouve, prend son nom complet pour
815 // la variable matériau.
816 const IVariable* global_var = m_variable_mng->findMeshVariable(mesh(), name);
817 if (global_var) {
818 v = _findVariableFullyQualified(global_var->fullName());
819 if (v)
820 return v;
821 }
822
823 return nullptr;
824}
825
826/*---------------------------------------------------------------------------*/
827/*---------------------------------------------------------------------------*/
828
829IMeshMaterialVariable* MeshMaterialMng::
830_findVariableFullyQualified(const String& name)
831{
832 auto i = m_full_name_variable_map.find(name);
833 if (i != m_full_name_variable_map.end())
834 return i->second;
835 return nullptr;
836}
837
838/*---------------------------------------------------------------------------*/
839/*---------------------------------------------------------------------------*/
840
841IMeshMaterialVariable* MeshMaterialMng::
842checkVariable(IVariable* global_var)
843{
844 auto i = m_var_to_mat_var_map.find(global_var);
845 if (i != m_var_to_mat_var_map.end())
846 return i->second;
847 return nullptr;
848}
849
850/*---------------------------------------------------------------------------*/
851/*---------------------------------------------------------------------------*/
852
853void MeshMaterialMng::
854fillWithUsedVariables(Array<IMeshMaterialVariable*>& variables)
855{
856 variables.clear();
857
858 // Utilise la map sur les noms des variables pour garantir un même
859 // ordre de parcours quels que soient les sous-domaines.
860 for (const auto& i : m_full_name_variable_map) {
861 IMeshMaterialVariable* ivar = i.second;
862 if (ivar->globalVariable()->isUsed())
863 variables.add(ivar);
864 }
865}
866
867/*---------------------------------------------------------------------------*/
868/*---------------------------------------------------------------------------*/
869
870void MeshMaterialMng::
871_addVariable(IMeshMaterialVariable* var)
872{
873 //TODO: le verrou m_variable_lock doit etre actif.
874 IVariable* gvar = var->globalVariable();
875 info(4) << "MAT_ADD_VAR global_var=" << gvar << " var=" << var << " this=" << this;
876 m_var_to_mat_var_map.insert(std::make_pair(gvar, var));
877 m_full_name_variable_map.insert(std::make_pair(gvar->fullName(), var));
878}
879
880/*---------------------------------------------------------------------------*/
881/*---------------------------------------------------------------------------*/
882
883void MeshMaterialMng::
884_removeVariable(IMeshMaterialVariable* var)
885{
886 //TODO: le verrou m_variable_lock doit etre actif.
887 IVariable* gvar = var->globalVariable();
888 info(4) << "MAT:Remove variable global_var=" << gvar << " var=" << var;
889 m_var_to_mat_var_map.erase(gvar);
890 m_full_name_variable_map.erase(gvar->fullName());
891}
892
893/*---------------------------------------------------------------------------*/
894/*---------------------------------------------------------------------------*/
895
896void MeshMaterialMng::
897dumpInfos(std::ostream& o)
898{
899 Integer nb_mat = m_materials.size();
900 Integer nb_env = m_environments.size();
901 Integer nb_var_idx = m_variables_indexer.size();
902 o << "-- Infos sur les milieux et matériaux\n";
903 o << "-- Nb Materiaux: " << nb_mat << '\n';
904 o << "-- Nb Milieux: " << nb_env << '\n';
905 o << "-- Nb Variables partielles: " << nb_var_idx << '\n';
906
907 o << "-- Liste des matériaux\n";
908 for (IMeshMaterial* mat : m_materials) {
909 o << "-- Materiau name=" << mat->name() << '\n';
910 }
911
912 o << "-- Liste des milieux\n";
913 for (IMeshEnvironment* me : m_environments) {
914 ConstArrayView<IMeshMaterial*> env_materials = me->materials();
915 const MeshMaterialVariableIndexer* env_var_idx = me->_internalApi()->variableIndexer();
916 Integer nb_env_mat = env_materials.size();
917 o << "-- Milieu name=" << me->name()
918 << " nb_mat=" << nb_env_mat
919 << " nb_cell=" << me->cells().size()
920 << " var_idx = " << env_var_idx->index()
921 << " ids=" << env_var_idx->matvarIndexes()
922 << '\n';
923 for (IMeshMaterial* mm : env_materials) {
924 const MeshMaterialVariableIndexer* idx = mm->_internalApi()->variableIndexer();
925 o << "-- Materiau\n";
926 o << "-- name = " << mm->name() << "\n";
927 o << "-- nb_cell = " << mm->cells().size() << "\n";
928 o << "-- var_idx = " << idx->index() << "\n";
929 }
930 }
931}
932
933/*---------------------------------------------------------------------------*/
934/*---------------------------------------------------------------------------*/
935
936// TODO: fusionner dumpInfos2() et dumpInfo().
937void MeshMaterialMng::
938dumpInfos2(std::ostream& o)
939{
940 const ConstituentConnectivityList& constituent_list = *m_all_env_data->componentConnectivityList();
941 ConstArrayView<Int16> nb_env_per_cell = constituent_list.cellsNbEnvironment();
942 Integer nb_mat = m_materials.size();
943 Integer nb_env = m_environments.size();
944 Integer nb_var_idx = m_variables_indexer.size();
945 o << "-- Material and Environment infos: nb_env=" << nb_env
946 << " nb_mat=" << nb_mat << " timestamp=" << m_timestamp
947 << " nb_var_idx=" << nb_var_idx
948 << "\n";
949 Integer nb_cell = mesh()->allCells().size();
950 if (nb_cell != 0) {
951 Integer nb_pure_env = 0;
952 ENUMERATE_CELL (icell, mesh()->allCells()) {
953 if (nb_env_per_cell[icell.localId()] <= 1)
954 ++nb_pure_env;
955 }
956 o << " nb_cell=" << nb_cell << " nb_pure_env=" << nb_pure_env
957 << " nb_partial=" << (nb_cell - nb_pure_env)
958 << " percent=" << (100 * nb_pure_env) / nb_cell
959 << "\n";
960 }
961
962 o << "-- Liste des milieux\n";
963 for (MeshEnvironment* me : m_true_environments) {
964 ConstArrayView<IMeshMaterial*> env_materials = me->materials();
965 const MeshMaterialVariableIndexer* env_var_idx = me->variableIndexer();
966 const Int16 env_id = me->componentId();
967 Integer nb_env_mat = env_materials.size();
968 Integer nb_env_cell = me->cells().size();
969 Integer nb_pure_mat = 0;
970 if (nb_env_mat > 1) {
971 ENUMERATE_CELL (icell, me->cells()) {
972 if (constituent_list.cellNbMaterial(icell, env_id) <= 1)
973 ++nb_pure_mat;
974 }
975 }
976 else
977 nb_pure_mat = nb_env_cell;
978 o << "-- Env name=" << me->name()
979 << " nb_mat=" << nb_env_mat
980 << " var_idx=" << env_var_idx->index()
981 << " nb_cell=" << nb_env_cell
982 << " nb_pure_mat=" << nb_pure_mat;
983 if (nb_env_cell != 0)
984 o << " percent=" << (nb_pure_mat * 100) / nb_env_cell;
985 o << '\n';
986 for (Integer j = 0; j < nb_env_mat; ++j) {
987 IMeshMaterial* mm = env_materials[j];
988 const MeshMaterialVariableIndexer* idx = mm->_internalApi()->variableIndexer();
989 o << "-- Mat name=" << mm->name()
990 << " nb_cell=" << mm->cells().size()
991 << " var_idx=" << idx->index()
992 << "\n";
993 }
994 }
995}
996
997/*---------------------------------------------------------------------------*/
998/*---------------------------------------------------------------------------*/
999
1000bool MeshMaterialMng::
1001synchronizeMaterialsInCells()
1002{
1003 return m_mms->synchronizeMaterialsInCells();
1004}
1005
1006/*---------------------------------------------------------------------------*/
1007/*---------------------------------------------------------------------------*/
1008
1009void MeshMaterialMng::
1010checkMaterialsInCells(Integer max_print)
1011{
1012 m_mms->checkMaterialsInCells(max_print);
1013}
1014
1015/*---------------------------------------------------------------------------*/
1016/*---------------------------------------------------------------------------*/
1017
1018void MeshMaterialMng::
1019dumpCellInfos(Cell cell, std::ostream& o)
1020{
1021 CellToAllEnvCellConverter all_env_cell_converter(this);
1022 AllEnvCell all_env_cell = all_env_cell_converter[cell];
1023 Cell global_cell = all_env_cell.globalCell();
1024 o << "Cell uid=" << ItemPrinter(global_cell) << '\n';
1025 ENUMERATE_CELL_ENVCELL (ienvcell, all_env_cell) {
1026 o << "ENV name=" << (*ienvcell).environment()->name()
1027 << " component_idx=" << ComponentItemLocalId(ienvcell) << '\n';
1028 ENUMERATE_CELL_MATCELL (imatcell, (*ienvcell)) {
1029 o << "MAT name=" << (*imatcell).material()->name()
1030 << " component_idx=" << ComponentItemLocalId(imatcell) << '\n';
1031 }
1032 }
1033}
1034
1035/*---------------------------------------------------------------------------*/
1036/*---------------------------------------------------------------------------*/
1037
1038CellToAllEnvCellConverter MeshMaterialMng::
1039cellToAllEnvCellConverter()
1040{
1041 return CellToAllEnvCellConverter(componentItemSharedInfo(LEVEL_ALLENVIRONMENT));
1042}
1043
1044/*---------------------------------------------------------------------------*/
1045/*---------------------------------------------------------------------------*/
1046
1047void MeshMaterialMng::
1048_checkEndCreate()
1049{
1050 if (m_is_end_create)
1051 ARCANE_FATAL("Invalid method call because endCreate() has already been called");
1052}
1053
1054/*---------------------------------------------------------------------------*/
1055/*---------------------------------------------------------------------------*/
1056
1057AllEnvCellVectorView MeshMaterialMng::
1058_view(SmallSpan<const Int32> local_ids)
1059{
1060 return AllEnvCellVectorView(local_ids.constSmallView(), componentItemSharedInfo(LEVEL_ALLENVIRONMENT));
1061}
1062
1063/*---------------------------------------------------------------------------*/
1064/*---------------------------------------------------------------------------*/
1065
1066class MeshMaterialMngFactory
1068{
1069 public:
1070
1071 MeshMaterialMngFactory()
1072 {
1073 IMeshMaterialMng::_internalSetFactory(this);
1074 }
1075 ~MeshMaterialMngFactory()
1076 {
1077 IMeshMaterialMng::_internalSetFactory(nullptr);
1078 }
1079
1080 public:
1081
1082 Ref<IMeshMaterialMng> getTrueReference(const MeshHandle& mesh_handle, bool is_create) override;
1083
1084 public:
1085
1086 static MeshMaterialMngFactory m_mesh_material_mng_factory;
1087};
1088
1089MeshMaterialMngFactory MeshMaterialMngFactory::m_mesh_material_mng_factory{};
1090
1091/*---------------------------------------------------------------------------*/
1092/*---------------------------------------------------------------------------*/
1093
1094Ref<IMeshMaterialMng> MeshMaterialMngFactory::
1095getTrueReference(const MeshHandle& mesh_handle, bool is_create)
1096{
1097 //TODO: faire lock pour multi-thread
1098 typedef AutoDestroyUserData<Ref<IMeshMaterialMng>> UserDataType;
1099
1100 const char* name = "MeshMaterialMng_StdMat";
1101 IUserDataList* udlist = mesh_handle.meshUserDataList();
1102
1103 IUserData* ud = udlist->data(name, true);
1104 if (!ud) {
1105 if (!is_create)
1106 return {};
1107 IMeshMaterialMng* mm = arcaneCreateMeshMaterialMng(mesh_handle, "StdMat");
1108 Ref<IMeshMaterialMng> mm_ref = makeRef(mm);
1109 udlist->setData(name, new UserDataType(new Ref<IMeshMaterialMng>(mm_ref)));
1110 return mm_ref;
1111 }
1112 auto adud = dynamic_cast<UserDataType*>(ud);
1113 if (!adud)
1114 ARCANE_FATAL("Can not cast to IMeshMaterialMng*");
1115 return *(adud->data());
1116}
1117
1118/*---------------------------------------------------------------------------*/
1119/*---------------------------------------------------------------------------*/
1120
1121bool MeshMaterialMng::
1122isInMeshMaterialExchange() const
1123{
1124 return m_exchange_mng->isInMeshMaterialExchange();
1125}
1126
1127/*---------------------------------------------------------------------------*/
1128/*---------------------------------------------------------------------------*/
1129
1130void MeshMaterialMng::
1131_checkCreateProperties()
1132{
1133 if (m_properties)
1134 return;
1135 m_properties = std::make_unique<Properties>(*(mesh()->properties()), String("MeshMaterialMng_") + name());
1136}
1137
1138/*---------------------------------------------------------------------------*/
1139/*---------------------------------------------------------------------------*/
1140namespace
1141{
1142 const Int32 SERIALIZE_VERSION = 1;
1143}
1144void MeshMaterialMng::
1145_saveInfosInProperties()
1146{
1147 _checkCreateProperties();
1148
1149 // Sauve le numéro de version pour être certain que c'est OK en reprise
1150 m_properties->set("Version", SERIALIZE_VERSION);
1151
1152 // Sauve dans les propriétés les infos nécessaires pour recréer les
1153 // matériaux et milieux.
1154 UniqueArray<String> material_info_names;
1155 for (MeshMaterialInfo* mat_info : m_materials_info) {
1156 material_info_names.add(mat_info->name());
1157 }
1158 m_properties->set("MaterialInfoNames", material_info_names);
1159
1160 UniqueArray<String> env_names;
1161 UniqueArray<Int32> env_nb_mat;
1162 UniqueArray<String> env_mat_names;
1163 ENUMERATE_ENV (ienv, this) {
1164 IMeshEnvironment* env = *ienv;
1165 env_names.add(env->name());
1166 info(5) << "SAVE ENV_NAME name=" << env->name() << " nb_mat=" << env->nbMaterial();
1167 env_nb_mat.add(env->nbMaterial());
1168 ENUMERATE_MAT (imat, env) {
1169 const String& name = (*imat)->infos()->name();
1170 info(5) << "SAVE MAT_NAME name=" << name;
1171 env_mat_names.add(name);
1172 }
1173 }
1174 m_properties->set("EnvNames", env_names);
1175 m_properties->set("EnvNbMat", env_nb_mat);
1176 m_properties->set("EnvMatNames", env_mat_names);
1177
1178 // Sauve les infos nécessaires pour les block.
1179 // Pour chaque bloc, son nom et le nom du groupe de maille correspondant.
1180 UniqueArray<String> block_names;
1181 UniqueArray<String> block_cell_group_names;
1182 UniqueArray<Int32> block_nb_env;
1183 UniqueArray<String> block_env_names;
1184 for (IMeshBlock* block : m_blocks) {
1185 block_names.add(block->name());
1186 block_cell_group_names.add(block->cells().name());
1187 block_nb_env.add(block->nbEnvironment());
1188 ENUMERATE_ENV (ienv, block) {
1189 const String& name = (*ienv)->name();
1190 info(5) << "SAVE BLOCK ENV_NAME name=" << name;
1191 block_env_names.add(name);
1192 }
1193 }
1194 m_properties->set("BlockNames", block_names);
1195 m_properties->set("BlockCellGroupNames", block_cell_group_names);
1196 m_properties->set("BlockNbEnv", block_nb_env);
1197 m_properties->set("BlockEnvNames", block_env_names);
1198}
1199
1200/*---------------------------------------------------------------------------*/
1201/*---------------------------------------------------------------------------*/
1202
1203void MeshMaterialMng::
1204recreateFromDump()
1205{
1206 if (m_is_end_create)
1207 ARCANE_FATAL("Can not recreate a created instance");
1208
1209 _checkCreateProperties();
1210
1211 info() << "Creating material infos from dump";
1212
1213 // Sauve le numéro de version pour être sur que c'est OK en reprise
1214 Int32 v = m_properties->getInt32("Version");
1215 if (v != SERIALIZE_VERSION)
1216 ARCANE_FATAL("Bad serializer version: trying to read from incompatible checkpoint v={0} expected={1}",
1217 v, SERIALIZE_VERSION);
1218
1219 UniqueArray<String> material_info_names;
1220 m_properties->get("MaterialInfoNames", material_info_names);
1221 for (const String& mat_name : material_info_names)
1222 this->registerMaterialInfo(mat_name);
1223
1224 UniqueArray<String> env_names;
1225 UniqueArray<Int32> env_nb_mat;
1226 UniqueArray<String> env_mat_names;
1227 m_properties->get("EnvNames", env_names);
1228 m_properties->get("EnvNbMat", env_nb_mat);
1229 m_properties->get("EnvMatNames", env_mat_names);
1230
1231 Integer mat_index = 0;
1232 for (Integer ienv = 0, nenv = env_names.size(); ienv < nenv; ++ienv) {
1233 Materials::MeshEnvironmentBuildInfo env_build(env_names[ienv]);
1234 Integer nb_mat = env_nb_mat[ienv];
1235 for (Integer imat = 0; imat < nb_mat; ++imat) {
1236 env_build.addMaterial(env_mat_names[mat_index]);
1237 ++mat_index;
1238 }
1239 this->createEnvironment(env_build);
1240 }
1241
1242 // Recréé les blocs.
1243 // Pour chaque bloc, son nom et le nom du groupe de maille correspondant.
1244 UniqueArray<String> block_names;
1245 UniqueArray<String> block_cell_group_names;
1246 UniqueArray<String> block_env_names;
1247 UniqueArray<Int32> block_nb_env;
1248 m_properties->get("BlockNames", block_names);
1249 m_properties->get("BlockCellGroupNames", block_cell_group_names);
1250 m_properties->get("BlockNbEnv", block_nb_env);
1251 m_properties->get("BlockEnvNames", block_env_names);
1252 const IItemFamily* cell_family = mesh()->cellFamily();
1253 Integer block_env_index = 0;
1254 for (Integer i = 0, n = block_names.size(); i < n; ++i) {
1255 String name = block_names[i];
1256 String cell_group_name = block_cell_group_names[i];
1257 CellGroup cells = cell_family->findGroup(cell_group_name);
1258 if (cells.null())
1259 ARCANE_FATAL("Can not find cell group '{0}' for block creation",
1260 cell_group_name);
1261 MeshBlockBuildInfo mbbi(name, cells);
1262 if (!block_nb_env.empty()) {
1263 Integer nb_env = block_nb_env[i];
1264 for (Integer ienv = 0; ienv < nb_env; ++ienv) {
1265 const String& name2 = block_env_names[block_env_index];
1266 ++block_env_index;
1267 IMeshEnvironment* env = findEnvironment(name2, false);
1268 if (!env)
1269 ARCANE_FATAL("Invalid environment name '{0}' for recreating blocks", name2);
1270 mbbi.addEnvironment(env);
1271 }
1272 }
1273 this->createBlock(mbbi);
1274 }
1275
1276 endCreate(true);
1277}
1278
1279/*---------------------------------------------------------------------------*/
1280/*---------------------------------------------------------------------------*/
1281
1282void MeshMaterialMng::
1283_onMeshDestroyed()
1284{
1285 // Il faut détruire cette instance ici car elle a besoin de IItemFamily
1286 // dans son destructeur et il est possible qu'il n'y ait plus de famille
1287 // si le destructeur de IMeshMaterialMng est appelé après la destruction
1288 // du maillage (ce qui peut arriver en C# par exemple).
1289 m_exchange_mng.reset();
1290
1291 _unregisterAllVariables();
1292}
1293
1294/*---------------------------------------------------------------------------*/
1295/*---------------------------------------------------------------------------*/
1296
1297void MeshMaterialMng::
1298_unregisterAllVariables()
1299{
1300 // Recopie dans un tableau toutes les références.
1301 // Il faut le faire avant les appels à unregisterVariable()
1302 // car ces derniers modifient la liste chainée des références
1303 UniqueArray<MeshMaterialVariableRef*> m_all_refs;
1304
1305 for (const auto& i : m_full_name_variable_map) {
1306 const IMeshMaterialVariable* var = i.second;
1307
1308 for (MeshMaterialVariableRef::Enumerator iref(var); iref.hasNext(); ++iref) {
1309 MeshMaterialVariableRef* ref = *iref;
1310 m_all_refs.add(ref);
1311 }
1312 }
1313
1314 for (MeshMaterialVariableRef* ref : m_all_refs)
1315 ref->unregisterVariable();
1316}
1317
1318/*---------------------------------------------------------------------------*/
1319/*---------------------------------------------------------------------------*/
1320
1321ComponentItemSharedInfo* MeshMaterialMng::
1322componentItemSharedInfo(Int32 level) const
1323{
1324 ComponentItemInternalData* data = m_all_env_data->componentItemInternalData();
1325 ComponentItemSharedInfo* shared_info = nullptr;
1326 if (level == LEVEL_MATERIAL)
1327 shared_info = data->matSharedInfo();
1328 else if (level == LEVEL_ENVIRONMENT)
1329 shared_info = data->envSharedInfo();
1330 else if (level == LEVEL_ALLENVIRONMENT)
1331 shared_info = data->allEnvSharedInfo();
1332 else
1333 ARCANE_FATAL("Bad internal type of component");
1334
1335 return shared_info;
1336}
1337
1338/*---------------------------------------------------------------------------*/
1339/*---------------------------------------------------------------------------*/
1340
1341void MeshMaterialMng::
1342_dumpStats()
1343{
1344 IEnumeratorTracer* tracer = IEnumeratorTracer::singleton();
1345 if (tracer)
1346 tracer->dumpStats();
1347
1348 if (m_modifier)
1349 m_modifier->dumpStats();
1350
1351 for (IMeshEnvironment* env : m_environments) {
1352 // N'affiche pas les statistiques si le milieu n'a qu'un seul matériau
1353 // car il utilise le même indexeur que la matériau et les statistiques
1354 // pour ce dernier seront affichées lors du parcours des matériaux.
1355 if (env->nbMaterial() > 1)
1356 env->_internalApi()->variableIndexer()->dumpStats();
1357 }
1358 for (IMeshMaterial* mat : m_materials) {
1359 mat->_internalApi()->variableIndexer()->dumpStats();
1360 }
1361}
1362
1363/*---------------------------------------------------------------------------*/
1364/*---------------------------------------------------------------------------*/
1365
1366void MeshMaterialMng::
1367createAllCellToAllEnvCell()
1368{
1369 if (!m_accelerator_envcell_container) {
1370 m_accelerator_envcell_container = std::make_unique<AllCellToAllEnvCellContainer>(this);
1371 m_accelerator_envcell_container->initialize();
1372 }
1373}
1374
1375/*---------------------------------------------------------------------------*/
1376/*---------------------------------------------------------------------------*/
1377
1378SmallSpan<const Int32> MeshMaterialMng::
1379identitySelectionView()
1380{
1381 // NOTE : ce tableau pourrait peut-être être géré directement
1382 // par la famille s'il y a un intérêt à l'utiliser dans d'autres contextes
1383 Int32 max_local_id = m_mesh_handle.mesh()->cellFamily()->maxLocalId();
1384 {
1385 std::scoped_lock sl(m_indexed_selection_identity_mutex);
1386 Int32 size = m_indexed_selection_identity.size();
1387 if (max_local_id > size) {
1388 m_indexed_selection_identity.resize(max_local_id);
1389 for (Int32 i = size; i < max_local_id; ++i)
1390 m_indexed_selection_identity[i] = i;
1391 }
1392 return m_indexed_selection_identity.constView();
1393 }
1394}
1395
1396/*---------------------------------------------------------------------------*/
1397/*---------------------------------------------------------------------------*/
1398
1399} // End namespace Arcane::Materials
1400
1401/*---------------------------------------------------------------------------*/
1402/*---------------------------------------------------------------------------*/
#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.
#define ENUMERATE_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
Fonctions de gestion mémoire et des allocateurs.
UserData s'auto-détruisant une fois détaché.
Interface d'une liste qui gère des données utilisateurs.
virtual void setData(const String &name, IUserData *ud)=0
Positionne le user-data associé au nom name.
virtual IUserData * data(const String &name, bool allow_null=false) const =0
Donnée associée à name.
Interface pour une donnée utilisateur attachée à un autre objet.
Definition IUserData.h:31
Interface du gestionnaire des matériaux et des milieux d'un maillage.
Handle sur un maillage.
Definition MeshHandle.h:47
IUserDataList * meshUserDataList() const
Données utilisateurs associées.
Definition MeshHandle.h:157
Référence à une instance.
#define ENUMERATE_ENV(ienv, container)
Macro pour itérer sur une liste de milieux.
#define ENUMERATE_CELL_MATCELL(iname, env_cell)
Macro pour itérer sur toutes les mailles MatCell d'une maille.
#define ENUMERATE_CELL_ENVCELL(iname, all_env_cell)
Macro pour itérer sur toutes les mailles EnvCell d'une maille.
#define ENUMERATE_ALLENVCELL(iname,...)
Macro pour itérer sur toutes les mailles AllEnvCell d'un groupe.
#define ENUMERATE_MAT(imat, container)
Macro pour itérer sur une liste de matériaux.
ItemGroupT< Cell > CellGroup
Groupe de mailles.
Definition ItemTypes.h:183
RunQueue makeQueue(const Runner &runner)
Créé une file associée à runner.
eExecutionPolicy
Politique d'exécution pour un Runner.
@ Sequential
Politique d'exécution séquentielle.
@ Thread
Politique d'exécution multi-thread.
bool isAcceleratorPolicy(eExecutionPolicy exec_policy)
Indique si exec_policy correspond à un accélérateur.
Active toujours les traces dans les parties Arcane concernant les matériaux.
IMemoryAllocator * getDefaultDataAllocator()
Allocateur par défaut pour les données.
bool arcaneIsCheck()
Vrai si on est en mode vérification.
Definition Misc.cc:68
Int32 Integer
Type représentant un entier.
@ Cell
Le maillage est AMR par maille.
Definition MeshKind.h:52
Fonctions utilitaires de gestion mémoire.