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