TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Probleme_U.cpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <Probleme_U.h>
17#include <Perf_counters.h>
18#include <ICoCoExceptions.h>
19#include <Ch_front_input_uniforme.h>
20#include <Ch_input_uniforme.h>
21#include <Champ_input_P0.h>
22
23#ifdef VTRACE
24#include <vt_user.h>
25#endif
26
27#include <Champ_Generique_base.h>
28#include <Convert_ICoCoTrioField.h>
29
30Implemente_base(Probleme_U,"Probleme_U",Objet_U);
31
32using ICoCo::WrongArgument;
33using ICoCo::TrioField;
34
36{
37 return os;
38}
39
41{
42 return is ;
43}
44
45/*! @brief This method is called once at the beginning, before any other one of the interface Problem.
46 *
47 * @throws WrongContext
48 */
52
53/*! @brief This method is called once at the end, after any other one.
54 *
55 * It frees the memory and saves anything that needs to be saved.
56 *
57 * @throws WrongContext
58 */
60{
61}
62
63/*! @brief Returns the present time.
64 *
65 * This value may change only at the call of validateTimeStep.
66 * A surcharger
67 *
68 * @return (double) present time
69 * @throws WrongContext
70 */
72{
73 return 0;
74}
75
76/*! @brief Compute the value the Problem would like for the next time step.
77 *
78 * This value will not necessarily be used at the call of initTimeStep,
79 * but it is a hint.
80 * This method may use all the internal state of the Problem.
81 *
82 * @param (stop) Does the Problem want to stop ?
83 * @return (double) The desired time step
84 * @throws WrongContext
85 */
86double Probleme_U::computeTimeStep(bool& stop) const
87{
88 stop=true;
89 return 0;
90}
91
92/*! @brief This method allocates and initializes the unknown and given fields for the future time step.
93 *
94 * The value of the interval is imposed through the parameter dt.
95 * In case of error, returns false.
96 *
97 * @param (double dt) the time interval to allocate
98 * @return (bool) true=OK, false=error, not able to tackle this dt
99 * @throws WrongContext, WrongArgument
100 */
102{
103 return false;
104}
105
106/*! @brief Validates the calculated unknown by moving the present time at the end of the time step.
107 *
108 * This method is allowed to free past values of the unknown and given
109 * fields.
110 *
111 * @throws WrongContext
112 */
116
117/*! @brief Tells if the Problem unknowns have changed during the last time step.
118 *
119 * @return (bool) true=stationary, false=not stationary
120 * @throws WrongContext
121 */
123{
124 return false;
125}
126
127/*! @brief Tells to the Problem that stationary is reached or not
128 *
129 */
131{
132}
133
134/*! @brief Aborts the resolution of the current time step.
135 *
136 * @throws WrongContext
137 */
141
142/*! @brief Reset the current time of the Problem to a given value.
143 *
144 * Particularly useful for the initialization of complex transients: the starting point of the transient
145 * of interest is computed first, the time is reset to 0, and then the actual transient of interest starts with proper
146 * initial conditions, and global time 0.
147 *
148 * @param[in] time the new current time.
149 * @throws ICoCo::WrongContext exception if called before initialize() or after terminate().
150 * @throws ICoCo::WrongContext exception if called inside the TIME_STEP_DEFINED context (see Problem documentation)
151 */
152void Probleme_U::resetTime(double time)
153{
154}
155
156/*! @brief In the case solveTimeStep uses an iterative process, this method executes a single iteration.
157 *
158 * It is thus possible to modify the given fields between iterations.
159 * converged is set to true if the process has converged, ie if the
160 * unknown fields are solution to the problem on the next time step.
161 * Otherwise converged is set to false.
162 * The return value indicates if the convergence process behaves normally.
163 * If false, the Problem wishes to abort the time step resolution.
164 *
165 * @param (bool& converged) It is a return value : true if the process has converged, false otherwise.
166 * @return (bool) true=OK, false=unable to converge
167 * @throws WrongContext
168 */
169bool Probleme_U::iterateTimeStep(bool& converged)
170{
171 return false;
172}
173
174/*! @brief Demande au probleme de postraiter ses champs, sondes,.
175 *
176 * .. Dans Probleme_U::run(), postraiter() est appele a chaque pas de
177 * temps avec force=0 et au debut et a la fin du calcul avec force=1.
178 * WEC : il serait bon que, un jour, postraiter soit const
179 *
180 * @param (force) 1=postraiter absolument, 0=postraiter si c'est necessaire.
181 * @return (0 en cas d'erreur, 1 sinon.)
182 */
184{
185 return 0;
186}
187
188/*! @brief Doit-on imprimer les statistiques d'execution maintenant ?
189 *
190 */
192{
193 return 0;
194}
195
196/*! @brief Doit-on sauvegarder l'etat du probleme sur disque maintenant ?
197 *
198 */
200{
201 return 0;
202}
203
204/*! @brief Sauvegarder l'etat du probleme sur disque
205 *
206 */
208{
209 return ;
210}
211
212
213/*! @brief ATTENTION :
214 *
215 * Rentre ici tout ce qui ne correspond pas a l'API normale de Problem.
216 *
217 * Actuellement on y met a jour les CLs et les termes sources, sachant
218 * que certains vont chercher eux-memes des informations dans les
219 * problemes voisins...
220 *
221 * Programme de travail : tout ce qui est dans cette methode doit etre
222 * rendu independant de l'exterieur, et peut du coup rejoindre
223 * initTimeStep.
224 * Le reste passe dans l'interface d'echange de champs.
225 * Ce travail sera fini quand updateGivenFields sera vide et supprime !
226 *
227 *
228 * @return (true=OK, false=error)
229 */
231{
232 return true;
233}
234
235
236/*! @brief Cette methode est une sorte de main() du Problem Elle peut etre utilisee si le probleme n'est couple a aucun autre.
237 *
238 * (s'il n'a besoin d'aucun champ d'entree).
239 *
240 * @return (bool) true=OK, false=error
241 */
243{
244 // Force the post process task at the beginning of the run
245 Cerr<<"First postprocessing, this can take some minutes"<<finl;
246 postraiter(1);
247 Cerr<<"First postprocessing OK"<<finl;
248 bool stop=false; // Does the Problem want to stop ?
249 bool ok=true; // Is the time interval successfully solved ?
250
251 // Compute the first time step
252 double dt=computeTimeStep(stop);
253
254 statistics().end_count(STD_COUNTERS::computation_start_up);
255 // Print the initialization CPU statistics
256 statistics().print_TU_files("Computation start-up statistics");
257#ifdef VTRACE
258 //VT_USER_END("Initialization");
259 VT_BUFFER_FLUSH();
260 VT_ON();
261 VT_USER_START("Resolution");
262#endif
263 // Time step loop
264 long int tstep = 0;
265 statistics().start_timeloop();
266 while(!stop)
267 {
268 // Begin the CPU measure of the time step
269 statistics().start_time_step();
270 statistics().begin_count(STD_COUNTERS::timeloop);
271 ok=false; // Is the time interval successfully solved ?
272 // Loop on the time interval tries
273 while (!ok && !stop)
274 {
275
276 // Prepare the next time step
277 if (!initTimeStep(dt))
278 return false;
279
280 // Backup unknown fields if necessary
281 if (lsauv())
282 sauver();
283
284 // Solve the next time step
285 ok=solveTimeStep();
286
287 if (!ok) // The resolution failed, try with a new time interval.
288 {
290 dt=computeTimeStep(stop);
291 }
292 else // The resolution was successful, validate and go to the next time step.
294 }
295 if (!ok) // Impossible to solve the next time step, the Problem has given up
296 {
297 statistics().end_count(STD_COUNTERS::timeloop);
298 statistics().end_time_step(tstep);
299 break;
300 }
301
302 // Compute the next time step length
303 dt=computeTimeStep(stop);
304
305 // Stop the resolution if the Problem is stationnary
306 if (isStationary())
307 {
308 stop=true;
309 setStationary(stop);
310 }
311
312 std::string newDirectory = stop ? newCompute() : "";
313 if (!newDirectory.empty())
314 {
315 // ToDo: ameliorer le message
316 //if (!isStationary()) Process::exit("Error, the parametric problem is not stationary! Check the convergence.");
317 // Keep on the resolution if parametric variation in a new directory:
318 stop = false;
319 setStationary(stop);
320 setInputStringValue("SORTIE_ROOT_DIRECTORY", newDirectory);
321 resetTime(0.);
322 }
323 else
324 {
325 // Post process task (Force the post processing/prints at the end of the run (stop=1))
326 postraiter(stop);
327 }
328
329 // Stop the CPU measure of the time step and print:
330 if (limpr())
331 {
332 double temps = statistics().get_time_since_last_open(STD_COUNTERS::timeloop);
333 Cout << finl << "clock: Time of the last time step: " << temps << " s" << finl << finl;
334 }
335 tstep++;
336 statistics().end_count(STD_COUNTERS::timeloop);
337 statistics().end_time_step(tstep);
338#ifdef VTRACE
339 // Flush the buffer regulary to avoid setting VT_MAX_FLUSHES=0 variable...
340 VT_BUFFER_FLUSH();
341#endif
342 }
343 statistics().end_timeloop();
344#ifdef VTRACE
345 VT_USER_END("Resolution");
346 VT_OFF();
347#endif
348 statistics().print_TU_files("Time loop statistics");
349 return ok;
350}
351
352/*! @brief This method has the same role as the method run, but it stops when reaching the time given in parameter.
353 *
354 * If this time cannot be reached, the method returns false.
355 *
356 * @param (double time) time to reach
357 * @return (true=OK, false=error)
358 */
359bool Probleme_U::runUntil(double time)
360{
361 // Error if time is already past
362 if (time<presentTime())
363 return false;
364
365 bool stop=false; // Does the Problem want to stop ?
366 bool ok=true; // Is the time interval successfully solved ?
367
368 // Compute the first time step length
369 double dt=computeTimeStep(stop);
370 statistics().start_timeloop();
371
372 // Boucle sur les pas de temps
373 while(!stop)
374 {
375 statistics().start_time_step();
376 statistics().begin_count(STD_COUNTERS::timeloop);
377 ok=false;
378
379 // Loop on the time interval tries
380 while (!ok && !stop)
381 {
382
383 // Do not go past time
384 if (presentTime()+dt>time)
385 dt=time-presentTime();
386
387 // Prepare the next time step
388 if (!initTimeStep(dt))
389 return false;
390
391 // Solve the next time step
392 ok=solveTimeStep();
393
394 if (!ok) // The resolution failed, try with a new time interval.
395 {
397 dt=computeTimeStep(stop);
398 }
399
400 else // The resolution was successful, validate and go to the
401 // next time step.
403 }
404 if (!ok) // Impossible to solve the next time step, the Problem has given up
405 break;
406
407 // time was reached
408 if (presentTime()==time)
409 return true;
410
411 // Compute the next time step length
412 dt=computeTimeStep(stop);
413
414 if (je_suis_maitre() && limpr())
415 {
416 double temps = statistics().get_time_since_last_open(STD_COUNTERS::timeloop);
417 Cout << finl << "clock: Total time of the time loop: " << temps << " s" << finl << finl;
418 }
419 statistics().end_count(STD_COUNTERS::timeloop);
420 postraiter(0);
421 }
422 statistics().end_timeloop();
423 statistics().print_TU_files("Time loop statistics");
424 return ok;
425}
426
427/*! @brief pour recodage eventuel et appel unifie en python
428 *
429 */
431{
432 bool converged = false;
433 bool ok = true;
434
435 while (!converged && ok)
436 {
437 ok= ok && updateGivenFields();
438 ok = ok && iterateTimeStep(converged);
439 }
440
441 return ok;
442}
443
444/*! @brief Returns the future time (end of current computing interval) This value is valid between initTimeStep and either
445 *
446 * validateTimeStep or abortTimeStep.
447 * A surcharger
448 *
449 * @return (double) future time
450 * @throws WrongContext
451 */
453{
454 return 0;
455}
456
457/*! @brief This method is used to find the names of input fields understood by the Problem
458 *
459 * @param (Noms) list of names where the Problem appends its input field names.
460 */
462{
463}
464
465/*! @brief This method is used to find in a hierarchy of problems the Champ_Input_Proto of a given name.
466 *
467 * Implementation is not optimal in 2 ways :
468 * - no error if two input fields have the same name.
469 * - no optimisation of the number of REF objects created and destroyed.
470 *
471 * @param (string name) name of the input field we are looking for
472 * @return (OBS_PTR(Field_base)) found <=> non_nul(), then points to a Champ_Input_Proto of that name.
473 */
474OBS_PTR(Field_base) Probleme_U::findInputField(const Nom& name) const
475{
477 return ch;
478}
479
480
481
482
483/*! @brief This method is used to find the names of output fields understood by the Problem
484 *
485 * @param (Noms) list of names where the Problem appends its output field names.
486 */
488{
489}
490
491OBS_PTR(Champ_Generique_base) Probleme_U::findOutputField(const Nom& name) const
492{
493 OBS_PTR(Champ_Generique_base) ch;
494 return ch;
495}
496
497
498
499/*! @brief This method is used to get a template of a field expected for the given name.
500 *
501 */
502void Probleme_U::getInputFieldTemplate(const Nom& name, TrioField& afield) const
503{
504 OBS_PTR(Field_base) ch=findInputField(name);
505 if (!ch)
506 throw WrongArgument(le_nom().getChar(),"getInputFieldTemplate",name.getString(),"no input field of that name");
507
508 // Du au fait qu'on ne peut pas faire une ref sur Champ_Input_Proto qui n'est pas un Objet_U...
509 Champ_Input_Proto * chip = dynamic_cast<Champ_Input_Proto *>(ch.operator->());
510 if (!chip)
511 throw WrongArgument(le_nom().getChar(),"getInputFieldTemplate",name.getString(),"field of this name is not an input field");
512
513 chip->getTemplate(afield);
514}
515
516/*! @brief This method is used to provide the Problem with an input field.
517 *
518 */
519void Probleme_U::setInputField(const Nom& name, const TrioField& afield)
520{
521 OBS_PTR(Field_base) ch=findInputField(name);
522 if (!ch)
523 throw WrongArgument(le_nom().getChar(),"setInputField",name.getString(),"no input field of that name");
524 if (!est_egal(afield._time1,presentTime()))
525 throw WrongArgument(le_nom().getChar(),"setInputField","afield","Should be defined on current time interval");
526 if (!est_egal(afield._time2,futureTime()))
527 throw WrongArgument(le_nom().getChar(),"setInputField","afield","Should be defined on current time interval");
528 if (strcmp(name.getChar(),afield.getCharName()))
529 throw WrongArgument(le_nom().getChar(),"setInputField","afield","Should have the same name as the argument name ");
530
531 // Du au fait qu'on ne peut pas faire une ref sur Champ_Input_Proto qui n'est pas un Objet_U...
532 Champ_Input_Proto * chip = dynamic_cast<Champ_Input_Proto *>(ch.operator->());
533 if (!chip)
534 throw WrongArgument(le_nom().getChar(),"setInputField",name.getString(),"field of this name is not an input field");
535
536 chip->setValue(afield);
537}
538
539void Probleme_U::getOutputField(const Nom& name, TrioField& afield) const
540{
541
542 OBS_PTR(Champ_Generique_base) ref_ch=findOutputField(name);
543 if (!ref_ch)
544 throw WrongArgument(le_nom().getChar(),"getOutputField",name.getString(),"no output field of that name");
545
546 const Champ_Generique_base& ch = ref_ch.valeur();
547 build_triofield(ch, afield);
548 afield.setName(name.getString());
549}
550
551// For now: set a field value provided the field has only one item.
552void Probleme_U::setInputDoubleValue(const Nom& name, const double val)
553{
554 OBS_PTR(Field_base) ch = findInputField(name);
555 if (!ch)
556 throw WrongArgument(le_nom().getChar(),"setInputDoubleValue",name.getString(),"no input field of that name");
557 if (ch->nb_comp() != 1)
558 throw WrongArgument(le_nom().getChar(),"getOutputDoubleValue",name.getString(),"invalid field size!!");
559
560 // Wa can not do a REF on Champ_Input_Proto which is not an Objet_U...
561 Champ_Input_Proto * chip = dynamic_cast<Champ_Input_Proto *>(ch.operator ->());
562 if (!chip)
563 throw WrongArgument(le_nom().getChar(),"setInputField",name.getString(),"field of this name is not an input field");
564 chip->setDoubleValue(val);
565}
566
567std::string Probleme_U::getOutputStringValue(const std::string& name)
568{
569 if(str_params_.count(name) == 0)
570 {
571 WrongArgument(name,"getOutputStringValue",name,"no string parameter with that name");
572 }
573 return str_params_[name];
574}
575
576void Probleme_U::setInputIntValue(const Nom& name, const int& val)
577{
578 // add value in ICoCoScalarRegister
579 reg_.setInputIntValue(name, val);
580}
581
582int Probleme_U::getOutputIntValue(const Nom& name) const
583{
584 return reg_.getOutputIntValue(name);
585}
586
588{
589 return reg_.checkOutputIntEntry(name);
590}
591
592double Probleme_U::getOutputPointValues(const Nom& name, const double x, const double y, const double z, int compo)
593{
594 std::vector<double> xx, yy, zz, vals;
595 xx.push_back(x);
596 yy.push_back(y);
597 zz.push_back(z);
598 getOutputPointValues(name, xx, yy, zz, vals, compo);
599 return vals[0];
600}
class Champ_Generique_base
This is the base class for all the Fields which can be written by a call to Problem::setInputField.
virtual void setValue(const TrioField &afield)=0
virtual void setDoubleValue(const double val)
virtual void getTemplate(TrioField &afield) const =0
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
const char * getChar() const
Definition Nom.h:91
const std::string & getString() const
Definition Nom.h:92
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
classe Objet_U Cette classe est la classe de base des Objets de TRUST
Definition Objet_U.h:73
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
classe Probleme_U
Definition Probleme_U.h:46
virtual void sauver() const
Sauvegarder l'etat du probleme sur disque.
virtual int postraiter(int force=1)
Demande au probleme de postraiter ses champs, sondes,.
virtual void getInputFieldsNames(Noms &noms) const
This method is used to find the names of input fields understood by the Problem.
virtual bool initTimeStep(double dt)
This method allocates and initializes the unknown and given fields for the future time step.
virtual std::string newCompute()
Definition Probleme_U.h:60
virtual OBS_PTR(Field_base) findInputField(const Nom &name) const
virtual void validateTimeStep()
Validates the calculated unknown by moving the present time at the end of the time step.
virtual int limpr() const
Doit-on imprimer les statistiques d'execution maintenant ?
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Probleme_U.h:109
virtual void setInputField(const Nom &name, const ICoCo::TrioField &afield)
virtual bool iterateTimeStep(bool &converged)
In the case solveTimeStep uses an iterative process, this method executes a single iteration.
virtual void setInputDoubleValue(const Nom &name, const double val)
virtual void getOutputPointValues(const Nom &name, const std::vector< double > &x, const std::vector< double > &y, const std::vector< double > &z, std::vector< double > &vals, int compo)
Definition Probleme_U.h:74
virtual void setInputStringValue(const std::string &name, const std::string &val)
Definition Probleme_U.h:88
virtual void terminate()
This method is called once at the end, after any other one.
virtual void abortTimeStep()
Aborts the resolution of the current time step.
virtual double futureTime() const
Returns the future time (end of current computing interval) This value is valid between initTimeStep ...
virtual bool checkOutputIntEntry(const Nom &name) const
virtual bool runUntil(double time)
This method has the same role as the method run, but it stops when reaching the time given in paramet...
virtual int lsauv() const
Doit-on sauvegarder l'etat du probleme sur disque maintenant ?
virtual bool run()
Cette methode est une sorte de main() du Problem Elle peut etre utilisee si le probleme n'est couple ...
virtual bool solveTimeStep()
pour recodage eventuel et appel unifie en python
virtual std::string getOutputStringValue(const std::string &name)
ScalarRegister reg_
Definition Probleme_U.h:113
virtual bool isStationary() const
Tells if the Problem unknowns have changed during the last time step.
virtual double presentTime() const
Returns the present time.
virtual void setStationary(bool)
Tells to the Problem that stationary is reached or not.
virtual void getOutputFieldsNames(Noms &noms) const
std::map< std::string, std::string > str_params_
Definition Probleme_U.h:114
virtual void setInputIntValue(const Nom &name, const int &val)
virtual int getOutputIntValue(const Nom &name) const
virtual void getOutputField(const Nom &nameField, ICoCo::TrioField &afield) const
virtual void resetTime(double time)
Reset the current time of the Problem to a given value.
virtual void getInputFieldTemplate(const Nom &name, ICoCo::TrioField &afield) const
virtual bool updateGivenFields()
ATTENTION :
virtual void initialize()
This method is called once at the beginning, before any other one of the interface Problem.
virtual double computeTimeStep(bool &stop) const
Compute the value the Problem would like for the next time step.
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
Definition Process.cpp:86
Classe de base des flux de sortie.
Definition Sortie.h:52