Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
OutputChecker.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 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/* OutputChecker.cc (C) 2000-2016 */
9/* */
10/* Sorties basées sur un temps (physique ou CPU) ou un nombre d'itération. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ArcanePrecomp.h"
15
16#include "arcane/utils/CheckedConvert.h"
17#include "arcane/utils/ITraceMng.h"
18
19#include "arcane/ISubDomain.h"
20#include "arcane/ICaseFunction.h"
21#include "arcane/CommonVariables.h"
22
23#include "arcane/OutputChecker.h"
24
25/*---------------------------------------------------------------------------*/
26/*---------------------------------------------------------------------------*/
27
28ARCANE_BEGIN_NAMESPACE
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33OutputChecker::
34OutputChecker(ISubDomain* sd,const String& name)
35: m_sub_domain(sd)
36, m_name(name)
37, m_out_type(OutTypeNone)
38, m_next_iteration(0)
39, m_next_global_time(0)
40, m_next_cpu_time(0)
41, m_step_iteration(0)
42, m_step_global_time(0)
43, m_step_cpu_time(0)
44{}
45
46void OutputChecker::
47assignGlobalTime(VariableScalarReal* variable,const CaseOptionReal* option)
48{
49 m_next_global_time = variable;
50 m_step_global_time = option;
51}
52
53void OutputChecker::
54assignCPUTime(VariableScalarInteger* variable,const CaseOptionInteger* option)
55{
56 m_next_cpu_time = variable;
57 m_step_cpu_time = option;
58}
59
60void OutputChecker::
61assignIteration(VariableScalarInteger* variable,const CaseOptionInteger* option)
62{
63 m_next_iteration = variable;
64 m_step_iteration = option;
65}
66
67/*---------------------------------------------------------------------------*/
68/*---------------------------------------------------------------------------*/
69/*!
70 * \brief Vérifie s'il faut effectuer une sortie.
71 *
72 * \arg \a old_time et \a current_time sont utilisés pour les sorties
73 * en temps physique.
74 * \arg \a current_iteration est utilisé pour les sorties en nombre d'itérations
75 * \arg \a cpu_time_used est utilisé pour les sorties en temps CPU.
76
77 Lorsqu'un type de sortie n'est pas disponible, la ou les valeurs associées
78 ne sont pas utilisées et peuvent être quelconques.
79
80 \param old_time temps physique de l'itération précédente.
81 \param current_time temps physique courant.
82 \param current_iteration itération courante.
83 \param cpu_time_used temps cpu utilisé
84 */
85bool OutputChecker::
86check(Real old_time,Real current_time,
87 Integer current_iteration,Integer cpu_time_used,
88 const String& from_function)
89{
90 String function_id = "OutputChecker::check >>> ";
91
92 if (m_out_type==OutTypeNone)
93 return false;
94
95 ITraceMng* trace = m_sub_domain->traceMng();
96
97 // \a true si on va effectuer une sortie
98 bool do_output = false;
99 switch(m_out_type){
100 case OutTypeGlobalTime:
101 {
102 Real next_time = (*m_next_global_time)();
103 trace->debug()<<from_function<<function_id << "Next out: " << next_time << " Saved Time: " << old_time
104 << " Current time: " << current_time << " step=" << m_step_global_time;
105 //if (math::isEqual(m_next_time(),old_time))
106 if (math::isEqual(next_time,current_time))
107 do_output = true;
108 // Pour faire une sortie, il faut qu'on ait dépassé
109 // le temps précédent et que le temps courant soit #strictement# supérieur
110 // au temps de la sortie.
111 else if (next_time>old_time && next_time<current_time){
112 do_output = true;
113 }
114 // TODO: diviser par le nombre de pas de sorties
115 if (do_output || next_time<old_time){
116 //Real to_add = m_step_time(); //old_time);
117 // S'il le temps est donné par une table de marche, il faut prendre
118 // sa valeur à l'instant courant.
119 //Il faut prendre la valeur
120 Real to_add = m_step_global_time->valueAtParameter(current_time); //old_time);
121 if (!math::isZero(to_add)){
122 //m_next_time += to_add;
123 Real diff = (current_time-next_time) / to_add;
124 if (diff<0.)
125 *m_next_global_time = next_time+to_add;
126 else{
127 double i_diff = math::floor(diff);
128 *m_next_global_time = next_time+(to_add*(i_diff+1));
129 }
130 trace->debug()<<from_function<<function_id
131 << "Next output at time " << next_time
132 << " (" << to_add << ' ' << old_time
133 << ' ' << current_iteration << ")";
134 }
135 }
136 }
137 break;
138 case OutTypeIteration:
139 {
140 Integer next_iteration = (*m_next_iteration)();
141 Integer to_add = m_step_iteration->valueAtParameter(current_time);
142
143 if (next_iteration>current_iteration+to_add){
144 // TH: En cas de reprise avec diminution de la période de sortie dans jdd
145 // TH: on reprend les sorties tout de suite
146 next_iteration = current_iteration;
147 }
148
149 if (next_iteration==current_iteration) do_output = true;
150
151 // Calcule la prochaine itération de sauvegarde si nécessaire
152 if (next_iteration<=current_iteration){
153 if (to_add!=0){
154 Integer diff = (current_iteration-next_iteration) / to_add;
155 (*m_next_iteration) = next_iteration + ((diff+1)*to_add);
156 trace->debug()<<from_function<<function_id
157 << "Next output at iteration " << (*m_next_iteration)()
158 << " (" << to_add << ' ' << old_time
159 << ' ' << current_iteration << " diff=" << diff << ")";
160 }
161 }
162 }
163 break;
164 case OutTypeCPUTime:
165 {
166 Integer next_cpu_time = (*m_next_cpu_time)();
167 Integer cpu_time = cpu_time_used;
168 // Converti le temps CPU en minutes (à garder cohérent avec la conversion dans _recomputeTypeCPUTime())
169
170 Integer current_cpu_time = cpu_time / 60;
171
172 if (next_cpu_time<=current_cpu_time)
173 do_output = true;
174
175 // Calcule le prochain temps CPU de sauvegarde si nécessaire
176 if (next_cpu_time<=current_cpu_time){
177 Integer to_add = m_step_cpu_time->valueAtParameter(current_time);
178 if (to_add!=0){
179 Integer diff = (current_cpu_time-next_cpu_time) / to_add;
180 (*m_next_cpu_time) = next_cpu_time + ((diff+1)*to_add);
181 trace->debug()<<from_function<<function_id
182 << "Next output at cpu time " << (*m_next_cpu_time)()
183 << " (" << to_add << ' ' << current_cpu_time << " diff=" << diff << ")";
184 }
185 }
186
187 // Ne fait rien la première minute.
188 if (current_cpu_time==0)
189 do_output = false;
190
191 //if (do_output)
192 //cerr << "** ** OUTPUT AT CPU TIME " << cpu_time
193 //<< ' ' << current_cpu_time << ' ' << (*m_next_cpu_time)()
194 // << ' ' << (*m_step_cpu_time)() << '\n';
195
196 }
197 //msg->warning() << "Not implemented";
198 break;
199 case OutTypeNone:
200 break;
201 }
202
203 return do_output;
204}
205
206/*---------------------------------------------------------------------------*/
207/*---------------------------------------------------------------------------*/
208
209/*---------------------------------------------------------------------------*/
210/*---------------------------------------------------------------------------*/
211
212void OutputChecker::
213_recomputeTypeGlobalTime()
214{
215 Real current_time = m_sub_domain->commonVariables().globalTime();
216 Real step = m_step_global_time->valueAtParameter(current_time);
217
218 Real old_next = (*m_next_global_time)();
219 Real next = old_next;
220 Real current_value = current_time;
221 if (!math::isZero(step)){
222 Real index = ::floor(current_value/step);
223 next = step*(index+1.0);
224 *m_next_global_time = next;
225 }
226
227 ITraceMng* tm = m_sub_domain->traceMng();
228 tm->info(4) << "Recompute OutputChecker for Global Time: old=" << old_next
229 << " new=" << next;
230}
231
232/*---------------------------------------------------------------------------*/
233/*---------------------------------------------------------------------------*/
234
235void OutputChecker::
236_recomputeTypeCPUTime()
237{
238 Real current_time = m_sub_domain->commonVariables().globalTime();
239 Integer step = m_step_cpu_time->valueAtParameter(current_time);
240
241 Integer old_next = (*m_next_cpu_time)();
242 Integer next = old_next;
243 double current_value = math::floor(m_sub_domain->commonVariables().globalCPUTime());
244
245 // Converti en minute (à garder cohérent avec la conversion dans check())
246 current_value /= 60.0;
247
248 if (step!=0){
249 Integer index = CheckedConvert::toInteger(current_value / step);
250 next = step*(index+1);
251 *m_next_cpu_time = next;
252 }
253
254 ITraceMng* tm = m_sub_domain->traceMng();
255 tm->info(4) << "Recompute OutputChecker for CPU Time: old=" << old_next << " new=" << next;
256}
257
258/*---------------------------------------------------------------------------*/
259/*---------------------------------------------------------------------------*/
260
261void OutputChecker::
262_recomputeTypeIteration()
263{
264 Real current_time = m_sub_domain->commonVariables().globalTime();
265 Integer step = m_step_iteration->valueAtParameter(current_time);
266
267 Integer old_next = (*m_next_iteration)();
268 Integer next = old_next;
269 Integer current_value = m_sub_domain->commonVariables().globalIteration();
270 if (step!=0){
271 if (old_next<=current_value){
272 *m_next_iteration = current_value;
273 }
274 else{
275 Integer index = current_value / step;
276 next = step*(index+1);
277 *m_next_iteration = next;
278 }
279 }
280
281 ITraceMng* tm = m_sub_domain->traceMng();
282 tm->info(4) << "Recompute OutputChecker for CPU Time: old=" << old_next << " new=" << next;
283}
284
285/*---------------------------------------------------------------------------*/
286/*---------------------------------------------------------------------------*/
287
288void OutputChecker::
289initialize()
290{
291 initialize(false);
292}
293
294/*---------------------------------------------------------------------------*/
295/*---------------------------------------------------------------------------*/
296
297void OutputChecker::
298initialize(bool recompute_next_value)
299{
300 ITraceMng* trace = m_sub_domain->traceMng();
301 m_out_type = OutTypeNone;
302
303 ICaseFunction* func = 0;
304 // Prioritairement prend les sorties en temps physique, puis en
305 // nombre d'itérations, puis en temps CPU.
306 if (m_step_global_time && m_next_global_time && m_step_global_time->isPresent()){
307 m_out_type = OutTypeGlobalTime;
308 func = m_step_global_time->function();
309 if (func)
310 trace->info() << "Output in real time controlled by function '" << func->name() << "'.";
311 else
312 trace->info() << "Output in real time every " << (*m_step_global_time)() << " seconds.";
313 if (recompute_next_value)
314 _recomputeTypeGlobalTime();
315 }
316 else if (m_step_iteration && m_next_iteration && m_step_iteration->value()!=0){
317 m_out_type = OutTypeIteration;
318 func = m_step_iteration->function();
319 if (func)
320 trace->info() << "Output in iterations controlled by function '" << func->name() << "'.";
321 else
322 trace->info() << "Output every " << (*m_step_iteration)() << " iterations.";
323 if (recompute_next_value)
324 _recomputeTypeIteration();
325 }
326 else if (m_step_cpu_time && m_next_cpu_time && m_step_cpu_time->isPresent()){
327 m_out_type = OutTypeCPUTime;
328 func = m_step_cpu_time->function();
329 if (func)
330 trace->info() << "Output in CPU time controlled by function '" << func->name() << "'.";
331 else
332 trace->info() << "Output in CPU time every " << (*m_step_cpu_time)() << " minutes.";
333 if (recompute_next_value)
334 _recomputeTypeCPUTime();
335 }
336 else
337 trace->info() << "No output required.";
338}
339
340/*---------------------------------------------------------------------------*/
341/*---------------------------------------------------------------------------*/
342
343Real OutputChecker::
344nextGlobalTime() const
345{
346 Real v = 0.0;
347 if (m_next_global_time)
348 v = (*m_next_global_time)();
349 return v;
350}
351
352/*---------------------------------------------------------------------------*/
353/*---------------------------------------------------------------------------*/
354
355Integer OutputChecker::
356nextIteration() const
357{
358 Integer v = 0;
359 if (m_next_iteration)
360 v = (*m_next_iteration)();
361 return v;
362}
363
364/*---------------------------------------------------------------------------*/
365/*---------------------------------------------------------------------------*/
366
367Integer OutputChecker::
368nextCPUTime() const
369{
370 Integer v = 0;
371 if (m_next_cpu_time)
372 v= (*m_next_cpu_time)();
373 return v;
374}
375
376/*---------------------------------------------------------------------------*/
377/*---------------------------------------------------------------------------*/
378
379ARCANE_END_NAMESPACE
380
381/*---------------------------------------------------------------------------*/
382/*---------------------------------------------------------------------------*/
Interface du gestionnaire de traces.
virtual TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium)=0
Flot pour un message de debug.
Chaîne de caractères unicode.
double Real
Type représentant un réel.
Int32 Integer
Type représentant un entier.