Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
MeshMaterialBackup.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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/* MeshMaterialBackup.cc (C) 2000-2023 */
9/* */
10/* Backup/restoration of material and environment values. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/materials/MeshMaterialBackup.h"
15
16#include "arcane/utils/IDataCompressor.h"
17
18#include "arcane/core/IVariable.h"
19#include "arcane/core/IData.h"
20#include "arcane/core/IMesh.h"
21#include "arcane/core/IItemFamily.h"
22#include "arcane/core/ServiceBuilder.h"
23#include "arcane/core/internal/IDataInternal.h"
24#include "arcane/core/materials/IMeshMaterialMng.h"
25#include "arcane/core/materials/IMeshMaterialVariable.h"
27#include "arcane/core/materials/internal/IMeshMaterialVariableInternal.h"
28#include "arcane/core/materials/internal/IMeshMaterialMngInternal.h"
29
30#include "arcane/materials/internal/MeshMaterialMng.h"
31#include "arcane/materials/internal/MeshMaterialVariableIndexer.h"
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36namespace Arcane::Materials
37{
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
43{
44 public:
45
46 VarData() = default;
47 explicit VarData(Ref<IData> d)
48 : data(d)
49 {}
50
51 public:
52
53 Ref<IData> data;
54 Integer data_index = 0;
55 DataCompressionBuffer m_data_buffer;
56 Ref<IDataCompressor> m_compressor;
57};
58
59/*---------------------------------------------------------------------------*/
60/*---------------------------------------------------------------------------*/
61
62MeshMaterialBackup::
63MeshMaterialBackup(IMeshMaterialMng* mm, bool use_unique_ids)
65, m_material_mng(mm)
66, m_use_unique_ids(use_unique_ids)
67{
68 m_compressor_service_name = mm->dataCompressorServiceName();
69}
70
71/*---------------------------------------------------------------------------*/
72/*---------------------------------------------------------------------------*/
73
74MeshMaterialBackup::
75~MeshMaterialBackup()
76{
77 for (const auto& iter : m_saved_data)
78 delete iter.second;
79}
80
81/*---------------------------------------------------------------------------*/
82/*---------------------------------------------------------------------------*/
83
84void MeshMaterialBackup::
85saveValues()
86{
87 _save();
88}
89
90/*---------------------------------------------------------------------------*/
91/*---------------------------------------------------------------------------*/
92
93void MeshMaterialBackup::
94restoreValues()
95{
96 _restore();
97}
98
99/*---------------------------------------------------------------------------*/
100/*---------------------------------------------------------------------------*/
101
104{
105 m_compressor_service_name = name;
106}
107
108/*---------------------------------------------------------------------------*/
109/*---------------------------------------------------------------------------*/
110
116{
117 MatVarSpace mvs = var->space();
119 return true;
120 if (mvs == MatVarSpace::Environment && component->isEnvironment())
121 return true;
122 return false;
123}
124
125/*---------------------------------------------------------------------------*/
126/*---------------------------------------------------------------------------*/
127
128void MeshMaterialBackup::
129_save()
130{
131 if (!m_compressor_service_name.null())
132 m_use_v2 = true;
133
135
136 Integer nb_index = indexers.size();
137 Integer nb_value = 0;
138 for (Integer i = 0; i < nb_index; ++i)
139 nb_value += indexers[i]->cells().size();
140
141 info(4) << "NB_EXPECTED_VALUE=" << nb_value;
142
143 MeshMaterialMng* mm = dynamic_cast<MeshMaterialMng*>(m_material_mng);
144 if (!mm)
145 ARCANE_FATAL("Can not cast to MeshMaterialMng");
146
147 // Store in \a vars the list of variables for easier access than with the map
148 Integer max_nb_var = arcaneCheckArraySize(mm->m_full_name_variable_map.size());
149 m_vars.reserve(max_nb_var);
150 for (const auto& i : mm->m_full_name_variable_map) {
151 IMeshMaterialVariable* mv = i.second;
152 if (mv->keepOnChange() && mv->globalVariable()->isUsed())
153 m_vars.add(mv);
154 }
155 for (IMeshMaterialVariable* mv : m_vars) {
156 info(4) << "SAVE MVAR=" << mv->name() << " is_used?=" << mv->globalVariable()->isUsed();
157 VarData* vd = new VarData(mv->_internalApi()->internalCreateSaveDataRef(nb_value));
158 m_saved_data.insert(std::make_pair(mv, vd));
159 }
160
161 if (m_use_v2)
162 _saveV2();
163 else
164 _saveV1();
165}
166
167/*---------------------------------------------------------------------------*/
168/*---------------------------------------------------------------------------*/
169
170void MeshMaterialBackup::
171_saveV1()
172{
173 ENUMERATE_COMPONENT (ic, m_material_mng->components()) {
174 IMeshComponent* c = *ic;
175 _saveIds(c);
176 for (IMeshMaterialVariable* var : m_vars) {
177 if (_isValidComponent(var, c))
178 var->_internalApi()->saveData(c, m_saved_data[var]->data.get());
179 }
180 }
181}
182
183/*---------------------------------------------------------------------------*/
184/*---------------------------------------------------------------------------*/
185
186void MeshMaterialBackup::
187_saveV2()
188{
189 IMesh* mesh = m_material_mng->mesh();
190 ServiceBuilder<IDataCompressor> sb(mesh->handle().application());
191 Ref<IDataCompressor> compressor_ref;
192 if (!m_compressor_service_name.empty())
193 compressor_ref = sb.createReference(m_compressor_service_name);
194 IDataCompressor* compressor = compressor_ref.get();
195 auto components = m_material_mng->components();
196
197 ENUMERATE_COMPONENT (ic, components) {
198 IMeshComponent* c = *ic;
199 _saveIds(c);
200 }
201
202 for (IMeshMaterialVariable* var : m_vars) {
203 VarData* var_data = m_saved_data[var];
204 IData* saved_data = var_data->data.get();
205 if (compressor) {
206 var_data->m_compressor = compressor_ref;
207 var_data->m_data_buffer.m_compressor = compressor;
208 }
209 ENUMERATE_COMPONENT (ic, components) {
210 IMeshComponent* c = *ic;
211 if (_isValidComponent(var, c)) {
212 var->_internalApi()->saveData(c, saved_data);
213 }
214 }
215 if (compressor) {
216 IDataInternal* d = saved_data->_commonInternal();
217 d->compressAndClear(var_data->m_data_buffer);
218 }
219 }
220}
221
222/*---------------------------------------------------------------------------*/
223/*---------------------------------------------------------------------------*/
224
225void MeshMaterialBackup::
226_saveIds(IMeshComponent* component)
227{
228 if (m_use_unique_ids) {
229 auto& ids = m_unique_ids_array[component];
230 ENUMERATE_COMPONENTCELL (icell, component) {
231 ComponentCell ec = *icell;
232 ids.add(ec.globalCell().uniqueId());
233 }
234 info(4) << "SAVE (uid) for component name=" << component->name()
235 << " nb=" << ids.size();
236 }
237 else {
238 Int32Array& ids = m_ids_array[component];
239 ENUMERATE_COMPONENTCELL (icell, component) {
240 ComponentCell ec = *icell;
241 ids.add(ec.globalCell().localId());
242 }
243 info(4) << "SAVE (lid) for component name=" << component->name()
244 << " nb=" << ids.size();
245 }
246}
247
248/*---------------------------------------------------------------------------*/
249/*---------------------------------------------------------------------------*/
250
251void MeshMaterialBackup::
252_restore()
253{
254 if (m_use_unique_ids) {
255 info(4) << "RESTORE using uniqueIds()";
256 IItemFamily* cell_family = m_material_mng->mesh()->cellFamily();
257 // If uniqueIds() are used, the m_unique_ids_array
258 // contains the uniqueId() values of the cells. It must
259 // then be converted to localId().
260 for (const auto& iter : m_unique_ids_array) {
261 IMeshComponent* component = iter.first;
262 auto& unique_ids = m_unique_ids_array[component];
263 auto& local_ids = m_ids_array[component];
264 local_ids.resize(unique_ids.size());
265 cell_family->itemsUniqueIdToLocalId(local_ids, unique_ids, false);
266 }
267 }
268
269 if (m_use_v2)
270 _restoreV2();
271 else
272 _restoreV1();
273}
274
275/*---------------------------------------------------------------------------*/
276/*---------------------------------------------------------------------------*/
277
278void MeshMaterialBackup::
279_restoreV1()
280{
281 // If uniqueIds() are used, then localIds() may be null
282 // if cells have been deleted.
283 bool allow_null_id = m_use_unique_ids;
284
285 ENUMERATE_COMPONENT (ic, m_material_mng->components()) {
286 IMeshComponent* c = *ic;
287 Int32ConstArrayView ids = m_ids_array[c];
288 info(4) << "RESTORE for component name=" << c->name() << " nb=" << ids.size();
289 for (IMeshMaterialVariable* var : m_vars) {
290 VarData* vd = m_saved_data[var];
291 if (_isValidComponent(var, c)) {
292 var->_internalApi()->restoreData(c, vd->data.get(), vd->data_index, ids, allow_null_id);
293 vd->data_index += ids.size();
294 }
295 }
296 }
297}
298
299/*---------------------------------------------------------------------------*/
300/*---------------------------------------------------------------------------*/
301
302void MeshMaterialBackup::
303_restoreV2()
304{
305 // If uniqueIds() are used, then localIds() may be null
306 // if cells have been deleted.
307 bool allow_null_id = m_use_unique_ids;
308
309 auto components = m_material_mng->components();
310
311 for (IMeshMaterialVariable* var : m_vars) {
312 VarData* vd = m_saved_data[var];
313 // Decompress the data if necessary
314 IDataCompressor* compressor = vd->m_data_buffer.m_compressor;
315 if (compressor) {
316 info(5) << "RESTORE decompress variable name=" << var->name();
317 IDataInternal* d = vd->data->_commonInternal();
318 d->decompressAndFill(vd->m_data_buffer);
319 }
320 info(4) << "RESTORE for variable name=" << var->name();
321 ENUMERATE_COMPONENT (ic, components) {
322 IMeshComponent* c = *ic;
323 Int32ConstArrayView ids = m_ids_array[c];
324 if (_isValidComponent(var, c)) {
325 var->_internalApi()->restoreData(c, vd->data.get(), vd->data_index, ids, allow_null_id);
326 vd->data_index += ids.size();
327 }
328 }
329 }
330}
331
332/*---------------------------------------------------------------------------*/
333/*---------------------------------------------------------------------------*/
334
335} // End namespace Arcane::Materials
336
337/*---------------------------------------------------------------------------*/
338/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
Class to manage data compression/decompression.
virtual bool isUsed() const =0
Usage state of the variable.
Interface of a component (material or environment) of a mesh.
virtual bool isEnvironment() const =0
True if the component is an environment.
virtual ConstArrayView< MeshMaterialVariableIndexer * > variablesIndexer()=0
List of information to index material variables.
Interface for the material and environment manager of a mesh.
virtual String dataCompressorServiceName() const =0
Virtual name of the service used to compress data.
virtual IMeshMaterialMngInternal * _internalApi() const =0
Internal API for Arcane.
virtual Ref< IData > internalCreateSaveDataRef(Integer nb_value)=0
Interface of a material variable on a mesh.
virtual bool keepOnChange() const =0
Indicates whether the variable value should be kept after a change in the list of materials.
virtual MatVarSpace space() const =0
Variable definition space (material+environment or environment only).
virtual IVariable * globalVariable() const =0
Associated global variable on the mesh.
virtual String name() const =0
Name of the variable.
bool _isValidComponent(IMeshMaterialVariable *var, IMeshComponent *component)
Indicates if the variable var is defined on the component component.
void setCompressorServiceName(const String &name)
Name of the service used to compress the data.
Implementation of a material manager.
Reference to an instance.
bool null() const
Returns true if the string is null.
Definition String.cc:306
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage info() const
Flow for an information message.
ITraceMng * traceMng() const
Trace manager.
#define ENUMERATE_COMPONENT(icomponent, container)
Macro to iterate over a list of components.
#define ENUMERATE_COMPONENTCELL(iname, component)
Macro to iterate over all ComponentCell cells of a component.
Always enables tracing in Arcane parts concerning materials.
MatVarSpace
Definition space for a material variable.
@ Environment
Variable having values only on environments.
@ MaterialAndEnvironment
Variable having values on environments and materials.
Integer arcaneCheckArraySize(unsigned long long size)
Checks that size can be converted into an 'Integer' to serve as the size of an array....
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:482
Array< Int32 > Int32Array
Dynamic one-dimensional array of 32-bit integers.
Definition UtilsTypes.h:127