Arcane  v3.16.0.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"
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::
96copyToBuffer(SmallSpan<const MatVarIndex> matvar_indexes,
97 Span<std::byte> bytes, RunQueue* queue) const
98{
99 m_variable->_copyToBuffer(matvar_indexes,bytes,queue);
100}
101
102/*---------------------------------------------------------------------------*/
103/*---------------------------------------------------------------------------*/
104
105void MeshMaterialVariablePrivate::
106copyFromBuffer(SmallSpan<const MatVarIndex> matvar_indexes,
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,
135 Int32ConstArrayView ids,bool allow_null_id)
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)
184: m_p(new MeshMaterialVariablePrivate(v,mvs,this))
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
242 MeshMaterialVariableRef* tmp = ref;
243 if (tmp->previousReference())
245 if (tmp->nextReference())
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
335 for( MeshMaterialVariableDependInfo& vdi : m_p->m_mat_depends ){
336 vdi.variable()->update(mat);
337 }
338 }
339 Int32 mat_id = mat->id();
340
341 bool need_update = false;
342 Int64 modified_time = m_p->m_modified_times[mat_id];
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){
351 for( MeshMaterialVariableDependInfo& vdi : m_p->m_mat_depends ){
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){
361 IMeshMaterialVariableComputeFunction* cf = m_p->m_compute_function.get();
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
376{
377 Int32 id = mat->id();
378 m_p->m_modified_times[id] = IVariable::incrementModifiedTime();
379}
380
383{
384 Int32 id = mat->id();
385 return m_p->m_modified_times[id];
386}
387
390{
391 m_p->m_mat_depends.add(MeshMaterialVariableDependInfo(var,TraceInfo()));
392}
393
396{
397 m_p->m_mat_depends.add(MeshMaterialVariableDependInfo(var,tinfo));
398}
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
414addDepend(IVariable* var,const TraceInfo& tinfo)
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
428{
429 m_p->m_compute_function = v;
430}
431
434{
435 return m_p->m_compute_function.get();
436}
437
441{
442 for( VariableDependInfo& vdi : m_p->m_depends ){
443 infos.add(vdi);
444 }
445
446 for( MeshMaterialVariableDependInfo& vdi : m_p->m_mat_depends ){
447 mat_infos.add(vdi);
448 }
449}
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::
485_copyToBuffer(SmallSpan<const MatVarIndex> matvar_indexes,
486 Span<std::byte> bytes, RunQueue* queue) const
487{
488 const Integer one_data_size = dataTypeSize();
489 SmallSpan<const Int32> indexes(_toInt32Indexes(matvar_indexes));
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::
500_copyFromBuffer(SmallSpan<const MatVarIndex> matvar_indexes,
501 Span<const std::byte> bytes, RunQueue* queue)
502{
503 const Int32 one_data_size = dataTypeSize();
504 SmallSpan<const Int32> indexes(_toInt32Indexes(matvar_indexes));
505 const Int32 nb_item = matvar_indexes.size();
506 MutableMultiMemoryView destination_view(m_views_as_bytes.view(),one_data_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.
Fonctions de gestion mémoire et des allocateurs.
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.
Tableau d'items de types quelconques.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Interface d'une donnée.
Definition IData.h:33
Interface du gestionnaire de traces.
Interface d'une variable.
Definition IVariable.h:56
virtual Int64 modifiedTime()=0
Temps auquel la variable a été mise à jour.
static Int64 incrementModifiedTime()
Incrémente le compteur de modification et retourne sa valeur avant modification.
Definition Variable.cc:197
virtual void update()=0
Recalcule la variable si nécessaire.
Arguments des méthodes de copie entre valeurs partielles et globales.
virtual MeshMaterialVariableIndexer * variableIndexer() const =0
Indexeur pour accéder aux variables partielles.
Interface d'un composant (matériau ou milieu) d'un maillage.
virtual Int32 id() const =0
Identifiant du composant.
virtual IMeshComponentInternal * _internalApi()=0
API interne.
virtual ITraceMng * traceMng()=0
Gestionnaire de traces.
virtual void execute(IMeshMaterial *mat)=0
Exécute la fonction de calcul.
API interne Arcane de 'IMeshMaterialVariable'.
Interface d'une variable matériau d'un maillage.
virtual Int64 modifiedTime(IMeshMaterial *mat)=0
Temps auquel la variable a été mise à jour.
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.
Classe de base des références aux variables matériaux.
MeshMaterialVariableRef * nextReference()
Référence suivante (ou null) sur variable()
void setNextReference(MeshMaterialVariableRef *v)
Positionne la référence suivante.
MeshMaterialVariableRef * previousReference()
Référence précédente (ou null) sur variable()
void setPreviousReference(MeshMaterialVariableRef *v)
Positionne la référence précédente.
Classe de base des variables matériaux.
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.
IMeshMaterialVariable * variable() const
Variable.
Exception lorsqu'une fonction n'est pas implémentée.
Référence à une instance.
Vue d'un tableau d'éléments de type T.
Definition Span.h:673
constexpr __host__ __device__ SizeType size() const noexcept
Retourne la taille du tableau.
Definition Span.h:212
constexpr __host__ __device__ pointer data() const noexcept
Pointeur sur le début de la vue.
Definition Span.h:422
Vue d'un tableau d'éléments de type T.
Definition Span.h:513
Chaîne de caractères unicode.
Informations sur une dépendance de variable.
IVariable * variable() const
Variable.
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.
Espace de noms pour les fonctions de gestion mémoire et des allocateurs.
ARCANE_DATATYPE_EXPORT Integer dataTypeSize(eDataType type)
Taille du type de donnée type (qui doit être différent de DT_String)
Definition DataTypes.cc:109
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:569
std::int32_t Int32
Type entier signé sur 32 bits.