Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
MeshMaterialMng.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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-2026 */
9/* */
10/* Material and mesh environment manager. */
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
62
63/*---------------------------------------------------------------------------*/
64/*---------------------------------------------------------------------------*/
65
66/*
67 * TODO:
68 * - Verify that only one instance of MeshModifier is created.
69 * - For example, check in synchronizeMaterialsInCells()
70 * that the mesh is not being modified.
71 */
72
73/*---------------------------------------------------------------------------*/
74/*---------------------------------------------------------------------------*/
75
76namespace Arcane::Materials
77{
78
80arcaneCreateMeshMaterialVariableFactoryMng(IMeshMaterialMng* mm);
81
82/*---------------------------------------------------------------------------*/
83/*---------------------------------------------------------------------------*/
84
85namespace
86{
88 arcaneCreateMeshMaterialMng(const MeshHandle& mesh_handle, const String& name)
89 {
90 MeshMaterialMng* mmm = new MeshMaterialMng(mesh_handle, name);
91 //std::cout << "CREATE MESH_MATERIAL_MNG mesh_name=" << mesh_handle.meshName()
92 // << " ref=" << mesh_handle.reference() << " this=" << mmm << "\n";
93 mmm->build();
94 return mmm;
95 }
96} // namespace
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100
101MeshMaterialMng::RunnerInfo::
102RunnerInfo(Runner& runner)
103: m_runner(runner)
104, m_run_queue(makeQueue(m_runner))
105, m_sequential_runner(Accelerator::eExecutionPolicy::Sequential)
106, m_sequential_run_queue(makeQueue(m_sequential_runner))
107, m_multi_thread_runner(Accelerator::eExecutionPolicy::Thread)
108, m_multi_thread_run_queue(makeQueue(m_multi_thread_runner))
109{
110}
111
112/*---------------------------------------------------------------------------*/
113/*---------------------------------------------------------------------------*/
114
115void MeshMaterialMng::RunnerInfo::
116initializeAsyncPool(Int32 nb_queue)
117{
118 // If an accelerator policy is used, create asynchronous RunQueues
119 // for independent operations. This will allow several to be executed
120 // at the same time.
121 bool is_accelerator = isAcceleratorPolicy(m_runner.executionPolicy());
122 m_async_queue_pool.initialize(m_runner, nb_queue);
123 if (is_accelerator)
124 m_async_queue_pool.setAsync(true);
125}
126
127/*---------------------------------------------------------------------------*/
128/*---------------------------------------------------------------------------*/
129
130RunQueue MeshMaterialMng::RunnerInfo::
131runQueue(Accelerator::eExecutionPolicy policy) const
132{
133 if (policy == Accelerator::eExecutionPolicy::None)
134 return m_run_queue;
135 if (policy == Accelerator::eExecutionPolicy::Sequential)
136 return m_sequential_run_queue;
137 if (policy == Accelerator::eExecutionPolicy::Thread)
138 return m_multi_thread_run_queue;
139 ARCANE_FATAL("Invalid value '{0}' for execution policy. Valid values are None, Sequential or Thread", policy);
140}
141
142/*---------------------------------------------------------------------------*/
143/*---------------------------------------------------------------------------*/
144
145/*---------------------------------------------------------------------------*/
146/*---------------------------------------------------------------------------*/
147
148MeshMaterialMng::
149MeshMaterialMng(const MeshHandle& mesh_handle, const String& name)
150// TODO: use the mesh's ITraceMng. Do it during init
151: TraceAccessor(mesh_handle.traceMng())
152, m_mesh_handle(mesh_handle)
153, m_internal_api(std::make_unique<InternalApi>(this))
154, m_variable_mng(mesh_handle.variableMng())
155, m_name(name)
156, m_indexed_selection_identity(MemoryUtils::getDefaultDataAllocator())
157{
158 m_all_env_data = std::make_unique<AllEnvData>(this);
159 m_exchange_mng = std::make_unique<MeshMaterialExchangeMng>(this);
160 m_variable_factory_mng = arcaneCreateMeshMaterialVariableFactoryMng(this);
161 m_observer_pool = std::make_unique<ObserverPool>();
162 m_observer_pool->addObserver(this, &MeshMaterialMng::_onMeshDestroyed, mesh_handle.onDestroyObservable());
163
164 String s = platform::getEnvironmentVariable("ARCANE_ALLENVCELL_FOR_RUNCOMMAND");
165 if (!s.null())
166 m_is_use_accelerator_envcell_container = true;
167 m_mms = new MeshMaterialSynchronizer(this);
168}
169
170/*---------------------------------------------------------------------------*/
171/*---------------------------------------------------------------------------*/
172
173MeshMaterialMng::
174~MeshMaterialMng()
175{
176 //std::cout << "DESTROY MESH MATERIAL MNG this=" << this << '\n';
177 _dumpStats();
178
179 delete m_mms;
180 delete m_variable_factory_mng;
181 m_exchange_mng.reset();
182 m_all_cells_env_only_synchronizer.reset();
183 m_all_cells_mat_env_synchronizer.reset();
184 m_all_env_data.reset();
185 m_properties.reset();
186
187 for (MeshMaterial* m : m_true_materials)
188 delete m;
189 m_true_materials.clear();
190
191 for (MeshEnvironment* e : m_true_environments)
192 delete e;
193 m_true_environments.clear();
194
195 for (IMeshBlock* b : m_true_blocks)
196 delete b;
197
198 for (MeshMaterialInfo* mmi : m_materials_info)
199 delete mmi;
200
201 for (MeshMaterialVariableIndexer* mvi : m_variables_indexer_to_destroy)
202 delete mvi;
203
204 m_modifier.reset();
205 m_internal_api.reset();
206
207 m_accelerator_envcell_container.reset();
208
209 // Destroy the Runner at the end to ensure there are no more
210 // references to it in other instances.
211 m_runner_info.reset();
212}
213
214/*---------------------------------------------------------------------------*/
215/*---------------------------------------------------------------------------*/
216
217/*---------------------------------------------------------------------------*/
218/*---------------------------------------------------------------------------*/
219
220void MeshMaterialMng::
221build()
222{
223 // Register variable factories
224 {
225 auto* x = MeshMaterialVariableFactoryRegisterer::firstRegisterer();
226 while (x) {
227 m_variable_factory_mng->registerFactory(x->createFactory());
228 x = x->nextRegisterer();
229 }
230 }
231
232 // Indicate whether the accelerator API is used for calculating
233 // ConstituentItemVectorImpl entities
234 {
235 if (auto v = Convert::Type<Real>::tryParseFromEnvironment("ARCANE_MATERIALMNG_USE_ACCELERATOR_FOR_CONSTITUENTITEMVECTOR", true)) {
236 m_is_use_accelerator_for_constituent_item_vector = (v.value() != 0);
237 }
238 // Do not activate the use of RunQueue for calculating
239 // 'ComponentItemVector' if multi-threading is active. Currently,
240 // using the same RunQueue is not multi-threaded (and therefore
241 // ComponentItemVector cannot be created concurrently)
242 if (TaskFactory::isActive())
243 m_is_use_accelerator_for_constituent_item_vector = false;
244 info() << "Use accelerator API for 'ConstituentItemVectorImpl' = " << m_is_use_accelerator_for_constituent_item_vector;
245 }
246
247 // Position the default runner
248 {
249 IAcceleratorMng* acc_mng = m_variable_mng->_internalApi()->acceleratorMng();
250 Runner runner;
251 if (acc_mng) {
252 Runner* default_runner = acc_mng->defaultRunner();
253 // Indicate whether the accelerator queue is activated
254 bool use_accelerator_runner = true;
255 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_MATERIALMNG_USE_QUEUE", true))
256 use_accelerator_runner = (v.value() != 0);
257 if (use_accelerator_runner && default_runner)
258 runner = *default_runner;
259 }
260 // If no runner is registered, use a sequential runner.
261 if (!runner.isInitialized())
262 runner.initialize(Accelerator::eExecutionPolicy::Sequential);
263 m_runner_info = std::make_unique<RunnerInfo>(runner);
264 Int32 nb_queue = isAcceleratorPolicy(runner.executionPolicy()) ? 8 : 1;
265 info() << "Use runner '" << this->runner().executionPolicy() << "' for MeshMaterialMng name=" << name()
266 << " async_queue_size=" << nb_queue;
267 m_runner_info->initializeAsyncPool(nb_queue);
268
269 // In release mode and if an accelerator is used, allocate by
270 // default on the accelerator. This is important especially for
271 // temporary arrays.
272 // In 'check' mode, unified memory must be left because tests are done
273 // on the CPU.
274 RunQueue& q = runQueue();
275 if (!arcaneIsCheck() && q.isAcceleratorPolicy())
276 q.setMemoryRessource(eMemoryRessource::Device);
277 }
278
279 // Choice of optimizations.
280 {
281 int default_flags = 0;
282
283 // Do not set these flags by default yet because it does not work
284 // for all codes
285 // default_flags = (int)eModificationFlags::GenericOptimize | (int)eModificationFlags::OptimizeMultiAddRemove;
286
287 int opt_flag_value = 0;
288 String env_name = "ARCANE_MATERIAL_MODIFICATION_FLAGS";
289 String opt_flag_str = platform::getEnvironmentVariable(env_name);
290 if (!opt_flag_str.null()) {
291 if (builtInGetValue(opt_flag_value, opt_flag_str)) {
292 pwarning() << "Invalid value '" << opt_flag_str
293 << " 'for environment variable '" << env_name
294 << "'";
295 opt_flag_value = default_flags;
296 }
297 }
298 else {
299 opt_flag_value = default_flags;
300 }
301 m_modification_flags = opt_flag_value;
302 }
303
304 // Choice of synchronization implementation version
305 {
306 String env_name = "ARCANE_MATSYNCHRONIZE_VERSION";
307 String env_value = platform::getEnvironmentVariable(env_name);
308 info() << "ENV_VALUE=" << env_value;
309 Integer version = m_synchronize_variable_version;
310 if (!env_value.null()) {
311 if (builtInGetValue(version, env_value)) {
312 pwarning() << "Invalid value '" << env_value
313 << " 'for environment variable '" << env_name
314 << "'";
315 }
316 else
317 m_synchronize_variable_version = version;
318 }
319 info() << "Set material variable synchronize version to "
320 << "'" << m_synchronize_variable_version << "'";
321 }
322
323 // Choice of compression service
324 {
325 String env_name = "ARCANE_MATERIAL_DATA_COMPRESSOR_NAME";
326 String env_value = platform::getEnvironmentVariable(env_name);
327 if (!env_value.null()) {
328 info() << "Use service '" << env_value << "' for material data compression";
329 m_data_compressor_service_name = env_value;
330 }
331 }
332
333 // Choice of additional capacity ratio
334 {
335 if (auto v = Convert::Type<Real>::tryParseFromEnvironment("ARCANE_MATERIALMNG_ADDITIONAL_CAPACITY_RATIO", true)) {
336 if (v >= 0.0) {
337 m_additional_capacity_ratio = v.value();
338 info() << "Set additional capacity ratio to " << m_additional_capacity_ratio;
339 }
340 }
341 }
342
343 m_exchange_mng->build();
344 // If enumerator traces on entities are active, activate those
345 // on materials.
346 // TODO: make this code thread-safe in case of using IParallelMng via threads
347 // and call it only once.
348 IItemEnumeratorTracer* item_tracer = IItemEnumeratorTracer::singleton();
349 if (item_tracer) {
350 info() << "Adding material enumerator tracing";
351 EnumeratorTracer::_setSingleton(new EnumeratorTracer(traceMng(), item_tracer->perfCounterRef()));
352 }
353}
354
355/*---------------------------------------------------------------------------*/
356/*---------------------------------------------------------------------------*/
357
358void MeshMaterialMng::
359_addVariableIndexer(MeshMaterialVariableIndexer* var_idx)
360{
361 var_idx->setIndex(m_variables_indexer.size());
362 m_variables_indexer.add(var_idx);
363}
364
365/*---------------------------------------------------------------------------*/
366/*---------------------------------------------------------------------------*/
367
374MeshMaterial* MeshMaterialMng::
375_createMaterial(MeshEnvironment* env, MeshMaterialInfo* infos, const String& name)
376{
377 _checkEndCreate();
378 if (infos->materialMng() != this)
379 ARCANE_FATAL("Invalid materialMng() for material info");
380 if (env->materialMng() != this)
381 ARCANE_FATAL("Invalid materialMng() for environment");
382 Integer var_index = m_variables_indexer.size();
383 Int16 mat_id = CheckedConvert::toInt16(m_materials.size());
384 MeshMaterial* mat = new MeshMaterial(infos, env, name, mat_id);
385 info() << "Create material name=" << name << "mat_id=" << mat_id << " var_index=" << var_index;
386 mat->build();
387 m_materials.add(mat);
388 m_materials_as_components.add(mat);
389 m_true_materials.add(mat);
390
391 _addVariableIndexer(mat->variableIndexer());
392 return mat;
393}
394
395/*---------------------------------------------------------------------------*/
396/*---------------------------------------------------------------------------*/
397
398MeshMaterialInfo* MeshMaterialMng::
399registerMaterialInfo(const String& name)
400{
401 _checkEndCreate();
402 // Check that the material is not already registered.
403 MeshMaterialInfo* old_mmi = _findMaterialInfo(name);
404 if (old_mmi)
405 ARCANE_FATAL("A material named '{0}' is already registered", name);
406
407 MeshMaterialInfo* mmi = new MeshMaterialInfo(this, name);
408 m_materials_info.add(mmi);
409 return mmi;
410}
411
412/*---------------------------------------------------------------------------*/
413/*---------------------------------------------------------------------------*/
414
421IMeshEnvironment* MeshMaterialMng::
422createEnvironment(const MeshEnvironmentBuildInfo& infos)
423{
424 _checkEndCreate();
425 Int16 env_index = CheckedConvert::toInt16(m_environments.size());
426 // Check that an environment with the same name does not exist.
427 const String& env_name = infos.name();
428 MeshEnvironment* old_me = _findEnvironment(env_name);
429 if (old_me)
430 ARCANE_FATAL("An environment named '{0}' is already registered", env_name);
431
432 info() << "Creating environment name=" << env_name << " index=" << env_index;
433 // Create the environment
434 MeshEnvironment* me = new MeshEnvironment(this, env_name, env_index);
435 me->build();
436 m_true_environments.add(me);
437 m_environments.add(me);
438 m_environments_as_components.add(me);
439
440 // Create and add the materials
441 Integer nb_mat = infos.materials().size();
443 for (Integer i = 0; i < nb_mat; ++i) {
444 const MeshEnvironmentBuildInfo::MatInfo& buildinfo = mat_build_infos[i];
445 const String& mat_name = buildinfo.m_name;
446 String new_mat_name = env_name + "_" + mat_name;
447 MeshMaterialInfo* mat_info = _findMaterialInfo(mat_name);
448 if (!mat_info) {
449 ARCANE_FATAL("No material named '{0}' is defined", mat_name);
450 }
451 MeshMaterial* mm = _createMaterial(me, mat_info, new_mat_name);
452 me->addMaterial(mm);
453 mat_info->_addEnvironment(env_name);
454 }
455 // If the environment contains multiple materials, it must be allocated
456 // with partial values. Otherwise, its partial values are those
457 // of its unique material.
458 {
459 MeshMaterialVariableIndexer* var_idx = nullptr;
460 if (nb_mat == 1) {
461 var_idx = me->materials()[0]->_internalApi()->variableIndexer();
462 }
463 else {
464 var_idx = new MeshMaterialVariableIndexer(traceMng(), me->name());
465 _addVariableIndexer(var_idx);
466 m_variables_indexer_to_destroy.add(var_idx);
467 }
468 me->setVariableIndexer(var_idx);
469 }
470 return me;
471}
472
473/*---------------------------------------------------------------------------*/
474/*---------------------------------------------------------------------------*/
475
476IMeshBlock* MeshMaterialMng::
477createBlock(const MeshBlockBuildInfo& infos)
478{
479 _checkEndCreate();
480
481 Int32 block_index = m_blocks.size();
482 // Checks that a block with the same name does not exist.
483 const String& name = infos.name();
484 const MeshBlock* old_mb = _findBlock(name);
485 if (old_mb)
486 ARCANE_FATAL("Un bloc de nom '{0}' est déjà enregistré", name);
487
488 info() << "Creating block name=" << name << " index=" << block_index
489 << " nb_env=" << infos.environments().size();
490 Integer nb_env = infos.environments().size();
491 for (Integer i = 0; i < nb_env; ++i)
492 info() << " Adding environment name=" << infos.environments()[i]->name() << " to block";
493
494 // Create the block
495 MeshBlock* mb = new MeshBlock(this, block_index, infos);
496 mb->build();
497 m_true_blocks.add(mb);
498 m_blocks.add(mb);
499
500 return mb;
501}
502
503/*---------------------------------------------------------------------------*/
504/*---------------------------------------------------------------------------*/
505
506void MeshMaterialMng::
507addEnvironmentToBlock(IMeshBlock* block, IMeshEnvironment* env)
508{
509 MeshBlock* mb = ARCANE_CHECK_POINTER(dynamic_cast<MeshBlock*>(block));
510 mb->addEnvironment(env);
511}
512
513/*---------------------------------------------------------------------------*/
514/*---------------------------------------------------------------------------*/
515
516void MeshMaterialMng::
517removeEnvironmentToBlock(IMeshBlock* block, IMeshEnvironment* env)
518{
519 MeshBlock* mb = ARCANE_CHECK_POINTER(dynamic_cast<MeshBlock*>(block));
520 mb->removeEnvironment(env);
521}
522
523/*---------------------------------------------------------------------------*/
524/*---------------------------------------------------------------------------*/
525
526void MeshMaterialMng::
527endCreate(bool is_continue)
528{
529 if (m_is_end_create)
530 return;
531
532 _saveInfosInProperties();
533
534 info() << "END CREATE MATERIAL_MNG is_continue=" << is_continue;
535
536 m_modifier = std::make_unique<MeshMaterialModifierImpl>(this);
537 m_modifier->initOptimizationFlags();
538
539 m_all_env_data->endCreate(is_continue);
540
541 auto synchronizer = mesh()->cellFamily()->allItemsSynchronizer();
542 m_all_cells_mat_env_synchronizer = std::make_unique<MeshMaterialVariableSynchronizer>(this, synchronizer, MatVarSpace::MaterialAndEnvironment);
543 m_all_cells_env_only_synchronizer = std::make_unique<MeshMaterialVariableSynchronizer>(this, synchronizer, MatVarSpace::Environment);
544
545 // Determines the list of all components.
546 {
547 Integer nb_component = m_environments_as_components.size() + m_materials_as_components.size();
548 m_components.reserve(nb_component);
549 m_components.addRange(m_environments_as_components);
550 m_components.addRange(m_materials_as_components);
551 }
552
553 // It is necessary to build and initialize the variables that were
554 // created before this allocation.
555 for (const auto& i : m_full_name_variable_map) {
556 IMeshMaterialVariable* mv = i.second;
557 info(4) << "BUILD FROM MANAGER name=" << mv->name() << " this=" << this;
558 mv->buildFromManager(is_continue);
559 }
560 if (is_continue)
561 _endUpdate();
562 m_is_end_create = true;
563
564 // Checks that the environments are valid.
565 // NOTE: we cannot always call checkValid()
566 // (especially at startup) because the entity groups exist,
567 // but the associated material info are not
568 // necessarily created yet.
569 // (It will be necessary to check if this is due to compatible mode or not).
570 for (IMeshEnvironment* env : m_environments) {
571 env->checkValid();
572 }
573
574 // Now that everything is created, it is valid to register the mechanisms
575 // of exchange.
576 m_exchange_mng->registerFactory();
577}
578
579/*---------------------------------------------------------------------------*/
580/*---------------------------------------------------------------------------*/
581
582void MeshMaterialMng::
583setModificationFlags(int v)
584{
585 _checkEndCreate();
586 m_modification_flags = v;
587 info() << "Setting ModificationFlags to v=" << v;
588}
589
590/*---------------------------------------------------------------------------*/
591/*---------------------------------------------------------------------------*/
592
593void MeshMaterialMng::
594setAllocateScalarEnvironmentVariableAsMaterial(bool v)
595{
596 _checkEndCreate();
597 m_is_allocate_scalar_environment_variable_as_material = v;
598 info() << "Setting AllocateScalarEnvironmentVariableAsMaterial to v=" << v;
599}
600
601/*---------------------------------------------------------------------------*/
602/*---------------------------------------------------------------------------*/
603
604void MeshMaterialMng::
605setDataCompressorServiceName(const String& name)
606{
607 m_data_compressor_service_name = name;
608}
609
610/*---------------------------------------------------------------------------*/
611/*---------------------------------------------------------------------------*/
612
613MeshMaterialModifierImpl* MeshMaterialMng::
614_modifier()
615{
616 return m_modifier.get();
617}
618
619/*---------------------------------------------------------------------------*/
620/*---------------------------------------------------------------------------*/
621
622MeshMaterialInfo* MeshMaterialMng::
623_findMaterialInfo(const String& name)
624{
625 for (MeshMaterialInfo* mmi : m_materials_info)
626 if (mmi->name() == name)
627 return mmi;
628 return nullptr;
629}
630
631/*---------------------------------------------------------------------------*/
632/*---------------------------------------------------------------------------*/
633
634IMeshEnvironment* MeshMaterialMng::
635findEnvironment(const String& name, bool throw_exception)
636{
637 IMeshEnvironment* env = _findEnvironment(name);
638 if (env)
639 return env;
640 if (throw_exception)
641 ARCANE_FATAL("No environment named '{0}'", name);
642 return nullptr;
643}
644
645/*---------------------------------------------------------------------------*/
646/*---------------------------------------------------------------------------*/
647
648MeshEnvironment* MeshMaterialMng::
649_findEnvironment(const String& name)
650{
651 for (MeshEnvironment* env : m_true_environments)
652 if (env->name() == name)
653 return env;
654 return nullptr;
655}
656
657/*---------------------------------------------------------------------------*/
658/*---------------------------------------------------------------------------*/
659
660IMeshBlock* MeshMaterialMng::
661findBlock(const String& name, bool throw_exception)
662{
663 IMeshBlock* block = _findBlock(name);
664 if (block)
665 return block;
666 if (throw_exception)
667 ARCANE_FATAL("No block named '{0}'", name);
668 return nullptr;
669}
670
671/*---------------------------------------------------------------------------*/
672/*---------------------------------------------------------------------------*/
673
674MeshBlock* MeshMaterialMng::
675_findBlock(const String& name)
676{
677 for (MeshBlock* b : m_true_blocks)
678 if (b->name() == name)
679 return b;
680 return nullptr;
681}
682
683/*---------------------------------------------------------------------------*/
684/*---------------------------------------------------------------------------*/
685
686void MeshMaterialMng::
687forceRecompute()
688{
689 _endUpdate();
690}
691
692/*---------------------------------------------------------------------------*/
693/*---------------------------------------------------------------------------*/
694
699void MeshMaterialMng::
700_endUpdate()
701{
702 m_all_env_data->forceRecompute(true);
703}
704
705/*---------------------------------------------------------------------------*/
706/*---------------------------------------------------------------------------*/
707
715void MeshMaterialMng::
716syncVariablesReferences(bool check_resize)
717{
718 for (const auto& i : m_full_name_variable_map) {
719 IMeshMaterialVariable* mv = i.second;
720 info(4) << "SYNC REFERENCES FROM MANAGER name=" << mv->name();
721 mv->_internalApi()->syncReferences(check_resize);
722 }
723}
724
725/*---------------------------------------------------------------------------*/
726/*---------------------------------------------------------------------------*/
727
728void MeshMaterialMng::
730{
731 if (!functor)
732 return;
733 for (const auto& i : m_full_name_variable_map) {
734 IMeshMaterialVariable* mv = i.second;
735 functor->executeFunctor(mv);
736 }
737}
738
739/*---------------------------------------------------------------------------*/
740/*---------------------------------------------------------------------------*/
741
742void MeshMaterialMng::
743checkValid()
744{
745 const IItemFamily* cell_family = mesh()->cellFamily();
746 ItemGroup all_cells = cell_family->allItems();
747 ConstArrayView<Int16> nb_env_per_cell = m_all_env_data->componentConnectivityList()->cellsNbEnvironment();
748 ENUMERATE_ALLENVCELL (iallenvcell, view(all_cells.view().localIds())) {
749 AllEnvCell all_env_cell = *iallenvcell;
750 Integer cell_nb_env = all_env_cell.nbEnvironment();
751 Cell cell = all_env_cell.globalCell();
752 Int64 cell_uid = cell.uniqueId();
753 if (all_env_cell.level() != LEVEL_ALLENVIRONMENT)
754 ARCANE_FATAL("Bad level for all_env_item");
755
756 if (all_env_cell.globalCell() != cell)
757 ARCANE_FATAL("Bad corresponding globalCell() in all_env_item");
758 if (cell_nb_env != nb_env_per_cell[cell.localId()])
759 ARCANE_FATAL("Bad value for nb_env direct='{0}' var='{1}'",
760 cell_nb_env, nb_env_per_cell[cell.localId()]);
761 for (Integer z = 0; z < cell_nb_env; ++z) {
762 EnvCell ec = all_env_cell.cell(z);
763 Integer cell_nb_mat = ec.nbMaterial();
764 matimpl::ConstituentItemBase eii = ec.constituentItemBase();
765 if (all_env_cell.constituentItemBase() != eii._superItemBase())
766 ARCANE_FATAL("Bad corresponding allEnvItem() in env_item uid={0}", cell_uid);
767 if (eii.globalItemBase() != cell)
768 ARCANE_FATAL("Bad corresponding globalItem() in env_item");
769 if (eii.level() != LEVEL_ENVIRONMENT)
770 ARCANE_FATAL("Bad level '{0}' for in env_item", eii.level());
771 // If the cell is not pure, the environment variable cannot be equivalent to
772 // the global variable.
773 if (cell_nb_env > 1 && ec._varIndex().arrayIndex() == 0)
774 ARCANE_FATAL("Global index for a partial cell env_item={0}", ec);
775
776 for (Integer k = 0; k < cell_nb_mat; ++k) {
777 MatCell mc = ec.cell(k);
778 matimpl::ConstituentItemBase mci = mc.constituentItemBase();
779 if (eii != mci._superItemBase())
780 ARCANE_FATAL("Bad corresponding env_item in mat_item k={0} mc={1}", k, mc);
781 if (mci.globalItemBase() != cell)
782 ARCANE_FATAL("Bad corresponding globalItem() in mat_item");
783 if (mci.level() != LEVEL_MATERIAL)
784 ARCANE_FATAL("Bad level '{0}' for in mat_item", mci.level());
785 // If the cell is not pure, the material variable cannot be equivalent to
786 // the global variable.
787 if ((cell_nb_env > 1 || cell_nb_mat > 1) && mc._varIndex().arrayIndex() == 0) {
788 ARCANE_FATAL("Global index for a partial cell matitem={0} name={1} nb_mat={2} nb_env={3}",
789 mc, mc.material()->name(), cell_nb_mat, cell_nb_env);
790 }
791 }
792 }
793 }
794
795 for (IMeshEnvironment* env : m_environments) {
796 env->checkValid();
797 }
798}
799
800/*---------------------------------------------------------------------------*/
801/*---------------------------------------------------------------------------*/
802
803IMeshMaterialVariable* MeshMaterialMng::
804findVariable(const String& name)
805{
806 IMeshMaterialVariable* v = _findVariableFullyQualified(name);
807 if (v)
808 return v;
809
810 // Searches for the global variable named \a name
811 // and if found, takes its full name for
812 // the material variable.
813 const IVariable* global_var = m_variable_mng->findMeshVariable(mesh(), name);
814 if (global_var) {
815 v = _findVariableFullyQualified(global_var->fullName());
816 if (v)
817 return v;
818 }
819
820 return nullptr;
821}
822
823/*---------------------------------------------------------------------------*/
824/*---------------------------------------------------------------------------*/
825
826IMeshMaterialVariable* MeshMaterialMng::
827_findVariableFullyQualified(const String& name)
828{
829 auto i = m_full_name_variable_map.find(name);
830 if (i != m_full_name_variable_map.end())
831 return i->second;
832 return nullptr;
833}
834
835/*---------------------------------------------------------------------------*/
836/*---------------------------------------------------------------------------*/
837
838IMeshMaterialVariable* MeshMaterialMng::
839checkVariable(IVariable* global_var)
840{
841 auto i = m_var_to_mat_var_map.find(global_var);
842 if (i != m_var_to_mat_var_map.end())
843 return i->second;
844 return nullptr;
845}
846
847/*---------------------------------------------------------------------------*/
848/*---------------------------------------------------------------------------*/
849
850void MeshMaterialMng::
851fillWithUsedVariables(Array<IMeshMaterialVariable*>& variables)
852{
853 variables.clear();
854
855 // Uses the map based on variable names to ensure the same
856 // traversal order regardless of sub-domains.
857 for (const auto& i : m_full_name_variable_map) {
858 IMeshMaterialVariable* ivar = i.second;
859 if (ivar->globalVariable()->isUsed())
860 variables.add(ivar);
861 }
862}
863
864/*---------------------------------------------------------------------------*/
865/*---------------------------------------------------------------------------*/
866
867void MeshMaterialMng::
868_addVariable(IMeshMaterialVariable* var)
869{
870 //TODO: the lock m_variable_lock must be active.
871 IVariable* gvar = var->globalVariable();
872 info(4) << "MAT_ADD_VAR global_var=" << gvar << " var=" << var << " this=" << this;
873 m_var_to_mat_var_map.insert(std::make_pair(gvar, var));
874 m_full_name_variable_map.insert(std::make_pair(gvar->fullName(), var));
875}
876
877/*---------------------------------------------------------------------------*/
878/*---------------------------------------------------------------------------*/
879
880void MeshMaterialMng::
881_removeVariable(IMeshMaterialVariable* var)
882{
883 //TODO: the lock m_variable_lock must be active.
884 IVariable* gvar = var->globalVariable();
885 info(4) << "MAT:Remove variable global_var=" << gvar << " var=" << var;
886 m_var_to_mat_var_map.erase(gvar);
887 m_full_name_variable_map.erase(gvar->fullName());
888}
889
890/*---------------------------------------------------------------------------*/
891/*---------------------------------------------------------------------------*/
892
893void MeshMaterialMng::
894dumpInfos(std::ostream& o)
895{
896 Integer nb_mat = m_materials.size();
897 Integer nb_env = m_environments.size();
898 Integer nb_var_idx = m_variables_indexer.size();
899 o << "-- Infos sur les milieux et matériaux\n";
900 o << "-- Nb Materiaux: " << nb_mat << '\n';
901 o << "-- Nb Milieux: " << nb_env << '\n';
902 o << "-- Nb Variables partielles: " << nb_var_idx << '\n';
903
904 o << "-- Liste des matériaux\n";
905 for (IMeshMaterial* mat : m_materials) {
906 o << "-- Materiau name=" << mat->name() << '\n';
907 }
908
909 o << "-- Liste des milieux\n";
910 for (IMeshEnvironment* me : m_environments) {
911 ConstArrayView<IMeshMaterial*> env_materials = me->materials();
912 const MeshMaterialVariableIndexer* env_var_idx = me->_internalApi()->variableIndexer();
913 Integer nb_env_mat = env_materials.size();
914 o << "-- Milieu name=" << me->name()
915 << " nb_mat=" << nb_env_mat
916 << " nb_cell=" << me->cells().size()
917 << " var_idx = " << env_var_idx->index()
918 << " ids=" << env_var_idx->matvarIndexes()
919 << '\n';
920 for (IMeshMaterial* mm : env_materials) {
921 const MeshMaterialVariableIndexer* idx = mm->_internalApi()->variableIndexer();
922 o << "-- Materiau\n";
923 o << "-- name = " << mm->name() << "\n";
924 o << "-- nb_cell = " << mm->cells().size() << "\n";
925 o << "-- var_idx = " << idx->index() << "\n";
926 }
927 }
928}
929
930/*---------------------------------------------------------------------------*/
931/*---------------------------------------------------------------------------*/
932
933// TODO: merge dumpInfos2() and dumpInfo().
934void MeshMaterialMng::
935dumpInfos2(std::ostream& o)
936{
937 const ConstituentConnectivityList& constituent_list = *m_all_env_data->componentConnectivityList();
938 ConstArrayView<Int16> nb_env_per_cell = constituent_list.cellsNbEnvironment();
939 Integer nb_mat = m_materials.size();
940 Integer nb_env = m_environments.size();
941 Integer nb_var_idx = m_variables_indexer.size();
942 o << "-- Material and Environment infos: nb_env=" << nb_env
943 << " nb_mat=" << nb_mat << " timestamp=" << m_timestamp
944 << " nb_var_idx=" << nb_var_idx
945 << "\n";
946 Integer nb_cell = mesh()->allCells().size();
947 if (nb_cell != 0) {
948 Integer nb_pure_env = 0;
949 ENUMERATE_CELL (icell, mesh()->allCells()) {
950 if (nb_env_per_cell[icell.localId()] <= 1)
951 ++nb_pure_env;
952 }
953 o << " nb_cell=" << nb_cell << " nb_pure_env=" << nb_pure_env
954 << " nb_partial=" << (nb_cell - nb_pure_env)
955 << " percent=" << (100 * nb_pure_env) / nb_cell
956 << "\n";
957 }
958
959 o << "-- Liste des milieux\n";
960 for (MeshEnvironment* me : m_true_environments) {
961 ConstArrayView<IMeshMaterial*> env_materials = me->materials();
962 const MeshMaterialVariableIndexer* env_var_idx = me->variableIndexer();
963 const Int16 env_id = me->componentId();
964 Integer nb_env_mat = env_materials.size();
965 Integer nb_env_cell = me->cells().size();
966 Integer nb_pure_mat = 0;
967 if (nb_env_mat > 1) {
968 ENUMERATE_CELL (icell, me->cells()) {
969 if (constituent_list.cellNbMaterial(icell, env_id) <= 1)
970 ++nb_pure_mat;
971 }
972 }
973 else
974 nb_pure_mat = nb_env_cell;
975 o << "-- Env name=" << me->name()
976 << " nb_mat=" << nb_env_mat
977 << " var_idx=" << env_var_idx->index()
978 << " nb_cell=" << nb_env_cell
979 << " nb_pure_mat=" << nb_pure_mat;
980 if (nb_env_cell != 0)
981 o << " percent=" << (nb_pure_mat * 100) / nb_env_cell;
982 o << '\n';
983 for (Integer j = 0; j < nb_env_mat; ++j) {
984 IMeshMaterial* mm = env_materials[j];
985 const MeshMaterialVariableIndexer* idx = mm->_internalApi()->variableIndexer();
986 o << "-- Mat name=" << mm->name()
987 << " nb_cell=" << mm->cells().size()
988 << " var_idx=" << idx->index()
989 << "\n";
990 }
991 }
992}
993
994/*---------------------------------------------------------------------------*/
995/*---------------------------------------------------------------------------*/
996
997bool MeshMaterialMng::
998synchronizeMaterialsInCells()
999{
1000 return m_mms->synchronizeMaterialsInCells();
1001}
1002
1003/*---------------------------------------------------------------------------*/
1004/*---------------------------------------------------------------------------*/
1005
1006void MeshMaterialMng::
1007checkMaterialsInCells(Integer max_print)
1008{
1009 m_mms->checkMaterialsInCells(max_print);
1010}
1011
1012/*---------------------------------------------------------------------------*/
1013/*---------------------------------------------------------------------------*/
1014
1015void MeshMaterialMng::
1016dumpCellInfos(Cell cell, std::ostream& o)
1017{
1018 CellToAllEnvCellConverter all_env_cell_converter(this);
1019 AllEnvCell all_env_cell = all_env_cell_converter[cell];
1020 Cell global_cell = all_env_cell.globalCell();
1021 o << "Cell uid=" << ItemPrinter(global_cell) << '\n';
1022 ENUMERATE_CELL_ENVCELL (ienvcell, all_env_cell) {
1023 o << "ENV name=" << (*ienvcell).environment()->name()
1024 << " component_idx=" << ComponentItemLocalId(ienvcell) << '\n';
1025 ENUMERATE_CELL_MATCELL (imatcell, (*ienvcell)) {
1026 o << "MAT name=" << (*imatcell).material()->name()
1027 << " component_idx=" << ComponentItemLocalId(imatcell) << '\n';
1028 }
1029 }
1030}
1031
1032/*---------------------------------------------------------------------------*/
1033/*---------------------------------------------------------------------------*/
1034
1036cellToAllEnvCellConverter()
1037{
1038 return CellToAllEnvCellConverter(componentItemSharedInfo(LEVEL_ALLENVIRONMENT));
1039}
1040
1041/*---------------------------------------------------------------------------*/
1042/*---------------------------------------------------------------------------*/
1043
1044void MeshMaterialMng::
1045_checkEndCreate()
1046{
1047 if (m_is_end_create)
1048 ARCANE_FATAL("Invalid method call because endCreate() has already been called");
1049}
1050
1051/*---------------------------------------------------------------------------*/
1052/*---------------------------------------------------------------------------*/
1053
1054AllEnvCellVectorView MeshMaterialMng::
1055_view(SmallSpan<const Int32> local_ids)
1056{
1057 return AllEnvCellVectorView(local_ids.constSmallView(), componentItemSharedInfo(LEVEL_ALLENVIRONMENT));
1058}
1059
1060/*---------------------------------------------------------------------------*/
1061/*---------------------------------------------------------------------------*/
1062
1063class MeshMaterialMngFactory
1065{
1066 public:
1067
1068 MeshMaterialMngFactory()
1069 {
1071 }
1072 ~MeshMaterialMngFactory()
1073 {
1075 }
1076
1077 public:
1078
1079 Ref<IMeshMaterialMng> getTrueReference(const MeshHandle& mesh_handle, bool is_create) override;
1080
1081 public:
1082
1083 static MeshMaterialMngFactory m_mesh_material_mng_factory;
1084};
1085
1086MeshMaterialMngFactory MeshMaterialMngFactory::m_mesh_material_mng_factory{};
1087
1088/*---------------------------------------------------------------------------*/
1089/*---------------------------------------------------------------------------*/
1090
1091Ref<IMeshMaterialMng> MeshMaterialMngFactory::
1092getTrueReference(const MeshHandle& mesh_handle, bool is_create)
1093{
1094 //TODO: implement lock for multi-threading
1095 typedef AutoDestroyUserData<Ref<IMeshMaterialMng>> UserDataType;
1096
1097 const char* name = "MeshMaterialMng_StdMat";
1098 IUserDataList* udlist = mesh_handle.meshUserDataList();
1099
1100 IUserData* ud = udlist->data(name, true);
1101 if (!ud) {
1102 if (!is_create)
1103 return {};
1104 IMeshMaterialMng* mm = arcaneCreateMeshMaterialMng(mesh_handle, "StdMat");
1105 Ref<IMeshMaterialMng> mm_ref = makeRef(mm);
1106 udlist->setData(name, new UserDataType(new Ref<IMeshMaterialMng>(mm_ref)));
1107 return mm_ref;
1108 }
1109 auto adud = dynamic_cast<UserDataType*>(ud);
1110 if (!adud)
1111 ARCANE_FATAL("Can not cast to IMeshMaterialMng*");
1112 return *(adud->data());
1113}
1114
1115/*---------------------------------------------------------------------------*/
1116/*---------------------------------------------------------------------------*/
1117
1118bool MeshMaterialMng::
1119isInMeshMaterialExchange() const
1120{
1121 return m_exchange_mng->isInMeshMaterialExchange();
1122}
1123
1124/*---------------------------------------------------------------------------*/
1125/*---------------------------------------------------------------------------*/
1126
1127void MeshMaterialMng::
1128_checkCreateProperties()
1129{
1130 if (m_properties)
1131 return;
1132 m_properties = std::make_unique<Properties>(*(mesh()->properties()), String("MeshMaterialMng_") + name());
1133}
1134
1135/*---------------------------------------------------------------------------*/
1136/*---------------------------------------------------------------------------*/
1137namespace
1138{
1139 const Int32 SERIALIZE_VERSION = 1;
1140}
1141void MeshMaterialMng::
1142_saveInfosInProperties()
1143{
1144 _checkCreateProperties();
1145
1146 // Save the version number to ensure compatibility during recovery
1147 m_properties->set("Version", SERIALIZE_VERSION);
1148
1149 // Save the necessary information in the properties to recreate the
1150 // materials and environments.
1151 UniqueArray<String> material_info_names;
1152 for (MeshMaterialInfo* mat_info : m_materials_info) {
1153 material_info_names.add(mat_info->name());
1154 }
1155 m_properties->set("MaterialInfoNames", material_info_names);
1156
1157 UniqueArray<String> env_names;
1158 UniqueArray<Int32> env_nb_mat;
1159 UniqueArray<String> env_mat_names;
1160 ENUMERATE_ENV (ienv, this) {
1161 IMeshEnvironment* env = *ienv;
1162 env_names.add(env->name());
1163 info(5) << "SAVE ENV_NAME name=" << env->name() << " nb_mat=" << env->nbMaterial();
1164 env_nb_mat.add(env->nbMaterial());
1165 ENUMERATE_MAT (imat, env) {
1166 const String& name = (*imat)->infos()->name();
1167 info(5) << "SAVE MAT_NAME name=" << name;
1168 env_mat_names.add(name);
1169 }
1170 }
1171 m_properties->set("EnvNames", env_names);
1172 m_properties->set("EnvNbMat", env_nb_mat);
1173 m_properties->set("EnvMatNames", env_mat_names);
1174
1175 // Save the necessary information for the blocks.
1176 // For each block, its name and the name of the corresponding cell group.
1177 UniqueArray<String> block_names;
1178 UniqueArray<String> block_cell_group_names;
1179 UniqueArray<Int32> block_nb_env;
1180 UniqueArray<String> block_env_names;
1181 for (IMeshBlock* block : m_blocks) {
1182 block_names.add(block->name());
1183 block_cell_group_names.add(block->cells().name());
1184 block_nb_env.add(block->nbEnvironment());
1185 ENUMERATE_ENV (ienv, block) {
1186 const String& name = (*ienv)->name();
1187 info(5) << "SAVE BLOCK ENV_NAME name=" << name;
1188 block_env_names.add(name);
1189 }
1190 }
1191 m_properties->set("BlockNames", block_names);
1192 m_properties->set("BlockCellGroupNames", block_cell_group_names);
1193 m_properties->set("BlockNbEnv", block_nb_env);
1194 m_properties->set("BlockEnvNames", block_env_names);
1195}
1196
1197/*---------------------------------------------------------------------------*/
1198/*---------------------------------------------------------------------------*/
1199
1200void MeshMaterialMng::
1201recreateFromDump()
1202{
1203 if (m_is_end_create)
1204 ARCANE_FATAL("Can not recreate a created instance");
1205
1206 _checkCreateProperties();
1207
1208 info() << "Creating material infos from dump";
1209
1210 // Save the version number to ensure compatibility during recovery
1211 Int32 v = m_properties->getInt32("Version");
1212 if (v != SERIALIZE_VERSION)
1213 ARCANE_FATAL("Bad serializer version: trying to read from incompatible checkpoint v={0} expected={1}",
1214 v, SERIALIZE_VERSION);
1215
1216 UniqueArray<String> material_info_names;
1217 m_properties->get("MaterialInfoNames", material_info_names);
1218 for (const String& mat_name : material_info_names)
1219 this->registerMaterialInfo(mat_name);
1220
1221 UniqueArray<String> env_names;
1222 UniqueArray<Int32> env_nb_mat;
1223 UniqueArray<String> env_mat_names;
1224 m_properties->get("EnvNames", env_names);
1225 m_properties->get("EnvNbMat", env_nb_mat);
1226 m_properties->get("EnvMatNames", env_mat_names);
1227
1228 Integer mat_index = 0;
1229 for (Integer ienv = 0, nenv = env_names.size(); ienv < nenv; ++ienv) {
1230 Materials::MeshEnvironmentBuildInfo env_build(env_names[ienv]);
1231 Integer nb_mat = env_nb_mat[ienv];
1232 for (Integer imat = 0; imat < nb_mat; ++imat) {
1233 env_build.addMaterial(env_mat_names[mat_index]);
1234 ++mat_index;
1235 }
1236 this->createEnvironment(env_build);
1237 }
1238
1239 // Recreate the blocks.
1240 // For each block, its name and the name of the corresponding cell group.
1241 UniqueArray<String> block_names;
1242 UniqueArray<String> block_cell_group_names;
1243 UniqueArray<String> block_env_names;
1244 UniqueArray<Int32> block_nb_env;
1245 m_properties->get("BlockNames", block_names);
1246 m_properties->get("BlockCellGroupNames", block_cell_group_names);
1247 m_properties->get("BlockNbEnv", block_nb_env);
1248 m_properties->get("BlockEnvNames", block_env_names);
1249 const IItemFamily* cell_family = mesh()->cellFamily();
1250 Integer block_env_index = 0;
1251 for (Integer i = 0, n = block_names.size(); i < n; ++i) {
1252 String name = block_names[i];
1253 String cell_group_name = block_cell_group_names[i];
1254 CellGroup cells = cell_family->findGroup(cell_group_name);
1255 if (cells.null())
1256 ARCANE_FATAL("Can not find cell group '{0}' for block creation",
1257 cell_group_name);
1258 MeshBlockBuildInfo mbbi(name, cells);
1259 if (!block_nb_env.empty()) {
1260 Integer nb_env = block_nb_env[i];
1261 for (Integer ienv = 0; ienv < nb_env; ++ienv) {
1262 const String& name2 = block_env_names[block_env_index];
1263 ++block_env_index;
1264 IMeshEnvironment* env = findEnvironment(name2, false);
1265 if (!env)
1266 ARCANE_FATAL("Invalid environment name '{0}' for recreating blocks", name2);
1267 mbbi.addEnvironment(env);
1268 }
1269 }
1270 this->createBlock(mbbi);
1271 }
1272
1273 endCreate(true);
1274}
1275
1276/*---------------------------------------------------------------------------*/
1277/*---------------------------------------------------------------------------*/
1278
1279void MeshMaterialMng::
1280_onMeshDestroyed()
1281{
1282 // This instance must be destroyed here because it requires IItemFamily
1283 // in its destructor, and it is possible that the family no longer exists
1284 // if the IMeshMaterialMng destructor is called after the mesh destruction
1285 // (which can happen in C# for example).
1286 m_exchange_mng.reset();
1287
1288 _unregisterAllVariables();
1289}
1290
1291/*---------------------------------------------------------------------------*/
1292/*---------------------------------------------------------------------------*/
1293
1294void MeshMaterialMng::
1295_unregisterAllVariables()
1296{
1297 // Copy all references into an array.
1298 // This must be done before calling unregisterVariable()
1299 // because the latter modifies the linked list of references
1301
1302 for (const auto& i : m_full_name_variable_map) {
1303 const IMeshMaterialVariable* var = i.second;
1304
1305 for (MeshMaterialVariableRef::Enumerator iref(var); iref.hasNext(); ++iref) {
1306 MeshMaterialVariableRef* ref = *iref;
1307 m_all_refs.add(ref);
1308 }
1309 }
1310
1311 for (MeshMaterialVariableRef* ref : m_all_refs)
1312 ref->unregisterVariable();
1313}
1314
1315/*---------------------------------------------------------------------------*/
1316/*---------------------------------------------------------------------------*/
1317
1318ComponentItemSharedInfo* MeshMaterialMng::
1319componentItemSharedInfo(Int32 level) const
1320{
1321 ComponentItemInternalData* data = m_all_env_data->componentItemInternalData();
1322 ComponentItemSharedInfo* shared_info = nullptr;
1323 if (level == LEVEL_MATERIAL)
1324 shared_info = data->matSharedInfo();
1325 else if (level == LEVEL_ENVIRONMENT)
1326 shared_info = data->envSharedInfo();
1327 else if (level == LEVEL_ALLENVIRONMENT)
1328 shared_info = data->allEnvSharedInfo();
1329 else
1330 ARCANE_FATAL("Bad internal type of component");
1331
1332 return shared_info;
1333}
1334
1335/*---------------------------------------------------------------------------*/
1336/*---------------------------------------------------------------------------*/
1337
1338void MeshMaterialMng::
1339_dumpStats()
1340{
1341 IEnumeratorTracer* tracer = IEnumeratorTracer::singleton();
1342 if (tracer)
1343 tracer->dumpStats();
1344
1345 if (m_modifier)
1346 m_modifier->dumpStats();
1347
1348 for (IMeshEnvironment* env : m_environments) {
1349 // Do not display statistics if the environment has only one material
1350 // because it uses the same indexer as the material and the statistics
1351 // for it will be displayed when iterating over the materials.
1352 if (env->nbMaterial() > 1)
1353 env->_internalApi()->variableIndexer()->dumpStats();
1354 }
1355 for (IMeshMaterial* mat : m_materials) {
1356 mat->_internalApi()->variableIndexer()->dumpStats();
1357 }
1358}
1359
1360/*---------------------------------------------------------------------------*/
1361/*---------------------------------------------------------------------------*/
1362
1363void MeshMaterialMng::
1364createAllCellToAllEnvCell()
1365{
1366 if (!m_accelerator_envcell_container) {
1367 m_accelerator_envcell_container = std::make_unique<AllCellToAllEnvCellContainer>(this);
1368 m_accelerator_envcell_container->initialize();
1369 }
1370}
1371
1372/*---------------------------------------------------------------------------*/
1373/*---------------------------------------------------------------------------*/
1374
1375SmallSpan<const Int32> MeshMaterialMng::
1376identitySelectionView()
1377{
1378 // NOTE: this array could perhaps be managed directly
1379 // by the family if there is interest in using it in other contexts
1380 Int32 max_local_id = m_mesh_handle.mesh()->cellFamily()->maxLocalId();
1381 {
1382 std::scoped_lock sl(m_indexed_selection_identity_mutex);
1383 Int32 size = m_indexed_selection_identity.size();
1384 if (max_local_id > size) {
1385 m_indexed_selection_identity.resize(max_local_id);
1386 for (Int32 i = size; i < max_local_id; ++i)
1387 m_indexed_selection_identity[i] = i;
1388 }
1389 return m_indexed_selection_identity.constView();
1390 }
1391}
1392
1393/*---------------------------------------------------------------------------*/
1394/*---------------------------------------------------------------------------*/
1395
1396} // End namespace Arcane::Materials
1397
1398/*---------------------------------------------------------------------------*/
1399/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
#define ENUMERATE_CELL(name, group)
Generic enumerator for a cell group.
Memory and allocator management functions.
Integer size() const
Number of elements in the vector.
bool empty() const
Capacity (number of allocated elements) of the vector.
Base class for 1D data vectors.
void clear()
Removes the elements from the array.
void add(ConstReferenceType val)
Adds element val to the end of the array.
UserData that self-destructs once detached.
Cell of a mesh.
Definition Item.h:1300
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
Interface of a functor with an argument but without a return value.
Interface of an entity family.
Definition IItemFamily.h:83
virtual ItemGroup findGroup(const String &name) const =0
Searches for a group.
virtual ItemGroup allItems() const =0
Group of all entities.
Interface of a list that manages user data.
virtual void setData(const String &name, IUserData *ud)=0
Sets the user data associated with the name name.
virtual IUserData * data(const String &name, bool allow_null=false) const =0
Data associated with name.
Interface for user data attached to another object.
Definition IUserData.h:33
Interface of a variable.
Definition IVariable.h:40
virtual String fullName() const =0
Full variable name (with family prefix).
virtual bool isUsed() const =0
Usage state of the variable.
Mesh entity group.
Definition ItemGroup.h:51
ItemVectorView view() const
View of the group entities.
Definition ItemGroup.cc:580
bool null() const
true means the group is the null group
Definition ItemGroup.h:75
Utility class for printing information about an entity.
Definition ItemPrinter.h:35
Int32ConstArrayView localIds() const
Array of local IDs of entities.
constexpr Int32 localId() const
Local identifier of the entity in the processor subdomain.
Definition Item.h:233
ItemUniqueId uniqueId() const
Unique identifier across all domains.
Definition Item.h:239
View over a list of cells with environment information.
Arcane cell with material and environment information.
__host__ __device__ Int32 nbEnvironment() const
Number of environments present in the cell.
EnvCell cell(Int32 i) const
i-th environment cell
Management of constituent connectivity lists.
Int16 cellNbMaterial(CellLocalId cell_id, Int16 env_id)
Number of materials of the cell cell_id for environment index env_id.
Cell globalCell() const
Global cell.
__host__ __device__ Int32 level() const
Hierarchical level of the entity.
__host__ __device__ MatVarIndex _varIndex() const
Arcane cell of an environment.
__host__ __device__ MatCell cell(Integer i) const
i-th material cell of this cell
virtual String name() const =0
Component name.
Interface for the material and environment manager of a mesh.
static void _internalSetFactory(IFactory *f)
Interface of the material variable factory manager.
virtual void syncReferences(bool check_resize)=0
Synchronizes references.
Interface of a material variable on a mesh.
virtual IVariable * globalVariable() const =0
Associated global variable on the mesh.
virtual String name() const =0
Name of the variable.
virtual void buildFromManager(bool is_continue)=0
Builds the variable information. For internal use in Arcane.
Represents a material in a multi-material cell.
IMeshMaterial * material() const
Associated material.
constexpr __host__ __device__ Int32 arrayIndex() const
Returns the index of the value array in the list of variables.
Brief: Information for the creation of a block.
const String & name() const
Block name.
void addEnvironment(IMeshEnvironment *env)
Brief: Adds the environment env to the block.
ConstArrayView< IMeshEnvironment * > environments() const
List of environments in the block.
void addEnvironment(IMeshEnvironment *env)
Adds the environment env to the block.
Definition MeshBlock.cc:69
void build()
Public functions but reserved for IMeshMaterialMng.
Definition MeshBlock.cc:46
void removeEnvironment(IMeshEnvironment *env)
Removes the environment env from the block.
Definition MeshBlock.cc:88
Information for creating an environment.
void addMaterial(const String &name)
Adds the material named name to the environment.
const String & name() const
Name of the environment.
void build()
Public functions but reserved for IMeshMaterialMng.
ConstArrayView< IMeshMaterial * > materials() override
List of materials in this environment.
IMeshMaterialMng * materialMng() override
Associated manager.
String name() const override
Component name.
Info about a material of a mesh.
IMeshMaterialMng * materialMng()
Associated manager.
Implementation of a material manager.
AllEnvCellVectorView view(const CellGroup &cells) final
View of environment cells corresponding to the group cells.
void endCreate(bool is_continue) override
Indicates that environment creation is finished.
IMeshBlock * createBlock(const MeshBlockBuildInfo &infos) override
Creates a block.
ITraceMng * traceMng() override
Trace manager.
IMesh * mesh() override
Associated mesh.
MeshMaterialInfo * registerMaterialInfo(const String &name) override
Registers the material info with name name.
IMeshEnvironment * createEnvironment(const MeshEnvironmentBuildInfo &infos) override
Creation of an environment.
void _endUpdate()
Updates the structures following a modification of material or environment cells.
IMeshEnvironment * findEnvironment(const String &name, bool throw_exception=true) override
Returns the environment with name name.
MeshMaterial * _createMaterial(MeshEnvironment *env, MeshMaterialInfo *infos, const String &name)
Creation of a material.
String name() const override
Manager name.
const String & name() const
Name of the indexer.
void build()
Public functions but reserved for IMeshMaterialMng.
General information about a constituent entity.
__host__ __device__ matimpl::ConstituentItemBase _superItemBase() const
Parent component (0 if none).
impl::ItemBase globalItemBase() const
Corresponding global entity.
Handle on a mesh.
Definition MeshHandle.h:48
IUserDataList * meshUserDataList() const
Associated user data.
Definition MeshHandle.h:158
Reference to an instance.
View of an array of elements of type T.
Definition Span.h:805
constexpr ConstArrayView< value_type > constSmallView() const
Constant view of this view.
Definition Span.h:401
TraceMessage info() const
Flow for an information message.
1D data vector with value semantics (STL style).
#define ENUMERATE_ENV(ienv, container)
Macro to iterate over a list of environments.
#define ENUMERATE_CELL_MATCELL(iname, env_cell)
Macro to iterate over all MatCell cells of a cell.
#define ENUMERATE_CELL_ENVCELL(iname, all_env_cell)
Macro to iterate over all EnvCell cells of a cell.
#define ENUMERATE_ALLENVCELL(iname,...)
Macro to iterate over all AllEnvCell cells of a group.
#define ENUMERATE_MAT(imat, container)
Macro to iterate over a list of materials.
ItemGroupT< Cell > CellGroup
Group of cells.
Definition ItemTypes.h:184
RunQueue makeQueue(const Runner &runner)
Creates a queue associated with runner.
eExecutionPolicy
Execution policy for a Runner.
@ Thread
Multi-threaded execution policy.
bool isAcceleratorPolicy(eExecutionPolicy exec_policy)
Indicates if exec_policy corresponds to an accelerator.
Always enables tracing in Arcane parts concerning materials.
@ Environment
Variable having values only on environments.
@ MaterialAndEnvironment
Variable having values on environments and materials.
IMemoryAllocator * getDefaultDataAllocator()
Default allocator for data.
bool arcaneIsCheck()
True if running in check mode.
Definition Misc.cc:66
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
std::int16_t Int16
Signed integer type of 16 bits.
std::int32_t Int32
Signed integer type of 32 bits.
Memory management utility functions.