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 mesh=" << m_material_mng->mesh()->name();
433 info() <<
" Nb update : " << nb_update;
434 info() <<
" Nb save/restore : " << nb_save_restore;
435 info() <<
" Nb optimized add : " << nb_optimize_add;
436 info() <<
" Nb optimized remove : " << nb_optimize_remove;
void clear()
Supprime les éléments du tableau.
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.
Int32 Integer
Type représentant un entier.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.