Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
MeshMaterialVariable.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/* MeshMaterialVariable.cc (C) 2000-2024 */
9/* */
10/* Variable sur un matériau du maillage. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/materials/MeshMaterialVariable.h"
15
16#include "arcane/utils/NotImplementedException.h"
17#include "arcane/utils/TraceInfo.h"
18#include "arcane/utils/ITraceMng.h"
19#include "arcane/utils/Real2.h"
20#include "arcane/utils/Real3.h"
21#include "arcane/utils/Real2x2.h"
22#include "arcane/utils/Real3x3.h"
23#include "arcane/utils/Mutex.h"
24#include "arcane/utils/MemoryUtils.h"
25#include "arcane/utils/PlatformUtils.h"
26
27#include "arcane/core/materials/IMeshMaterial.h"
28#include "arcane/core/materials/ComponentItemVectorView.h"
29#include "arcane/core/Variable.h"
30#include "arcane/core/VariableDependInfo.h"
31#include "arcane/core/MeshVariable.h"
32#include "arcane/core/IItemFamily.h"
33#include "arcane/core/IMesh.h"
34#include "arcane/core/IObserver.h"
35#include "arcane/core/IParallelMng.h"
37#include "arcane/core/materials/internal/IMeshComponentInternal.h"
38#include "arcane/core/materials/internal/IMeshMaterialMngInternal.h"
39
40#include "arcane/materials/MaterialVariableBuildInfo.h"
41#include "arcane/materials/MatItemEnumerator.h"
42#include "arcane/materials/MeshMaterialVariableRef.h"
43#include "arcane/materials/MeshMaterialVariableDependInfo.h"
44#include "arcane/materials/IMeshMaterialVariableComputeFunction.h"
45#include "arcane/materials/IMeshMaterialVariableSynchronizer.h"
46#include "arcane/materials/internal/MeshMaterialVariablePrivate.h"
47#include "arcane/materials/internal/MeshMaterialVariableIndexer.h"
48
50
51/*---------------------------------------------------------------------------*/
52/*---------------------------------------------------------------------------*/
53
54namespace Arcane::Materials
55{
56
57/*---------------------------------------------------------------------------*/
58/*---------------------------------------------------------------------------*/
59
60MeshMaterialVariablePrivate::
61MeshMaterialVariablePrivate(const MaterialVariableBuildInfo& v,MatVarSpace mvs,
62 MeshMaterialVariable* variable)
63: m_name(v.name())
64, m_material_mng(v.materialMng())
65, m_var_space(mvs)
66, m_variable(variable)
67{
68 // Pour test uniquement
69 if (!platform::getEnvironmentVariable("ARCANE_NO_RECURSIVE_DEPEND").null())
70 m_has_recursive_depend = false;
71}
72
73 /*---------------------------------------------------------------------------*/
74/*---------------------------------------------------------------------------*/
75
76MeshMaterialVariablePrivate::
77~MeshMaterialVariablePrivate()
78{
79 if (m_global_variable_changed_observer)
80 std::cerr << "WARNING: MeshMaterialVariablePrivate: in destructor: observer is not destroyed\n";
81}
82
83/*---------------------------------------------------------------------------*/
84/*---------------------------------------------------------------------------*/
85
86Int32 MeshMaterialVariablePrivate::
87dataTypeSize() const
88{
89 return m_variable->dataTypeSize();
90}
91
92/*---------------------------------------------------------------------------*/
93/*---------------------------------------------------------------------------*/
94
95void MeshMaterialVariablePrivate::
97 Span<std::byte> bytes, RunQueue* queue) const
98{
99 m_variable->_copyToBuffer(matvar_indexes,bytes,queue);
100}
101
102/*---------------------------------------------------------------------------*/
103/*---------------------------------------------------------------------------*/
104
105void MeshMaterialVariablePrivate::
107 Span<const std::byte> bytes, RunQueue* queue)
108{
109 m_variable->_copyFromBuffer(matvar_indexes,bytes,queue);
110}
111
112/*---------------------------------------------------------------------------*/
113/*---------------------------------------------------------------------------*/
114
115Ref<IData> MeshMaterialVariablePrivate::
116internalCreateSaveDataRef(Integer nb_value)
117{
118 return m_variable->_internalCreateSaveDataRef(nb_value);
119}
120
121/*---------------------------------------------------------------------------*/
122/*---------------------------------------------------------------------------*/
123
124void MeshMaterialVariablePrivate::
125saveData(IMeshComponent* component,IData* data)
126{
127 m_variable->_saveData(component,data);
128}
129
130/*---------------------------------------------------------------------------*/
131/*---------------------------------------------------------------------------*/
132
133void MeshMaterialVariablePrivate::
134restoreData(IMeshComponent* component,IData* data,Integer data_index,
136{
137 m_variable->_restoreData(component,data,data_index,ids,allow_null_id);
138}
139
140/*---------------------------------------------------------------------------*/
141/*---------------------------------------------------------------------------*/
142
143void MeshMaterialVariablePrivate::
144copyBetweenPartialAndGlobal(const CopyBetweenPartialAndGlobalArgs& args)
145{
146 m_variable->_copyBetweenPartialAndGlobal(args);
147}
148
149/*---------------------------------------------------------------------------*/
150/*---------------------------------------------------------------------------*/
151
152void MeshMaterialVariablePrivate::
153initializeNewItemsWithZero(InitializeWithZeroArgs& args)
154{
155 m_variable->_initializeNewItemsWithZero(args);
156}
157
158/*---------------------------------------------------------------------------*/
159/*---------------------------------------------------------------------------*/
160
161void MeshMaterialVariablePrivate::
162syncReferences(bool check_resize)
163{
164 m_variable->_syncReferences(check_resize);
165}
166
167/*---------------------------------------------------------------------------*/
168/*---------------------------------------------------------------------------*/
169
170void MeshMaterialVariablePrivate::
171resizeForIndexer(ResizeVariableIndexerArgs& args)
172{
173 m_variable->_resizeForIndexer(args);
174}
175
176/*---------------------------------------------------------------------------*/
177/*---------------------------------------------------------------------------*/
178
179/*---------------------------------------------------------------------------*/
180/*---------------------------------------------------------------------------*/
181
182MeshMaterialVariable::
183MeshMaterialVariable(const MaterialVariableBuildInfo& v,MatVarSpace mvs)
185, m_views_as_bytes(MemoryUtils::getAllocatorForMostlyReadOnlyData())
186{
187}
188
189/*---------------------------------------------------------------------------*/
190/*---------------------------------------------------------------------------*/
191
192MeshMaterialVariable::
193~MeshMaterialVariable()
194{
195 delete m_p;
196}
197
198/*---------------------------------------------------------------------------*/
199/*---------------------------------------------------------------------------*/
200
203{
204 // Cette méthode ne doit être appelé que par le constructeur de recopie
205 // d'une référence. Pour les autres cas, le compteur de référence est incrémenté
206 // automatiquement.
207 // TODO: regarder si utiliser un AtomicInt32 pour le compteur de référence est
208 // préférable ce qui permettrait de supprimer le verrou.
209 Mutex::ScopedLock sl(m_p->materialMng()->variableLock());
210 ++m_p->m_nb_reference;
211}
212
213/*---------------------------------------------------------------------------*/
214/*---------------------------------------------------------------------------*/
215
218{
219 Mutex::ScopedLock sl(m_p->materialMng()->variableLock());
220 // L'incrément de m_p->m_nb_reference est fait dans getReference()
221 ref->setNextReference(m_p->m_first_reference);
222 if (m_p->m_first_reference){
223 MeshMaterialVariableRef* _list = m_p->m_first_reference;
224 if (_list->previousReference())
225 _list->previousReference()->setNextReference(ref);
226 _list->setPreviousReference(ref);
227 }
228 else{
229 ref->setPreviousReference(nullptr);
230 }
231 m_p->m_first_reference = ref;
232}
233
234/*---------------------------------------------------------------------------*/
235/*---------------------------------------------------------------------------*/
236
239{
240 Mutex::ScopedLock sl(m_p->materialMng()->variableLock());
241
243 if (tmp->previousReference())
244 tmp->previousReference()->setNextReference(tmp->nextReference());
245 if (tmp->nextReference())
246 tmp->nextReference()->setPreviousReference(tmp->previousReference());
247 if (m_p->m_first_reference==tmp)
248 m_p->m_first_reference = m_p->m_first_reference->nextReference();
249
250 // La référence peut être utilisée par la suite donc il ne faut pas oublier
251 // de supprimer le précédent et le suivant.
252 ref->setNextReference(nullptr);
253 ref->setPreviousReference(nullptr);
254
255 Int32 nb_ref = --m_p->m_nb_reference;
256
257 // Vérifie que le nombre de références est valide.
258 // En cas d'erreur, on ne peut rien afficher, car il est possible que m_p ait
259 // déjà été détruit.
260 if (nb_ref<0)
261 ARCANE_FATAL("Invalid reference number for variable");
262
263 // Lorsqu'il n'y a plus de références sur cette variable, le signale au
264 // gestionnaire de variable et se détruit
265 if (nb_ref==0){
266 // Attention : il faut d'abord détruire l'observable,
267 // car removeVariable() peut détruire la variable globale s'il n'y
268 // a plus de références dessus et comme il restera un observateur dessus,
269 // cela provoquera une fuite mémoire car l'observable associé ne sera
270 // pas détruit.
271 delete m_p->m_global_variable_changed_observer;
272 m_p->m_global_variable_changed_observer = nullptr;
273 m_p->materialMng()->_internalApi()->removeVariable(this);
274 delete this;
275 }
276}
277
278/*---------------------------------------------------------------------------*/
279/*---------------------------------------------------------------------------*/
280
282firstReference() const
283{
284 return m_p->m_first_reference;
285}
286
287/*---------------------------------------------------------------------------*/
288/*---------------------------------------------------------------------------*/
289
291name() const
292{
293 return m_p->name();
294}
295
296/*---------------------------------------------------------------------------*/
297/*---------------------------------------------------------------------------*/
298
301{
302 Int32 index = mat->_internalApi()->variableIndexer()->index() + 1;
303 return m_p->m_refs[index]->variable();
304}
305
306/*---------------------------------------------------------------------------*/
307/*---------------------------------------------------------------------------*/
308
310setKeepOnChange(bool v)
311{
312 m_p->m_keep_on_change = v;
313}
314
315/*---------------------------------------------------------------------------*/
316/*---------------------------------------------------------------------------*/
317
319keepOnChange() const
320{
321 return m_p->m_keep_on_change;
322}
323
324/*---------------------------------------------------------------------------*/
325/*---------------------------------------------------------------------------*/
326
329{
330 if (m_p->hasRecursiveDepend()){
331 for( VariableDependInfo& vdi : m_p->m_depends ){
332 vdi.variable()->update();
333 }
334
336 vdi.variable()->update(mat);
337 }
338 }
339 Int32 mat_id = mat->id();
340
341 bool need_update = false;
343 for( VariableDependInfo& vdi : m_p->m_depends ){
344 Int64 mt = vdi.variable()->modifiedTime();
345 if (mt>modified_time){
346 need_update = true;
347 break;
348 }
349 }
350 if (!need_update){
352 Int64 mt = vdi.variable()->modifiedTime(mat);
353 if (mt>modified_time){
354 need_update = true;
355 break;
356 }
357 }
358 }
359
360 if (need_update){
362 if (cf){
363 cf->execute(mat);
364 }
365 else{
366 ARCANE_FATAL("no compute function for variable '{0}'",name());
367 }
368 }
369}
370
371/*---------------------------------------------------------------------------*/
372/*---------------------------------------------------------------------------*/
373
380
383{
384 Int32 id = mat->id();
385 return m_p->m_modified_times[id];
386}
387
393
399
402{
403 ARCANE_UNUSED(var);
404 throw NotImplementedException(A_FUNCINFO);
405}
406
409{
410 m_p->m_depends.add(VariableDependInfo(var,IVariable::DPT_CurrentTime,TraceInfo()));
411}
412
415{
416 m_p->m_depends.add(VariableDependInfo(var,IVariable::DPT_CurrentTime,tinfo));
417}
418
421{
422 ARCANE_UNUSED(var);
423 throw NotImplementedException(A_FUNCINFO);
424}
425
431
437
450
451ITraceMng* MeshMaterialVariable::
452_traceMng() const
453{
454 return m_p->materialMng()->traceMng();
455}
456
457/*---------------------------------------------------------------------------*/
458/*---------------------------------------------------------------------------*/
459
461space() const
462{
463 return m_p->space();
464}
465
466/*---------------------------------------------------------------------------*/
467/*---------------------------------------------------------------------------*/
475{
476 static_assert(sizeof(MatVarIndex)==2*sizeof(Int32),"Bad size for MatVarIndex");
477 auto* ptr = reinterpret_cast<const Int32*>(indexes.data());
478 return { ptr, indexes.size()*2 };
479}
480
481/*---------------------------------------------------------------------------*/
482/*---------------------------------------------------------------------------*/
483
484void MeshMaterialVariable::
486 Span<std::byte> bytes, RunQueue* queue) const
487{
488 const Integer one_data_size = dataTypeSize();
490 const Int32 nb_item = matvar_indexes.size();
491 MutableMemoryView destination_buffer(makeMutableMemoryView(bytes.data(),one_data_size,nb_item));
492 ConstMultiMemoryView source_view(m_views_as_bytes.view(),one_data_size);
493 source_view.copyToIndexes(destination_buffer,indexes,queue);
494}
495
496/*---------------------------------------------------------------------------*/
497/*---------------------------------------------------------------------------*/
498
499void MeshMaterialVariable::
501 Span<const std::byte> bytes, RunQueue* queue)
502{
503 const Int32 one_data_size = dataTypeSize();
505 const Int32 nb_item = matvar_indexes.size();
507 ConstMemoryView source_buffer(makeConstMemoryView(bytes.data(),one_data_size,nb_item));
508 destination_view.copyFromIndexes(source_buffer,indexes,queue);
509}
510
511/*---------------------------------------------------------------------------*/
512/*---------------------------------------------------------------------------*/
513
514void MeshMaterialVariable::
515_genericCopyTo(Span<const std::byte> input,
516 SmallSpan<const Int32> input_indexes,
517 Span<std::byte> output,
518 SmallSpan<const Int32> output_indexes,
519 const RunQueue& queue, Int32 data_type_size)
520{
521 // TODO: vérifier tailles des indexes identiques
522 Integer nb_value = input_indexes.size();
523 auto command = makeCommand(queue);
524
525 ARCANE_CHECK_ACCESSIBLE_POINTER(queue, output.data());
526 ARCANE_CHECK_ACCESSIBLE_POINTER(queue, input.data());
527 ARCANE_CHECK_ACCESSIBLE_POINTER(queue, input_indexes.data());
528 ARCANE_CHECK_ACCESSIBLE_POINTER(queue, output_indexes.data());
529 const Int32 dim2_size = data_type_size;
530
531 command << RUNCOMMAND_LOOP1(iter, nb_value)
532 {
533 auto [i] = iter();
534
535 Int32 output_base = output_indexes[i] * dim2_size;
536 Int32 input_base = input_indexes[i] * dim2_size;
537 for (Int32 j = 0; j < dim2_size; ++j)
538 output[output_base + j] = input[input_base + j];
539 };
540}
541
542/*---------------------------------------------------------------------------*/
543/*---------------------------------------------------------------------------*/
544
545IMeshMaterialVariableInternal* MeshMaterialVariable::
546_internalApi()
547{
548 return m_p->_internalApi();
549}
550
551/*---------------------------------------------------------------------------*/
552/*---------------------------------------------------------------------------*/
553
554} // End namespace Arcane::Materials
555
556/*---------------------------------------------------------------------------*/
557/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_ACCESSIBLE_POINTER(queue_or_runner_or_policy, ptr)
Macro qui vérifie en mode check si ptr est accessible pour une RunQueue ou un Runner.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fichier contenant les déclarations concernant le modèle de programmation par échange de message.
Types et macros pour gérer les boucles sur les accélérateurs.
#define RUNCOMMAND_LOOP1(iter_name, x1,...)
Boucle sur accélérateur avec arguments supplémentaires pour les réductions.
File d'exécution pour un accélérateur.
Interface d'une donnée.
Definition IData.h:33
Interface d'une variable.
Definition IVariable.h:54
static Int64 incrementModifiedTime()
Incrémente le compteur de modification et retourne sa valeur avant modification.
Definition Variable.cc:197
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Arguments des méthodes de copie entre valeurs partielles et globales.
Interface d'un composant (matériau ou milieu) d'un maillage.
virtual Mutex * variableLock()=0
Verrou utilisé pour le multi-threading.
virtual ITraceMng * traceMng()=0
Gestionnaire de traces.
virtual IMeshMaterialMngInternal * _internalApi() const =0
API interne à Arcane.
Interface d'une variable matériau d'un maillage.
Interface d'un matériau d'un maillage.
Arguments des méthodes de copie entre valeurs partielles et globales.
Représente un index sur les variables matériaux et milieux.
UniqueArray< VariableRef * > m_refs
Stocke les références sur les variables tableaux qui servent pour stocker les valeurs par matériau....
UniqueArray< VariableDependInfo > m_depends
Liste des dépendances de cette variable.
UniqueArray< Int64 > m_modified_times
Tag de la dernière modification par matériau.
ScopedPtrT< IMeshMaterialVariableComputeFunction > m_compute_function
Fonction de calcul.
UniqueArray< MeshMaterialVariableDependInfo > m_mat_depends
Liste des dépendances de cette variable.
Classe de base des références aux variables matériaux.
MeshMaterialVariableRef * nextReference()
Référence suivante (ou null) sur variable()
void setUpToDate(IMeshMaterial *mat) override
Indique que la variable vient d'être mise à jour.
MeshMaterialVariableRef * firstReference() const override
Int64 modifiedTime(IMeshMaterial *mat) override
Temps auquel la variable a été mise à jour.
void removeVariableRef(MeshMaterialVariableRef *var_ref) override
Supprime une référence à cette variable.
void update(IMeshMaterial *mat) override
Recalcule la variable pour le matériau mat si nécessaire.
void dependInfos(Array< VariableDependInfo > &infos, Array< MeshMaterialVariableDependInfo > &mat_infos) override
Infos de dépendances.
void addVariableRef(MeshMaterialVariableRef *var_ref) override
Ajoute une référence à cette variable.
IMeshMaterialVariableComputeFunction * computeFunction() override
Fonction utilisée pour mettre à jour la variable.
void setKeepOnChange(bool v) override
Indique si on souhaite conserver la valeur de la variable apres un changement de la liste des matéria...
void addDepend(IMeshMaterialVariable *var) override
Ajoute var à la liste des dépendances.
void removeDepend(IMeshMaterialVariable *var) override
Supprime var de la liste des dépendances.
IVariable * materialVariable(IMeshMaterial *mat) override
Variable contenant les valeurs spécifiques du matériau mat.
void setComputeFunction(IMeshMaterialVariableComputeFunction *v) override
Positionne la fonction de recalcule de la variable.
String name() const override
Nom de la variable.
MatVarSpace space() const override
Espace de définition de la variable (matériau+milieu ou milieu uniquement)
static SmallSpan< const Int32 > _toInt32Indexes(SmallSpan< const MatVarIndex > indexes)
Convertit une vue de MatVarIndex en vue de Int32.
bool keepOnChange() const override
Indique si on souhaite conserver la valeur de la variable apres un changement de la liste des matéria...
Arguments des méthodes de copie entre valeurs partielles et globales.
Informations sur une dépendance de variable.
Informations sur une dépendance de variable.
Vue constante d'un tableau de type T.
Interface du gestionnaire de traces.
Exception lorsqu'une fonction n'est pas implémentée.
Chaîne de caractères unicode.
RunCommand makeCommand(const RunQueue &run_queue)
Créé une commande associée à la file run_queue.
Active toujours les traces dans les parties Arcane concernant les matériaux.
MatVarSpace
Espace de définition d'une variable matériau.