Arcane  v4.1.1.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
MeshMaterialVariable.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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-2025 */
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
49#include "arcane/accelerator/RunCommandLoop.h"
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))
186{
187}
188
189/*---------------------------------------------------------------------------*/
190/*---------------------------------------------------------------------------*/
191
192MeshMaterialVariable::
193~MeshMaterialVariable()
194{
195 delete m_p;
196}
197
198/*---------------------------------------------------------------------------*/
199/*---------------------------------------------------------------------------*/
200
201void MeshMaterialVariable::
202incrementReference()
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
216void MeshMaterialVariable::
217addVariableRef(MeshMaterialVariableRef* ref)
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
237void MeshMaterialVariable::
238removeVariableRef(MeshMaterialVariableRef* ref)
239{
240 Mutex::ScopedLock sl(m_p->materialMng()->variableLock());
241
242 MeshMaterialVariableRef* tmp = ref;
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
281MeshMaterialVariableRef* MeshMaterialVariable::
282firstReference() const
283{
284 return m_p->m_first_reference;
285}
286
287/*---------------------------------------------------------------------------*/
288/*---------------------------------------------------------------------------*/
289
290String MeshMaterialVariable::
291name() const
292{
293 return m_p->name();
294}
295
296/*---------------------------------------------------------------------------*/
297/*---------------------------------------------------------------------------*/
298
299IVariable* MeshMaterialVariable::
300materialVariable(IMeshMaterial* mat)
301{
302 Int32 index = mat->_internalApi()->variableIndexer()->index() + 1;
303 return m_p->m_refs[index]->variable();
304}
305
306/*---------------------------------------------------------------------------*/
307/*---------------------------------------------------------------------------*/
308
309void MeshMaterialVariable::
310setKeepOnChange(bool v)
311{
312 m_p->m_keep_on_change = v;
313}
314
315/*---------------------------------------------------------------------------*/
316/*---------------------------------------------------------------------------*/
317
318bool MeshMaterialVariable::
319keepOnChange() const
320{
321 return m_p->m_keep_on_change;
322}
323
324/*---------------------------------------------------------------------------*/
325/*---------------------------------------------------------------------------*/
326
327void MeshMaterialVariable::
328update(IMeshMaterial* mat)
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
374void MeshMaterialVariable::
375setUpToDate(IMeshMaterial* mat)
376{
377 Int32 id = mat->id();
378 m_p->m_modified_times[id] = IVariable::incrementModifiedTime();
379}
380
381Int64 MeshMaterialVariable::
382modifiedTime(IMeshMaterial* mat)
383{
384 Int32 id = mat->id();
385 return m_p->m_modified_times[id];
386}
387
388void MeshMaterialVariable::
389addDepend(IMeshMaterialVariable* var)
390{
391 m_p->m_mat_depends.add(MeshMaterialVariableDependInfo(var,TraceInfo()));
392}
393
394void MeshMaterialVariable::
395addDepend(IMeshMaterialVariable* var,const TraceInfo& tinfo)
396{
397 m_p->m_mat_depends.add(MeshMaterialVariableDependInfo(var,tinfo));
398}
399
400void MeshMaterialVariable::
401removeDepend(IMeshMaterialVariable* var)
402{
403 ARCANE_UNUSED(var);
404 throw NotImplementedException(A_FUNCINFO);
405}
406
407void MeshMaterialVariable::
408addDepend(IVariable* var)
409{
410 m_p->m_depends.add(VariableDependInfo(var,IVariable::DPT_CurrentTime,TraceInfo()));
411}
412
413void MeshMaterialVariable::
414addDepend(IVariable* var,const TraceInfo& tinfo)
415{
416 m_p->m_depends.add(VariableDependInfo(var,IVariable::DPT_CurrentTime,tinfo));
417}
418
419void MeshMaterialVariable::
420removeDepend(IVariable* var)
421{
422 ARCANE_UNUSED(var);
423 throw NotImplementedException(A_FUNCINFO);
424}
425
426void MeshMaterialVariable::
427setComputeFunction(IMeshMaterialVariableComputeFunction* v)
428{
429 m_p->m_compute_function = v;
430}
431
433computeFunction()
434{
435 return m_p->m_compute_function.get();
436}
437
438void MeshMaterialVariable::
439dependInfos(Array<VariableDependInfo>& infos,
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
460MatVarSpace MeshMaterialVariable::
461space() const
462{
463 return m_p->space();
464}
465
466/*---------------------------------------------------------------------------*/
467/*---------------------------------------------------------------------------*/
468/*!
469 * \brief Convertit une vue de MatVarIndex en vue de Int32.
470 *
471 * Considère qu'un MatVarIndex contient 2 Int32.
472 */
473SmallSpan<const Int32> MeshMaterialVariable::
474_toInt32Indexes(SmallSpan<const MatVarIndex> indexes)
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 MemoryUtils::copyWithIndexedSource(destination_buffer,source_view,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 MemoryUtils::copyWithIndexedDestination(destination_view, 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_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fichier contenant les déclarations concernant le modèle de programmation par échange de message.
Fonctions de gestion mémoire et des allocateurs.
#define RUNCOMMAND_LOOP1(iter_name, x1,...)
Boucle 1D sur accélérateur avec arguments supplémentaires.
Classe de base des vecteurs 1D de données.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Interface du gestionnaire de traces.
Interface d'une variable.
Definition IVariable.h:39
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:204
virtual void update()=0
Recalcule la variable si nécessaire.
virtual Int32 id() const =0
Identifiant du composant.
virtual IMeshComponentInternal * _internalApi()=0
API interne.
virtual void execute(IMeshMaterial *mat)=0
Exécute la fonction de calcul.
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.
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()
MeshMaterialVariableRef * previousReference()
Référence précédente (ou null) sur variable()
String name() const override
Nom de la variable.
Informations sur une dépendance de variable.
IMeshMaterialVariable * variable() const
Variable.
Vue d'un tableau d'éléments de type T.
Definition Span.h:801
constexpr __host__ __device__ pointer data() const noexcept
Pointeur sur le début de la vue.
Definition Span.h:537
constexpr __host__ __device__ SizeType size() const noexcept
Retourne la taille du tableau.
Definition Span.h:325
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.
MemoryAllocationOptions getAllocatorForMostlyReadOnlyData()
Allocateur par défaut pour les données essentiellement en lecture.
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.
ConstMemoryView makeConstMemoryView(const void *ptr, Int32 datatype_size, Int64 nb_element)
Créé une vue mémoire en lecture seule.
Definition MemoryView.cc:36
std::int32_t Int32
Type entier signé sur 32 bits.
Fonctions utilitaires de gestion mémoire.