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