Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
MeshMaterialModifierImpl.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 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/* MeshMaterialModifierImpl.cc (C) 2000-2024 */
9/* */
10/* Implémentation de la modification des matériaux et milieux. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/NotSupportedException.h"
15#include "arcane/utils/PlatformUtils.h"
16#include "arcane/utils/ITraceMng.h"
17#include "arcane/utils/ValueConvert.h"
18
19#include "arcane/core/IItemFamily.h"
20#include "arcane/core/IData.h"
21#include "arcane/core/materials/internal/IMeshComponentInternal.h"
22
23#include "arcane/accelerator/core/ProfileRegion.h"
24
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"
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37
38namespace Arcane::Materials
39{
40
41/*---------------------------------------------------------------------------*/
42/*---------------------------------------------------------------------------*/
43
44/*---------------------------------------------------------------------------*/
45/*---------------------------------------------------------------------------*/
46
47MeshMaterialModifierImpl::OperationList::
48~OperationList()
49{
50 clear();
51}
52
53/*---------------------------------------------------------------------------*/
54/*---------------------------------------------------------------------------*/
55
56void MeshMaterialModifierImpl::OperationList::
57add(Operation* o)
58{
59 m_operations.add(o);
60}
61
62/*---------------------------------------------------------------------------*/
63/*---------------------------------------------------------------------------*/
64
65void MeshMaterialModifierImpl::OperationList::
66clear()
67{
68 for( Operation* o : m_operations )
69 delete o;
70 m_operations.clear();
71}
72
73/*---------------------------------------------------------------------------*/
74/*---------------------------------------------------------------------------*/
75
76/*---------------------------------------------------------------------------*/
77/*---------------------------------------------------------------------------*/
78
79MeshMaterialModifierImpl::
80MeshMaterialModifierImpl(MeshMaterialMng* mm)
81: TraceAccessor(mm->traceMng())
82, m_material_mng(mm)
83, m_queue(m_material_mng->runQueue())
84{
85 _setLocalVerboseLevel(4);
86 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_DEBUG_MATERIAL_MODIFIER", true)) {
87 Int32 value = v.value();
88 if (value > 0) {
89 _setLocalVerboseLevel(3);
90 m_is_debug = true;
91 }
92 if (value > 1)
93 m_print_component_list = true;
94 }
95}
96
97/*---------------------------------------------------------------------------*/
98/*---------------------------------------------------------------------------*/
99
100/*---------------------------------------------------------------------------*/
101/*---------------------------------------------------------------------------*/
102
103void MeshMaterialModifierImpl::
104initOptimizationFlags()
105{
106 int opt_flag_value = m_material_mng->modificationFlags();
107
108 m_allow_optimization = false;
109
110 info() << "OptimizationFlag = " << opt_flag_value;
111
112 if (opt_flag_value!=0){
113 info() << "Using optimization !";
114 m_allow_optimization = true;
115 }
116
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;
122 }
123
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;
129}
130
131/*---------------------------------------------------------------------------*/
132/*---------------------------------------------------------------------------*/
133
134void MeshMaterialModifierImpl::
135addCells(IMeshMaterial* mat, SmallSpan<const Int32> ids)
136{
137 if (ids.empty())
138 return;
139 m_operations.add(Operation::createAdd(mat, ids));
140}
141
142/*---------------------------------------------------------------------------*/
143/*---------------------------------------------------------------------------*/
144
145void MeshMaterialModifierImpl::
146removeCells(IMeshMaterial* mat, SmallSpan<const Int32> ids)
147{
148 if (ids.empty())
149 return;
150 m_operations.add(Operation::createRemove(mat, ids));
151}
152
153/*---------------------------------------------------------------------------*/
154/*---------------------------------------------------------------------------*/
155
156void MeshMaterialModifierImpl::
157_addCellsToGroupDirect(IMeshMaterial* mat,SmallSpan<const Int32> ids)
158{
159 CellGroup cells = mat->cells();
160 info(4) << "ADD_CELLS_TO_MATERIAL: mat=" << mat->name()
161 << " nb_item=" << ids.size();
162 cells.addItems(ids.smallView());
163}
164
165/*---------------------------------------------------------------------------*/
166/*---------------------------------------------------------------------------*/
167
168void MeshMaterialModifierImpl::
169_removeCellsToGroupDirect(IMeshMaterial* mat,SmallSpan<const Int32> ids)
170{
171 CellGroup cells = mat->cells();
172 info(4) << "REMOVE_CELLS_TO_MATERIAL: mat=" << mat->name()
173 << " nb_item=" << ids.size();
174 cells.removeItems(ids.smallView());
175}
176
177/*---------------------------------------------------------------------------*/
178/*---------------------------------------------------------------------------*/
179
180bool MeshMaterialModifierImpl::
181_checkMayOptimize()
182{
183 Integer nb_operation = m_operations.values().size();
184 if (nb_operation>1 && !m_allow_optimize_multiple_operation)
185 return false;
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";
191 return false;
192 }
193 }
194 return true;
195}
196
197/*---------------------------------------------------------------------------*/
198/*---------------------------------------------------------------------------*/
199/*!
200 * \brief Applique les opérations enregistrées.
201 */
202void MeshMaterialModifierImpl::
203endUpdate()
204{
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();
210 }
211 _endUpdate();
212 if (m_print_component_list){
213 info() << "MeshMaterialModifierImpl::endUpdate(): END"
214 << " modification_id=" << m_modification_id;
215 list_printer.print();
216 }
217 ++m_modification_id;
218}
219
220/*---------------------------------------------------------------------------*/
221/*---------------------------------------------------------------------------*/
222
223void MeshMaterialModifierImpl::
224_endUpdate()
225{
226 Accelerator::ProfileRegion ps(m_queue,"ConstituentsEndUpdate", 0x97599A);
227
228 bool is_keep_value = m_material_mng->isKeepValuesAfterChange();
229 Integer nb_operation = m_operations.values().size();
230
231 linfo() << "END_UPDATE_MAT_Begin keep=" << is_keep_value
232 << " nb_operation=" << nb_operation;
233
234 m_material_mng->incrementTimestamp();
235
236 MeshMaterialBackup backup(m_material_mng, false);
237
238 bool no_optimization_done = true;
239
240 ++nb_update;
241 AllEnvData* all_env_data = m_material_mng->allEnvData();
242
243 bool is_display = traceMng()->verbosityLevel() >= _localVerboseLevel();
244
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();
249
250 // N'appelle la méthode que si l'affichage sera réalisé pour éviter
251 // de recopier 'op->ids()' sur l'hôte.
252 if (is_display)
253 linfo() << "MODIFIER_CELLS_TO_MATERIAL: mat=" << mat->name()
254 << " is_add=" << op->isAdd()
255 << " mat_index=" << mci->variableIndexer()->index()
256 << " op_index=" << i
257 << " ids=" << op->ids();
258 }
259
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;
264
265 // Tableau de travail utilisé lors des modifications incrémentales
266 if (!m_incremental_modifier){
267 linfo() << "Creating IncrementalComponentModifier";
268 m_incremental_modifier = std::make_unique<IncrementalComponentModifier>(all_env_data, m_queue);
269 }
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);
274 }
275
276 if (is_optimization_active) {
277 for (Operation* op : m_operations.values()) {
278 const IMeshMaterial* mat = op->material();
279
280 if (op->isAdd()) {
281 linfo() << "ONLY_ONE_ADD: using optimization mat=" << mat->name();
282 ++nb_optimize_add;
283 }
284 else {
285 linfo() << "ONLY_ONE_REMOVE: using optimization mat=" << mat->name();
286 ++nb_optimize_remove;
287 }
288
289 m_incremental_modifier->m_work_info.setCurrentOperation(op);
290
291 // Vérifie dans le cas des mailles à ajouter si elles ne sont pas déjà
292 // dans le matériau et dans le cas des mailles à supprimer si elles y sont.
293 if (arcaneIsCheck())
294 op->filterIds();
295
296 m_incremental_modifier->apply(op);
297 }
298 no_optimization_done = false;
299 }
300
301 if (no_optimization_done) {
302 if (is_keep_value) {
303 ++nb_save_restore;
304 backup.saveValues();
305 }
306
307 _applyOperationsNoOptimize();
308 _updateEnvironmentsNoOptimize();
309
310 all_env_data->forceRecompute(true);
311
312 if (is_keep_value) {
313 backup.restoreValues();
314 }
315 }
316 else {
317 m_incremental_modifier->finalize();
318 all_env_data->recomputeIncremental();
319 }
320
321 if (!m_is_keep_work_buffer)
322 m_incremental_modifier = nullptr;
323
324 linfo() << "END_UPDATE_MAT End";
325}
326
327/*---------------------------------------------------------------------------*/
328/*---------------------------------------------------------------------------*/
329
330void MeshMaterialModifierImpl::
331_applyOperationsNoOptimize()
332{
333 for( Operation* o : m_operations.values() ){
334 IMeshMaterial* mat = o->material();
335 if (o->isAdd())
336 _addCellsToGroupDirect(mat,o->ids());
337 else
338 _removeCellsToGroupDirect(mat,o->ids());
339 }
340 m_operations.clear();
341}
342
343/*---------------------------------------------------------------------------*/
344/*---------------------------------------------------------------------------*/
345
346void MeshMaterialModifierImpl::
347_updateEnvironmentsNoOptimize()
348{
349 ConstArrayView<IMeshEnvironment*> envs = m_material_mng->environments();
350 Int32UniqueArray cells_to_add;
351 Int32UniqueArray cells_to_remove;
352 info(4) << "CHECK ENVIRONMENTS";
353
354 // Regarde s'il faut ajouter ou supprimer des mailles d'un milieu
355 // en fonction de celles qui ont été ajoutées ou supprimées dans les
356 // matériaux.
357 for( IMeshEnvironment* env : envs ){
358
359 // Pour les milieux ne contenant qu'un seul materiau, il n'y a rien
360 // à faire car le groupe materiau est le meme que le groupe milieu
361 if (env->nbMaterial()==1)
362 continue;
363
364 CellGroup env_cells = env->cells();
365 info(4) << "CHECK ENV name=" << env->name() << " nb_cell=" << env_cells.size();
366 Integer max_id = env_cells.itemFamily()->maxLocalId();
367 Int32UniqueArray cells_marker(max_id,-1);
368 ENUMERATE_CELL(icell,env_cells){
369 cells_marker[icell.itemLocalId()] = 0;
370 }
371 cells_to_add.clear();
372 cells_to_remove.clear();
373 ConstArrayView<IMeshMaterial*> env_materials = env->materials();
374 for( IMeshMaterial* mat : env_materials ){
375 ENUMERATE_CELL(icell,mat->cells()){
376 Int32 mark = cells_marker[icell.itemLocalId()];
377 if (mark==(-1)){
378 //mark = 0;
379 // Maille a ajouter.
380 cells_to_add.add(icell.itemLocalId());
381 }
382 //++mark;
383 cells_marker[icell.itemLocalId()] = 1;
384 }
385 }
386
387 ENUMERATE_CELL(icell,env_cells){
388 Int32 mark = cells_marker[icell.itemLocalId()];
389 if (mark==0)
390 cells_to_remove.add(icell.itemLocalId());
391 }
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);
395 }
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);
399 }
400
401 }
402}
403
404/*---------------------------------------------------------------------------*/
405/*---------------------------------------------------------------------------*/
406
407void MeshMaterialModifierImpl::
408reset()
409{
410 m_do_copy_between_partial_and_pure = true;
411 m_do_init_new_items = true;
412 m_is_keep_work_buffer = true;
413}
414
415/*---------------------------------------------------------------------------*/
416/*---------------------------------------------------------------------------*/
417
418void MeshMaterialModifierImpl::
419beginUpdate()
420{
421 m_material_mng->info(4) << "BEGIN_UPDATE_MAT";
422 m_operations.clear();
423}
424
425/*---------------------------------------------------------------------------*/
426/*---------------------------------------------------------------------------*/
427
428void MeshMaterialModifierImpl::
429dumpStats()
430{
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;
436}
437
438/*---------------------------------------------------------------------------*/
439/*---------------------------------------------------------------------------*/
440
441} // End namespace Arcane::Materials
442
443/*---------------------------------------------------------------------------*/
444/*---------------------------------------------------------------------------*/
#define ENUMERATE_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
const String & name() const
Nom du groupe.
Definition ItemGroup.h:76
ItemGroupT< Cell > CellGroup
Groupe de mailles.
Definition ItemTypes.h:183
Active toujours les traces dans les parties Arcane concernant les matériaux.
bool arcaneIsCheck()
Vrai si on est en mode vérification.
Definition Misc.cc:151
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:515
Int32 Integer
Type représentant un entier.