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