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