Arcane  v3.16.3.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();
438 for( Integer i=0; i<nb_mat; ++i ){
439 const MeshEnvironmentBuildInfo::MatInfo& buildinfo = infos.materials()[i];
440 const String& mat_name = buildinfo.m_name;
441 String new_mat_name = env_name + "_" + mat_name;
442 MeshMaterialInfo* mat_info = _findMaterialInfo(mat_name);
443 if (!mat_info){
444 ARCANE_FATAL("Aucun matériau de nom '{0}' n'est défini",mat_name);
445 }
446 MeshMaterial* mm = _createMaterial(me,mat_info,new_mat_name);
447 me->addMaterial(mm);
448 mat_info->_addEnvironment(env_name);
449 }
450 // Si le milieu contient plusieurs matériaux, il faut lui allouer
451 // des valeurs partielles. Sinon, ses valeurs partielles sont celles
452 // de son unique matériau.
453 {
454 MeshMaterialVariableIndexer* var_idx = nullptr;
455 if (nb_mat==1){
456 var_idx = me->materials()[0]->_internalApi()->variableIndexer();
457 }
458 else{
459 var_idx = new MeshMaterialVariableIndexer(traceMng(),me->name());
460 _addVariableIndexer(var_idx);
461 m_variables_indexer_to_destroy.add(var_idx);
462 }
463 me->setVariableIndexer(var_idx);
464 }
465 return me;
466}
467
468/*---------------------------------------------------------------------------*/
469/*---------------------------------------------------------------------------*/
470
471IMeshBlock* MeshMaterialMng::
472createBlock(const MeshBlockBuildInfo& infos)
473{
474 _checkEndCreate();
475
476 Int32 block_index = m_blocks.size();
477 // Vérifie qu'un bloc de même nom n'existe pas.
478 const String& name = infos.name();
479 const MeshBlock* old_mb = _findBlock(name);
480 if (old_mb)
481 ARCANE_FATAL("Un bloc de nom '{0}' est déjà enregistré",name);
482
483 info() << "Creating block name=" << name << " index=" << block_index
484 << " nb_env=" << infos.environments().size();
485 Integer nb_env = infos.environments().size();
486 for( Integer i=0; i<nb_env; ++i )
487 info() << " Adding environment name=" << infos.environments()[i]->name() << " to block";
488
489 // Créé le bloc
490 MeshBlock* mb = new MeshBlock(this,block_index,infos);
491 mb->build();
492 m_true_blocks.add(mb);
493 m_blocks.add(mb);
494
495 return mb;
496}
497
498/*---------------------------------------------------------------------------*/
499/*---------------------------------------------------------------------------*/
500
501void MeshMaterialMng::
502addEnvironmentToBlock(IMeshBlock* block,IMeshEnvironment* env)
503{
504 MeshBlock* mb = ARCANE_CHECK_POINTER(dynamic_cast<MeshBlock*>(block));
505 mb->addEnvironment(env);
506}
507
508/*---------------------------------------------------------------------------*/
509/*---------------------------------------------------------------------------*/
510
511void MeshMaterialMng::
512removeEnvironmentToBlock(IMeshBlock* block,IMeshEnvironment* env)
513{
514 MeshBlock* mb = ARCANE_CHECK_POINTER(dynamic_cast<MeshBlock*>(block));
515 mb->removeEnvironment(env);
516}
517
518/*---------------------------------------------------------------------------*/
519/*---------------------------------------------------------------------------*/
520
521void MeshMaterialMng::
522endCreate(bool is_continue)
523{
524 if (m_is_end_create)
525 return;
526
527 _saveInfosInProperties();
528
529 info() << "END CREATE MATERIAL_MNG is_continue=" << is_continue;
530
531 m_modifier = std::make_unique<MeshMaterialModifierImpl>(this);
532 m_modifier->initOptimizationFlags();
533
534 m_all_env_data->endCreate(is_continue);
535
536 auto synchronizer = mesh()->cellFamily()->allItemsSynchronizer();
537 m_all_cells_mat_env_synchronizer = std::make_unique<MeshMaterialVariableSynchronizer>(this,synchronizer,MatVarSpace::MaterialAndEnvironment);
538 m_all_cells_env_only_synchronizer = std::make_unique<MeshMaterialVariableSynchronizer>(this,synchronizer,MatVarSpace::Environment);
539
540 // Détermine la liste de tous les composants.
541 {
542 Integer nb_component = m_environments_as_components.size() + m_materials_as_components.size();
543 m_components.reserve(nb_component);
544 m_components.addRange(m_environments_as_components);
545 m_components.addRange(m_materials_as_components);
546 }
547
548 // Il faut construire et initialiser les variables qui ont été
549 // créées avant cette allocation.
550 for( const auto& i : m_full_name_variable_map ){
551 IMeshMaterialVariable* mv = i.second;
552 info(4) << "BUILD FROM MANAGER name=" << mv->name() << " this=" << this;
553 mv->buildFromManager(is_continue);
554 }
555 if (is_continue)
556 _endUpdate();
557 m_is_end_create = true;
558
559 // Vérifie que les milieux sont valides.
560 // NOTE: on ne peut pas toujours appeler checkValid()
561 // (notamment au démarrage) car les groupes d'entités existent,
562 // mais les infos matériaux associées ne sont pas
563 // forcément encore créés.
564 // (Il faudra regarder une si cela est dû au mode compatible ou pas).
565 for( IMeshEnvironment* env : m_environments ){
566 env->checkValid();
567 }
568
569 // Maintenant que tout est créé, il est valide d'enregistrer les mécanismes
570 // d'échange.
571 m_exchange_mng->registerFactory();
572}
573
574/*---------------------------------------------------------------------------*/
575/*---------------------------------------------------------------------------*/
576
577void MeshMaterialMng::
578setModificationFlags(int v)
579{
580 _checkEndCreate();
581 m_modification_flags = v;
582 info() << "Setting ModificationFlags to v=" << v;
583}
584
585/*---------------------------------------------------------------------------*/
586/*---------------------------------------------------------------------------*/
587
588void MeshMaterialMng::
589setAllocateScalarEnvironmentVariableAsMaterial(bool v)
590{
591 _checkEndCreate();
592 m_is_allocate_scalar_environment_variable_as_material = v;
593 info() << "Setting AllocateScalarEnvironmentVariableAsMaterial to v=" << v;
594}
595
596/*---------------------------------------------------------------------------*/
597/*---------------------------------------------------------------------------*/
598
599void MeshMaterialMng::
600setDataCompressorServiceName(const String& name)
601{
602 m_data_compressor_service_name = name;
603}
604
605/*---------------------------------------------------------------------------*/
606/*---------------------------------------------------------------------------*/
607
608MeshMaterialModifierImpl* MeshMaterialMng::
609_modifier()
610{
611 return m_modifier.get();
612}
613
614/*---------------------------------------------------------------------------*/
615/*---------------------------------------------------------------------------*/
616
617MeshMaterialInfo* MeshMaterialMng::
618_findMaterialInfo(const String& name)
619{
620 for( MeshMaterialInfo* mmi : m_materials_info )
621 if (mmi->name()==name)
622 return mmi;
623 return nullptr;
624}
625
626/*---------------------------------------------------------------------------*/
627/*---------------------------------------------------------------------------*/
628
629IMeshEnvironment* MeshMaterialMng::
630findEnvironment(const String& name,bool throw_exception)
631{
632 IMeshEnvironment* env = _findEnvironment(name);
633 if (env)
634 return env;
635 if (throw_exception)
636 ARCANE_FATAL("No environment named '{0}'",name);
637 return nullptr;
638}
639
640/*---------------------------------------------------------------------------*/
641/*---------------------------------------------------------------------------*/
642
643MeshEnvironment* MeshMaterialMng::
644_findEnvironment(const String& name)
645{
646 for( MeshEnvironment* env : m_true_environments )
647 if (env->name()==name)
648 return env;
649 return nullptr;
650}
651
652/*---------------------------------------------------------------------------*/
653/*---------------------------------------------------------------------------*/
654
655IMeshBlock* MeshMaterialMng::
656findBlock(const String& name,bool throw_exception)
657{
658 IMeshBlock* block = _findBlock(name);
659 if (block)
660 return block;
661 if (throw_exception)
662 ARCANE_FATAL("No block named '{0}'",name);
663 return nullptr;
664}
665
666/*---------------------------------------------------------------------------*/
667/*---------------------------------------------------------------------------*/
668
669MeshBlock* MeshMaterialMng::
670_findBlock(const String& name)
671{
672 for( MeshBlock* b : m_true_blocks )
673 if (b->name()==name)
674 return b;
675 return nullptr;
676}
677
678/*---------------------------------------------------------------------------*/
679/*---------------------------------------------------------------------------*/
680
681void MeshMaterialMng::
682forceRecompute()
683{
684 _endUpdate();
685}
686
687/*---------------------------------------------------------------------------*/
688/*---------------------------------------------------------------------------*/
693void MeshMaterialMng::
694_endUpdate()
695{
696 m_all_env_data->forceRecompute(true);
697}
698
699/*---------------------------------------------------------------------------*/
700/*---------------------------------------------------------------------------*/
708void MeshMaterialMng::
709syncVariablesReferences(bool check_resize)
710{
711 for( const auto& i : m_full_name_variable_map ){
712 IMeshMaterialVariable* mv = i.second;
713 info(4) << "SYNC REFERENCES FROM MANAGER name=" << mv->name();
714 mv->_internalApi()->syncReferences(check_resize);
715 }
716}
717
718/*---------------------------------------------------------------------------*/
719/*---------------------------------------------------------------------------*/
720
721void MeshMaterialMng::
723{
724 if (!functor)
725 return;
726 for( const auto& i : m_full_name_variable_map ){
727 IMeshMaterialVariable* mv = i.second;
728 functor->executeFunctor(mv);
729 }
730}
731
732/*---------------------------------------------------------------------------*/
733/*---------------------------------------------------------------------------*/
734
735void MeshMaterialMng::
736checkValid()
737{
738 const IItemFamily* cell_family = mesh()->cellFamily();
739 ItemGroup all_cells = cell_family->allItems();
740 ConstArrayView<Int16> nb_env_per_cell = m_all_env_data->componentConnectivityList()->cellsNbEnvironment();
741 ENUMERATE_ALLENVCELL(iallenvcell,view(all_cells.view().localIds())){
742 AllEnvCell all_env_cell = *iallenvcell;
743 Integer cell_nb_env = all_env_cell.nbEnvironment();
744 Cell cell = all_env_cell.globalCell();
745 Int64 cell_uid = cell.uniqueId();
746 if (all_env_cell.level()!=LEVEL_ALLENVIRONMENT)
747 ARCANE_FATAL("Bad level for all_env_item");
748
749 if (all_env_cell.globalCell()!=cell)
750 ARCANE_FATAL("Bad corresponding globalCell() in all_env_item");
751 if (cell_nb_env != nb_env_per_cell[cell.localId()])
752 ARCANE_FATAL("Bad value for nb_env direct='{0}' var='{1}'",
753 cell_nb_env, nb_env_per_cell[cell.localId()]);
754 for( Integer z=0; z<cell_nb_env; ++z ){
755 EnvCell ec = all_env_cell.cell(z);
756 Integer cell_nb_mat = ec.nbMaterial();
757 matimpl::ConstituentItemBase eii = ec.constituentItemBase();
758 if (all_env_cell.constituentItemBase()!=eii._superItemBase())
759 ARCANE_FATAL("Bad corresponding allEnvItem() in env_item uid={0}",cell_uid);
760 if (eii.globalItemBase()!=cell)
761 ARCANE_FATAL("Bad corresponding globalItem() in env_item");
762 if (eii.level()!=LEVEL_ENVIRONMENT)
763 ARCANE_FATAL("Bad level '{0}' for in env_item",eii.level());
764 // Si la maille n'est pas pure, la variable milieu ne peut être équivalente à
765 // la variable globale.
766 if (cell_nb_env>1 && ec._varIndex().arrayIndex()==0)
767 ARCANE_FATAL("Global index for a partial cell env_item={0}",ec);
768
769 for( Integer k=0; k<cell_nb_mat; ++k ){
770 MatCell mc = ec.cell(k);
771 matimpl::ConstituentItemBase mci = mc.constituentItemBase();
772 if (eii!=mci._superItemBase())
773 ARCANE_FATAL("Bad corresponding env_item in mat_item k={0} mc={1}",k,mc);
774 if (mci.globalItemBase()!=cell)
775 ARCANE_FATAL("Bad corresponding globalItem() in mat_item");
776 if (mci.level()!=LEVEL_MATERIAL)
777 ARCANE_FATAL("Bad level '{0}' for in mat_item",mci.level());
778 // Si la maille n'est pas pure, la variable matériau ne peut être équivalente à
779 // la variable globale.
780 if ((cell_nb_env>1 || cell_nb_mat>1) && mc._varIndex().arrayIndex()==0){
781 ARCANE_FATAL("Global index for a partial cell matitem={0} name={1} nb_mat={2} nb_env={3}",
782 mc,mc.material()->name(),cell_nb_mat,cell_nb_env);
783 }
784 }
785 }
786 }
787
788 for( IMeshEnvironment* env : m_environments ){
789 env->checkValid();
790 }
791}
792
793/*---------------------------------------------------------------------------*/
794/*---------------------------------------------------------------------------*/
795
796IMeshMaterialVariable* MeshMaterialMng::
797findVariable(const String& name)
798{
799 IMeshMaterialVariable* v = _findVariableFullyQualified(name);
800 if (v)
801 return v;
802
803 // Recherche la variable globale de nom \a name
804 // et si on la trouve, prend son nom complet pour
805 // la variable matériau.
806 const IVariable* global_var = m_variable_mng->findMeshVariable(mesh(),name);
807 if (global_var){
808 v = _findVariableFullyQualified(global_var->fullName());
809 if (v)
810 return v;
811 }
812
813 return nullptr;
814}
815
816/*---------------------------------------------------------------------------*/
817/*---------------------------------------------------------------------------*/
818
819IMeshMaterialVariable* MeshMaterialMng::
820_findVariableFullyQualified(const String& name)
821{
822 auto i = m_full_name_variable_map.find(name);
823 if (i!=m_full_name_variable_map.end())
824 return i->second;
825 return nullptr;
826}
827
828/*---------------------------------------------------------------------------*/
829/*---------------------------------------------------------------------------*/
830
831IMeshMaterialVariable* MeshMaterialMng::
832checkVariable(IVariable* global_var)
833{
834 auto i = m_var_to_mat_var_map.find(global_var);
835 if (i!=m_var_to_mat_var_map.end())
836 return i->second;
837 return nullptr;
838}
839
840/*---------------------------------------------------------------------------*/
841/*---------------------------------------------------------------------------*/
842
843void MeshMaterialMng::
844fillWithUsedVariables(Array<IMeshMaterialVariable*>& variables)
845{
846 variables.clear();
847
848 // Utilise la map sur les noms des variables pour garantir un même
849 // ordre de parcours quels que soient les sous-domaines.
850 for( const auto& i : m_full_name_variable_map ){
851 IMeshMaterialVariable* ivar = i.second;
852 if (ivar->globalVariable()->isUsed())
853 variables.add(ivar);
854 }
855}
856
857/*---------------------------------------------------------------------------*/
858/*---------------------------------------------------------------------------*/
859
860void MeshMaterialMng::
861_addVariable(IMeshMaterialVariable* var)
862{
863 //TODO: le verrou m_variable_lock doit etre actif.
864 IVariable* gvar = var->globalVariable();
865 info(4) << "MAT_ADD_VAR global_var=" << gvar << " var=" << var << " this=" << this;
866 m_var_to_mat_var_map.insert(std::make_pair(gvar,var));
867 m_full_name_variable_map.insert(std::make_pair(gvar->fullName(),var));
868}
869
870/*---------------------------------------------------------------------------*/
871/*---------------------------------------------------------------------------*/
872
873void MeshMaterialMng::
874_removeVariable(IMeshMaterialVariable* var)
875{
876 //TODO: le verrou m_variable_lock doit etre actif.
877 IVariable* gvar = var->globalVariable();
878 info(4) << "MAT:Remove variable global_var=" << gvar << " var=" << var;
879 m_var_to_mat_var_map.erase(gvar);
880 m_full_name_variable_map.erase(gvar->fullName());
881}
882
883/*---------------------------------------------------------------------------*/
884/*---------------------------------------------------------------------------*/
885
886void MeshMaterialMng::
887dumpInfos(std::ostream& o)
888{
889 Integer nb_mat = m_materials.size();
890 Integer nb_env = m_environments.size();
891 Integer nb_var_idx = m_variables_indexer.size();
892 o << "-- Infos sur les milieux et matériaux\n";
893 o << "-- Nb Materiaux: " << nb_mat << '\n';
894 o << "-- Nb Milieux: " << nb_env << '\n';
895 o << "-- Nb Variables partielles: " << nb_var_idx << '\n';
896
897 o << "-- Liste des matériaux\n";
898 for( IMeshMaterial* mat : m_materials ){
899 o << "-- Materiau name=" << mat->name() << '\n';
900 }
901
902 o << "-- Liste des milieux\n";
903 for( IMeshEnvironment* me : m_environments ){
904 ConstArrayView<IMeshMaterial*> env_materials = me->materials();
905 const MeshMaterialVariableIndexer* env_var_idx = me->_internalApi()->variableIndexer();
906 Integer nb_env_mat = env_materials.size();
907 o << "-- Milieu name=" << me->name()
908 << " nb_mat=" << nb_env_mat
909 << " nb_cell=" << me->cells().size()
910 << " var_idx = " << env_var_idx->index()
911 << " ids=" << env_var_idx->matvarIndexes()
912 << '\n';
913 for( IMeshMaterial* mm : env_materials ){
914 const MeshMaterialVariableIndexer* idx = mm->_internalApi()->variableIndexer();
915 o << "-- Materiau\n";
916 o << "-- name = " << mm->name() << "\n";
917 o << "-- nb_cell = " << mm->cells().size() << "\n";
918 o << "-- var_idx = " << idx->index() << "\n";
919 }
920 }
921}
922
923/*---------------------------------------------------------------------------*/
924/*---------------------------------------------------------------------------*/
925// TODO: fusionner dumpInfos2() et dumpInfo().
926void MeshMaterialMng::
927dumpInfos2(std::ostream& o)
928{
929 const ConstituentConnectivityList& constituent_list = *m_all_env_data->componentConnectivityList();
930 ConstArrayView<Int16> nb_env_per_cell = constituent_list.cellsNbEnvironment();
931 Integer nb_mat = m_materials.size();
932 Integer nb_env = m_environments.size();
933 Integer nb_var_idx = m_variables_indexer.size();
934 o << "-- Material and Environment infos: nb_env=" << nb_env
935 << " nb_mat=" << nb_mat << " timestamp=" << m_timestamp
936 << " nb_var_idx=" << nb_var_idx
937 << "\n";
938 Integer nb_cell = mesh()->allCells().size();
939 if (nb_cell!=0){
940 Integer nb_pure_env = 0;
941 ENUMERATE_CELL(icell,mesh()->allCells()){
942 if (nb_env_per_cell[icell.localId()] <= 1)
943 ++nb_pure_env;
944 }
945 o << " nb_cell=" << nb_cell << " nb_pure_env=" << nb_pure_env
946 << " nb_partial=" << (nb_cell-nb_pure_env)
947 << " percent=" << (100*nb_pure_env)/nb_cell
948 << "\n";
949 }
950
951 o << "-- Liste des milieux\n";
952 for( MeshEnvironment* me : m_true_environments ){
953 ConstArrayView<IMeshMaterial*> env_materials = me->materials();
954 const MeshMaterialVariableIndexer* env_var_idx = me->variableIndexer();
955 const Int16 env_id = me->componentId();
956 Integer nb_env_mat = env_materials.size();
957 Integer nb_env_cell = me->cells().size();
958 Integer nb_pure_mat = 0;
959 if (nb_env_mat>1){
960 ENUMERATE_CELL(icell,me->cells()){
961 if (constituent_list.cellNbMaterial(icell, env_id) <= 1)
962 ++nb_pure_mat;
963 }
964 }
965 else
966 nb_pure_mat = nb_env_cell;
967 o << "-- Env name=" << me->name()
968 << " nb_mat=" << nb_env_mat
969 << " var_idx=" << env_var_idx->index()
970 << " nb_cell=" << nb_env_cell
971 << " nb_pure_mat=" << nb_pure_mat;
972 if (nb_env_cell!=0)
973 o << " percent=" << (nb_pure_mat*100)/nb_env_cell;
974 o << '\n';
975 for( Integer j=0; j<nb_env_mat; ++j ){
976 IMeshMaterial* mm = env_materials[j];
977 const MeshMaterialVariableIndexer* idx = mm->_internalApi()->variableIndexer();
978 o << "-- Mat name=" << mm->name()
979 << " nb_cell=" << mm->cells().size()
980 << " var_idx=" << idx->index()
981 << "\n";
982 }
983 }
984}
985
986/*---------------------------------------------------------------------------*/
987/*---------------------------------------------------------------------------*/
988
989bool MeshMaterialMng::
990synchronizeMaterialsInCells()
991{
992 return m_mms->synchronizeMaterialsInCells();
993}
994
995/*---------------------------------------------------------------------------*/
996/*---------------------------------------------------------------------------*/
997
998void MeshMaterialMng::
999checkMaterialsInCells(Integer max_print)
1000{
1001 m_mms->checkMaterialsInCells(max_print);
1002}
1003
1004/*---------------------------------------------------------------------------*/
1005/*---------------------------------------------------------------------------*/
1006
1007void MeshMaterialMng::
1008dumpCellInfos(Cell cell,std::ostream& o)
1009{
1010 CellToAllEnvCellConverter all_env_cell_converter(this);
1011 AllEnvCell all_env_cell = all_env_cell_converter[cell];
1012 Cell global_cell = all_env_cell.globalCell();
1013 o << "Cell uid=" << ItemPrinter(global_cell) << '\n';
1014 ENUMERATE_CELL_ENVCELL(ienvcell,all_env_cell){
1015 o << "ENV name=" << (*ienvcell).environment()->name()
1016 << " component_idx=" << ComponentItemLocalId(ienvcell) << '\n';
1017 ENUMERATE_CELL_MATCELL(imatcell,(*ienvcell)){
1018 o << "MAT name=" << (*imatcell).material()->name()
1019 << " component_idx=" << ComponentItemLocalId(imatcell) << '\n';
1020 }
1021 }
1022}
1023
1024/*---------------------------------------------------------------------------*/
1025/*---------------------------------------------------------------------------*/
1026
1028cellToAllEnvCellConverter()
1029{
1030 return CellToAllEnvCellConverter(componentItemSharedInfo(LEVEL_ALLENVIRONMENT));
1031}
1032
1033/*---------------------------------------------------------------------------*/
1034/*---------------------------------------------------------------------------*/
1035
1036void MeshMaterialMng::
1037_checkEndCreate()
1038{
1039 if (m_is_end_create)
1040 ARCANE_FATAL("Invalid method call because endCreate() has already been called");
1041}
1042
1043/*---------------------------------------------------------------------------*/
1044/*---------------------------------------------------------------------------*/
1045
1046AllEnvCellVectorView MeshMaterialMng::
1047_view(SmallSpan<const Int32> local_ids)
1048{
1049 return AllEnvCellVectorView(local_ids.constSmallView(), componentItemSharedInfo(LEVEL_ALLENVIRONMENT));
1050}
1051
1052/*---------------------------------------------------------------------------*/
1053/*---------------------------------------------------------------------------*/
1054
1055class MeshMaterialMngFactory
1057{
1058 public:
1059 MeshMaterialMngFactory()
1060 {
1062 }
1063 ~MeshMaterialMngFactory()
1064 {
1066 }
1067 public:
1068 Ref<IMeshMaterialMng> getTrueReference(const MeshHandle& mesh_handle,bool is_create) override;
1069 public:
1070 static MeshMaterialMngFactory m_mesh_material_mng_factory;
1071};
1072
1073MeshMaterialMngFactory MeshMaterialMngFactory::m_mesh_material_mng_factory{};
1074
1075/*---------------------------------------------------------------------------*/
1076/*---------------------------------------------------------------------------*/
1077
1078Ref<IMeshMaterialMng> MeshMaterialMngFactory::
1079getTrueReference(const MeshHandle& mesh_handle,bool is_create)
1080{
1081 //TODO: faire lock pour multi-thread
1082 typedef AutoDestroyUserData<Ref<IMeshMaterialMng>> UserDataType;
1083
1084 const char* name = "MeshMaterialMng_StdMat";
1085 IUserDataList* udlist = mesh_handle.meshUserDataList();
1086
1087 IUserData* ud = udlist->data(name,true);
1088 if (!ud){
1089 if (!is_create)
1090 return {};
1091 IMeshMaterialMng* mm = arcaneCreateMeshMaterialMng(mesh_handle,"StdMat");
1092 Ref<IMeshMaterialMng> mm_ref = makeRef(mm);
1093 udlist->setData(name,new UserDataType(new Ref<IMeshMaterialMng>(mm_ref)));
1094 return mm_ref;
1095 }
1096 auto adud = dynamic_cast<UserDataType*>(ud);
1097 if (!adud)
1098 ARCANE_FATAL("Can not cast to IMeshMaterialMng*");
1099 return *(adud->data());
1100}
1101
1102/*---------------------------------------------------------------------------*/
1103/*---------------------------------------------------------------------------*/
1104
1105bool MeshMaterialMng::
1106isInMeshMaterialExchange() const
1107{
1108 return m_exchange_mng->isInMeshMaterialExchange();
1109}
1110
1111/*---------------------------------------------------------------------------*/
1112/*---------------------------------------------------------------------------*/
1113
1114void MeshMaterialMng::
1115_checkCreateProperties()
1116{
1117 if (m_properties)
1118 return;
1119 m_properties = std::make_unique<Properties>(*(mesh()->properties()),String("MeshMaterialMng_")+name());
1120}
1121
1122/*---------------------------------------------------------------------------*/
1123/*---------------------------------------------------------------------------*/
1124namespace
1125{
1126const Int32 SERIALIZE_VERSION = 1;
1127}
1128void MeshMaterialMng::
1129_saveInfosInProperties()
1130{
1131 _checkCreateProperties();
1132
1133 // Sauve le numéro de version pour être certain que c'est OK en reprise
1134 m_properties->set("Version",SERIALIZE_VERSION);
1135
1136 // Sauve dans les propriétés les infos nécessaires pour recréer les
1137 // matériaux et milieux.
1138 UniqueArray<String> material_info_names;
1139 for( MeshMaterialInfo* mat_info : m_materials_info ){
1140 material_info_names.add(mat_info->name());
1141 }
1142 m_properties->set("MaterialInfoNames",material_info_names);
1143
1144 UniqueArray<String> env_names;
1145 UniqueArray<Int32> env_nb_mat;
1146 UniqueArray<String> env_mat_names;
1147 ENUMERATE_ENV(ienv,this){
1148 IMeshEnvironment* env = *ienv;
1149 env_names.add(env->name());
1150 info(5) << "SAVE ENV_NAME name=" << env->name() << " nb_mat=" << env->nbMaterial();
1151 env_nb_mat.add(env->nbMaterial());
1152 ENUMERATE_MAT(imat,env){
1153 const String& name = (*imat)->infos()->name();
1154 info(5) << "SAVE MAT_NAME name=" << name;
1155 env_mat_names.add(name);
1156 }
1157 }
1158 m_properties->set("EnvNames",env_names);
1159 m_properties->set("EnvNbMat",env_nb_mat);
1160 m_properties->set("EnvMatNames",env_mat_names);
1161
1162 // Sauve les infos nécessaires pour les block.
1163 // Pour chaque bloc, son nom et le nom du groupe de maille correspondant.
1164 UniqueArray<String> block_names;
1165 UniqueArray<String> block_cell_group_names;
1166 UniqueArray<Int32> block_nb_env;
1167 UniqueArray<String> block_env_names;
1168 for( IMeshBlock* block : m_blocks ){
1169 block_names.add(block->name());
1170 block_cell_group_names.add(block->cells().name());
1171 block_nb_env.add(block->nbEnvironment());
1172 ENUMERATE_ENV(ienv,block){
1173 const String& name = (*ienv)->name();
1174 info(5) << "SAVE BLOCK ENV_NAME name=" << name;
1175 block_env_names.add(name);
1176 }
1177 }
1178 m_properties->set("BlockNames",block_names);
1179 m_properties->set("BlockCellGroupNames",block_cell_group_names);
1180 m_properties->set("BlockNbEnv",block_nb_env);
1181 m_properties->set("BlockEnvNames",block_env_names);
1182}
1183
1184/*---------------------------------------------------------------------------*/
1185/*---------------------------------------------------------------------------*/
1186
1187void MeshMaterialMng::
1188recreateFromDump()
1189{
1190 if (m_is_end_create)
1191 ARCANE_FATAL("Can not recreate a created instance");
1192
1193 _checkCreateProperties();
1194
1195 info() << "Creating material infos from dump";
1196
1197 // Sauve le numéro de version pour être sur que c'est OK en reprise
1198 Int32 v = m_properties->getInt32("Version");
1199 if (v!=SERIALIZE_VERSION)
1200 ARCANE_FATAL("Bad serializer version: trying to read from incompatible checkpoint v={0} expected={1}",
1201 v,SERIALIZE_VERSION);
1202
1203 UniqueArray<String> material_info_names;
1204 m_properties->get("MaterialInfoNames",material_info_names);
1205 for( const String& mat_name : material_info_names )
1206 this->registerMaterialInfo(mat_name);
1207
1208 UniqueArray<String> env_names;
1209 UniqueArray<Int32> env_nb_mat;
1210 UniqueArray<String> env_mat_names;
1211 m_properties->get("EnvNames",env_names);
1212 m_properties->get("EnvNbMat",env_nb_mat);
1213 m_properties->get("EnvMatNames",env_mat_names);
1214
1215 Integer mat_index = 0;
1216 for( Integer ienv=0, nenv=env_names.size(); ienv<nenv; ++ienv ){
1217 Materials::MeshEnvironmentBuildInfo env_build(env_names[ienv]);
1218 Integer nb_mat = env_nb_mat[ienv];
1219 for( Integer imat=0; imat<nb_mat; ++imat ){
1220 env_build.addMaterial(env_mat_names[mat_index]);
1221 ++mat_index;
1222 }
1223 this->createEnvironment(env_build);
1224 }
1225
1226 // Recréé les blocs.
1227 // Pour chaque bloc, son nom et le nom du groupe de maille correspondant.
1228 UniqueArray<String> block_names;
1229 UniqueArray<String> block_cell_group_names;
1230 UniqueArray<String> block_env_names;
1231 UniqueArray<Int32> block_nb_env;
1232 m_properties->get("BlockNames",block_names);
1233 m_properties->get("BlockCellGroupNames",block_cell_group_names);
1234 m_properties->get("BlockNbEnv",block_nb_env);
1235 m_properties->get("BlockEnvNames",block_env_names);
1236 const IItemFamily* cell_family = mesh()->cellFamily();
1237 Integer block_env_index = 0;
1238 for( Integer i=0, n=block_names.size(); i<n; ++i ){
1239 String name = block_names[i];
1240 String cell_group_name = block_cell_group_names[i];
1241 CellGroup cells = cell_family->findGroup(cell_group_name);
1242 if (cells.null())
1243 ARCANE_FATAL("Can not find cell group '{0}' for block creation",
1244 cell_group_name);
1245 MeshBlockBuildInfo mbbi(name,cells);
1246 if (!block_nb_env.empty()){
1247 Integer nb_env = block_nb_env[i];
1248 for( Integer ienv=0; ienv<nb_env; ++ienv ){
1249 const String& name2 = block_env_names[block_env_index];
1250 ++block_env_index;
1251 IMeshEnvironment* env = findEnvironment(name2,false);
1252 if (!env)
1253 ARCANE_FATAL("Invalid environment name '{0}' for recreating blocks",name2);
1254 mbbi.addEnvironment(env);
1255 }
1256 }
1257 this->createBlock(mbbi);
1258 }
1259
1260 endCreate(true);
1261}
1262
1263/*---------------------------------------------------------------------------*/
1264/*---------------------------------------------------------------------------*/
1265
1266void MeshMaterialMng::
1267_onMeshDestroyed()
1268{
1269 // Il faut détruire cette instance ici car elle a besoin de IItemFamily
1270 // dans son destructeur et il est possible qu'il n'y ait plus de famille
1271 // si le destructeur de IMeshMaterialMng est appelé après la destruction
1272 // du maillage (ce qui peut arriver en C# par exemple).
1273 m_exchange_mng.reset();
1274
1275 _unregisterAllVariables();
1276}
1277
1278/*---------------------------------------------------------------------------*/
1279/*---------------------------------------------------------------------------*/
1280
1281void MeshMaterialMng::
1282_unregisterAllVariables()
1283{
1284 // Recopie dans un tableau toutes les références.
1285 // Il faut le faire avant les appels à unregisterVariable()
1286 // car ces derniers modifient la liste chainée des références
1288
1289 for( const auto& i : m_full_name_variable_map ){
1290 const IMeshMaterialVariable* var = i.second;
1291
1292 for( MeshMaterialVariableRef::Enumerator iref(var); iref.hasNext(); ++iref ){
1293 MeshMaterialVariableRef* ref = *iref;
1294 m_all_refs.add(ref);
1295 }
1296 }
1297
1298 for( MeshMaterialVariableRef* ref : m_all_refs )
1299 ref->unregisterVariable();
1300}
1301
1302/*---------------------------------------------------------------------------*/
1303/*---------------------------------------------------------------------------*/
1304
1305ComponentItemSharedInfo* MeshMaterialMng::
1306componentItemSharedInfo(Int32 level) const
1307{
1308 ComponentItemInternalData* data = m_all_env_data->componentItemInternalData();
1309 ComponentItemSharedInfo* shared_info = nullptr;
1310 if (level == LEVEL_MATERIAL)
1311 shared_info = data->matSharedInfo();
1312 else if (level == LEVEL_ENVIRONMENT)
1313 shared_info = data->envSharedInfo();
1314 else if (level==LEVEL_ALLENVIRONMENT)
1315 shared_info = data->allEnvSharedInfo();
1316 else
1317 ARCANE_FATAL("Bad internal type of component");
1318
1319 return shared_info;
1320}
1321
1322/*---------------------------------------------------------------------------*/
1323/*---------------------------------------------------------------------------*/
1324
1325void MeshMaterialMng::
1326_dumpStats()
1327{
1328 IEnumeratorTracer* tracer = IEnumeratorTracer::singleton();
1329 if (tracer)
1330 tracer->dumpStats();
1331
1332 if (m_modifier)
1333 m_modifier->dumpStats();
1334
1335 for (IMeshEnvironment* env : m_environments) {
1336 // N'affiche pas les statistiques si le milieu n'a qu'un seul matériau
1337 // car il utilise le même indexeur que la matériau et les statistiques
1338 // pour ce dernier seront affichées lors du parcours des matériaux.
1339 if (env->nbMaterial() > 1)
1340 env->_internalApi()->variableIndexer()->dumpStats();
1341 }
1342 for (IMeshMaterial* mat : m_materials) {
1343 mat->_internalApi()->variableIndexer()->dumpStats();
1344 }
1345}
1346
1347/*---------------------------------------------------------------------------*/
1348/*---------------------------------------------------------------------------*/
1349
1350void MeshMaterialMng::
1351createAllCellToAllEnvCell()
1352{
1353 if (!m_accelerator_envcell_container) {
1354 m_accelerator_envcell_container = std::make_unique<AllCellToAllEnvCellContainer>(this);
1355 m_accelerator_envcell_container->initialize();
1356 }
1357}
1358
1359/*---------------------------------------------------------------------------*/
1360/*---------------------------------------------------------------------------*/
1361
1362} // End namespace Arcane::Materials
1363
1364/*---------------------------------------------------------------------------*/
1365/*---------------------------------------------------------------------------*/
#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:56
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.