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