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"
47MeshMaterialModifierImpl::OperationList::
56void MeshMaterialModifierImpl::OperationList::
65void MeshMaterialModifierImpl::OperationList::
68 for( Operation* o : m_operations )
79MeshMaterialModifierImpl::
80MeshMaterialModifierImpl(MeshMaterialMng* mm)
81: TraceAccessor(mm->traceMng())
83, m_queue(m_material_mng->runQueue())
85 _setLocalVerboseLevel(4);
86 if (
auto v = Convert::Type<Int32>::tryParseFromEnvironment(
"ARCANE_DEBUG_MATERIAL_MODIFIER",
true)) {
87 Int32 value = v.value();
89 _setLocalVerboseLevel(3);
93 m_print_component_list =
true;
103void MeshMaterialModifierImpl::
104initOptimizationFlags()
106 int opt_flag_value = m_material_mng->modificationFlags();
108 m_allow_optimization =
false;
110 info() <<
"OptimizationFlag = " << opt_flag_value;
112 if (opt_flag_value!=0){
113 info() <<
"Using optimization !";
114 m_allow_optimization =
true;
117 m_allow_optimize_multiple_operation = (opt_flag_value & (int)eModificationFlags::OptimizeMultiAddRemove)!=0;
118 m_allow_optimize_multiple_material = (opt_flag_value & (int)eModificationFlags::OptimizeMultiMaterialPerEnvironment)!=0;
119 m_use_incremental_recompute =
true;
120 if (m_use_incremental_recompute){
121 m_allow_optimize_multiple_operation =
true;
124 info() <<
"MeshMaterialModifier::optimization: "
125 <<
" allow?=" << m_allow_optimization
126 <<
" allow_multiple?=" << m_allow_optimize_multiple_operation
127 <<
" allow_multiple_mat?=" << m_allow_optimize_multiple_material
128 <<
" use_incremental_recompute?=" << m_use_incremental_recompute;
134void MeshMaterialModifierImpl::
135addCells(IMeshMaterial* mat, SmallSpan<const Int32> ids)
139 m_operations.add(Operation::createAdd(mat, ids));
145void MeshMaterialModifierImpl::
146removeCells(IMeshMaterial* mat, SmallSpan<const Int32> ids)
150 m_operations.add(Operation::createRemove(mat, ids));
156void MeshMaterialModifierImpl::
157_addCellsToGroupDirect(IMeshMaterial* mat,SmallSpan<const Int32> ids)
160 info(4) <<
"ADD_CELLS_TO_MATERIAL: mat=" << mat->
name()
161 <<
" nb_item=" << ids.size();
162 cells.addItems(ids.smallView());
168void MeshMaterialModifierImpl::
169_removeCellsToGroupDirect(IMeshMaterial* mat,SmallSpan<const Int32> ids)
172 info(4) <<
"REMOVE_CELLS_TO_MATERIAL: mat=" << mat->
name()
173 <<
" nb_item=" << ids.size();
174 cells.removeItems(ids.smallView());
180bool MeshMaterialModifierImpl::
183 Integer nb_operation = m_operations.values().size();
184 if (nb_operation>1 && !m_allow_optimize_multiple_operation)
186 for( Integer i=0; i<nb_operation; ++i ){
187 Operation* op = m_operations.values()[i];
188 IMeshMaterial* mat = op->material();
189 if (mat->environment()->nbMaterial()!=1 && !m_allow_optimize_multiple_material){
190 linfo() <<
"_checkMayOptimize(): not allowing optimization because environment has several material";
202void MeshMaterialModifierImpl::
205 ConstituentListPrinter list_printer(m_material_mng);
206 if (m_print_component_list){
207 info() <<
"MeshMaterialModifierImpl::endUpdate(): BEGIN"
208 <<
" modification_id=" << m_modification_id;
209 list_printer.print();
212 if (m_print_component_list){
213 info() <<
"MeshMaterialModifierImpl::endUpdate(): END"
214 <<
" modification_id=" << m_modification_id;
215 list_printer.print();
223void MeshMaterialModifierImpl::
226 Accelerator::ProfileRegion ps(m_queue,
"ConstituentsEndUpdate", 0x97599A);
228 bool is_keep_value = m_material_mng->isKeepValuesAfterChange();
229 Integer nb_operation = m_operations.values().size();
231 linfo() <<
"END_UPDATE_MAT_Begin keep=" << is_keep_value
232 <<
" nb_operation=" << nb_operation;
234 m_material_mng->incrementTimestamp();
236 MeshMaterialBackup backup(m_material_mng,
false);
238 bool no_optimization_done =
true;
241 AllEnvData* all_env_data = m_material_mng->allEnvData();
243 bool is_display = traceMng()->verbosityLevel() >= _localVerboseLevel();
245 for (Integer i = 0; i < nb_operation; ++i) {
246 const Operation* op = m_operations.values()[i];
247 IMeshMaterial* mat = op->material();
248 const IMeshComponentInternal* mci = mat->_internalApi();
253 linfo() <<
"MODIFIER_CELLS_TO_MATERIAL: mat=" << mat->name()
254 <<
" is_add=" << op->isAdd()
255 <<
" mat_index=" << mci->variableIndexer()->index()
257 <<
" ids=" << op->ids();
260 bool is_optimization_active = m_allow_optimization;
261 if (is_optimization_active)
262 is_optimization_active = _checkMayOptimize();
263 linfo() <<
"Check optimize ? = " << is_optimization_active;
266 if (!m_incremental_modifier){
267 linfo() <<
"Creating IncrementalComponentModifier";
268 m_incremental_modifier = std::make_unique<IncrementalComponentModifier>(all_env_data, m_queue);
270 if (is_optimization_active && m_use_incremental_recompute) {
271 m_incremental_modifier->initialize(m_is_debug);
272 m_incremental_modifier->setDoCopyBetweenPartialAndPure(m_do_copy_between_partial_and_pure);
273 m_incremental_modifier->setDoInitNewItems(m_do_init_new_items);
276 if (is_optimization_active) {
277 for (Operation* op : m_operations.values()) {
278 const IMeshMaterial* mat = op->material();
281 linfo() <<
"ONLY_ONE_ADD: using optimization mat=" << mat->name();
285 linfo() <<
"ONLY_ONE_REMOVE: using optimization mat=" << mat->name();
286 ++nb_optimize_remove;
289 m_incremental_modifier->m_work_info.setCurrentOperation(op);
296 m_incremental_modifier->apply(op);
298 no_optimization_done =
false;
301 if (no_optimization_done) {
307 _applyOperationsNoOptimize();
308 _updateEnvironmentsNoOptimize();
310 all_env_data->forceRecompute(
true);
313 backup.restoreValues();
317 m_incremental_modifier->finalize();
318 all_env_data->recomputeIncremental();
321 if (!m_is_keep_work_buffer)
322 m_incremental_modifier =
nullptr;
324 linfo() <<
"END_UPDATE_MAT End";
330void MeshMaterialModifierImpl::
331_applyOperationsNoOptimize()
333 for( Operation* o : m_operations.values() ){
334 IMeshMaterial* mat = o->material();
336 _addCellsToGroupDirect(mat,o->ids());
338 _removeCellsToGroupDirect(mat,o->ids());
340 m_operations.clear();
346void MeshMaterialModifierImpl::
347_updateEnvironmentsNoOptimize()
349 ConstArrayView<IMeshEnvironment*> envs = m_material_mng->environments();
352 info(4) <<
"CHECK ENVIRONMENTS";
357 for( IMeshEnvironment* env : envs ){
361 if (env->nbMaterial()==1)
365 info(4) <<
"CHECK ENV name=" << env->
name() <<
" nb_cell=" << env_cells.size();
366 Integer max_id = env_cells.itemFamily()->maxLocalId();
369 cells_marker[icell.itemLocalId()] = 0;
371 cells_to_add.clear();
372 cells_to_remove.clear();
373 ConstArrayView<IMeshMaterial*> env_materials = env->materials();
374 for( IMeshMaterial* mat : env_materials ){
376 Int32 mark = cells_marker[icell.itemLocalId()];
380 cells_to_add.add(icell.itemLocalId());
383 cells_marker[icell.itemLocalId()] = 1;
388 Int32 mark = cells_marker[icell.itemLocalId()];
390 cells_to_remove.add(icell.itemLocalId());
392 if (!cells_to_add.empty()){
393 info(4) <<
"ADD_CELLS to env " << env->name() <<
" n=" << cells_to_add.size();
394 env_cells.addItems(cells_to_add);
396 if (!cells_to_remove.empty()){
397 info(4) <<
"REMOVE_CELLS to env " << env->name() <<
" n=" << cells_to_remove.size();
398 env_cells.removeItems(cells_to_remove);
407void MeshMaterialModifierImpl::
410 m_do_copy_between_partial_and_pure =
true;
411 m_do_init_new_items =
true;
412 m_is_keep_work_buffer =
true;
418void MeshMaterialModifierImpl::
421 m_material_mng->info(4) <<
"BEGIN_UPDATE_MAT";
422 m_operations.clear();
428void MeshMaterialModifierImpl::
431 info() <<
"MeshMaterialModifierImpl statistics:";
432 info() <<
" Nb update : " << nb_update;
433 info() <<
" Nb save/restore : " << nb_save_restore;
434 info() <<
" Nb optimized add : " << nb_optimize_add;
435 info() <<
" Nb optimized remove : " << nb_optimize_remove;
const String & name() const
Nom du groupe.
ItemGroupT< Cell > CellGroup
Groupe de mailles.
Active toujours les traces dans les parties Arcane concernant les matériaux.
bool arcaneIsCheck()
Vrai si on est en mode vérification.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Int32 Integer
Type représentant un entier.