14#include "arcane/utils/NotSupportedException.h"
15#include "arcane/utils/PlatformUtils.h"
16#include "arcane/utils/ITraceMng.h"
17#include "arcane/utils/ValueConvert.h"
19#include "arcane/core/IItemFamily.h"
20#include "arcane/core/IData.h"
21#include "arcane/core/materials/internal/IMeshComponentInternal.h"
23#include "arcane/accelerator/core/ProfileRegion.h"
25#include "arcane/materials/IMeshMaterial.h"
26#include "arcane/materials/IMeshMaterialVariable.h"
27#include "arcane/materials/MeshMaterialBackup.h"
28#include "arcane/materials/internal/MeshMaterialMng.h"
29#include "arcane/materials/internal/AllEnvData.h"
30#include "arcane/materials/internal/MeshMaterialModifierImpl.h"
31#include "arcane/materials/internal/MaterialModifierOperation.h"
32#include "arcane/materials/internal/IncrementalComponentModifier.h"
33#include "arcane/materials/internal/ConstituentListPrinter.h"
44MeshMaterialModifierImpl::OperationList::
53void MeshMaterialModifierImpl::OperationList::
62void MeshMaterialModifierImpl::OperationList::
65 for (Operation* o : m_operations)
76MeshMaterialModifierImpl::
77MeshMaterialModifierImpl(MeshMaterialMng* mm)
80, m_queue(m_material_mng->runQueue())
82 _setLocalVerboseLevel(4);
83 if (
auto v = Convert::Type<Int32>::tryParseFromEnvironment(
"ARCANE_DEBUG_MATERIAL_MODIFIER",
true)) {
84 Int32 value = v.value();
86 _setLocalVerboseLevel(3);
90 m_print_component_list =
true;
100void MeshMaterialModifierImpl::
101initOptimizationFlags()
103 int opt_flag_value = m_material_mng->modificationFlags();
105 m_allow_optimization =
false;
107 info() <<
"OptimizationFlag = " << opt_flag_value;
109 if (opt_flag_value != 0) {
110 info() <<
"Using optimization !";
111 m_allow_optimization =
true;
114 m_allow_optimize_multiple_operation = (opt_flag_value & (int)eModificationFlags::OptimizeMultiAddRemove) != 0;
115 m_allow_optimize_multiple_material = (opt_flag_value & (int)eModificationFlags::OptimizeMultiMaterialPerEnvironment) != 0;
116 m_use_incremental_recompute =
true;
117 if (m_use_incremental_recompute) {
118 m_allow_optimize_multiple_operation =
true;
121 info() <<
"MeshMaterialModifier::optimization:"
122 <<
" allow?=" << m_allow_optimization
123 <<
" allow_multiple?=" << m_allow_optimize_multiple_operation
124 <<
" allow_multiple_mat?=" << m_allow_optimize_multiple_material
125 <<
" use_incremental_recompute?=" << m_use_incremental_recompute;
131void MeshMaterialModifierImpl::
132addCells(IMeshMaterial* mat, SmallSpan<const Int32> ids)
136 m_operations.add(Operation::createAdd(mat, ids));
142void MeshMaterialModifierImpl::
143removeCells(IMeshMaterial* mat, SmallSpan<const Int32> ids)
147 m_operations.add(Operation::createRemove(mat, ids));
153void MeshMaterialModifierImpl::
154_addCellsToGroupDirect(IMeshMaterial* mat, SmallSpan<const Int32> ids)
157 info(4) <<
"ADD_CELLS_TO_MATERIAL: mat=" << mat->
name()
158 <<
" nb_item=" << ids.size();
159 cells.addItems(ids.smallView());
165void MeshMaterialModifierImpl::
166_removeCellsToGroupDirect(IMeshMaterial* mat, SmallSpan<const Int32> ids)
169 info(4) <<
"REMOVE_CELLS_TO_MATERIAL: mat=" << mat->
name()
170 <<
" nb_item=" << ids.size();
171 cells.removeItems(ids.smallView());
177bool MeshMaterialModifierImpl::
180 Integer nb_operation = m_operations.values().size();
181 if (nb_operation > 1 && !m_allow_optimize_multiple_operation)
183 for (Integer i = 0; i < nb_operation; ++i) {
184 Operation* op = m_operations.values()[i];
185 IMeshMaterial* mat = op->material();
186 if (mat->environment()->nbMaterial() != 1 && !m_allow_optimize_multiple_material) {
187 linfo() <<
"_checkMayOptimize(): not allowing optimization because environment has several material";
200void MeshMaterialModifierImpl::
204 if (m_print_component_list) {
205 info() <<
"MeshMaterialModifierImpl::endUpdate(): BEGIN"
206 <<
" modification_id=" << m_modification_id;
207 list_printer.print();
210 if (m_print_component_list) {
211 info() <<
"MeshMaterialModifierImpl::endUpdate(): END"
212 <<
" modification_id=" << m_modification_id;
213 list_printer.print();
221void MeshMaterialModifierImpl::
226 bool is_keep_value = m_material_mng->isKeepValuesAfterChange();
227 Integer nb_operation = m_operations.values().size();
229 linfo() <<
"END_UPDATE_MAT_Begin keep=" << is_keep_value
230 <<
" nb_operation=" << nb_operation;
232 m_material_mng->incrementTimestamp();
236 bool no_optimization_done =
true;
239 AllEnvData* all_env_data = m_material_mng->allEnvData();
241 bool is_display = traceMng()->verbosityLevel() >= _localVerboseLevel();
243 for (
Integer i = 0; i < nb_operation; ++i) {
244 const Operation* op = m_operations.values()[i];
251 linfo() <<
"MODIFIER_CELLS_TO_MATERIAL: mat=" << mat->
name()
252 <<
" is_add=" << op->isAdd()
255 <<
" ids=" << op->ids();
258 bool is_optimization_active = m_allow_optimization;
259 if (is_optimization_active)
260 is_optimization_active = _checkMayOptimize();
261 linfo() <<
"Check optimize ? = " << is_optimization_active;
264 if (!m_incremental_modifier) {
265 linfo() <<
"Creating IncrementalComponentModifier";
266 m_incremental_modifier = std::make_unique<IncrementalComponentModifier>(all_env_data, m_queue);
268 if (is_optimization_active && m_use_incremental_recompute) {
269 m_incremental_modifier->initialize(m_is_debug);
270 m_incremental_modifier->setDoCopyBetweenPartialAndPure(m_do_copy_between_partial_and_pure);
271 m_incremental_modifier->setDoInitNewItems(m_do_init_new_items);
274 if (is_optimization_active) {
275 for (Operation* op : m_operations.values()) {
276 const IMeshMaterial* mat = op->material();
279 linfo() <<
"ONLY_ONE_ADD: using optimization mat=" << mat->name();
283 linfo() <<
"ONLY_ONE_REMOVE: using optimization mat=" << mat->name();
284 ++nb_optimize_remove;
287 m_incremental_modifier->m_work_info.setCurrentOperation(op);
294 m_incremental_modifier->apply(op);
296 no_optimization_done =
false;
299 if (no_optimization_done) {
305 _applyOperationsNoOptimize();
306 _updateEnvironmentsNoOptimize();
311 backup.restoreValues();
315 m_incremental_modifier->finalize();
316 all_env_data->recomputeIncremental();
319 if (!m_is_keep_work_buffer)
320 m_incremental_modifier =
nullptr;
322 linfo() <<
"END_UPDATE_MAT End";
328void MeshMaterialModifierImpl::
329_applyOperationsNoOptimize()
331 for (Operation* o : m_operations.values()) {
332 IMeshMaterial* mat = o->material();
334 _addCellsToGroupDirect(mat, o->ids());
336 _removeCellsToGroupDirect(mat, o->ids());
338 m_operations.clear();
344void MeshMaterialModifierImpl::
345_updateEnvironmentsNoOptimize()
347 ConstArrayView<IMeshEnvironment*> envs = m_material_mng->environments();
350 info(4) <<
"CHECK ENVIRONMENTS";
355 for (IMeshEnvironment* env : envs) {
359 if (env->nbMaterial() == 1)
363 info(4) <<
"CHECK ENV name=" << env->
name() <<
" nb_cell=" << env_cells.size();
364 Integer max_id = env_cells.itemFamily()->maxLocalId();
367 cells_marker[icell.itemLocalId()] = 0;
369 cells_to_add.
clear();
370 cells_to_remove.clear();
371 ConstArrayView<IMeshMaterial*> env_materials = env->materials();
372 for (IMeshMaterial* mat : env_materials) {
374 Int32 mark = cells_marker[icell.itemLocalId()];
378 cells_to_add.add(icell.itemLocalId());
381 cells_marker[icell.itemLocalId()] = 1;
386 Int32 mark = cells_marker[icell.itemLocalId()];
388 cells_to_remove.add(icell.itemLocalId());
390 if (!cells_to_add.empty()) {
391 info(4) <<
"ADD_CELLS to env " << env->name() <<
" n=" << cells_to_add.size();
392 env_cells.addItems(cells_to_add);
394 if (!cells_to_remove.empty()) {
395 info(4) <<
"REMOVE_CELLS to env " << env->name() <<
" n=" << cells_to_remove.size();
396 env_cells.removeItems(cells_to_remove);
404void MeshMaterialModifierImpl::
407 m_do_copy_between_partial_and_pure =
true;
408 m_do_init_new_items =
true;
409 m_is_keep_work_buffer =
true;
415void MeshMaterialModifierImpl::
418 m_material_mng->info(4) <<
"BEGIN_UPDATE_MAT";
419 m_operations.clear();
425void MeshMaterialModifierImpl::
428 info() <<
"MeshMaterialModifierImpl statistics mesh=" << m_material_mng->mesh()->name();
430 info() <<
" Nb update : " << nb_update;
431 info() <<
" Nb save/restore : " << nb_save_restore;
432 info() <<
" Nb optimized add : " << nb_optimize_add;
433 info() <<
" Nb optimized remove : " << nb_optimize_remove;
void clear()
Removes the elements from the array.
const String & name() const
Group name.
Information on environment values.
void forceRecompute(bool compute_all)
Updates structures following a modification of material or environment cells.
Utility functions for displaying constituents.
Arcane internal API for 'IMeshComponent'.
virtual MeshMaterialVariableIndexer * variableIndexer() const =0
Indexer to access partial variables.
virtual String name() const =0
Component name.
virtual IMeshComponentInternal * _internalApi()=0
Internal API.
Interface of a mesh material.
Saving/restoring material and medium values.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage info() const
Flow for an information message.
ITraceMng * traceMng() const
Trace manager.
ItemGroupT< Cell > CellGroup
Group of cells.
Always enables tracing in Arcane parts concerning materials.
bool arcaneIsCheck()
True if running in check mode.
Int32 Integer
Type representing an integer.
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.