Arcane  4.1.11.0
Documentation développeur
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/*---------------------------------------------------------------------------*/
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/*---------------------------------------------------------------------------*/
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/*---------------------------------------------------------------------------*/
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();
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/*---------------------------------------------------------------------------*/
695void MeshMaterialMng::
696_endUpdate()
697{
698 m_all_env_data->forceRecompute(true);
699}
700
701/*---------------------------------------------------------------------------*/
702/*---------------------------------------------------------------------------*/
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::
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
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 {
1065 }
1066 ~MeshMaterialMngFactory()
1067 {
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
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.
Integer size() const
Nombre d'éléments du vecteur.
bool empty() const
Capacité (nombre d'éléments alloués) du vecteur.
Tableau d'items de types quelconques.
void clear()
Supprime les éléments du tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
UserData s'auto-détruisant une fois détaché.
Maille d'un maillage.
Definition Item.h:1214
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Interface d'un fonctor avec argument mais sans valeur de retour.
Interface d'une famille d'entités.
Definition IItemFamily.h:84
virtual ItemGroup findGroup(const String &name) const =0
Recherche un groupe.
virtual ItemGroup allItems() const =0
Groupe de toutes les entités.
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 d'une variable.
Definition IVariable.h:39
virtual String fullName() const =0
Nom complet de la variable (avec le préfixe de la famille).
virtual bool isUsed() const =0
Etat d'utilisation de la variable.
Groupe d'entités de maillage.
Definition ItemGroup.h:49
ItemVectorView view() const
Vue sur les entités du groupe.
Definition ItemGroup.cc:583
bool null() const
true is le groupe est le groupe nul
Definition ItemGroup.h:70
Classe utilitaire pour imprimer les infos sur une entité.
Definition ItemPrinter.h:34
Int32ConstArrayView localIds() const
Tableau des numéros locaux des entités.
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:219
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:225
Vue sur une liste de mailles avec infos sur les milieux.
Maille arcane avec info matériaux et milieux.
__host__ __device__ Int32 nbEnvironment() const
Nombre de milieux présents dans la maille.
EnvCell cell(Int32 i) const
i-ème maille milieu
Gestion des listes de connectivité des constituants.
Int16 cellNbMaterial(CellLocalId cell_id, Int16 env_id)
Nombre de matériaux de la maille cell_id pour le milieu d'indice env_id.
Cell globalCell() const
Maille globale.
__host__ __device__ Int32 level() const
Niveau hiérarchique de l'entité
__host__ __device__ MatVarIndex _varIndex() const
Maille arcane d'un milieu.
__host__ __device__ MatCell cell(Integer i) const
i-ème maille matériau de cette maille
Interface d'un bloc d'un maillage.
virtual String name() const =0
Nom du composant.
Interface du gestionnaire des matériaux et des milieux d'un maillage.
static void _internalSetFactory(IFactory *f)
Interface du gestionnaire de fabrique de variables matériaux.
virtual void syncReferences(bool check_resize)=0
Synchronise les références.
Interface d'une variable matériau d'un maillage.
virtual IVariable * globalVariable() const =0
Variable globale sur le maillage associée.
virtual String name() const =0
Nom de la variable.
virtual void buildFromManager(bool is_continue)=0
Construit les infos de la variable. A usage interne à Arcane.
Interface d'un matériau d'un maillage.
Représente un matériau d'une maille multi-matériau.
IMeshMaterial * material() const
Materiau associé
constexpr __host__ __device__ Int32 arrayIndex() const
Retourne l'indice du tableau de valeur dans la liste des variables.
Informations pour la création d'un milieu.
void addMaterial(const String &name)
Ajoute le matériau de nom name au milieu.
const String & name() const
Nom du milieu.
void build()
Fonctions publiques mais réservées au IMeshMaterialMng.
ConstArrayView< IMeshMaterial * > materials() override
Liste des matériaux de ce milieu.
IMeshMaterialMng * materialMng() override
Gestionnaire associé.
String name() const override
Nom du composant.
Infos d'un matériau d'un maillage.
IMeshMaterialMng * materialMng()
Gestionnaire associé.
Implémentation d'un gestion des matériaux.
AllEnvCellVectorView view(const CellGroup &cells) final
Vue sur les mailles milieux correspondant au groupe cells.
void endCreate(bool is_continue) override
Indique qu'on a fini de créer les milieux.
IMeshBlock * createBlock(const MeshBlockBuildInfo &infos) override
Créé un bloc.
ITraceMng * traceMng() override
Gestionnaire de traces.
IMesh * mesh() override
Maillage associé.
MeshMaterialInfo * registerMaterialInfo(const String &name) override
Enregistre les infos du matériau de nom name.
IMeshEnvironment * createEnvironment(const MeshEnvironmentBuildInfo &infos) override
Création d'un milieu.
void _endUpdate()
Remise à jour des structures suite à une modification des mailles de matériaux ou de milieux.
IMeshEnvironment * findEnvironment(const String &name, bool throw_exception=true) override
Retourne le milieux de nom name.
MeshMaterial * _createMaterial(MeshEnvironment *env, MeshMaterialInfo *infos, const String &name)
Création d'un matériau.
String name() const override
Nom du gestionnaire.
const String & name() const
Nom de l'indexeur.
Classe de base des références aux variables matériaux.
Matériau d'un maillage.
void build()
Fonctions publiques mais réservées au IMeshMaterialMng.
Informations génériques sur une entité d'un constituant.
__host__ __device__ matimpl::ConstituentItemBase _superItemBase() const
Composant supérieur (0 si aucun).
impl::ItemBase globalItemBase() const
Entité globale correspondante.
Informations pour la création d'un bloc.
ConstArrayView< IMeshEnvironment * > environments() const
Liste des milieux du bloc.
void addEnvironment(IMeshEnvironment *env)
Ajoute le milieu env au bloc.
const String & name() const
Nom du bloc.
Bloc d'un maillage.
Definition MeshBlock.h:50
void removeEnvironment(IMeshEnvironment *env)
Supprime le milieu env au bloc.
Definition MeshBlock.cc:92
void build()
Fonctions publiques mais réservées au IMeshMaterialMng.
Definition MeshBlock.cc:52
void addEnvironment(IMeshEnvironment *env)
Ajoute le milieu env au bloc.
Definition MeshBlock.cc:74
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.
Vue d'un tableau d'éléments de type T.
Definition Span.h:801
constexpr ConstArrayView< value_type > constSmallView() const
Vue constante sur cette vue.
Definition Span.h:399
Chaîne de caractères unicode.
TraceMessage info() const
Flot pour un message d'information.
Vecteur 1D de données avec sémantique par valeur (style STL).
#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.
@ Environment
Variable ayant des valeurs uniquement sur les milieux.
@ MaterialAndEnvironment
Variable ayant des valeurs sur les milieux et 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
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
std::int16_t Int16
Type entier signé sur 16 bits.
std::int32_t Int32
Type entier signé sur 32 bits.
Fonctions utilitaires de gestion mémoire.