Arcane  v3.14.10.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-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::
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
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 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.
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.
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.
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()
Informations sur une dépendance de variable.
Informations sur une dépendance de variable.
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.
Vue d'un tableau d'éléments de type T.
Definition Span.h:670
constexpr __host__ __device__ SizeType size() const noexcept
Retourne la taille du tableau.
Definition Span.h:209
constexpr __host__ __device__ pointer data() const noexcept
Pointeur sur le début de la vue.
Definition Span.h:419
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.
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
Int32 Integer
Type représentant un entier.