Arcane  4.2.1.0
User documentation
Loading...
Searching...
No Matches
Variable.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/* Variable.cc (C) 2000-2026 */
9/* */
10/* Class managing a variable. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13#ifndef ARCANE_VARIABLE_CC
14#define ARCANE_VARIABLE_CC
15/*---------------------------------------------------------------------------*/
16/*---------------------------------------------------------------------------*/
17
18#include "arcane/utils/List.h"
19#include "arcane/utils/FatalErrorException.h"
20#include "arcane/utils/OStringStream.h"
21#include "arcane/utils/Iterator.h"
22#include "arcane/utils/Iostream.h"
23#include "arcane/utils/String.h"
24#include "arcane/utils/ITraceMng.h"
25#include "arcane/utils/PlatformUtils.h"
26#include "arcane/utils/IStackTraceService.h"
27#include "arcane/utils/MemoryAccessInfo.h"
28#include "arcane/utils/NotImplementedException.h"
29#include "arcane/utils/ScopedPtr.h"
30#include "arcane/utils/StringBuilder.h"
31#include "arcane/utils/MemoryView.h"
32#include "arcane/utils/Convert.h"
33
34#include "arcane/core/ItemGroupObserver.h"
35#include "arcane/core/Variable.h"
36#include "arcane/core/VarRefEnumerator.h"
37#include "arcane/core/IVariableAccessor.h"
38#include "arcane/core/ItemGroup.h"
39#include "arcane/core/IMesh.h"
40#include "arcane/core/IItemFamily.h"
41#include "arcane/core/ISubDomain.h"
42#include "arcane/core/VariableInfo.h"
43#include "arcane/core/ISerializer.h"
44#include "arcane/core/VariableBuildInfo.h"
45#include "arcane/core/VariableComputeFunction.h"
46#include "arcane/core/CommonVariables.h"
47#include "arcane/core/Observable.h"
48#include "arcane/core/IVariableMng.h"
49#include "arcane/core/IDataReader.h"
50#include "arcane/core/IDataWriter.h"
51#include "arcane/core/IParallelMng.h"
52#include "arcane/core/VariableDependInfo.h"
53#include "arcane/core/IParallelReplication.h"
54#include "arcane/core/VariableMetaData.h"
55#include "arcane/core/IMeshMng.h"
56#include "arcane/core/MeshHandle.h"
57#include "arcane/core/VariableComparer.h"
58#include "arcane/core/datatype/DataAllocationInfo.h"
59#include "arcane/core/internal/IItemFamilyInternal.h"
60#include "arcane/core/internal/IVariableMngInternal.h"
61#include "arcane/core/internal/IVariableInternal.h"
62#include "arcane/core/internal/IDataInternal.h"
63#include "arcane/core/internal/IParallelMngInternal.h"
64
65#include <map>
66#include <set>
67#include <atomic>
68
69/*---------------------------------------------------------------------------*/
70/*---------------------------------------------------------------------------*/
71
72namespace Arcane
73{
74
75/*---------------------------------------------------------------------------*/
76/*---------------------------------------------------------------------------*/
77
78const char* IVariable::TAG_POST_PROCESSING = "PostProcessing";
79const char* IVariable::TAG_POST_PROCESSING_AT_THIS_ITERATION = "PostProcessingAtThisIteration";
80
81/*---------------------------------------------------------------------------*/
82/*---------------------------------------------------------------------------*/
83
84/*
85 * \brief Private part of a variable.
86 */
87class VariablePrivate
88: public IVariableInternal
89{
90 public:
91
92 VariablePrivate(const VariableBuildInfo& v, const VariableInfo& vi, Variable* var);
93
94 public:
95
96 static std::atomic<Int64> modified_time_global_value;
97
98 public:
99
100 ISubDomain* m_sub_domain = nullptr;
101 IDataFactoryMng* m_data_factory_mng = nullptr;
102 MeshHandle m_mesh_handle; //!< Mesh (can be null)
103 Ref<IData> m_data; //!< Variable data
104 ItemGroup m_item_group; //!< Entity group to which the variable is associated
105 IItemFamily* m_item_family = nullptr; //!< Entity family (can be null)
106 VariableInfo m_infos; //!< Characteristic information of the variable
107 int m_property = 0; //!< Properties of the variable
108 bool m_is_partial = false; //!< True if the variable is partial
109 bool m_need_property_update = false;
110 bool m_is_used = false; //!< Usage status of the variable
111 bool m_has_valid_data = false; //!< True if the data is valid
112 Real m_last_update_time = 0.0; //!< Physical time of the last update
113 VariableRef* m_first_reference = nullptr; //! First reference on the variable
115 UniqueArray<VariableDependInfo> m_depends; //!< List of dependencies for this variable
116 Int64 m_modified_time = 0; //!< Tag of the last modification
121 std::map<String, String> m_tags; //!< List of tags
122 bool m_has_recursive_depend = true; //!< True if dependencies are recursive
123 bool m_want_shrink = false;
124 Variable* m_variable = nullptr; //!< Associated variable
125
126 public:
127
128 /*!
129 * \brief Serializes the `hashid`.
130 *
131 * During deserialization, verifies that the `hashid` is correct
132 * and throws an exception if not.
133 */
135 {
136 switch (sbuf->mode()) {
137 case ISerializer::ModeReserve:
138 sbuf->reserveSpan(eBasicDataType::Byte, HASHID_SIZE);
139 break;
141 sbuf->putSpan(Span<const Byte>(m_hash_id, HASHID_SIZE));
142 break;
144 Byte read_hash_id_buf[HASHID_SIZE];
145 Span<Byte> read_span(read_hash_id_buf, HASHID_SIZE);
146 sbuf->getSpan(read_span);
147 Span<const Byte> ref_span(m_hash_id, HASHID_SIZE);
148 if (ref_span != Span<const Byte>(read_span))
149 ARCANE_FATAL("Bad hashid for variable name='{0}'\n"
150 " expected_hash_id='{1}'\n"
151 " hash_id ='{2}'\n"
152 " This may be due to incoherence in variable list (order) between ranks"
153 " during serialization",
154 m_infos.fullName(), String(ref_span), String(read_span));
155 } break;
156 }
157 }
158
159 public:
160
161 //!@{ \name Implementation of IVariableInternal
162 String computeComparisonHashCollective(IHashAlgorithm* hash_algo, IData* sorted_data) override;
163 void changeAllocator(const MemoryAllocationOptions& alloc_info) override;
164 void resize(const VariableResizeArgs& resize_args) override;
165 VariableComparerResults compareVariable(const VariableComparerArgs& compare_args) override;
166 IParallelMng* replicaParallelMng() const;
167 //!@}
168
169 private:
170
171 static const int HASHID_SIZE = 64;
172 /*!
173 * \brief Hash of the variable to check serialization consistency.
174 *
175 * The first 16 bytes are the hash of the name in hexadecimal format (derived from an Int64)
176 * and the following are the full name (fullName()), possibly truncated, of the variable.
177 * Any remaining characters are '~'.
178 */
179 Byte m_hash_id[HASHID_SIZE];
180
181 void _setHashId()
182 {
183 constexpr Int64 hashid_hexa_length = 16;
184 constexpr Int64 name_length = HASHID_SIZE - hashid_hexa_length;
185 Span<Byte> hash_id(m_hash_id, HASHID_SIZE);
186 hash_id.fill('~');
187 const String& full_name = m_infos.fullName();
188 Int64 hash_value = IntegerHashFunctionT<StringView>::hashfunc(full_name.view());
189 Convert::toHexaString(hash_value, hash_id);
190 Span<const Byte> bytes = full_name.bytes();
191 if (bytes.size() > name_length)
192 bytes = bytes.subspan(0, name_length);
193 auto hash_id2 = hash_id.subspan(hashid_hexa_length, name_length);
194 hash_id2.copy(bytes);
195 }
196};
197
198/*---------------------------------------------------------------------------*/
199/*---------------------------------------------------------------------------*/
200
201std::atomic<Int64> VariablePrivate::modified_time_global_value = 1;
202
203/*---------------------------------------------------------------------------*/
204/*---------------------------------------------------------------------------*/
205
208{
209 Int64 v = VariablePrivate::modified_time_global_value;
210 ++VariablePrivate::modified_time_global_value;
211 return v;
212}
213
214/*---------------------------------------------------------------------------*/
215/*---------------------------------------------------------------------------*/
216
217VariablePrivate::
218VariablePrivate(const VariableBuildInfo& v, const VariableInfo& vi, Variable* var)
219: m_sub_domain(v._subDomain())
220, m_data_factory_mng(v.dataFactoryMng())
221, m_mesh_handle(v.meshHandle())
222, m_infos(vi)
223, m_property(v.property())
224, m_is_partial(vi.isPartial())
225, m_variable(var)
226{
227 _setHashId();
228 m_infos.setDefaultItemGroupName();
229
230 // For testing only
231 if (!platform::getEnvironmentVariable("ARCANE_NO_RECURSIVE_DEPEND").null())
232 m_has_recursive_depend = false;
233
234 // For memory release testing.
235 {
236 String str = platform::getEnvironmentVariable("ARCANE_VARIABLE_SHRINK_MEMORY");
237 if (str == "1")
238 m_want_shrink = true;
239 }
240}
241
242/*---------------------------------------------------------------------------*/
243/*---------------------------------------------------------------------------*/
244
245//! Observer events on the underlying ItemGroup.
246class ItemGroupPartialVariableObserver
247: public IItemGroupObserver
248{
249 public:
250
251 explicit ItemGroupPartialVariableObserver(IVariable* var)
252 : m_var(var)
253 {
254 ARCANE_ASSERT((m_var), ("Variable pointer null"));
255
256 if (var->itemGroup().isAllItems())
257 ARCANE_FATAL("No observer should be attached on all items group");
258 }
259
260 void executeExtend(const Int32ConstArrayView* info) override
261 {
262 const Int32ConstArrayView& new_ids = *info;
263 if (new_ids.empty())
264 return;
265 ItemGroup group = m_var->itemGroup();
266 SharedPtrT<GroupIndexTable> id_to_index = group.localIdToIndex();
267
268 const Integer old_size = id_to_index->size();
269 const Integer group_size = group.size();
270 if (group_size != (old_size + new_ids.size()))
271 ARCANE_FATAL("Inconsistent extended size");
272 m_var->resizeFromGroup();
273 //id_to_index->update();
274 }
275
276 void executeReduce(const Int32ConstArrayView* info) override
277 {
278 // Contains the list of local IDs of items removed from the old group
279 const Int32ConstArrayView& removed_lids = *info;
280 if (removed_lids.empty())
281 return;
282 ItemGroup group = m_var->itemGroup();
283 SharedPtrT<GroupIndexTable> id_to_index = group.localIdToIndex();
284
285 const Integer old_size = id_to_index->size();
286 const Integer group_size = group.size();
287
288 if (group_size != (old_size - removed_lids.size()))
289 ARCANE_FATAL("Inconsistent reduced size {0} vs {1}", group_size, old_size);
290 [[maybe_unused]] ItemVectorView view = group.view();
291 Int32UniqueArray source;
292 Int32UniqueArray destination;
293 source.reserve(group_size);
294 destination.reserve(group_size);
295 for (Integer i = 0, index = 0, removed_index = 0; i < old_size; ++i) {
296 if (removed_index < removed_lids.size() &&
297 id_to_index->keyLocalId(i) == removed_lids[removed_index]) {
298 ++removed_index;
299 }
300 else {
301 ARCANE_ASSERT((id_to_index->keyLocalId(i) == view[index].localId()),
302 ("Inconsistent key (pos=%d,key=%d) vs (pos=%d,key=%d)",
303 i, id_to_index->keyLocalId(i), index, view[index].localId()));
304 if (i != index) {
305 destination.add(index);
306 source.add(i);
307 }
308 ++index;
309 }
310 }
311 m_var->copyItemsValues(source, destination);
312 m_var->resizeFromGroup();
313 }
314
315 void executeCompact(const Int32ConstArrayView* info) override
316 {
317 const Int32ConstArrayView& ids = *info;
318 if (ids.empty())
319 return;
320 ItemGroup group = m_var->itemGroup();
321 SharedPtrT<GroupIndexTable> id_to_index = group.localIdToIndex();
322 m_var->compact(*info);
323 //id_to_index->compact(info);
324 }
325
326 void executeInvalidate() override
327 {
328 ItemGroup group = m_var->itemGroup();
329 SharedPtrT<GroupIndexTable> id_to_index = group.localIdToIndex();
330 m_var->resizeFromGroup();
331 //id_to_index->update();
332 }
333
334 bool needInfo() const override { return true; }
335
336 private:
337
338 IVariable* m_var = nullptr;
339};
340
341/*---------------------------------------------------------------------------*/
342/*---------------------------------------------------------------------------*/
343
345Variable(const VariableBuildInfo& v, const VariableInfo& vi)
347, m_p(new VariablePrivate(v, vi, this))
348{
349}
350
351/*---------------------------------------------------------------------------*/
352/*---------------------------------------------------------------------------*/
353
355~Variable()
356{
357 //NOTE: if the variable has a group, it is the IVariableMng
358 // that removes the reference of this variable from the group
359 delete m_p;
360}
361
362/*---------------------------------------------------------------------------*/
363/*---------------------------------------------------------------------------*/
364
365bool Variable::
366_hasReference() const
367{
368 return m_p->m_first_reference;
369}
370
371/*---------------------------------------------------------------------------*/
372/*---------------------------------------------------------------------------*/
373
376{
377 _checkSetProperty(ref);
378 ++m_p->m_nb_reference;
379 ref->setNextReference(m_p->m_first_reference);
380 if (m_p->m_first_reference) {
381 VariableRef* _list = m_p->m_first_reference;
382 if (_list->previousReference())
383 _list->previousReference()->setNextReference(ref);
384 _list->setPreviousReference(ref);
385 }
386 else {
387 ref->setPreviousReference(0);
388 }
389 m_p->m_first_reference = ref;
390}
391
392/*---------------------------------------------------------------------------*/
393/*---------------------------------------------------------------------------*/
394
397{
398 {
399 VariableRef* tmp = ref;
400 if (tmp->previousReference())
401 tmp->previousReference()->setNextReference(tmp->nextReference());
402 if (tmp->nextReference())
403 tmp->nextReference()->setPreviousReference(tmp->previousReference());
404 if (m_p->m_first_reference == tmp)
405 m_p->m_first_reference = m_p->m_first_reference->nextReference();
406 }
407 // The reference may be used later, so we must remember to clear the
408 // previous and next references.
409 ref->setNextReference(0);
410 ref->setPreviousReference(0);
411
412 --m_p->m_nb_reference;
413 _checkSetProperty(ref);
414
415 // When there are no more references on this variable, it signals the
416 // variable manager, unless it is a persistent variable
417 if (!_hasReference()) {
418 bool is_persistant = property() & IVariable::PPersistant;
419 if (!is_persistant) {
420 //m_p->m_trace->info() << " REF PROPERTY name=" << name() << " " << ref->referenceProperty();
421 _removeMeshReference();
422 ISubDomain* sd = m_p->m_sub_domain;
423 IVariableMng* vm = sd->variableMng();
424 vm->_internalApi()->removeVariable(this);
425 }
426 }
427}
428
429/*---------------------------------------------------------------------------*/
430/*---------------------------------------------------------------------------*/
431
433firstReference() const
434{
435 return m_p->m_first_reference;
436}
437
438/*---------------------------------------------------------------------------*/
439/*---------------------------------------------------------------------------*/
440
441void Variable::
442_checkSetProperty(VariableRef* ref)
443{
444 // Guarantees that the property is correctly updated with the value
445 // of the single reference.
446 if (!_hasReference()) {
447 m_p->m_property = ref->referenceProperty();
448 m_p->m_need_property_update = false;
449 }
450 else
451 m_p->m_need_property_update = true;
452}
453
454/*---------------------------------------------------------------------------*/
455/*---------------------------------------------------------------------------*/
456
458nbReference() const
459{
460 return m_p->m_nb_reference;
461}
462
463/*---------------------------------------------------------------------------*/
464/*---------------------------------------------------------------------------*/
465
467subDomain()
468{
469 return m_p->m_sub_domain;
470}
471
472/*---------------------------------------------------------------------------*/
473/*---------------------------------------------------------------------------*/
474
476variableMng() const
477{
478 return m_p->m_sub_domain->variableMng();
479}
480
481/*---------------------------------------------------------------------------*/
482/*---------------------------------------------------------------------------*/
483
485name() const
486{
487 return m_p->m_infos.localName();
488}
489
490/*---------------------------------------------------------------------------*/
491/*---------------------------------------------------------------------------*/
492
494fullName() const
495{
496 return m_p->m_infos.fullName();
497}
498
499/*---------------------------------------------------------------------------*/
500/*---------------------------------------------------------------------------*/
501
503itemFamilyName() const
504{
505 return m_p->m_infos.itemFamilyName();
506}
507
508/*---------------------------------------------------------------------------*/
509/*---------------------------------------------------------------------------*/
510
512itemGroupName() const
513{
514 return m_p->m_infos.itemGroupName();
515}
516
517/*---------------------------------------------------------------------------*/
518/*---------------------------------------------------------------------------*/
519
521meshName() const
522{
523 return m_p->m_infos.meshName();
524}
525
526/*---------------------------------------------------------------------------*/
527/*---------------------------------------------------------------------------*/
528
530dataType() const
531{
532 return m_p->m_infos.dataType();
533}
534
535/*---------------------------------------------------------------------------*/
536/*---------------------------------------------------------------------------*/
537
538/*!
539 * \todo handle the PSubDomainPrivate case.
540 */
542property() const
543{
544 if (!m_p->m_need_property_update)
545 return m_p->m_property;
546
547 // The variable's properties depend on what each
548 // reference wants, and they must be updated when they change.
549 // For example, if all references are PNoDump but only one is not,
550 // the variable should not be.
551 m_p->m_need_property_update = false;
552
553 bool want_dump = false;
554 bool want_sync = false;
555 bool want_replica_sync = false;
556 bool sub_domain_depend = false;
557 bool execution_depend = false;
558 bool want_private = false;
559 bool want_restore = false;
560 bool want_notemporary = false;
561 bool want_exchange = false;
562 bool want_persistant = false;
563 bool want_shmem = false;
564 bool want_dumpnull = false;
565
566 int property = 0;
567 for (VarRefEnumerator i(this); i.hasNext(); ++i) {
568 VariableRef* vref = *i;
569 int p = vref->referenceProperty();
570 if (!(p & IVariable::PNoDump))
571 want_dump = true;
572 if (!(p & IVariable::PNoNeedSync))
573 want_sync = true;
574 if (!(p & IVariable::PNoReplicaSync))
575 want_replica_sync = true;
577 sub_domain_depend = true;
579 execution_depend = true;
580 if ((p & IVariable::PPersistant))
581 want_persistant = true;
582 if ((p & IVariable::PPrivate))
583 want_private = true;
584 if (!(p & IVariable::PNoRestore))
585 want_restore = true;
586 if (!(p & IVariable::PNoExchange))
587 want_exchange = true;
588 if (!(p & IVariable::PTemporary))
589 want_notemporary = true;
590 if ((p & IVariable::PInShMem))
591 want_shmem = true;
592 if ((p & IVariable::PDumpNull))
593 want_dumpnull = true;
594 }
595
596 if (!want_dump)
597 property |= IVariable::PNoDump;
598 if (!want_sync)
599 property |= IVariable::PNoNeedSync;
600 if (!want_replica_sync)
601 property |= IVariable::PNoReplicaSync;
602 if (sub_domain_depend)
603 property |= IVariable::PSubDomainDepend;
604 if (execution_depend)
605 property |= IVariable::PExecutionDepend;
606 if (want_private)
607 property |= IVariable::PPrivate;
608 if (want_persistant)
609 property |= IVariable::PPersistant;
610 if (!want_restore)
611 property |= IVariable::PNoRestore;
612 if (!want_exchange)
613 property |= IVariable::PNoExchange;
614 if (!want_notemporary)
615 property |= IVariable::PTemporary;
616 if (want_shmem)
617 property |= IVariable::PInShMem;
618 if (want_dumpnull)
619 property |= IVariable::PDumpNull;
620
621 m_p->m_property = property;
622 return m_p->m_property;
623}
624
625/*---------------------------------------------------------------------------*/
626/*---------------------------------------------------------------------------*/
627
630{
631 m_p->m_need_property_update = true;
632}
633
634/*---------------------------------------------------------------------------*/
635/*---------------------------------------------------------------------------*/
636
638setUsed(bool is_used)
639{
640 if (m_p->m_is_used == is_used)
641 return;
642
643 m_p->m_is_used = is_used;
644
645 eItemKind ik = itemKind();
646
647 if (m_p->m_is_used) {
648 if (m_p->m_property & IVariable::PInShMem) {
649 if (m_p->m_property & IVariable::PSubDomainPrivate) {
650 ARCANE_FATAL("Variable with PInShMem property must be in all sub-domains (PSubDomainPrivate property cannot be set with PInShMem)");
651 }
652 if (m_p->m_data->_commonInternal()->numericData() == nullptr) {
653 ARCANE_FATAL("Variable without NumericData cannot change allocator");
654 }
655 // TODO: Even if changeAllocator() with the same allocator already in
656 // place just returns, it's still messy...
657 IParallelMng* pm{};
658 if (m_p->m_mesh_handle.hasMesh()) {
659 pm = m_p->m_mesh_handle.mesh()->parallelMng();
660 }
661 else {
662 pm = subDomain()->parallelMng();
663 }
664 m_p->changeAllocator(pm->_internalApi()->machineShMemWinMemoryAllocator());
665 }
666
667 if (m_p->m_item_group.null() && ik != IK_Unknown) {
668 _checkSetItemFamily();
669 _checkSetItemGroup();
670 // Be careful not to reset the values when they are valid, which
671 // is the case for example after a protection.
672 if (!m_p->m_has_valid_data) {
674 // Historically, we filled the variable with the default constructor
675 // of the data by systematically calling fillDefautt(). However,
676 // this was not the desired behavior, which should be defined by
677 // getGlobalDataInitialisationPolicy() (in DataTypes.h).
678 // We only do this now if the initialization mode is equal
679 // to DIP_Legacy. This mode must eventually disappear.
681 m_p->m_data->fillDefault();
682 m_p->m_has_valid_data = true;
683 }
684 }
685 }
686 else {
687 _removeMeshReference();
688 if (ik == IK_Unknown)
689 resize(0);
690 else
692 // Indicates that the values are no longer valid
693 m_p->m_has_valid_data = false;
694 }
695
696 for (VarRefEnumerator i(this); i.hasNext(); ++i) {
697 VariableRef* ref = *i;
698 ref->internalSetUsed(m_p->m_is_used);
699 }
700}
701
702/*---------------------------------------------------------------------------*/
703/*---------------------------------------------------------------------------*/
704
705void Variable::
706_removeMeshReference()
707{
708 IItemFamily* family = m_p->m_item_family;
709 if (family)
710 family->_internalApi()->removeVariable(this);
711
712 if (isPartial())
713 m_p->m_item_group.internal()->detachObserver(this);
714
715 m_p->m_item_group = ItemGroup();
716 m_p->m_item_family = 0;
717}
718
719/*---------------------------------------------------------------------------*/
720/*---------------------------------------------------------------------------*/
721
723isUsed() const
724{
725 return m_p->m_is_used;
726}
727
728/*---------------------------------------------------------------------------*/
729/*---------------------------------------------------------------------------*/
730
731namespace
732{
733
734 String _buildVariableFullType(const IVariable* var)
735 {
736 StringBuilder full_type_b;
737 full_type_b = dataTypeName(var->dataType());
738 full_type_b += ".";
739 full_type_b += itemKindName(var->itemKind());
740 full_type_b += ".";
741 full_type_b += var->dimension();
742 full_type_b += ".";
743 full_type_b += var->multiTag();
744 if (var->isPartial())
745 full_type_b += ".Partial";
746 return full_type_b.toString();
747 }
748
749} // namespace
750
751/*---------------------------------------------------------------------------*/
752/*---------------------------------------------------------------------------*/
753
754VariableMetaData* Variable::
755_createMetaData() const
756{
757 auto vmd = new VariableMetaData(name(), meshName(), itemFamilyName(),
759 vmd->setFullType(_buildVariableFullType(this));
760 vmd->setMultiTag(String::fromNumber(multiTag()));
761 vmd->setProperty(property());
762 return vmd;
763}
764
765/*---------------------------------------------------------------------------*/
766/*---------------------------------------------------------------------------*/
767
769createMetaData() const
770{
771 return _createMetaData();
772}
773
774/*---------------------------------------------------------------------------*/
775/*---------------------------------------------------------------------------*/
776
778createMetaDataRef() const
779{
780 return makeRef(_createMetaData());
781}
782
783/*---------------------------------------------------------------------------*/
784/*---------------------------------------------------------------------------*/
785
788{
789 //cout << "** SYNC REFERENCE N=" << m_p->m_nb_reference << " F=" << m_p->m_first_reference << '\n';
790 for (VarRefEnumerator i(this); i.hasNext(); ++i) {
791 VariableRef* ref = *i;
792 //cout << "** SYNC REFERENCE V=" << ref << '\n';
793 ref->updateFromInternal();
794 }
795 // It must be done after updating references
796 // because observers may read values via a reference
798}
799
800/*---------------------------------------------------------------------------*/
801/*---------------------------------------------------------------------------*/
802
804checkIfSync(int max_print)
805{
806 VariableComparerArgs compare_args;
807 compare_args.setCompareMode(eVariableComparerCompareMode::Sync);
808 compare_args.setMaxPrint(max_print);
809 compare_args.setCompareGhost(true);
810 VariableComparerResults results = _compareVariable(compare_args);
811 return results.nbDifference();
812}
813
814/*---------------------------------------------------------------------------*/
815/*---------------------------------------------------------------------------*/
816
819{
820 VariableComparerArgs compare_args;
821 compare_args.setCompareMode(eVariableComparerCompareMode::SameOnAllReplica);
822 compare_args.setMaxPrint(max_print);
824 return r.nbDifference();
825}
826
827/*---------------------------------------------------------------------------*/
828/*---------------------------------------------------------------------------*/
829
831checkIfSame(IDataReader* reader, Integer max_print, bool compare_ghost)
832{
833 VariableComparerArgs compare_args;
834 compare_args.setMaxPrint(max_print);
835 compare_args.setCompareGhost(compare_ghost);
836 compare_args.setDataReader(reader);
838 return r.nbDifference();
839}
840
841/*---------------------------------------------------------------------------*/
842/*---------------------------------------------------------------------------*/
843
845mesh() const
846{
847 if (m_p->m_mesh_handle.hasMesh())
848 return m_p->m_mesh_handle.mesh();
849 return nullptr;
850}
851
852/*---------------------------------------------------------------------------*/
853/*---------------------------------------------------------------------------*/
854
856meshHandle() const
857{
858 return m_p->m_mesh_handle;
859}
860
861/*---------------------------------------------------------------------------*/
862/*---------------------------------------------------------------------------*/
863
865itemGroup() const
866{
867 return m_p->m_item_group;
868}
869
870/*---------------------------------------------------------------------------*/
871/*---------------------------------------------------------------------------*/
872
874itemKind() const
875{
876 return m_p->m_infos.itemKind();
877}
878
879/*---------------------------------------------------------------------------*/
880/*---------------------------------------------------------------------------*/
881
883dimension() const
884{
885 return m_p->m_infos.dimension();
886}
887
888/*---------------------------------------------------------------------------*/
889/*---------------------------------------------------------------------------*/
890
892multiTag() const
893{
894 return m_p->m_infos.multiTag();
895}
896
897/*---------------------------------------------------------------------------*/
898/*---------------------------------------------------------------------------*/
899
901isPartial() const
902{
903 return m_p->m_is_partial;
904}
905
906/*---------------------------------------------------------------------------*/
907/*---------------------------------------------------------------------------*/
908
910itemFamily() const
911{
912 return m_p->m_item_family;
913}
914
915/*---------------------------------------------------------------------------*/
916/*---------------------------------------------------------------------------*/
917
920{
921 m_p->m_data = data;
922 if (!data.get()) {
923 ARCANE_FATAL("Invalid data: name={0} datatype={1} dimension={2} multitag={3}",
924 m_p->m_infos.fullName(), m_p->m_infos.dataType(),
925 m_p->m_infos.dimension(), m_p->m_infos.multiTag());
926 }
927 data->setName(m_p->m_infos.fullName());
928}
929
930/*---------------------------------------------------------------------------*/
931/*---------------------------------------------------------------------------*/
932
934_setValidData(bool valid_data)
935{
936 m_p->m_has_valid_data = valid_data;
937}
938
939/*---------------------------------------------------------------------------*/
940/*---------------------------------------------------------------------------*/
941
943_hasValidData() const
944{
945 return m_p->m_has_valid_data;
946}
947
948/*---------------------------------------------------------------------------*/
949/*---------------------------------------------------------------------------*/
950
951void Variable::
952_setProperty(int property)
953{
954 m_p->m_property |= property;
955}
956
957/*---------------------------------------------------------------------------*/
958/*---------------------------------------------------------------------------*/
959
961dataFactoryMng() const
962{
963 return m_p->m_data_factory_mng;
964}
965
966/*---------------------------------------------------------------------------*/
967/*---------------------------------------------------------------------------*/
968
971{
972 debug(Trace::High) << "Serialize (partial) variable name=" << fullName();
973 m_p->serializeHashId(sbuffer);
974 m_p->m_data->serialize(sbuffer, ids, operation);
975 // In read mode, data is modified
976 if (sbuffer->mode() == ISerializer::ModeGet)
978}
979
980/*---------------------------------------------------------------------------*/
981/*---------------------------------------------------------------------------*/
982
984serialize(ISerializer* sbuffer, IDataOperation* operation)
985{
986 debug(Trace::High) << "Serialize (full) variable name=" << fullName();
987
988 m_p->serializeHashId(sbuffer);
989 m_p->m_data->serialize(sbuffer, operation);
990 // In read mode, data is modified
991 if (sbuffer->mode() == ISerializer::ModeGet)
993}
994
995/*---------------------------------------------------------------------------*/
996/*---------------------------------------------------------------------------*/
997
998void Variable::
999_resize(const VariableResizeArgs& resize_args)
1000{
1001 eItemKind ik = itemKind();
1002 if (ik != IK_Unknown) {
1003 ARCANE_FATAL("This call is invalid for item variable. Use resizeFromGroup() instead");
1004 }
1005 _internalResize(resize_args);
1007}
1008
1009/*---------------------------------------------------------------------------*/
1010/*---------------------------------------------------------------------------*/
1011
1013resize(Integer new_size)
1014{
1015 _resize(VariableResizeArgs(new_size));
1016}
1017
1018/*---------------------------------------------------------------------------*/
1019/*---------------------------------------------------------------------------*/
1020
1023{
1024 eItemKind ik = itemKind();
1025 if (ik == IK_Unknown)
1026 return;
1027 Integer new_size = 0;
1028 IItemFamily* family = m_p->m_item_family;
1029 if (family) {
1030 if (m_p->m_item_group.isAllItems())
1031 new_size = m_p->m_item_family->maxLocalId();
1032 else
1033 new_size = m_p->m_item_group.size();
1034 }
1035 else {
1036 ItemGroup group = m_p->m_item_group;
1037 if (!group.null()) {
1038 ARCANE_FATAL("Variable '{0}' has group but no family", fullName());
1039 }
1040 }
1041 debug(Trace::High) << "Variable::resizeFromGroup() var='" << fullName()
1042 << "' with " << new_size << " items "
1043 << " this=" << this;
1044 _internalResize(VariableResizeArgs(new_size, new_size / 20));
1046}
1047
1048/*---------------------------------------------------------------------------*/
1049/*---------------------------------------------------------------------------*/
1050
1051void Variable::
1052_checkSetItemFamily()
1053{
1054 if (m_p->m_item_family || !m_p->m_item_group.null())
1055 return;
1056
1057 if (m_p->m_mesh_handle.isNull())
1058 m_p->m_mesh_handle = m_p->m_sub_domain->meshMng()->findMeshHandle(m_p->m_infos.meshName());
1059
1060 IMesh* mesh = m_p->m_mesh_handle.mesh();
1061 if (!mesh)
1062 ARCANE_FATAL("No mesh named '{0}' exists for variable '{1}'", m_p->m_infos.meshName(), name());
1063
1064 eItemKind ik = itemKind();
1065
1066 IItemFamily* family = 0;
1067 const String& family_name = m_p->m_infos.itemFamilyName();
1068 if (ik == IK_Particle || ik == IK_DoF) {
1069 if (family_name.null()) {
1070 ARCANE_FATAL("family name not specified for variable {0}", name());
1071 }
1072 family = mesh->findItemFamily(ik, family_name, true);
1073 }
1074 else {
1075 family = mesh->itemFamily(ik);
1076 }
1077
1078 if (family && family->itemKind() != itemKind())
1079 ARCANE_FATAL("Bad family kind '{0}' '{1}'", family->itemKind(), itemKind());
1080
1081 if (family && family->name() != itemFamilyName())
1082 ARCANE_FATAL("Incoherent family name. var={0} from_type={1} given={2}",
1083 name(), family->name(), itemFamilyName());
1084
1085 if (!family)
1086 ARCANE_FATAL("Family not found");
1087
1088 if (isPartial() && !family->hasUniqueIdMap())
1089 ARCANE_FATAL("Cannot have partial variable for a family without unique id map");
1090
1091 m_p->m_item_family = family;
1092 debug(Trace::High) << "Variable::setItemFamily() name=" << name()
1093 << " family=" << family
1094 << " familyname='" << family_name << "'";
1095 family->_internalApi()->addVariable(this);
1096}
1097
1098/*---------------------------------------------------------------------------*/
1099/*---------------------------------------------------------------------------*/
1100
1101void Variable::
1102_checkSetItemGroup()
1103{
1104 if (!m_p->m_item_group.null())
1105 return;
1106 const String& group_name = m_p->m_infos.itemGroupName();
1107 //info() << " CHECK SET GROUP var=" << name() << " group=" << group_name;
1108 if (group_name.null()) {
1109 m_p->m_item_group = m_p->m_item_family->allItems();
1110 }
1111 else
1112 m_p->m_item_group = m_p->m_item_family->findGroup(group_name, true);
1113
1114 ItemGroupImpl* internal = m_p->m_item_group.internal();
1115 // (HP) TODO: should we keep this check inherited from the old addVariable implementation
1116 if (internal->parent() && (mesh()->parallelMng()->isParallel() && internal->isOwn()))
1117 ARCANE_FATAL("Cannot add variable ({0}) on a own group (name={1})",
1118 fullName(), internal->name());
1119 if (isPartial()) {
1120 if (group_name.empty())
1121 ARCANE_FATAL("Cannot create a partial variable with an empty item_group_name");
1122 debug(Trace::High) << "Attach ItemGroupPartialVariableObserver from " << fullName()
1123 << " to " << m_p->m_item_group.name();
1124 internal->attachObserver(this, new ItemGroupPartialVariableObserver(this));
1125 }
1126}
1127
1128/*---------------------------------------------------------------------------*/
1129/*---------------------------------------------------------------------------*/
1130
1133{
1134 return &(m_p->m_write_observable);
1135}
1136
1137/*---------------------------------------------------------------------------*/
1138/*---------------------------------------------------------------------------*/
1139
1142{
1143 return &(m_p->m_read_observable);
1144}
1145
1146/*---------------------------------------------------------------------------*/
1147/*---------------------------------------------------------------------------*/
1148
1151{
1152 return &(m_p->m_on_size_changed_observable);
1153}
1154
1155/*---------------------------------------------------------------------------*/
1156/*---------------------------------------------------------------------------*/
1157
1158/*---------------------------------------------------------------------------*/
1159/*---------------------------------------------------------------------------*/
1160
1162update()
1163{
1164 update(DPT_PreviousTime);
1165}
1166
1167/*---------------------------------------------------------------------------*/
1168/*---------------------------------------------------------------------------*/
1169
1170void Variable::
1171update(Real wanted_time)
1172{
1173 if (m_p->m_last_update_time < wanted_time) {
1174 for (Integer k = 0, n = m_p->m_depends.size(); k < n; ++k) {
1175 VariableDependInfo& vdi = m_p->m_depends[k];
1176 if (vdi.dependType() == DPT_PreviousTime)
1177 vdi.variable()->update(wanted_time);
1178 }
1179 }
1180
1181 if (m_p->m_has_recursive_depend) {
1182 for (Integer k = 0, n = m_p->m_depends.size(); k < n; ++k) {
1183 VariableDependInfo& vdi = m_p->m_depends[k];
1184 if (vdi.dependType() == DPT_CurrentTime)
1185 vdi.variable()->update(m_p->m_last_update_time);
1186 }
1187 }
1188
1189 bool need_update = false;
1190 Int64 modified_time = m_p->m_modified_time;
1191 for (Integer k = 0, n = m_p->m_depends.size(); k < n; ++k) {
1192 VariableDependInfo& vdi = m_p->m_depends[k];
1193 Int64 mt = vdi.variable()->modifiedTime();
1194 if (mt > modified_time) {
1195 need_update = true;
1196 break;
1197 }
1198 }
1199 if (need_update) {
1200 IVariableComputeFunction* cf = m_p->m_compute_function.get();
1201 //msg->info() << "Need Compute For Variable <" << name() << "> " << cf;
1202 if (cf) {
1203 //msg->info() << "Compute For Variable <" << name() << ">";
1204 cf->execute();
1205 }
1206 else {
1207 ARCANE_FATAL("No compute function for variable '{0}'", fullName());
1208 }
1209 }
1210}
1211
1212/*---------------------------------------------------------------------------*/
1213/*---------------------------------------------------------------------------*/
1214
1217{
1218 m_p->m_last_update_time = subDomain()->commonVariables().globalTime();
1219 m_p->m_modified_time = IVariable::incrementModifiedTime();
1220}
1221
1222/*---------------------------------------------------------------------------*/
1223/*---------------------------------------------------------------------------*/
1224
1227{
1228 return m_p->m_modified_time;
1229}
1230
1231/*---------------------------------------------------------------------------*/
1232/*---------------------------------------------------------------------------*/
1233
1236{
1237 m_p->m_depends.add(VariableDependInfo(var, dt, TraceInfo()));
1238}
1239
1240/*---------------------------------------------------------------------------*/
1241/*---------------------------------------------------------------------------*/
1242
1244addDepend(IVariable* var, eDependType dt, const TraceInfo& tinfo)
1245{
1246 m_p->m_depends.add(VariableDependInfo(var, dt, tinfo));
1247}
1248
1249/*---------------------------------------------------------------------------*/
1250/*---------------------------------------------------------------------------*/
1251
1254{
1255 ARCANE_UNUSED(var);
1256 throw NotImplementedException(A_FUNCINFO);
1257}
1258
1259/*---------------------------------------------------------------------------*/
1260/*---------------------------------------------------------------------------*/
1261
1264{
1265 m_p->m_compute_function = v;
1266}
1267
1268/*---------------------------------------------------------------------------*/
1269/*---------------------------------------------------------------------------*/
1270
1273{
1274 return m_p->m_compute_function.get();
1275}
1276
1277/*---------------------------------------------------------------------------*/
1278/*---------------------------------------------------------------------------*/
1279
1282{
1283 for (Integer k = 0, n = m_p->m_depends.size(); k < n; ++k) {
1284 VariableDependInfo& vdi = m_p->m_depends[k];
1285 infos.add(vdi);
1286 }
1287}
1288
1289/*---------------------------------------------------------------------------*/
1290/*---------------------------------------------------------------------------*/
1291
1292/*---------------------------------------------------------------------------*/
1293/*---------------------------------------------------------------------------*/
1294
1296addTag(const String& tagname, const String& tagvalue)
1297{
1298 m_p->m_tags[tagname] = tagvalue;
1299}
1300
1301/*---------------------------------------------------------------------------*/
1302/*---------------------------------------------------------------------------*/
1303
1305removeTag(const String& tagname)
1306{
1307 m_p->m_tags.erase(tagname);
1308}
1309
1310/*---------------------------------------------------------------------------*/
1311/*---------------------------------------------------------------------------*/
1312
1314hasTag(const String& tagname)
1315{
1316 return m_p->m_tags.find(tagname) != m_p->m_tags.end();
1317}
1318
1319/*---------------------------------------------------------------------------*/
1320/*---------------------------------------------------------------------------*/
1321
1323tagValue(const String& tagname)
1324{
1325 std::map<String, String>::const_iterator i = m_p->m_tags.find(tagname);
1326 if (i == m_p->m_tags.end())
1327 return String();
1328 return i->second;
1329}
1330
1331/*---------------------------------------------------------------------------*/
1332/*---------------------------------------------------------------------------*/
1333
1336{
1337 setUpToDate();
1340 _setValidData(true);
1341}
1342
1343/*---------------------------------------------------------------------------*/
1344/*---------------------------------------------------------------------------*/
1345
1351
1352/*---------------------------------------------------------------------------*/
1353/*---------------------------------------------------------------------------*/
1354
1356read(IDataReader* reader)
1357{
1358 reader->read(this, data());
1359 notifyEndRead();
1360}
1361
1362/*---------------------------------------------------------------------------*/
1363/*---------------------------------------------------------------------------*/
1364
1366write(IDataWriter* writer)
1367{
1369 writer->write(this, data());
1370}
1371
1372/*---------------------------------------------------------------------------*/
1373/*---------------------------------------------------------------------------*/
1374
1376changeGroupIds(Int32ConstArrayView old_to_new_ids)
1377{
1378 ARCANE_UNUSED(old_to_new_ids);
1379 // pH: default implementation since this method is not yet official
1380}
1381
1382/*---------------------------------------------------------------------------*/
1383/*---------------------------------------------------------------------------*/
1384
1385/*!
1386 * \brief Checks if it is possible to swap the values of the instance
1387 * with those of \a rhs.
1388 *
1389 * Since this method is called by a derived class, we are sure that \a rhs
1390 * is the same C++ type as the instance and therefore there is no need to
1391 * check, for example, that the dimensions or the data type are the same. For the
1392 * swap to be valid, the mesh, the family and the group must be the same. To do
1393 * this, it is sufficient to check that the group is the same.
1394 */
1397{
1398 if (!m_p->m_is_used)
1399 ARCANE_FATAL("Can not swap variable values for unused variable (instance)");
1400 if (!rhs->m_p->m_is_used)
1401 ARCANE_FATAL("Can not swap variable values for unused variable (argument)");
1402 if (isPartial() || rhs->isPartial())
1403 ARCANE_FATAL("Can not swap variable values for partial variables");
1404 if (itemGroup() != rhs->itemGroup())
1405 ARCANE_FATAL("Can not swap variable values for variables from different groups");
1406}
1407
1408/*---------------------------------------------------------------------------*/
1409/*---------------------------------------------------------------------------*/
1410
1411bool Variable::
1412_wantShrink() const
1413{
1414 return m_p->m_want_shrink;
1415}
1416
1417/*---------------------------------------------------------------------------*/
1418/*---------------------------------------------------------------------------*/
1419
1422{
1423 data()->setAllocationInfo(v);
1424 // It is possible that the allocation change modifies the * allocated
1425 // data. Therefore, references must be synchronized.
1427}
1428
1429/*---------------------------------------------------------------------------*/
1430/*---------------------------------------------------------------------------*/
1431
1433allocationInfo() const
1434{
1435 return data()->allocationInfo();
1436}
1437
1438/*---------------------------------------------------------------------------*/
1439/*---------------------------------------------------------------------------*/
1440
1441IVariableInternal* Variable::
1443{
1444 return m_p;
1445}
1446
1447/*---------------------------------------------------------------------------*/
1448/*---------------------------------------------------------------------------*/
1449
1450/*---------------------------------------------------------------------------*/
1451/*---------------------------------------------------------------------------*/
1452
1453String VariablePrivate::
1454computeComparisonHashCollective(IHashAlgorithm* hash_algo,
1455 IData* sorted_data)
1456{
1457 ARCANE_CHECK_POINTER(hash_algo);
1458 ARCANE_CHECK_POINTER(sorted_data);
1459
1460 INumericDataInternal* num_data = sorted_data->_commonInternal()->numericData();
1461 if (!num_data)
1462 return {};
1463 if (!m_item_family)
1464 return {};
1465
1466 IParallelMng* pm = m_item_family->parallelMng();
1467 Int32 my_rank = pm->commRank();
1468 Int32 master_rank = pm->masterIORank();
1469 ConstMemoryView memory_view = num_data->memoryView();
1470
1471 UniqueArray<Byte> bytes;
1472
1473 pm->gatherVariable(Arccore::asSpan<Byte>(memory_view.bytes()).smallView(), bytes, master_rank);
1474
1475 String hash_string;
1476 if (my_rank == master_rank) {
1477 HashAlgorithmValue hash_value;
1478 hash_algo->computeHash(asBytes(bytes), hash_value);
1479 hash_string = Convert::toHexaString(asBytes(hash_value.bytes()));
1480 }
1481 return hash_string;
1482}
1483
1484/*---------------------------------------------------------------------------*/
1485/*---------------------------------------------------------------------------*/
1486
1487void VariablePrivate::
1488changeAllocator(const MemoryAllocationOptions& mem_options)
1489{
1490 INumericDataInternal* dx = m_data->_commonInternal()->numericData();
1491 if (dx) {
1492 dx->changeAllocator(mem_options);
1493 m_variable->syncReferences();
1494 }
1495}
1496
1497/*---------------------------------------------------------------------------*/
1498/*---------------------------------------------------------------------------*/
1499
1500void VariablePrivate::
1501resize(const VariableResizeArgs& resize_args)
1502{
1503 return m_variable->_resize(resize_args);
1504}
1505
1506/*---------------------------------------------------------------------------*/
1507/*---------------------------------------------------------------------------*/
1508
1509VariableComparerResults VariablePrivate::
1510compareVariable(const VariableComparerArgs& compare_args)
1511{
1512 return m_variable->_compareVariable(compare_args);
1513}
1514
1515/*---------------------------------------------------------------------------*/
1516/*---------------------------------------------------------------------------*/
1517
1518IParallelMng* VariablePrivate::
1519replicaParallelMng() const
1520{
1521 //TODO: check if the variable is used.
1522 IMesh* mesh = m_variable->mesh();
1523 // TODO: should we take the subdomain in this case?
1524 IParallelMng* pm = (mesh) ? mesh->parallelMng() : m_variable->subDomain()->parallelMng();
1525 IParallelReplication* pr = pm->replication();
1526 if (!pr->hasReplication())
1527 return nullptr;
1528 return pr->replicaParallelMng();
1529}
1530
1531/*---------------------------------------------------------------------------*/
1532/*---------------------------------------------------------------------------*/
1533
1534} // End namespace Arcane
1535
1536/*---------------------------------------------------------------------------*/
1537/*---------------------------------------------------------------------------*/
1538
1539#endif
#define ARCANE_CHECK_POINTER(ptr)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Base class for 1D data vectors.
void add(ConstReferenceType val)
Adds element val to the end of the array.
void reserve(Int64 new_capacity)
Reserves memory for new_capacity elements.
Observable that automatically calls IObservable::detachAllObservers() in the destructor.
Real globalTime() const
Current time.
constexpr Integer size() const noexcept
Number of elements in the array.
constexpr bool empty() const noexcept
true if the array is empty (size()==0)
Information on data allocation.
Interface for reading variable data.
Definition IDataReader.h:35
virtual void read(IVariable *var, IData *data)=0
Reads the data data of the variable var.
Interface for writing variable data.
Definition IDataWriter.h:45
virtual void write(IVariable *var, IData *data)=0
Writes the data data of the variable var.
Interface of a data item.
Definition IData.h:34
virtual DataAllocationInfo allocationInfo() const =0
Allocation information.
virtual void setAllocationInfo(const DataAllocationInfo &v)=0
Sets the allocation information.
Interface of a hashing algorithm.
virtual void computeHash(Span< const std::byte > input, HashAlgorithmValue &value)
Calculates the hash value for the array input.
Interface of an entity family.
Definition IItemFamily.h:83
virtual bool hasUniqueIdMap() const =0
Indicates if the family has a uniqueId to localId conversion table.
virtual String name() const =0
Family name.
virtual eItemKind itemKind() const =0
Entity kind.
virtual IItemFamilyInternal * _internalApi()=0
Internal Arcane API.
virtual IItemFamily * findItemFamily(eItemKind ik, const String &name, bool create_if_needed=false, bool register_modifier_if_created=false)=0
Returns the family named name.
virtual MeshHandle * findMeshHandle(const String &name, bool throw_exception)=0
Searches for the mesh with name name.
virtual void notifyAllObservers()=0
Notifies all observers.
Interface of the parallelism manager for a subdomain.
virtual IParallelMngInternal * _internalApi()=0
Internal Arcane API.
virtual void putSpan(Span< const Real > values)
Add the array values.
virtual eMode mode() const =0
Current operating mode.
virtual void getSpan(Span< Real > values)
Retrieve the array values.
virtual void reserveSpan(eBasicDataType dt, Int64 n)=0
Reserves memory for n values of dt.
Interface of the subdomain manager.
Definition ISubDomain.h:75
virtual const CommonVariables & commonVariables() const =0
Information on standard variables.
virtual IParallelMng * parallelMng()=0
Returns the parallelism manager.
virtual IMeshMng * meshMng() const =0
Returns the mesh manager.
virtual IVariableMng * variableMng()=0
Returns the variable manager.
Interface of the functor class for recalculating a variable.
Variable manager interface.
virtual IVariableMngInternal * _internalApi()=0
Internal Arcane API.
Interface of a variable.
Definition IVariable.h:40
virtual eDataType dataType() const =0
Data type managed by the variable (Real, Integer, ...).
eDependType
Dependency Type.
Definition IVariable.h:45
@ 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
@ PTemporary
Indicates that the variable is temporary.
Definition IVariable.h:114
@ PInShMem
Indicates that the variable must be allocated in shared memory.
Definition IVariable.h:156
@ PExecutionDepend
Indicates that the variable value is dependent on the execution.
Definition IVariable.h:96
@ 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 eItemKind itemKind() const =0
Kind of mesh entities on which the variable is based.
virtual bool isPartial() const =0
Indicates if the variable is partial.
virtual Integer dimension() const =0
Dimension of the variable.
virtual IData * data()=0
Data associated with the variable.
virtual ItemGroup itemGroup() const =0
Associated mesh group.
static Int64 incrementModifiedTime()
Increments the modification counter and returns its value before modification.
Definition Variable.cc:207
virtual Integer multiTag() const =0
Indicates if the variable is a multi-sized array.
virtual void update()=0
Recalculates the variable if necessary.
static const char * TAG_POST_PROCESSING
Tag used to indicate if a variable will be post-processed.
Definition IVariable.h:173
static const char * TAG_POST_PROCESSING_AT_THIS_ITERATION
Tag used to indicate if a variable will be post-processed at this iteration.
Definition IVariable.h:176
void detachObserver(const void *ref)
Detaches an observer.
void executeExtend(const Int32ConstArrayView *info) override
Execute the action associated with the extension.
Definition Variable.cc:260
void executeReduce(const Int32ConstArrayView *info) override
Execute the action associated with the extension.
Definition Variable.cc:276
void executeInvalidate() override
Execute the action associated with invalidation.
Definition Variable.cc:326
void executeCompact(const Int32ConstArrayView *info) override
Executes the action associated with compaction.
Definition Variable.cc:315
bool needInfo() const override
Indicates whether the observer will need transition information.
Definition Variable.cc:334
Mesh entity group.
Definition ItemGroup.h:51
SharedPtrT< GroupIndexTable > localIdToIndex() const
Table of local ids to a position for all entities in the group.
Definition ItemGroup.h:312
ItemVectorView view() const
View of the group entities.
Definition ItemGroup.cc:580
Integer size() const
Number of elements in the group.
Definition ItemGroup.h:93
bool isAllItems() const
Indicates if the group is that of all entities.
Definition ItemGroup.cc:607
bool null() const
true means the group is the null group
Definition ItemGroup.h:75
View on a vector of entities.
Handle on a mesh.
Definition MeshHandle.h:48
bool isNull() const
Indicates if the handle is null (it does not reference any existing mesh or not).
Definition MeshHandle.h:163
IMesh * mesh() const
Associated mesh.
Reference to an instance.
Encapsulation of an automatically destructing pointer.
Definition ScopedPtr.h:44
constexpr __host__ __device__ SizeType size() const noexcept
Returns the size of the array.
Definition Span.h:325
View of an array of elements of type T.
Definition Span.h:633
constexpr __host__ __device__ Span< T, DynExtent > subspan(Int64 abegin, Int64 asize) const
Sub-view starting from element abegin and containing asize elements.
Definition Span.h:722
Unicode character string constructor.
String toString() const
Returns the constructed character string.
bool null() const
Returns true if the string is null.
Definition String.cc:306
Span< const Byte > bytes() const
Returns the conversion of the instance into UTF-8 encoding.
Definition String.cc:293
StringView view() const
Returns a view of the current string.
Definition String.cc:369
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
ITraceMng * traceMng() const
Trace manager.
1D data vector with value semantics (STL style).
Parameters necessary for building a variable.
Arguments for VariableComparer methods.
void setMaxPrint(Int32 v)
Sets the number of errors to display in the listing.
void setCompareGhost(bool v)
Indicates on which entities the comparison is performed.
Results of a comparison operation.
Information about a variable dependency.
IVariable::eDependType dependType() const
Dependency type.
IVariable * variable() const
Variable.
Information characterizing a variable.
const String & itemFamilyName() const
Name of the entity family to which the variable is associated.
const String & meshName() const
Name of the mesh to which the variable is associated.
const String & fullName() const
Full name of the variable (associated with the family).
void setDefaultItemGroupName()
If null, changes itemGroupName() to the name of the group of all entities in the family.
Metadata on a variable.
bool m_has_recursive_depend
True if dependencies are recursive.
Definition Variable.cc:122
VariableInfo m_infos
Characteristic information of the variable.
Definition Variable.cc:106
IItemFamily * m_item_family
Entity family (can be null).
Definition Variable.cc:105
Integer m_nb_reference
First reference on the variable.
Definition Variable.cc:114
UniqueArray< VariableDependInfo > m_depends
List of dependencies for this variable.
Definition Variable.cc:115
int m_property
Properties of the variable.
Definition Variable.cc:107
AutoDetachObservable m_on_size_changed_observable
Resize observable.
Definition Variable.cc:120
Real m_last_update_time
Physical time of the last update.
Definition Variable.cc:112
Int64 m_modified_time
Tag of the last modification.
Definition Variable.cc:116
MeshHandle m_mesh_handle
Mesh (can be null).
Definition Variable.cc:102
std::map< String, String > m_tags
List of tags.
Definition Variable.cc:121
ItemGroup m_item_group
Entity group to which the variable is associated.
Definition Variable.cc:104
bool m_is_used
Usage status of the variable.
Definition Variable.cc:110
void serializeHashId(ISerializer *sbuf)
Serializes the hashid.
Definition Variable.cc:134
ScopedPtrT< IVariableComputeFunction > m_compute_function
Calculation function.
Definition Variable.cc:117
AutoDetachObservable m_read_observable
Read observable.
Definition Variable.cc:119
AutoDetachObservable m_write_observable
Write observable.
Definition Variable.cc:118
bool m_has_valid_data
True if the data is valid.
Definition Variable.cc:111
bool m_is_partial
True if the variable is partial.
Definition Variable.cc:108
Variable * m_variable
Associated variable.
Definition Variable.cc:124
Ref< IData > m_data
Variable data.
Definition Variable.cc:103
Reference to a variable.
Definition VariableRef.h:56
virtual void updateFromInternal()
Updates from the internal part.
VariableRef * previousReference()
Previous reference (or null) to variable().
virtual int referenceProperty() const
Reference properties (internal).
VariableRef * nextReference()
Next reference (or null) to variable().
void resizeFromGroup() override
Sets the number of elements for a mesh variable.
Definition Variable.cc:1022
String itemGroupName() const final
Name of the associated entity group.
Definition Variable.cc:512
IMesh * mesh() const final
Mesh associated with the variable.
Definition Variable.cc:845
void notifyBeginWrite() override
Notifies of the start of writing data().
Definition Variable.cc:1347
Integer nbReference() const override
Number of references on this variable.
Definition Variable.cc:458
void removeVariableRef(VariableRef *ref) override
Removes a reference to this variable.
Definition Variable.cc:396
void _checkSwapIsValid(Variable *rhs)
Checks if it is possible to swap the values of the instance with those of rhs.
Definition Variable.cc:1396
bool isUsed() const override
Usage state of the variable.
Definition Variable.cc:723
Variable(const VariableBuildInfo &v, const VariableInfo &vi)
Creates a variable linked to the reference v.
Definition Variable.cc:345
void _setData(const Ref< IData > &data)
Positions the data.
Definition Variable.cc:919
void _setValidData(bool valid_data)
Indicates if the variable data is valid.
Definition Variable.cc:934
VariableMetaData * createMetaData() const override
Creates an instance containing the variable's metadata.
Definition Variable.cc:769
IVariableComputeFunction * computeFunction() override
Function used to update the variable.
Definition Variable.cc:1272
Ref< VariableMetaData > createMetaDataRef() const override
Creates an instance containing the variable's metadata.
Definition Variable.cc:778
bool isPartial() const override
Indicates if the variable is partial.
Definition Variable.cc:901
String tagValue(const String &tagname) override
Value of the tag tagname. The string is null if the tag does not exist.
Definition Variable.cc:1323
void notifyReferencePropertyChanged() override
Definition Variable.cc:629
IVariableMng * variableMng() const override
Variable manager associated with the variable.
Definition Variable.cc:476
void removeTag(const String &tagname) override
Removes the tag tagname.
Definition Variable.cc:1305
void addDepend(IVariable *var, eDependType dt) override
Adds var to the list of dependencies.
Definition Variable.cc:1235
String name() const final
Variable name.
Definition Variable.cc:485
IObservable * readObservable() override
Read observable.
Definition Variable.cc:1141
virtual VariableComparerResults _compareVariable(const VariableComparerArgs &compare_args)=0
Comparison of values between variables.
void serialize(ISerializer *sbuffer, IDataOperation *operation) override
Definition Variable.cc:984
ItemGroup itemGroup() const final
Associated mesh group.
Definition Variable.cc:865
IObservable * onSizeChangedObservable() override
Size change observable.
Definition Variable.cc:1150
void notifyEndRead() override
Notifies of external modification of data().
Definition Variable.cc:1335
void read(IDataReader *d) override
Definition Variable.cc:1356
void syncReferences() override
Synchronizes references.
Definition Variable.cc:787
void setUsed(bool v) override
Sets the usage state of the variable.
Definition Variable.cc:638
VariableRef * firstReference() const override
First reference (or null) on this variable.
Definition Variable.cc:433
String fullName() const final
Full variable name (with family prefix).
Definition Variable.cc:494
eItemKind itemKind() const override
Kind of mesh entities on which the variable is based.
Definition Variable.cc:874
ISubDomain * subDomain() override
Subdomain associated with the variable (TODO deprecate end of 2023).
Definition Variable.cc:467
void update() override
Recalculates the variable if necessary.
Definition Variable.cc:1162
Integer dimension() const override
Dimension of the variable.
Definition Variable.cc:883
Int64 modifiedTime() override
Time when the variable was updated.
Definition Variable.cc:1226
void setUpToDate() override
Indicates that the variable has just been updated.
Definition Variable.cc:1216
void addTag(const String &tagname, const String &tagvalue) override
Adds the tag tagname with the value tagvalue.
Definition Variable.cc:1296
Int32 checkIfSame(IDataReader *reader, Integer max_print, bool compare_ghost) final
Checks that the variable is identical to a reference value.
Definition Variable.cc:831
~Variable() override
Frees resources.
Definition Variable.cc:355
bool _hasValidData() const
Indicates if the variable data is valid.
Definition Variable.cc:943
IObservable * writeObservable() override
Write observable.
Definition Variable.cc:1132
void addVariableRef(VariableRef *ref) override
Adds a reference to this variable.
Definition Variable.cc:375
Integer multiTag() const override
Indicates if the variable is a multi-sized array.
Definition Variable.cc:892
void setComputeFunction(IVariableComputeFunction *v) override
Sets the variable's recalculation function.
Definition Variable.cc:1263
void resize(Integer n) override
Sets the number of elements for an array variable.
Definition Variable.cc:1013
IVariableInternal * _internalApi() override
Internal Arcane API.
Definition Variable.cc:1442
IItemFamily * itemFamily() const final
Associated entity family.
Definition Variable.cc:910
eDataType dataType() const override
Data type managed by the variable (Real, Integer, ...).
Definition Variable.cc:530
void write(IDataWriter *d) override
Saves the variable.
Definition Variable.cc:1366
IDataFactoryMng * dataFactoryMng() const final
Data factory associated with the variable.
Definition Variable.cc:961
void changeGroupIds(Int32ConstArrayView old_to_new_ids) override
pH: EXPERIMENTAL
Definition Variable.cc:1376
void removeDepend(IVariable *var) override
Removes var from the list of dependencies.
Definition Variable.cc:1253
String itemFamilyName() const final
Name of the associated family (null if none).
Definition Variable.cc:503
Int32 checkIfSync(Integer max_print) final
Checks if the variable is properly synchronized.
Definition Variable.cc:804
DataAllocationInfo allocationInfo() const override
Allocation information.
Definition Variable.cc:1433
int property() const override
Definition Variable.cc:542
Int32 checkIfSameOnAllReplica(Integer max_print) final
Checks if the variable has the same values on all replicas.
Definition Variable.cc:818
void dependInfos(Array< VariableDependInfo > &infos) override
Dependency information.
Definition Variable.cc:1281
bool hasTag(const String &tagname) override
true if the variable has the tag tagname
Definition Variable.cc:1314
void setAllocationInfo(const DataAllocationInfo &v) override
Sets allocation information.
Definition Variable.cc:1421
MeshHandle meshHandle() const final
Mesh associated with the variable.
Definition Variable.cc:856
String meshName() const final
Name of the associated mesh (null if none).
Definition Variable.cc:521
String toHexaString(ByteConstArrayView input)
Converts a byte array to its hexadecimal representation.
String getEnvironmentVariable(const String &name)
Environment variable named name.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
@ DIP_Legacy
Initialization in historical mode.
Definition DataTypes.h:166
std::int64_t Int64
Signed integer type of 64 bits.
eDataInitialisationPolicy getGlobalDataInitialisationPolicy()
Gets the initialization policy for variables.
Definition DataTypes.cc:164
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:476
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
Definition UtilsTypes.h:335
@ SameOnAllReplica
Checks that the variable values are the same on all replicas.
@ Sync
Checks that the variable is synchronized.
eItemKind
Mesh entity type.
@ IK_Particle
Particle mesh entity.
@ IK_Unknown
Unknown or uninitialized mesh entity.
@ IK_DoF
Degree of Freedom mesh entity.
const char * itemKindName(eItemKind kind)
Entity kind name.
double Real
Type representing a real number.
Impl::SpanTypeFromSize< conststd::byte, SizeType >::SpanType asBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Converts the view into an array of non-modifiable bytes.
Definition Span.h:1030
unsigned char Byte
Type of a byte.
Definition BaseTypes.h:42
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
eDataType
Data type.
Definition DataTypes.h:41
const char * dataTypeName(eDataType type)
Data type name.
Definition DataTypes.cc:72
std::int32_t Int32
Signed integer type of 32 bits.
Span< DataType > asSpan(Span< std::byte, Extent > bytes)
Converts a Span<std::byte> into a Span<DataType>.
Definition Span.h:1122