Arcane  v3.16.7.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
MeshMaterialMng.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-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/*---------------------------------------------------------------------------*/
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/*---------------------------------------------------------------------------*/
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/*---------------------------------------------------------------------------*/
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();
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/*---------------------------------------------------------------------------*/
694void MeshMaterialMng::
695_endUpdate()
696{
697 m_all_env_data->forceRecompute(true);
698}
699
700/*---------------------------------------------------------------------------*/
701/*---------------------------------------------------------------------------*/
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::
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
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 {
1063 }
1064 ~MeshMaterialMngFactory()
1065 {
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
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.
Integer size() const
Nombre d'éléments du vecteur.
bool empty() const
Capacité (nombre d'éléments alloués) du vecteur.
Tableau d'items de types quelconques.
void clear()
Supprime les éléments du tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
UserData s'auto-détruisant une fois détaché.
Maille d'un maillage.
Definition Item.h:1205
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Interface d'un fonctor avec argument mais sans valeur de retour.
Interface d'une famille d'entités.
Definition IItemFamily.h:84
virtual ItemGroup findGroup(const String &name) const =0
Recherche un groupe.
virtual ItemGroup allItems() const =0
Groupe de toutes les entités.
Interface d'une liste qui gère des données utilisateurs.
virtual void setData(const String &name, IUserData *ud)=0
Positionne le user-data associé au nom name.
virtual IUserData * data(const String &name, bool allow_null=false) const =0
Donnée associée à name.
Interface pour une donnée utilisateur attachée à un autre objet.
Definition IUserData.h:31
Interface d'une variable.
Definition IVariable.h:39
virtual String fullName() const =0
Nom complet de la variable (avec le préfixe de la famille)
virtual bool isUsed() const =0
Etat d'utilisation de la variable.
Groupe d'entités de maillage.
Definition ItemGroup.h:49
ItemVectorView view() const
Vue sur les entités du groupe.
Definition ItemGroup.cc:583
bool null() const
true is le groupe est le groupe nul
Definition ItemGroup.h:70
Classe utilitaire pour imprimer les infos sur une entité.
Definition ItemPrinter.h:35
Int32ConstArrayView localIds() const
Tableau des numéros locaux des entités.
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:219
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:225
Vue sur une liste de mailles avec infos sur les milieux.
Maille arcane avec info matériaux et milieux.
__host__ __device__ Int32 nbEnvironment() const
Nombre de milieux présents dans la maille.
EnvCell cell(Int32 i) const
i-ème maille milieu
Gestion des listes de connectivité des constituants.
Int16 cellNbMaterial(CellLocalId cell_id, Int16 env_id)
Nombre de matériaux de la maille cell_id pour le milieu d'indice env_id.
Cell globalCell() const
Maille globale.
__host__ __device__ Int32 level() const
Niveau hiérarchique de l'entité
__host__ __device__ MatVarIndex _varIndex() const
Maille arcane d'un milieu.
__host__ __device__ MatCell cell(Integer i) const
i-ème maille matériau de cette maille
Interface d'un bloc d'un maillage.
virtual String name() const =0
Nom du composant.
Interface du gestionnaire des matériaux et des milieux d'un maillage.
static void _internalSetFactory(IFactory *f)
Interface du gestionnaire de fabrique de variables matériaux.
virtual void syncReferences(bool check_resize)=0
Synchronise les références.
Interface d'une variable matériau d'un maillage.
virtual IVariable * globalVariable() const =0
Variable globale sur le maillage associée.
virtual String name() const =0
Nom de la variable.
virtual void buildFromManager(bool is_continue)=0
Construit les infos de la variable. A usage interne à Arcane.
Interface d'un matériau d'un maillage.
Représente un matériau d'une maille multi-matériau.
IMeshMaterial * material() const
Materiau associé
constexpr __host__ __device__ Int32 arrayIndex() const
Retourne l'indice du tableau de valeur dans la liste des variables.
Informations pour la création d'un milieu.
void addMaterial(const String &name)
Ajoute le matériau de nom name au milieu.
const String & name() const
Nom du milieu.
void build()
Fonctions publiques mais réservées au IMeshMaterialMng.
ConstArrayView< IMeshMaterial * > materials() override
Liste des matériaux de ce milieu.
IMeshMaterialMng * materialMng() override
Gestionnaire associé.
String name() const override
Nom du composant.
Infos d'un matériau d'un maillage.
IMeshMaterialMng * materialMng()
Gestionnaire associé.
Implémentation d'un gestion des matériaux.
AllEnvCellVectorView view(const CellGroup &cells) final
Vue sur les mailles milieux correspondant au groupe cells.
void endCreate(bool is_continue) override
Indique qu'on a fini de créer les milieux.
IMeshBlock * createBlock(const MeshBlockBuildInfo &infos) override
Créé un bloc.
ITraceMng * traceMng() override
Gestionnaire de traces.
IMesh * mesh() override
Maillage associé.
MeshMaterialInfo * registerMaterialInfo(const String &name) override
Enregistre les infos du matériau de nom name.
IMeshEnvironment * createEnvironment(const MeshEnvironmentBuildInfo &infos) override
Création d'un milieu.
void _endUpdate()
Remise à jour des structures suite à une modification des mailles de matériaux ou de milieux.
IMeshEnvironment * findEnvironment(const String &name, bool throw_exception=true) override
Retourne le milieux de nom name.
MeshMaterial * _createMaterial(MeshEnvironment *env, MeshMaterialInfo *infos, const String &name)
Création d'un matériau.
String name() const override
Nom du gestionnaire.
const String & name() const
Nom de l'indexeur.
Classe de base des références aux variables matériaux.
Matériau d'un maillage.
void build()
Fonctions publiques mais réservées au IMeshMaterialMng.
Informations génériques sur une entité d'un constituant.
__host__ __device__ matimpl::ConstituentItemBase _superItemBase() const
Composant supérieur (0 si aucun)
impl::ItemBase globalItemBase() const
Entité globale correspondante.
Informations pour la création d'un bloc.
ConstArrayView< IMeshEnvironment * > environments() const
Liste des milieux du bloc.
void addEnvironment(IMeshEnvironment *env)
Ajoute le milieu env au bloc.
const String & name() const
Nom du bloc.
Bloc d'un maillage.
Definition MeshBlock.h:50
void removeEnvironment(IMeshEnvironment *env)
Supprime le milieu env au bloc.
Definition MeshBlock.cc:92
void build()
Fonctions publiques mais réservées au IMeshMaterialMng.
Definition MeshBlock.cc:52
void addEnvironment(IMeshEnvironment *env)
Ajoute le milieu env au bloc.
Definition MeshBlock.cc:74
Handle sur un maillage.
Definition MeshHandle.h:47
IUserDataList * meshUserDataList() const
Données utilisateurs associées.
Definition MeshHandle.h:157
Référence à une instance.
Vue d'un tableau d'éléments de type T.
Definition Span.h:673
constexpr ConstArrayView< value_type > constSmallView() const
Vue constante sur cette vue.
Definition Span.h:282
Chaîne de caractères unicode.
TraceMessage info() const
Flot pour un message d'information.
Vecteur 1D de données avec sémantique par valeur (style STL).
#define ENUMERATE_ENV(ienv, container)
Macro pour itérer sur une liste de milieux.
#define ENUMERATE_CELL_MATCELL(iname, env_cell)
Macro pour itérer sur tous les matériaux d'une maille.
#define ENUMERATE_CELL_ENVCELL(iname, all_env_cell)
Macro pour itérer sur tous les milieux d'une maille.
#define ENUMERATE_ALLENVCELL(iname,...)
Macro pour itérer sur toutes les mailles AllEnvCell d'un groupe.
#define ENUMERATE_MAT(imat, container)
Macro pour itérer sur une liste de matériaux.
ItemGroupT< Cell > CellGroup
Groupe de mailles.
Definition ItemTypes.h:183
RunQueue makeQueue(const Runner &runner)
Créé une file associée à runner.
eExecutionPolicy
Politique d'exécution pour un Runner.
@ Sequential
Politique d'exécution séquentielle.
@ Thread
Politique d'exécution multi-thread.
bool isAcceleratorPolicy(eExecutionPolicy exec_policy)
Indique si exec_policy correspond à un accélérateur.
Int16 toInt16(Int64 v)
Converti un Int64 en un Int16.
Active toujours les traces dans les parties Arcane concernant les matériaux.
@ Environment
Variable ayant des valeurs uniquement sur les milieux.
@ MaterialAndEnvironment
Variable ayant des valeurs sur les milieux et matériaux.
bool arcaneIsCheck()
Vrai si on est en mode vérification.
Definition Misc.cc:68
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
std::int16_t Int16
Type entier signé sur 16 bits.
std::int32_t Int32
Type entier signé sur 32 bits.