Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
TimeLoopReader.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/* TimeLoopReader.cc (C) 2000-2020 */
9/* */
10/* Loading a time loop. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/Iterator.h"
15#include "arcane/utils/ScopedPtr.h"
16#include "arcane/utils/ApplicationInfo.h"
17#include "arcane/utils/ITraceMng.h"
18#include "arcane/utils/List.h"
19#include "arcane/utils/OStringStream.h"
20#include "arcane/utils/FatalErrorException.h"
21
22#include "arcane/impl/TimeLoopReader.h"
23
24#include "arcane/core/IApplication.h"
25#include "arcane/core/IXmlDocumentHolder.h"
26#include "arcane/core/IIOMng.h"
27#include "arcane/core/ISubDomain.h"
28#include "arcane/core/XmlNode.h"
29#include "arcane/core/XmlNodeList.h"
30#include "arcane/core/XmlNodeIterator.h"
31#include "arcane/core/ICaseDocument.h"
32#include "arcane/core/ArcaneException.h"
33#include "arcane/core/ITimeLoopMng.h"
34#include "arcane/core/ITimeLoop.h"
35#include "arcane/core/IMainFactory.h"
36#include "arcane/core/SequentialSection.h"
37#include "arcane/core/TimeLoopEntryPointInfo.h"
38#include "arcane/core/TimeLoopSingletonServiceInfo.h"
39#include "arcane/impl/ConfigurationReader.h"
40
41/*---------------------------------------------------------------------------*/
42/*---------------------------------------------------------------------------*/
43
44namespace Arcane
45{
46
47/*---------------------------------------------------------------------------*/
48/*---------------------------------------------------------------------------*/
49
56
57/*---------------------------------------------------------------------------*/
58/*---------------------------------------------------------------------------*/
59
64
65/*---------------------------------------------------------------------------*/
66/*---------------------------------------------------------------------------*/
67
69setUsedTimeLoop(ISubDomain* sub_domain)
70{
71 ITimeLoopMng* loop_mng = sub_domain->timeLoopMng();
72
73 XmlNode time_loop_elem = sub_domain->caseDocument()->timeloopElement();
74
75 {
76 SequentialSection ss(sub_domain);
77 try {
78 String value;
79 if (!time_loop_elem.null())
80 value = time_loop_elem.value();
81 if (value.null())
82 ARCANE_FATAL("No time loop specified");
83 if (value.empty())
84 value = "ArcaneEmptyLoop";
85 // The time loop is specified in the config file.
86 m_time_loop_name = value;
87 info() << "Using the time loop <" << m_time_loop_name << ">";
88 loop_mng->setUsedTimeLoop(m_time_loop_name);
89 }
90 catch (const Exception& ex) {
91 error() << ex << '\n';
92 ss.setError(true);
93 }
94 catch (...) {
95 ss.setError(true);
96 }
97 }
98}
99
100/*---------------------------------------------------------------------------*/
101/*---------------------------------------------------------------------------*/
102
105{
106 IMainFactory* factory = m_application->mainFactory();
107
108 ByteConstSpan config_bytes = m_application->configBuffer();
109 ScopedPtrT<IXmlDocumentHolder> config_doc(m_application->ioMng()->parseXmlBuffer(config_bytes, String()));
110 if (!config_doc.get())
111 ARCANE_FATAL("Can not parse code configuration file");
112 XmlNode root_elem = config_doc->documentNode().documentElement();
113
114 // XmlNode root_elem = m_application->configRootElement();
115 XmlNode elem = root_elem.child(String("time-loops"));
116 XmlNodeList timeloops = elem.children(String("time-loop"));
117
118 StringList required_modules_list;
119 StringList optional_modules_list;
120 List<TimeLoopEntryPointInfo> entry_points;
121 StringList user_classes;
122 List<TimeLoopSingletonServiceInfo> singleton_services;
123
124 List<TimeLoopSingletonServiceInfo> global_singleton_services;
125
126 String ustr_name("name");
127 String ustr_modules("modules");
128
129 // List of global singleton services
130 XmlNodeList global_singleton_elems = root_elem.children("singleton-services");
131 info() << "CHECK GLOBAL SINGLETON SERVICES";
132 for (const auto& i : global_singleton_elems) {
133 info() << "CHECK GLOBAL SINGLETON SERVICES 2 " << i.name();
134
135 for (const auto& j_node : i) {
136 if (j_node.name() == "service") {
137 bool is_required = (j_node.attrValue("need") == "required");
138 info() << "GLOBAL SINGLETON SERVICE name=" << j_node.attrValue(ustr_name) << " is_required?=" << is_required;
139 global_singleton_services.add(TimeLoopSingletonServiceInfo(j_node.attrValue(ustr_name), is_required));
140 }
141 }
142 }
143
144 for (const auto& i : timeloops) {
145 optional_modules_list.clear();
146 required_modules_list.clear();
147 user_classes.clear();
148 singleton_services.clone(global_singleton_services);
149
150 String name = i.attrValue(ustr_name);
151
152 if (name.null())
153 continue;
154 ITimeLoop* time_loop = factory->createTimeLoop(m_application, name);
155 XmlNode timeloop_node = i;
156
157 for (const auto& j_node : timeloop_node) {
158 String elem_name = j_node.name();
159 String elem_value = j_node.value();
160
161 if (elem_name == ustr_modules) {
162 for (XmlNode::const_iter k(j_node); k(); ++k)
163 if (k->name() == "module") {
164 if (k->attrValue("need") == "required")
165 required_modules_list.add(k->attrValue(ustr_name));
166 else
167 optional_modules_list.add(k->attrValue(ustr_name));
168 }
169 }
170 else if (elem_name == "singleton-services") {
171 for (XmlNode::const_iter k(j_node); k(); ++k)
172 if (k->name() == "service") {
173 bool is_required = (k->attrValue("need") == "required");
174 //info() << "SINGLETON SERVICE name=" << k->attrValue(ustr_name) << " is_required?=" << is_required;
175 singleton_services.add(TimeLoopSingletonServiceInfo(k->attrValue(ustr_name), is_required));
176 }
177 }
178 else if (elem_name == "entry-points") {
179 entry_points.clear();
180 for (XmlNode::const_iter k(j_node); k(); ++k) {
181 XmlNode k_node = *k;
182 if (k_node.name() != "entry-point")
183 continue;
184 StringList depends;
185 entry_points.add(TimeLoopEntryPointInfo(k_node.attrValue(ustr_name), depends));
186 }
187
188 String cwhere = j_node.attrValue("where");
189 if (cwhere != ITimeLoop::WInit && cwhere != ITimeLoop::WComputeLoop && cwhere != ITimeLoop::WRestore && cwhere != ITimeLoop::WExit && cwhere != ITimeLoop::WBuild && cwhere != ITimeLoop::WOnMeshChanged && cwhere != ITimeLoop::WOnMeshRefinement) {
191 s() << "Incorrect value for the attribute \"where\" (time loop ";
192 s() << name << "): \"" << cwhere << "\".\n";
193 s() << "Available values are: "
195 << ", " << ITimeLoop::WComputeLoop
196 << ", " << ITimeLoop::WRestore
199 << ", " << ITimeLoop::WBuild
200 << ", " << ITimeLoop::WExit
201 << ".";
202 throw InternalErrorException(A_FUNCINFO, s.str());
203 }
204 time_loop->setEntryPoints(cwhere, entry_points);
205 }
206 else if (elem_name == "title") {
207 time_loop->setTitle(elem_value);
208 }
209 else if (elem_name == "description") {
210 time_loop->setDescription(elem_value);
211 }
212 else if (elem_name == "userclass") {
213 user_classes.add(elem_value);
214 }
215 else if (elem_name == "configuration") {
216 ConfigurationReader cr(traceMng(), time_loop->configuration());
217 cr.addValuesFromXmlNode(j_node, ConfigurationReader::P_TimeLoop);
218 }
219 }
220
221 time_loop->setRequiredModulesName(required_modules_list);
222 time_loop->setOptionalModulesName(optional_modules_list);
223 time_loop->setUserClasses(user_classes);
224 time_loop->setSingletonServices(singleton_services);
225
226 m_time_loops.add(time_loop);
227 }
228}
229
230/*---------------------------------------------------------------------------*/
231/*---------------------------------------------------------------------------*/
232
235{
236 ITimeLoopMng* loop_mng = sd->timeLoopMng();
237 for (TimeLoopList::Enumerator i(m_time_loops); ++i;)
238 loop_mng->registerTimeLoop(*i);
239}
240
241/*---------------------------------------------------------------------------*/
242/*---------------------------------------------------------------------------*/
243
244} // End namespace Arcane
245
246/*---------------------------------------------------------------------------*/
247/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
void clear()
Removes all elements from the collection.
Configuration file readers.
void addValuesFromXmlNode(const XmlNode &element, Integer priority)
Adds values to the configuration.
Application interface.
virtual XmlNode timeloopElement()=0
Returns the element containing the time loop choice.
Factory for Arcane classes.
virtual ITimeLoop * createTimeLoop(IApplication *sm, const String &name)=0
Creates a time loop named name.
Interface of the subdomain manager.
Definition ISubDomain.h:75
virtual ICaseDocument * caseDocument()=0
Case XML document.
virtual ITimeLoopMng * timeLoopMng()=0
Returns the time loop manager.
Interface for the time loop manager.
virtual void registerTimeLoop(ITimeLoop *time_loop)=0
Registration and selection of the time loop.
virtual void setUsedTimeLoop(const String &name)=0
Positions the time loop to be executed. Selects the time loop named name as the one to be executed....
Interface of a time loop.
Definition ITimeLoop.h:33
virtual void setUserClasses(const StringCollection &)=0
Returns the list of classes associated with the time loop.
static const char * WRestore
called to restore variables during a rollback
Definition ITimeLoop.h:47
virtual void setRequiredModulesName(const StringCollection &)=0
Sets the list of required modules.
static const char * WOnMeshChanged
called after a mesh change
Definition ITimeLoop.h:49
virtual void setTitle(const String &)=0
Sets the title of the time loop.
virtual void setSingletonServices(const TimeLoopSingletonServiceInfoCollection &c)=0
Sets the list of singleton services.
static const char * WExit
called upon termination of the code.
Definition ITimeLoop.h:53
virtual IConfiguration * configuration()=0
Configuration options.
static const char * WOnMeshRefinement
called after mesh refinement
Definition ITimeLoop.h:51
virtual void setDescription(const String &)=0
Sets the description of the time loop.
virtual void setOptionalModulesName(const StringCollection &)=0
Sets the list of optional modules.
static const char * WBuild
called when reading the dataset
Definition ITimeLoop.h:43
static const char * WComputeLoop
called during the calculation loop
Definition ITimeLoop.h:41
virtual void setEntryPoints(const String &where, const TimeLoopEntryPointInfoCollection &)=0
Sets the list of names of entry points for the call point where.
static const char * WInit
called during initialization, initialization of a restart, or a new case
Definition ITimeLoop.h:45
Exception when an internal error occurs.
Implementation of a collection of elements in vector form.
void clone(const Collection< T > &base)
Clone the collection base.
Output stream linked to a String.
T * get() const
Returns the object referenced by the instance.
Definition Ptr.h:122
Encapsulation of an automatically destructing pointer.
Definition ScopedPtr.h:44
Section of code to be executed sequentially.
bool null() const
Returns true if the string is null.
Definition String.cc:306
Info about a time loop entry point.
TimeLoopReader(IApplication *sm)
Creates an instance associated with the manager sm.
void setUsedTimeLoop(ISubDomain *sd)
Positions the used time loop in the manager sd.
void readTimeLoops()
Performs the reading of available time loops.
void registerTimeLoops(ISubDomain *sd)
Registers the list of time loops in the manager sd.
~TimeLoopReader()
Frees resources.
IApplication * m_application
Supervisor.
Info of a time loop singleton service.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage info() const
Flow for an information message.
TraceMessage error() const
Flow for an error message.
ITraceMng * traceMng() const
Trace manager.
List of nodes of a DOM tree.
Definition XmlNodeList.h:36
Node of a DOM tree.
Definition XmlNode.h:51
String attrValue(const String &name, bool throw_exception=false) const
Value of attribute name.
Definition XmlNode.cc:234
XmlNode child(const String &name) const
Child node of this node with name name.
Definition XmlNode.cc:73
String value() const
Node value.
Definition XmlNode.cc:208
XmlNodeList children(const String &name) const
Set of child nodes of this node having the name name.
Definition XmlNode.cc:102
bool null() const
True if the node is null.
Definition XmlNode.h:303
ConstIterT< XmlNode > const_iter
Type of a constant iterator over the entire array.
Definition XmlNode.h:76
String name() const
Node name.
Definition XmlNode.cc:141
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
List< String > StringList
Unicode string list.
Definition UtilsTypes.h:509