Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
MaterialModifierOperation.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2023 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/* MaterialModifierOperation.cc (C) 2000-2024 */
9/* */
10/* Opération d'ajout/suppression de mailles d'un matériau. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/materials/internal/MaterialModifierOperation.h"
15
16#include "arcane/utils/ITraceMng.h"
17#include "arcane/utils/FatalErrorException.h"
18#include "arcane/utils/MemoryUtils.h"
19#include "arcane/utils/IMemoryRessourceMng.h"
20
21#include "arcane/core/ItemPrinter.h"
22#include "arcane/core/ItemGroup.h"
23#include "arcane/core/IItemFamily.h"
24#include "arcane/core/materials/IMeshMaterial.h"
25#include "arcane/core/materials/internal/IMeshComponentInternal.h"
26
27#include "arcane/materials/internal/MeshMaterialVariableIndexer.h"
28
29/*---------------------------------------------------------------------------*/
30/*---------------------------------------------------------------------------*/
31
32namespace Arcane::Materials
33{
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37
38MaterialModifierOperation::
39MaterialModifierOperation()
40: m_ids(MemoryUtils::getDefaultDataAllocator())
41{
42}
43
44/*---------------------------------------------------------------------------*/
45/*---------------------------------------------------------------------------*/
46
47MaterialModifierOperation::
48MaterialModifierOperation(IMeshMaterial* mat, SmallSpan<const Int32> ids, bool is_add)
49: MaterialModifierOperation()
50{
51 m_mat = mat;
52 m_is_add = is_add;
53 m_ids.resize(ids.size());
54 MemoryUtils::copy<Int32>(m_ids, ids);
55}
56
57/*---------------------------------------------------------------------------*/
58/*---------------------------------------------------------------------------*/
59/*!
60 * \brief Vérifie si les mailles \a ids sont déjà dans le matériau \a mat.
61 *
62 * Si \a operation==eOperation::Add, vérifie que les mailles de \a ids
63 * ne sont pas déjà dans le matériau et si \a operation==eOperation::Remove, vérifie
64 * que les mailles de \a ids sont dans le matériau.
65 *
66 * Vérifie aussi qu'un élément n'est présent qu'une fois dans la liste \a ids.
67 *
68 * Retourne le nombre d'erreurs.
69 */
70Int32 MaterialModifierOperation::
71_checkMaterialPresence(MaterialModifierOperation* operation)
72{
73 IMeshMaterial* mat = operation->material();
74 SmallSpan<const Int32> ids = operation->ids();
75
76 const MeshMaterialVariableIndexer* indexer = mat->_internalApi()->variableIndexer();
77 IItemFamily* item_family = mat->cells().itemFamily();
78 ItemInfoListView items_internal(item_family);
79 Integer max_local_id = item_family->maxLocalId();
80 UniqueArray<bool> presence_flags(max_local_id, false);
81 SmallSpan<const Int32> mat_local_ids = indexer->localIds();
82 Integer nb_error = 0;
83 String name = mat->name();
84 ITraceMng* tm = mat->traceMng();
85
86 for (Int32 lid : ids) {
87 if (presence_flags[lid]) {
88 tm->info() << "ERROR: item " << ItemPrinter(items_internal[lid])
89 << " is present several times in add/remove list for material mat=" << name;
90 ++nb_error;
91 }
92 presence_flags[lid] = true;
93 }
94
95 if (operation->isAdd()) {
96 for (Int32 lid : mat_local_ids) {
97 if (presence_flags[lid]) {
98 tm->info() << "ERROR: item " << ItemPrinter(items_internal[lid])
99 << " is already in material mat=" << name;
100 ++nb_error;
101 }
102 }
103 }
104 else {
105 for (Int32 lid : mat_local_ids) {
106 presence_flags[lid] = false;
107 }
108
109 for (Int32 lid : ids) {
110 if (presence_flags[lid]) {
111 tm->info() << "ERROR: item " << ItemPrinter(items_internal[lid])
112 << " is not in material mat=" << name;
113 ++nb_error;
114 }
115 }
116 }
117
118 return nb_error;
119}
120
121/*---------------------------------------------------------------------------*/
122/*---------------------------------------------------------------------------*/
123/*!
124 * \brief Filtre le tableau des mailles \a ids pour qu'il soit valide.
125 *
126 * Cette méthode permet de filtrer les valeurs de \a ids afin
127 * qu'il ne reste que les valeurs valides pour qu'on puisse les ajouter
128 * (si \a do_add est vrai) ou supprimer (si \a do_add est faux) du matériau
129 * \a mat.
130 *
131 * Les valeurs valides sont stockées dans \a valid_ids.
132 */
133void MaterialModifierOperation::
134_filterValidIds(MaterialModifierOperation* operation, Int32Array& valid_ids)
135{
136 IMeshMaterial* mat = operation->material();
137 const bool do_add = operation->isAdd();
138 SmallSpan<const Int32> ids = operation->ids();
139 const MeshMaterialVariableIndexer* indexer = mat->_internalApi()->variableIndexer();
140 const IItemFamily* item_family = mat->cells().itemFamily();
141 Integer max_local_id = item_family->maxLocalId();
142 UniqueArray<bool> presence_flags(max_local_id, false);
143 SmallSpan<const Int32> mat_local_ids = indexer->localIds();
144 ITraceMng* tm = mat->traceMng();
145
146 UniqueArray<Int32> unique_occurence_lids;
147 unique_occurence_lids.reserve(ids.size());
148
149 for (Int32 lid : ids) {
150 if (!presence_flags[lid]) {
151 unique_occurence_lids.add(lid);
152 presence_flags[lid] = true;
153 }
154 }
155
156 valid_ids.clear();
157
158 if (do_add) {
159 for (Int32 lid : mat_local_ids) {
160 if (presence_flags[lid]) {
161 ;
162 }
163 else
164 valid_ids.add(lid);
165 }
166 }
167 else {
168 for (Int32 lid : mat_local_ids)
169 presence_flags[lid] = false;
170
171 for (Int32 lid : unique_occurence_lids) {
172 if (presence_flags[lid]) {
173 ;
174 }
175 else
176 valid_ids.add(lid);
177 }
178 }
179 tm->info(4) << "FILTERED_IDS n=" << valid_ids.size() << " ids=" << valid_ids;
180}
181
182/*---------------------------------------------------------------------------*/
183/*---------------------------------------------------------------------------*/
184
185void MaterialModifierOperation::
186filterIds()
187{
188 // TODO: changer le défaut à 'false' et tester les deux configurations
189 const bool filter_invalid = true;
190 Integer nb_error = _checkMaterialPresence(this);
191 if (nb_error != 0) {
192 if (filter_invalid) {
193 UniqueArray<Int32> filtered_ids;
194 _filterValidIds(this, filtered_ids);
195 m_ids.swap(filtered_ids);
196 }
197 else
198 ARCANE_FATAL("Invalid values for adding items in material name={0} nb_error={1}",
199 m_mat->name(), nb_error);
200 }
201}
202
203/*---------------------------------------------------------------------------*/
204/*---------------------------------------------------------------------------*/
205
206} // End namespace Arcane::Materials
207
208/*---------------------------------------------------------------------------*/
209/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Active toujours les traces dans les parties Arcane concernant les matériaux.
Int32 Integer
Type représentant un entier.