Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
VariableRef.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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/* VariableRef.cc (C) 2000-2026 */
9/* */
10/* Reference to a variable. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ArcanePrecomp.h"
15#include "arcane/utils/ITraceMng.h"
16#include "arcane/utils/InvalidArgumentException.h"
17#include "arcane/utils/IStackTraceService.h"
18#include "arcane/utils/TraceInfo.h"
19#include "arcane/utils/PlatformUtils.h"
20
21#include "arcane/core/VariableRef.h"
22#include "arcane/core/VariableBuildInfo.h"
23#include "arcane/core/ISubDomain.h"
24#include "arcane/core/IModule.h"
25#include "arcane/core/IVariableMng.h"
26#include "arcane/core/ArcaneException.h"
27
28#include <set>
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33namespace Arcane
34{
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
53{
54 public:
55
56 typedef void (*ChangedFunc)();
57
58 public:
59
60 UpdateNotifyFunctorList()
61 : m_is_destroyed(false)
62 {}
63
64 private:
65
66 std::set<ChangedFunc> m_funcs;
67 bool m_is_destroyed;
68
69 public:
70
71 void execute()
72 {
73 std::set<ChangedFunc>::const_iterator begin = m_funcs.begin();
74 std::set<ChangedFunc>::const_iterator end = m_funcs.end();
75 for (; begin != end; ++begin) {
76 ChangedFunc f = *begin;
77 (*f)();
78 }
79 }
80
81 void destroy()
82 {
83 // Indicates that we are destroying.
84 // But do not delete until m_funcs is empty.
85 m_is_destroyed = true;
86 if (m_funcs.empty())
87 delete this;
88 }
89
90 void add(ChangedFunc f)
91 {
92 m_funcs.insert(f);
93 }
94
95 void remove(ChangedFunc f)
96 {
97 m_funcs.erase(f);
98 _checkDestroy();
99 }
100
101 public:
102
103 static void* _add(VariableRef* var, void (*func)())
104 {
105 //std::cout << "_SET_MESH_VARIABLE_CHANGED_DELEGATE"
106 // << " name=" << var->name()
107 // << " func=" << (void*)func
108 // << " this=" << var
109 // << '\n';
110 if (!var->m_notify_functor_list) {
111 var->m_notify_functor_list = new VariableRef::UpdateNotifyFunctorList();
112 }
113 var->m_notify_functor_list->add(func);
114 return var->m_notify_functor_list;
115 }
116 static void _remove(UpdateNotifyFunctorList* functor_list,
117 void (*func)())
118 {
119 //std::cout << "_REMOVE_MESH_VARIABLE_CHANGED_DELEGATE"
120 // << " functor=" << functor_list
121 // << '\n';
122 functor_list->remove(func);
123 }
124
125 private:
126
127 void _checkDestroy()
128 {
129 if (m_is_destroyed && m_funcs.empty())
130 delete this;
131 }
132};
133
134/*---------------------------------------------------------------------------*/
135/*---------------------------------------------------------------------------*/
136
139: m_module(vbi.module())
141{
142 //cout << "VAR NAME=" << vbi.name() << " this="
143 // << this << " module=" << m_module << '\n';
144 _setAssignmentStackTrace();
145}
146
147/*---------------------------------------------------------------------------*/
148/*---------------------------------------------------------------------------*/
149
152: m_variable(var)
154{
155 //cout << "VAR NAME=" << vbi.name() << " this="
156 // << this << " module=" << m_module << '\n';
157 _setAssignmentStackTrace();
158}
159
160/*---------------------------------------------------------------------------*/
161/*---------------------------------------------------------------------------*/
162
174
175/*---------------------------------------------------------------------------*/
176/*---------------------------------------------------------------------------*/
177
179VariableRef(const VariableRef& from)
181, m_module(from.m_module)
183{
184 _setAssignmentStackTrace();
185 //cout << "** TODO: check variable copy constructor with linked list\n";
186 // NOTE:
187 // The variable updates m_previous_reference and m_next_reference
188 // in registerVariable.
189 if (from.m_variable)
191}
192
193/*---------------------------------------------------------------------------*/
194/*---------------------------------------------------------------------------*/
195
197operator=(const VariableRef& rhs)
198{
199 if (this != &rhs) {
200 if (rhs.m_variable != m_variable)
201 _internalAssignVariable(rhs);
202 }
203 return (*this);
204}
205
206/*---------------------------------------------------------------------------*/
207/*---------------------------------------------------------------------------*/
208
211{
212 //cout << "DESTROY VAR NAME=" << name() << " this=" << this << '\n';
213 //cout << "Unregistering variable ref " << this << '\n';
214 //cout.flush();
215 if (m_notify_functor_list)
216 m_notify_functor_list->destroy();
217 if (m_is_registered)
219}
220
221/*---------------------------------------------------------------------------*/
222/*---------------------------------------------------------------------------*/
223
224void VariableRef::
225_setAssignmentStackTrace()
226{
228 if (hasTraceCreation()) {
230 if (stack_service) {
231 m_assignment_stack_trace = stack_service->stackTrace().toString();
232 }
233 }
234}
235
236/*---------------------------------------------------------------------------*/
237/*---------------------------------------------------------------------------*/
238
241{
242 _checkValid();
243 m_variable->removeVariableRef(this);
244 m_is_registered = false;
245}
246
247/*---------------------------------------------------------------------------*/
248/*---------------------------------------------------------------------------*/
249
252{
253 _checkValid();
254 m_variable->addVariableRef(this);
255 m_is_registered = true;
256}
257
258/*---------------------------------------------------------------------------*/
259/*---------------------------------------------------------------------------*/
260
263{
267 // Variables other than those on the mesh are always used
268 // by default
269 if (variable->itemKind() == IK_Unknown)
270 setUsed(true);
271}
272
273/*---------------------------------------------------------------------------*/
274/*---------------------------------------------------------------------------*/
275
277dataType() const
278{
279 _checkValid();
280 return m_variable->dataType();
281}
282
283/*---------------------------------------------------------------------------*/
284/*---------------------------------------------------------------------------*/
285
287print(std::ostream& o) const
288{
289 _checkValid();
290 m_variable->print(o);
291}
292
293/*---------------------------------------------------------------------------*/
294/*---------------------------------------------------------------------------*/
295
297name() const
298{
299 _checkValid();
300 return m_variable->name();
301}
302
303/*---------------------------------------------------------------------------*/
304/*---------------------------------------------------------------------------*/
305
307property() const
308{
309 _checkValid();
310 return m_variable->property();
311}
312
313/*---------------------------------------------------------------------------*/
314/*---------------------------------------------------------------------------*/
315
317subDomain() const
318{
319 _checkValid();
320 return m_variable->subDomain();
321}
322
323/*---------------------------------------------------------------------------*/
324/*---------------------------------------------------------------------------*/
325
327variableMng() const
328{
329 _checkValid();
330 return m_variable->variableMng();
331}
332
333/*---------------------------------------------------------------------------*/
334/*---------------------------------------------------------------------------*/
335
337checkIfSync(int max_print)
338{
339 _checkValid();
340 return m_variable->checkIfSync(max_print);
341}
342
343/*---------------------------------------------------------------------------*/
344/*---------------------------------------------------------------------------*/
345
347checkIfSameOnAllReplica(int max_print)
348{
349 _checkValid();
350 return m_variable->checkIfSameOnAllReplica(max_print);
351}
352
353/*---------------------------------------------------------------------------*/
354/*---------------------------------------------------------------------------*/
355
357referenceProperty() const
358{
360}
361
362/*---------------------------------------------------------------------------*/
363/*---------------------------------------------------------------------------*/
364
369
370/*---------------------------------------------------------------------------*/
371/*---------------------------------------------------------------------------*/
372
373void VariableRef::
374_throwInvalid() const
375{
376 String msg("Using a reference on a uninitialized variable");
377 throw InternalErrorException(A_FUNCINFO, msg);
378}
379
380/*---------------------------------------------------------------------------*/
381/*---------------------------------------------------------------------------*/
382
385{
387 throw InvalidArgumentException(A_FUNCINFO, "property", property);
389 m_variable->notifyReferencePropertyChanged();
390}
391
392/*---------------------------------------------------------------------------*/
393/*---------------------------------------------------------------------------*/
394
397{
399 throw InvalidArgumentException(A_FUNCINFO, "property", property);
401 m_variable->notifyReferencePropertyChanged();
402}
403
404/*---------------------------------------------------------------------------*/
405/*---------------------------------------------------------------------------*/
406
412{
413 switch (property) {
424 return true;
427 return false;
428 default:
429 break;
430 }
431 return false;
432}
433
434/*---------------------------------------------------------------------------*/
435/*---------------------------------------------------------------------------*/
436
437/*---------------------------------------------------------------------------*/
438/*---------------------------------------------------------------------------*/
439
441update()
442{
443 m_variable->update();
444}
445
446/*---------------------------------------------------------------------------*/
447/*---------------------------------------------------------------------------*/
448
451{
452 m_variable->setUpToDate();
453}
454
455/*---------------------------------------------------------------------------*/
456/*---------------------------------------------------------------------------*/
457
460{
461 return m_variable->modifiedTime();
462}
463
464/*---------------------------------------------------------------------------*/
465/*---------------------------------------------------------------------------*/
466
469{
470 m_variable->addDepend(var.variable(), IVariable::DPT_CurrentTime);
471}
472
473/*---------------------------------------------------------------------------*/
474/*---------------------------------------------------------------------------*/
475
478{
479 m_variable->addDepend(var.variable(), IVariable::DPT_PreviousTime);
480}
481
482/*---------------------------------------------------------------------------*/
483/*---------------------------------------------------------------------------*/
484
486addDependCurrentTime(const VariableRef& var, const TraceInfo& tinfo)
487{
488 m_variable->addDepend(var.variable(), IVariable::DPT_CurrentTime, tinfo);
489}
490
491/*---------------------------------------------------------------------------*/
492/*---------------------------------------------------------------------------*/
493
495addDependPreviousTime(const VariableRef& var, const TraceInfo& tinfo)
496{
497 m_variable->addDepend(var.variable(), IVariable::DPT_PreviousTime, tinfo);
498}
499
500/*---------------------------------------------------------------------------*/
501/*---------------------------------------------------------------------------*/
502
504removeDepend(const VariableRef& var)
505{
506 m_variable->removeDepend(var.variable());
507}
508
509/*---------------------------------------------------------------------------*/
510/*---------------------------------------------------------------------------*/
511
512void VariableRef::
513_setComputeFunction(IVariableComputeFunction* v)
514{
516}
517
518/*---------------------------------------------------------------------------*/
519/*---------------------------------------------------------------------------*/
520
522addTag(const String& tagname, const String& tagvalue)
523{
524 m_variable->addTag(tagname, tagvalue);
525}
526
527/*---------------------------------------------------------------------------*/
528/*---------------------------------------------------------------------------*/
529
531removeTag(const String& tagname)
532{
533 m_variable->removeTag(tagname);
534}
535
536/*---------------------------------------------------------------------------*/
537/*---------------------------------------------------------------------------*/
538
540hasTag(const String& tagname) const
541{
542 return m_variable->hasTag(tagname);
543}
544
545/*---------------------------------------------------------------------------*/
546/*---------------------------------------------------------------------------*/
547
549tagValue(const String& tagname) const
550{
551 return m_variable->tagValue(tagname);
552}
553
554/*---------------------------------------------------------------------------*/
555/*---------------------------------------------------------------------------*/
556
562
563/*---------------------------------------------------------------------------*/
564/*---------------------------------------------------------------------------*/
565
571
572/*---------------------------------------------------------------------------*/
573/*---------------------------------------------------------------------------*/
574
580
581/*---------------------------------------------------------------------------*/
582/*---------------------------------------------------------------------------*/
583
589
590/*---------------------------------------------------------------------------*/
591/*---------------------------------------------------------------------------*/
592
593/*---------------------------------------------------------------------------*/
594/*---------------------------------------------------------------------------*/
595
596bool VariableRef::m_static_has_trace_creation = false;
597
598/*---------------------------------------------------------------------------*/
599/*---------------------------------------------------------------------------*/
600
601void VariableRef::
602setTraceCreation(bool v)
603{
604 m_static_has_trace_creation = v;
605}
606
607/*---------------------------------------------------------------------------*/
608/*---------------------------------------------------------------------------*/
609
610bool VariableRef::
611hasTraceCreation()
612{
613 return m_static_has_trace_creation;
614}
615
616/*---------------------------------------------------------------------------*/
617/*---------------------------------------------------------------------------*/
618
619void VariableRef::
620_executeUpdateFunctors()
621{
622 if (m_notify_functor_list)
623 m_notify_functor_list->execute();
624}
625
626/*---------------------------------------------------------------------------*/
627/*---------------------------------------------------------------------------*/
628
629void VariableRef::
630_internalAssignVariable(const VariableRef& var)
631{
632 _setAssignmentStackTrace();
633 if (m_is_registered)
635 m_module = var.m_module;
636 m_variable = var.m_variable;
637 m_reference_property = var.m_reference_property;
638 m_has_trace = false;
639 // DO NOT TOUCH: m_notify_functor_list
640 //NOTE:
641 // It is the variable that updates m_previous_reference and m_next_reference
642 // in registerVariable.
643 //cout << "** TODO: check variable operator= with linked list\n";
645}
646
647/*---------------------------------------------------------------------------*/
648/*---------------------------------------------------------------------------*/
649
650/*
651 * \internal
652 * \brief Adds a functor for C# wrapping.
653 */
654extern "C" ARCANE_CORE_EXPORT void*
655_AddVariableChangedDelegate(VariableRef* var, void (*func)())
656{
657 return VariableRef::UpdateNotifyFunctorList::_add(var, func);
658}
659
660/*
661 * \internal
662 * \brief Removes a functor for C# wrapping.
663 */
664extern "C" ARCANE_CORE_EXPORT void
665_RemoveVariableChangedDelegate(VariableRef::UpdateNotifyFunctorList* functor_list,
666 void (*func)())
667{
668 VariableRef::UpdateNotifyFunctorList::_remove(functor_list, func);
669}
670
671/*---------------------------------------------------------------------------*/
672/*---------------------------------------------------------------------------*/
673
674} // End namespace Arcane
675
676/*---------------------------------------------------------------------------*/
677/*---------------------------------------------------------------------------*/
Interface of a function call tracing service.
virtual StackTrace stackTrace(int first_function=0)=0
Character string indicating the call stack.
Interface of the subdomain manager.
Definition ISubDomain.h:75
Interface of the functor class for recalculating a variable.
Variable manager interface.
Interface of a variable.
Definition IVariable.h:40
@ PSubDomainDepend
Indicates that the variable value is dependent on the subdomain.
Definition IVariable.h:81
@ PNoExchange
Indicates that the variable should not be exchanged.
Definition IVariable.h:130
@ PNoReplicaSync
Indicates that the variable does not necessarily have the same value across replicas.
Definition IVariable.h:147
@ PExecutionDepend
Indicates that the variable value is dependent on the execution.
Definition IVariable.h:96
@ PHasTrace
Indicates that the variable is traced (only in trace mode).
Definition IVariable.h:73
@ PPrivate
Indicates that the variable is private.
Definition IVariable.h:103
@ PPersistant
Indicates that the variable is persistent.
Definition IVariable.h:138
@ PNoRestore
Indicates that the variable should not be restored.
Definition IVariable.h:120
@ PSubDomainPrivate
Indicates that the variable is private to the subdomain.
Definition IVariable.h:89
@ PNoNeedSync
Indicates that the variable is not necessarily synchronized.
Definition IVariable.h:70
@ PNoDump
Indicates that the variable should not be saved.
Definition IVariable.h:62
@ PDumpNull
Indicates that the save will be null for this variable and for this subdomain.
Definition IVariable.h:167
virtual void setComputeFunction(IVariableComputeFunction *v)=0
Sets the variable's recalculation function.
Exception when an internal error occurs.
Exception when a fatal error has occurred.
const String & toString() const
String indicating the call stack.
Parameters necessary for building a variable.
Internal class to manage functors called when the variable is updated.
Reference to a variable.
Definition VariableRef.h:56
IModule * m_module
Associated module (or 0 if none).
virtual Integer checkIfSameOnAllReplica(int max_print=0)
Checks if the variable has the same values on all replicas.
virtual void updateFromInternal()
Updates from the internal part.
VariableRef(const VariableBuildInfo &vbi)
Constructs a reference to a variable with the infos vbi.
bool _checkValidPropertyChanged(int property)
Checks if a property can be changed dynamically.
VariableRef & operator=(const VariableRef &from)
Copy assignment operator.
virtual void setProperty(int property)
Sets the property property.
VariableRef()
Default constructor.
bool m_is_registered
true if the variable has been registered
virtual eDataType dataType() const
Variable type (Real, Integer, ...).
void removeTag(const String &tagname)
Removes the tag tagname.
VariableRef * m_previous_reference
Previous reference on m_variable.
virtual Integer checkIfSync(int max_print=0)
Checks if the variable is synchronized.
virtual void print(std::ostream &o) const
Prints the variable value.
void setPreviousReference(VariableRef *v)
Sets the previous reference.
virtual int property() const
Variable properties.
virtual void unsetProperty(int property)
Unsets the property property.
void addTag(const String &tagname, const String &tagvalue)
Adds the tag tagname with the value tagvalue.
Int64 modifiedTime()
Time when the variable was updated.
virtual IModule * module() const
Module associated with the variable (or nullptr, if none).
VariableRef * previousReference()
Previous reference (or null) to variable().
String tagValue(const String &tagname) const
Value of the tag tagname. The string is null if the tag does not exist.
void setUpToDate()
Indicates that the variable has just been updated.
int m_reference_property
Reference properties.
String m_assignment_stack_trace
Call stack during variable assignment.
void addDependCurrentTime(const VariableRef &var)
Adds var to the dependency list at the current time.
IVariable * variable() const
Associated variable.
void update()
Recalculates the variable if necessary.
VariableRef * m_next_reference
Next reference on m_variable.
void _internalInit(IVariable *)
Internal initialization of the variable.
virtual void unregisterVariable()
Unregisters the variable (internal).
String name() const
Variable name.
ISubDomain * subDomain() const
Sub-domain associated with the variable (TODO deprecate end of 2023).
virtual void registerVariable()
Registers the variable (internal).
virtual int referenceProperty() const
Reference properties (internal).
bool hasTag(const String &tagname) const
true if the variable has the tag tagname
void removeDepend(const VariableRef &var)
Removes var from the dependency list.
IVariable * m_variable
Associated variable.
IVariableMng * variableMng() const
Variable manager associated with the variable.
void addDependPreviousTime(const VariableRef &var)
Adds var to the dependency list at the previous time.
void setNextReference(VariableRef *v)
Sets the next reference.
virtual ~VariableRef()
Releases resources.
VariableRef * nextReference()
Next reference (or null) to variable().
IStackTraceService * getStackTraceService()
Service used to obtain the call stack.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
@ IK_Unknown
Unknown or uninitialized mesh entity.
eDataType
Data type.
Definition DataTypes.h:41