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