Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
MeshMaterialBackup.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/* MeshMaterialBackup.cc (C) 2000-2023 */
9/* */
10/* Sauvegarde/restauration des valeurs des matériaux et milieux. */
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
40{
41 public:
42
43 VarData() = default;
44 explicit VarData(Ref<IData> d) : data(d) {}
45
46 public:
47
48 Ref<IData> data;
49 Integer data_index = 0;
50 DataCompressionBuffer m_data_buffer;
51 Ref<IDataCompressor> m_compressor;
52};
53
54/*---------------------------------------------------------------------------*/
55/*---------------------------------------------------------------------------*/
56
57MeshMaterialBackup::
58MeshMaterialBackup(IMeshMaterialMng* mm,bool use_unique_ids)
59: TraceAccessor(mm->traceMng())
60, m_material_mng(mm)
61, m_use_unique_ids(use_unique_ids)
62{
63 m_compressor_service_name = mm->dataCompressorServiceName();
64}
65
66/*---------------------------------------------------------------------------*/
67/*---------------------------------------------------------------------------*/
68
69MeshMaterialBackup::
70~MeshMaterialBackup()
71{
72 for( const auto& iter : m_saved_data )
73 delete iter.second;
74}
75
76/*---------------------------------------------------------------------------*/
77/*---------------------------------------------------------------------------*/
78
79void MeshMaterialBackup::
80saveValues()
81{
82 _save();
83}
84
85/*---------------------------------------------------------------------------*/
86/*---------------------------------------------------------------------------*/
87
88void MeshMaterialBackup::
89restoreValues()
90{
91 _restore();
92}
93
94/*---------------------------------------------------------------------------*/
95/*---------------------------------------------------------------------------*/
96
99{
100 m_compressor_service_name = name;
101}
102
103/*---------------------------------------------------------------------------*/
104/*---------------------------------------------------------------------------*/
105/*!
106 * \brief Indique si la variable \a var est définie sur le composant \a component.
107 */
108bool MeshMaterialBackup::
109_isValidComponent(IMeshMaterialVariable* var,IMeshComponent* component)
110{
111 MatVarSpace mvs = var->space();
113 return true;
114 if (mvs==MatVarSpace::Environment && component->isEnvironment())
115 return true;
116 return false;
117}
118
119/*---------------------------------------------------------------------------*/
120/*---------------------------------------------------------------------------*/
121
122void MeshMaterialBackup::
123_save()
124{
125 if (!m_compressor_service_name.null())
126 m_use_v2 = true;
127
128 ConstArrayView<MeshMaterialVariableIndexer*> indexers = m_material_mng->_internalApi()->variablesIndexer();
129
130 Integer nb_index = indexers.size();
131 Integer nb_value = 0;
132 for( Integer i=0; i<nb_index; ++i )
133 nb_value += indexers[i]->cells().size();
134
135 info(4) << "NB_EXPECTED_VALUE=" << nb_value;
136
137 MeshMaterialMng* mm = dynamic_cast<MeshMaterialMng*>(m_material_mng);
138 if (!mm)
139 ARCANE_FATAL("Can not cast to MeshMaterialMng");
140
141 // Stocke dans \a vars la liste des variables pour accès plus simple qu'avec la map
142 Integer max_nb_var = arcaneCheckArraySize(mm->m_full_name_variable_map.size());
143 m_vars.reserve(max_nb_var);
144 for( const auto& i : mm->m_full_name_variable_map){
145 IMeshMaterialVariable* mv = i.second;
146 if (mv->keepOnChange() && mv->globalVariable()->isUsed())
147 m_vars.add(mv);
148 }
149 for( IMeshMaterialVariable* mv : m_vars ){
150 info(4) << "SAVE MVAR=" << mv->name() << " is_used?=" << mv->globalVariable()->isUsed();
151 VarData* vd = new VarData(mv->_internalApi()->internalCreateSaveDataRef(nb_value));
152 m_saved_data.insert(std::make_pair(mv,vd));
153 }
154
155 if (m_use_v2)
156 _saveV2();
157 else
158 _saveV1();
159}
160
161/*---------------------------------------------------------------------------*/
162/*---------------------------------------------------------------------------*/
163
164void MeshMaterialBackup::
165_saveV1()
166{
167 ENUMERATE_COMPONENT(ic,m_material_mng->components()){
168 IMeshComponent* c = *ic;
169 _saveIds(c);
170 for( IMeshMaterialVariable* var : m_vars ){
171 if (_isValidComponent(var,c))
172 var->_internalApi()->saveData(c,m_saved_data[var]->data.get());
173 }
174 }
175}
176
177/*---------------------------------------------------------------------------*/
178/*---------------------------------------------------------------------------*/
179
180void MeshMaterialBackup::
181_saveV2()
182{
183 IMesh* mesh = m_material_mng->mesh();
184 ServiceBuilder<IDataCompressor> sb(mesh->handle().application());
185 Ref<IDataCompressor> compressor_ref;
186 if (!m_compressor_service_name.empty())
187 compressor_ref = sb.createReference(m_compressor_service_name);
188 IDataCompressor* compressor = compressor_ref.get();
189 auto components = m_material_mng->components();
190
191 ENUMERATE_COMPONENT(ic,components){
192 IMeshComponent* c = *ic;
193 _saveIds(c);
194 }
195
196 for( IMeshMaterialVariable* var : m_vars ){
197 VarData* var_data = m_saved_data[var];
198 IData* saved_data = var_data->data.get();
199 if (compressor){
200 var_data->m_compressor = compressor_ref;
201 var_data->m_data_buffer.m_compressor = compressor;
202 }
203 ENUMERATE_COMPONENT(ic,components){
204 IMeshComponent* c = *ic;
205 if (_isValidComponent(var,c)){
206 var->_internalApi()->saveData(c,saved_data);
207 }
208 }
209 if (compressor){
210 IDataInternal* d = saved_data->_commonInternal();
211 d->compressAndClear(var_data->m_data_buffer);
212 }
213 }
214}
215
216/*---------------------------------------------------------------------------*/
217/*---------------------------------------------------------------------------*/
218
219void MeshMaterialBackup::
220_saveIds(IMeshComponent* component)
221{
222 if (m_use_unique_ids){
223 auto& ids = m_unique_ids_array[component];
224 ENUMERATE_COMPONENTCELL(icell,component){
225 ComponentCell ec = *icell;
226 ids.add(ec.globalCell().uniqueId());
227 }
228 info(4) << "SAVE (uid) for component name=" << component->name()
229 << " nb=" << ids.size();
230 }
231 else{
232 Int32Array& ids = m_ids_array[component];
233 ENUMERATE_COMPONENTCELL(icell,component){
234 ComponentCell ec = *icell;
235 ids.add(ec.globalCell().localId());
236 }
237 info(4) << "SAVE (lid) for component name=" << component->name()
238 << " nb=" << ids.size();
239 }
240}
241
242/*---------------------------------------------------------------------------*/
243/*---------------------------------------------------------------------------*/
244
245void MeshMaterialBackup::
246_restore()
247{
248 if (m_use_unique_ids){
249 info(4) << "RESTORE using uniqueIds()";
250 IItemFamily* cell_family = m_material_mng->mesh()->cellFamily();
251 // Si on utilise les uniqueId(), le tableau m_unique_ids_array
252 // contient les valeurs des uniqueId() des mailles. Il faut
253 // ensuite le convertir en localId().
254 for( const auto& iter : m_unique_ids_array ){
255 IMeshComponent* component = iter.first;
256 auto& unique_ids = m_unique_ids_array[component];
257 auto& local_ids = m_ids_array[component];
258 local_ids.resize(unique_ids.size());
259 cell_family->itemsUniqueIdToLocalId(local_ids,unique_ids,false);
260 }
261 }
262
263 if (m_use_v2)
264 _restoreV2();
265 else
266 _restoreV1();
267}
268
269/*---------------------------------------------------------------------------*/
270/*---------------------------------------------------------------------------*/
271
272void MeshMaterialBackup::
273_restoreV1()
274{
275 // Si on utilise les uniqueId(), alors les localId() peuvent être nuls
276 // si on a supprimé des mailles.
277 bool allow_null_id = m_use_unique_ids;
278
279 ENUMERATE_COMPONENT(ic,m_material_mng->components()){
280 IMeshComponent* c = *ic;
281 Int32ConstArrayView ids = m_ids_array[c];
282 info(4) << "RESTORE for component name=" << c->name() << " nb=" << ids.size();
283 for( IMeshMaterialVariable* var : m_vars ){
284 VarData* vd = m_saved_data[var];
285 if (_isValidComponent(var,c)){
286 var->_internalApi()->restoreData(c,vd->data.get(),vd->data_index,ids,allow_null_id);
287 vd->data_index += ids.size();
288 }
289 }
290 }
291}
292
293/*---------------------------------------------------------------------------*/
294/*---------------------------------------------------------------------------*/
295
296void MeshMaterialBackup::
297_restoreV2()
298{
299 // Si on utilise les uniqueId(), alors les localId() peuvent être nuls
300 // si on a supprimé des mailles.
301 bool allow_null_id = m_use_unique_ids;
302
303 auto components = m_material_mng->components();
304
305 for( IMeshMaterialVariable* var : m_vars ){
306 VarData* vd = m_saved_data[var];
307 // Décompresse les données si nécessaire
308 IDataCompressor* compressor = vd->m_data_buffer.m_compressor;
309 if (compressor){
310 info(5) << "RESTORE decompress variable name=" << var->name();
311 IDataInternal* d = vd->data->_commonInternal();
312 d->decompressAndFill(vd->m_data_buffer);
313 }
314 info(4) << "RESTORE for variable name=" << var->name();
315 ENUMERATE_COMPONENT(ic,components){
316 IMeshComponent* c = *ic;
317 Int32ConstArrayView ids = m_ids_array[c];
318 if (_isValidComponent(var,c)){
319 var->_internalApi()->restoreData(c,vd->data.get(),vd->data_index,ids,allow_null_id);
320 vd->data_index += ids.size();
321 }
322 }
323 }
324}
325
326/*---------------------------------------------------------------------------*/
327/*---------------------------------------------------------------------------*/
328
329} // End namespace Arcane::Materials
330
331/*---------------------------------------------------------------------------*/
332/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
virtual bool isUsed() const =0
Etat d'utilisation de la variable.
Interface d'un composant (matériau ou milieu) d'un maillage.
virtual bool isEnvironment() const =0
Vrai si le composant est un milieu.
Interface du gestionnaire des matériaux et des milieux d'un maillage.
virtual MeshComponentList components() const =0
Liste de tous les composants.
virtual String dataCompressorServiceName() const =0
virtual Nom du service utilisé pour compresser les données
virtual IMesh * mesh()=0
Maillage associé.
virtual IMeshMaterialMngInternal * _internalApi() const =0
API interne à Arcane.
Interface d'une variable matériau d'un maillage.
virtual bool keepOnChange() const =0
Indique si on souhaite conserver la valeur de la variable apres un changement de la liste des matéria...
virtual MatVarSpace space() const =0
Espace de définition de la variable (matériau+milieu ou milieu uniquement)
virtual IVariable * globalVariable() const =0
Variable globale sur le maillage associée.
virtual String name() const =0
Nom de la variable.
void setCompressorServiceName(const String &name)
Nom du service utilisé pour compresser les données.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Chaîne de caractères unicode.
bool empty() const
Vrai si la chaîne est vide (nulle ou "")
Definition String.cc:315
bool null() const
Retourne true si la chaîne est nulle.
Definition String.cc:304
TraceMessage info() const
Flot pour un message d'information.
#define ENUMERATE_COMPONENT(icomponent, container)
Macro pour itérer sur une liste de composants.
#define ENUMERATE_COMPONENTCELL(iname, component)
Macro pour itérer sur toutes les mailles d'un composant.
Active toujours les traces dans les parties Arcane concernant les matériaux.
MatVarSpace
Espace de définition d'une variable matériau.
@ Environment
Variable ayant des valeurs uniquement sur les milieux.
@ MaterialAndEnvironment
Variable ayant des valeurs sur les milieux et matériaux.
Integer arcaneCheckArraySize(unsigned long long size)
Vérifie que size peut être converti dans un 'Integer' pour servir de taille à un tableau....
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:640
Array< Int32 > Int32Array
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:327