TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Schema_Temps_base.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 <Schema_Temps_base.h>
17#include <EcrFicCollecte.h>
18#include <communications.h>
19#include <Probleme_base.h>
20#include <Matrice_Morse.h> // necessary for visual
21#include <LecFicDiffuse.h>
22#include <Equation_base.h>
23#include <TRUST_2_PDI.h>
24#include <sys/stat.h>
25#include <SFichier.h>
26#include <Param.h>
27#include <Debog.h>
28#include <cfloat>
29#include <DeviceMemory.h>
30#include <Perf_counters.h>
31
32// XD dt_start class_generic dt_start NO_BRACE not_set
33// XD dt_calc_dt_calc dt_start dt_calc NO_BRACE The time step at first iteration is calculated in agreement with CFL
34// XD_CONT condition.
35// XD dt_calc_dt_min dt_start dt_min NO_BRACE The first iteration is based on dt_min.
36
37// XD dt_calc_dt_fixe dt_start dt_fixe NO_BRACE The first time step is fixed by the user (recommended when resuming
38// XD_CONT calculation with Crank Nicholson temporal scheme to ensure continuity).
39// XD attr value floattant value REQ first time step.
40
41
42Implemente_base_sans_constructeur(Schema_Temps_base,"Schema_Temps_base",Objet_U);
43// XD schema_temps_base objet_u schema_temps_base INHERITS_BRACE Basic class for time schemes. This scheme will be
44// XD_CONT associated with a problem and the equations of this problem.
45/* Attributes further down in the cpp: */
46
47/*! @brief Default constructor of a time scheme.
48 *
49 * Initializes different class members.
50 *
51 */
52Schema_Temps_base::Schema_Temps_base() :
53 norm_residu_("max")
54{
55}
56
58{
59 nb_impr_= 0;
60 nb_pas_dt_ = 0;
61
62 // GF re-calling calculer_pas_de_temps because some implicit time schemes use it for dimensioning (in particular ovap)
64 // calling it a second time for alternating schemes....
66
67 // Outputs:
68 bool init = true;
69 write_dt_ev(init);
70 write_progress(init);
71
72 if ( nb_pas_dt_ == 0 && ( ( mode_dt_start_ == 0. && est_egal(tinit_,0.)) || mode_dt_start_ == -1.) )
73 {
74 //We divide by facsec_ because multiplication by facsec_ is done in corriger_dt_calcule()
75 //regardless of the dt_ initialization mode
77 }
78 else if (mode_dt_start_ > 0.)
79 {
81 }
82 else
83 {
86 }
88 dt_failed_ = DBL_MAX;
89}
90
91double Schema_Temps_base::computeTimeStep(bool& is_stop) const
92{
93 //re-evaluation of dt_max_ if it is a function of time
94 if (dt_max_str_ != Nom())
95 {
96 dt_max_fn_.setVar(0, temps_courant());
97 dt_max_ = dt_max_fn_.eval();
98 }
99 is_stop=false;
100 // First correct the time step
101 double dt = dt_stab_;
102 if (!corriger_dt_calcule(dt)) // Change le contenu de dt
103 is_stop=true;
104 dt = std::min(dt, dt_failed_ / sqrt(2)); //to force a dt decrease in case of failure at the previous resolution
106 dt = std::min(dt, (temps_courant_ - temps_precedent_) * dt_gf_); //to avoid increasing dt too fast (like facsec)
107
108 if (limpr() || (nb_pas_dt_ == 0))
109 Cout << "Time step finally used to solve the next time step (taking into account facsec) : " << dt << " s." << finl;
110
111 // If dt has been reduced after a failed step, enforce dt_min check again.
112 if ((dt - dt_min_) / (dt + DMINFLOAT) < -1.e-6 && !adapt_dt_tmax_)
113 {
114 Cerr << "---------------------------------------------------------" << finl;
115 Cerr << "Problem with the time step " << dt << " which is less than dt_min " << dt_min_ << finl;
116 Cerr << "Lower dt_min value or check why the time step decreases..." << finl;
117 Cerr << "Results are saved to provide help." << finl;
118 Cerr << "---------------------------------------------------------" << finl;
119 Probleme_base& pb = ref_cast_non_const(Probleme_base, mon_probleme.valeur());
120 pb.postraiter(1);
121 pb.sauver();
123 }
124
125 // Immediate update of dt_ attribute so that pas_de_temps()
126 // is always up to date (especially at post-processing time)
127 // This was not the case for versions <= 1.6.3 and fields depending
128 // on dt were not correct if facsec<>1
129 // dt_ = dt;
130
131 if (this->stop())
132 {
133 is_stop=true;
134 //return 0; Why ?
135 return dt;
136 }
137 else
138 return dt;
139}
140
142{
143
144 dt_=dt;
145 stationnaire_atteint_ = -1;
146 residu_=0;
147
148 return true;
149}
150
151/*! @brief Calculate the U(n+1) unknown for each equation (if solved) of the problem with the selected time scheme
152 *
153 */
155{
156 // Loop on the equations of the problem:
157 for(int i=0; i<pb_base().nombre_d_equations(); i++)
158 {
159 Equation_base& equation=pb_base().equation(i);
160 // Calculate (if equation is solved) the unknown equation U(n+1)
161 // according to the selected time scheme:
162 if (!equation.equation_non_resolue())
164 else
165 {
166 Cout<< "====================================================" << finl;
167 Cout<< equation.que_suis_je()<<" equation is not solved."<<finl;
168 Cout<< "====================================================" << finl;
169 // Compute the derivative once to obtain the boundary fluxes
170 if (equation.schema_temps().nb_pas_dt()==0)
171 {
172 DoubleTab inconnue_valeurs(equation.inconnue().valeurs());
173 equation.derivee_en_temps_inco(inconnue_valeurs);
174 }
175 }
176 }
177 converged=true;
178 return true;
179}
180
181/*! @brief Returns 1 if there is a need to perform a print (cf dt_impr) Returns 0 otherwise
182 *
183 * @return (int) 1 if there is a need to perform a print 0 otherwise
184 */
186{
187 if (dt_impr_<=0)
188 return 0; // Negative value for dt_impr : we never print
189 if (nb_pas_dt_==0)
190 return 0; // No solve cause 0 time step : we print nothing
191 if (dt_impr_<=dt_)
192 return 1; // We print every time step if dt_impr is lower than dt
193 if (nb_pas_dt_<=1)
194 return 1; // We print the first time step
195 if (tmax_<=temps_courant_ || nb_pas_dt_max_<=nb_pas_dt_ || stationnaires_atteints_)
196 return 1; // We print the last time step
197
198 // 26/01/2010: We now use the function "modf(operation, &integer_part)" from math.h
199 // This function decomposes the result of "operation" into an integer part and a decimal part.
200 // This avoids converting a double to int with all the associated risks.
201 // ex: modf(9/7,&i) gives 1.000000 for the integer part and 0.285714 for the decimal part
202 //
203 // epsilon ensures that the result of the operation is independent of machine precision:
204 // ex: 0.99999999/1.00000000 can give 0.99999999 or 1.00000000 depending on the machine
205 // whereas
206 // ex: 0.99999999/1.00000000 + 1.e-8 always gives 1.00000000.
207 double i, j, epsilon = 1.e-8;
208 modf(temps_courant_/dt_impr_ + epsilon, &i);
209 modf(temps_precedent_/dt_impr_ + epsilon, &j);
210 return ( i>j );
211}
212
214{
215 statistics().begin_count(STD_COUNTERS::update_variables,statistics().get_last_opened_counter_level()+1);
216 // Update the problem:
217 Probleme_base& problem=pb_base();
219
220 // Outputs
221 bool init=false;
222 write_dt_ev(init);
223 write_progress(init);
224
225 // Update time scheme:
227 statistics().end_count(STD_COUNTERS::update_variables);
228 dt_failed_ = DBL_MAX;
229}
231{
233 progress_<< (int)100<< finl;
234}
235
236/*! @brief Returns 1 if during the last time step, the problem has not evolved.
237 *
238 * @param (temps) the time to reach
239 * @return (1 if the problem has not evolved, 0 otherwise.)
240 */
242{
243 if (stationnaire_atteint_ && (nb_pas_dt_ >= 2))
244 {
245 Cerr << "---------------------------------------------------------"
246 << finl
247 << "The problem " << pb_base().le_nom()
248 << " has reached the steady state"
249 << finl << finl;
250 return true;
251 }
252 return false;
253}
254
256{
257 Probleme_base& prob=pb_base();
258 for(int i=0; i<prob.nombre_d_equations(); i++)
259 prob.equation(i).abortTimeStep();
260
261 dt_ = prob.calculer_pas_de_temps();
262}
263
265{
266 //
267 // It happens here: -)
268 //
269 temps_courant_ = time;
270}
271
273{
274 mon_probleme=un_probleme;
275}
276
277
278
280{
281 param.ajouter("tinit",&tinit_); // XD_ADD_P double
282 // XD_CONT Value of initial calculation time (0 by default).
283 param.ajouter( "tmax",&tmax_); // XD_ADD_P double
284 // XD_CONT Time during which the calculation will be stopped (1e30s by default).
285 param.ajouter_non_std( "tcpumax",(this)); // XD_ADD_P double
286 // XD_CONT CPU time limit (must be specified in hours) for which the calculation is stopped (1e30s by default).
287 param.ajouter( "dt_min",&dt_min_); // XD_ADD_P double
288 // XD_CONT Minimum calculation time step (1e-16s by default).
289 param.ajouter( "dt_max",&dt_max_str_); // XD_ADD_P chaine
290 // XD_CONT Maximum calculation time step as function of time (1e30s by default).
291 param.ajouter( "dt_sauv",&dt_sauv_); // XD_ADD_P double
292 // XD_CONT Save time step value (1e30s by default). Every dt_sauv, fields are saved in the .sauv file. The file
293 // XD_CONT contains all the information saved over time. If this instruction is not entered, results are saved only
294 // XD_CONT upon calculation completion. To disable the writing of the .sauv files, you must specify 0. Note that
295 // XD_CONT dt_sauv is in terms of physical time (not cpu time).
296 param.ajouter( "nb_sauv_max",&nb_sauv_max_); // XD_ADD_P entier
297 // XD_CONT Maximum number of timesteps that will be stored in backup file (10 by default). This value is only useful
298 // XD_CONT when doing a complete backup of the calculation with parallel PDI (as it needs to allocate the proper
299 // XD_CONT amount of dataspace in advance). If this number is reached (ie we already stored the data of nb_sauv_max
300 // XD_CONT timesteps in the file), the next checkpoints will overwrite the first ones
301 param.ajouter( "dt_impr",&dt_impr_); // XD_ADD_P double
302 // XD_CONT Scheme parameter printing time step in time (1e30s by default). The time steps and the flux balances are
303 // XD_CONT printed (incorporated onto every side of processed domains) into the .out file.
304 param.ajouter_non_std("facsec",(this)); // XD_ADD_P chaine
305 // XD_CONT Value assigned to the safety factor for the time step (1. by default). It can also be a function of time.
306 // XD_CONT The time step calculated is multiplied by the safety factor. The first thing to try when a calculation does
307 // XD_CONT not converge with an explicit time scheme is to reduce the facsec to 0.5. NL2 Warning: Some schemes needs a
308 // XD_CONT facsec lower than 1 (0.5 is a good start), for example Schema_Adams_Bashforth_order_3.
309 param.ajouter( "seuil_statio",&seuil_statio_); // XD_ADD_P double
310 // XD_CONT Value of the convergence threshold (1e-12 by default). Problems using this type of time scheme converge
311 // XD_CONT when the derivatives dGi/dt NL1 of all the unknown transported values Gi have a combined absolute value
312 // XD_CONT less than this value. This is the keyword used to set the permanent rating threshold.
313 param.ajouter_non_std("residuals", (this)); // XD_ADD_P residuals
314 // XD_CONT To specify how the residuals will be computed (default max norm, possible to choose L2-norm instead).
315 param.ajouter( "diffusion_implicite",&ind_diff_impl_); // XD_ADD_P entier
316 // XD_CONT Keyword to make the diffusive term in the Navier-Stokes equations implicit (in this case, it should be set
317 // XD_CONT to 1). The stability time step is then only based on the convection time step (dt=facsec*dt_convection).
318 // XD_CONT Thus, in some circumstances, an important gain is achieved with respect to the time step (large diffusion
319 // XD_CONT with respect to convection on tightened meshes). Caution: It is however recommended that the user avoids
320 // XD_CONT exceeding the convection time step by selecting a too large facsec value. Start with a facsec value of 1
321 // XD_CONT and then increase it gradually if you wish to accelerate calculation. In addition, for a natural convection
322 // XD_CONT calculation with a zero initial velocity, in the first time step, the convection time is infinite and
323 // XD_CONT therefore dt=facsec*dt_max.
324 param.ajouter( "seuil_diffusion_implicite",&seuil_diff_impl_); // XD_ADD_P double
325 // XD_CONT This keyword changes the default value (1e-6) of convergency criteria for the resolution by conjugate
326 // XD_CONT gradient used for implicit diffusion.
327 param.ajouter( "impr_diffusion_implicite",&impr_diff_impl_); // XD_ADD_P entier
328 // XD_CONT Unactivate (default) or not the printing of the convergence during the resolution of the conjugate
329 // XD_CONT gradient.
330 param.ajouter( "impr_extremums",&impr_extremums_); // XD_ADD_P entier
331 // XD_CONT Print unknowns extremas
332 param.ajouter( "no_error_if_not_converged_diffusion_implicite",&no_error_if_not_converged_diff_impl_); // XD_ADD_P entier
333 // XD_CONT not_set
334 param.ajouter( "no_conv_subiteration_diffusion_implicite",&no_conv_subiteration_diff_impl_); // XD_ADD_P entier
335 // XD_CONT not_set
336 param.ajouter_non_std( "dt_start",(this)); // XD_ADD_P dt_start
337 // XD_CONT dt_start dt_min : the first iteration is based on dt_min. NL2 dt_start dt_calc : the time step at first
338 // XD_CONT iteration is calculated in agreement with CFL condition. NL2 dt_start dt_fixe value : the first time step
339 // XD_CONT is fixed by the user (recommended when resuming calculation with Crank Nicholson temporal scheme to ensure
340 // XD_CONT continuity). NL2 By default, the first iteration is based on dt_calc.
341 param.ajouter_non_std( "nb_pas_dt_max",(this)); // XD_ADD_P entier
342 // XD_CONT Maximum number of calculation time steps (1e9 by default).
343 param.ajouter( "niter_max_diffusion_implicite",&niter_max_diff_impl_); // XD_ADD_P entier
344 // XD_CONT This keyword changes the default value (number of unknowns) of the maximal iterations number in the
345 // XD_CONT conjugate gradient method used for implicit diffusion.
346 param.ajouter( "precision_impr",&precision_impr_); // XD_ADD_P entier
347 // XD_CONT Optional keyword to define the digit number for flux values printed into .out files (by default 3).
348 param.ajouter_non_std( "periode_sauvegarde_securite_en_heures",(this)); // XD_ADD_P double
349 // XD_CONT To change the default period (23 hours) between the save of the fields in .sauv file.
350 param.ajouter_non_std( "no_check_disk_space",(this)); // XD_ADD_P flag
351 // XD_CONT To disable the check of the available amount of disk space during the calculation.
352 param.ajouter_flag( "disable_progress",&disable_progress_); // XD_ADD_P flag
353 // XD_CONT To disable the writing of the .progress file.
354 param.ajouter_flag( "disable_dt_ev",&disable_dt_ev_); // XD_ADD_P flag
355 // XD_CONT To disable the writing of the .dt_ev file.
356 param.ajouter_flag("adapt_dt_tmax", &adapt_dt_tmax_); // XD_ADD_P flag
357 // XD_CONT Use to adapt final dt when approaching tmax.
358 param.ajouter( "gnuplot_header",&gnuplot_header_); // XD_ADD_P entier
359 // XD_CONT Optional keyword to modify the header of the .out files. Allows to use the column title instead of columns
360 // XD_CONT number.
361
362 // XD residuals interprete nul BRACE To specify how the residuals will be computed.
363 // XD attr norm chaine(into=["L2","max"]) norm OPT allows to choose the norm we want to use (max norm by default).
364 // XD_CONT Possible to specify L2-norm.
365// XD attr relative chaine(into=["0","1","2"]) relative OPT This is the old keyword seuil_statio_relatif_deconseille. If
366// XD_CONT it is set to 1, it will normalize the residuals with the residuals of the first 5 timesteps (default is 0).
367// XD_CONT if set to 2, residual will be computed as R/(max-min).
368}
369
370/*! @brief Overrides Objet_U::printOn(Sortie&): prints the time scheme to an output stream.
371 *
372 * !! Note: this is not symmetric with reading !!
373 * Writes the various parameters of the time scheme.
374 *
375 * @param (Sortie& os) the output stream
376 * @return (Sortie&) the modified output stream
377 */
379{
380 os << "dt " << dt_ << finl;
381 os << "temps_courant " << temps_courant_ << finl ;
382 os << "tinit " << tinit_ << finl;
383 os << "tmax " << tmax_ << finl ;
384 os << "tcpumax " << tcpumax_ << finl ;
385 os << "nb_pas_dt " << nb_pas_dt_ << finl;
386 os << "nb_pas_dt_max " << nb_pas_dt_max_ << finl;
387 os << "dt_min " << dt_min_ << finl;
388 os << "dt_max " << dt_max_ << finl;
389 os << "facsec " << facsec_ << finl;
390 os << "seuil_statio" << seuil_statio_ << finl;
391 os << "seuil_statio_relatif_deconseille" << seuil_statio_relatif_deconseille_ << finl;
392 os << "norm_residu" << norm_residu_ << finl;
393 os << "dt_sauv " << dt_sauv_ << finl;
394 os << "nb_sauv_max " << nb_sauv_max_ << finl;
395 os << "limite_cpu_sans_sauvegarde " << limite_cpu_sans_sauvegarde_ << finl;
396 os << "dt_impr " << dt_impr_ << finl;
397 os << "precision_impr " << precision_impr_ << finl;
398 os << "stationnaire_atteint " << stationnaire_atteint_ << finl;
399 os << "diffusion_implicite " << ind_diff_impl_ << finl ;
400 os << "seuil_diffusion_implicite " << seuil_diff_impl_ << finl ;
401 os << "impr_diffusion_implicite " << impr_diff_impl_ << finl ;
402 os << "impr_extremums " << impr_extremums_ << finl ;
403 os << "niter_max_diffusion_implicite " << niter_max_diff_impl_ << finl ;
404 os << "no_file_allocation " << file_allocation_ << finl ;
405 os << "disable_progress " << int(disable_progress_) << finl ; // TODO allow outputs of bool in Sortie
406 os << "disable_dt_ev " << int(disable_dt_ev_) << finl ;
407 os << "adapt_dt_tmax " << int(adapt_dt_tmax_) << finl ;
408 os << "fin " << finl;
409 return os ;
410}
411
412
413/*! @brief Reads a time scheme from an input stream.
414 *
415 * The expected read format is:
416 * {
417 * [Motcle valeur_reelle]
418 * }
419 * The keywords can be:
420 * tinit, tmax, nb_pas_dt_max, dt_min, dt_max,
421 * dt_sauv, dt_impr, facsec, seuil_statio,
422 *
423 * @param (Entree& is) the input stream
424 * @return (Entree&) the modified input stream
425 * @throws opening brace expected
426 * @throws unknown keyword at this location
427 */
429{
430 Cerr<<"Reading of data for a "<<que_suis_je()<<" time scheme"<<finl;
431 Param param(que_suis_je());
432 set_param(param);
433 param.lire_avec_accolades_depuis(is);
434 if (dt_min_==0)
435 {
436 Cerr<<"dt_min has not been read or is set to 0."<<finl;
437 Cerr<<"Assign a value strictly positive to dt_min."<<finl;
438 exit();
439 }
442 lu_=true;
443 if (dt_sauv_ <= 0.)
444 Cerr << "NO next backup, by security, because dt_sauv = " << dt_sauv_ << finl;
445 else
446 Cerr << "The next backup, by security, will take place after " << limite_cpu_sans_sauvegarde_/3600 << " hours of calculation." << finl;
447
448 if (dt_max_str_ != Nom())
449 {
450 dt_max_fn_.setNbVar(1);
451 dt_max_fn_.setString(dt_max_str_);
452 dt_max_fn_.addVar("t");
453 dt_max_fn_.parseString();
454 dt_max_ = dt_max_fn_.eval();
455 }
456 return is ;
457}
458
460{
461 Motcle motlu;
462 int retval = 1;
463 if (mot=="dt_start")
464 {
465 is>>motlu;
466 Motcles les_mots2(4);
467 les_mots2[0]="dt_std";
468 les_mots2[1]="dt_min";
469 les_mots2[2]="dt_calc";
470 les_mots2[3]="dt_fixe";
471 int rang2=les_mots2.search(motlu);
472 switch(rang2)
473 {
474 case 0:
475 case 1:
476 case 2:
477 {
478 mode_dt_start_ = (double)(-rang2);
479 break;
480 }
481 case 3:
482 {
483 is >> mode_dt_start_;
484 break;
485 }
486 default:
487 {
488 Cerr<<" We do not understand "<<motlu <<"in Schema_Temps_base::lire_motcle_non_standard"<<finl;
489 Cerr<<"keywords understood "<<les_mots2<<finl;
490 exit();
491 }
492 }
493 return 1;
494 }
495 else if (mot=="nb_pas_dt_max")
497 else if (mot=="periode_sauvegarde_securite_en_heures")
499 else if (mot=="tcpumax")
501 else if (mot=="no_check_disk_space")
503 else if (mot == "residuals")
504 lire_residuals(is);
505 else if(mot == "facsec")
506 is >> facsec_;
507 else
508 retval = -1;
509
510 return retval;
511}
512
513/*! @brief Reads the maximum number of time steps.
514 *
515 */
517{
518 Cerr << "Reading of the maximum number of time steps" << finl;
519 is >> nb_pas_dt_max_;
520 return is;
521}
522
524{
525 Cerr << "Reading of the safety backup period in hours" << finl;
527 periode_cpu_sans_sauvegarde_*=3600; // Conversion to seconds
529 return is;
530}
531
533{
534 Cerr << "Reading the max cpu time allowed" << finl;
535 is >> tcpumax_;
536 tcpumax_*=3600; // Conversion to seconds
537 return is;
538}
539
540
542{
543 Motcle m;
544 is >> m;
545 assert (m == "{");
546 is >> m;
547 while (m != "}")
548 {
549 Motcles residuals_mots(2);
550 residuals_mots[0]="relative";
551 residuals_mots[1]="norm";
552 int res_rang=residuals_mots.search(m);
553 switch(res_rang)
554 {
555 case 0:
557 break;
558 case 1:
559 is >> norm_residu_;
560 break;
561 default :
562 {
563 Cerr<<" We do not understand "<<m <<"in Schema_Temps_base::lire_motcle_non_standard"<<finl;
564 Cerr<<" keywords understood "<<residuals_mots<<finl;
565 exit();
566 }
567 }
568 is >> m;
569 }
570 return is;
571}
572
573
574/*! @brief Prints the time step number, the time step value, and the current time.
575 *
576 * @param (Sortie& os) the output stream
577 * @return (int) always returns 0
578 */
580{
581 os << finl;
582 os << "-------------------------------------------------------------------" << finl;
583 os << "We finished treating the time step number "<< nb_pas_dt_ << " , for the time scheme ..." << finl
584 << " stable dt used = " << dt_ << finl /* dt_stab_ perhaps? it is the same I think */
585 << " time achieved (in seconds) = " << temps_courant_ << finl;
586 return 0;
587}
588
589/*! @brief Prints the time step number, the time step value, and the current time.
590 *
591 * @param (Sortie& os) the output stream
592 * @return (int) always returns 0
593 */
595{
596 os << finl;
597 os << " Problem : " << pb.le_nom() << finl;
598 os << "We treat the time step number "<< nb_pas_dt_ << finl;
599 os << " dt = " << dt_ << finl;
600 os << " time = " << temps_courant_ << finl;
601 os << " time scheme : " << pb.schema_temps() << finl;
602 return 0;
603}
605{
606 os << finl;
607 os << " Problem : " << pb.le_nom() << finl;
608 os << "We treat the time step number "<< nb_pas_dt_ << finl;
609 os << " dt = " << dt_ << finl;
610 os << " time = " << temps_courant_ << finl;
611 os << " time scheme : " << pb.schema_temps() << finl;
612 return 0;
613}
614
615extern "C" {
616 int ccc_tremain(double*);
617}
618/*! @brief Updates the current time (t+=dt) and the number of time steps performed (nb_pas_dt_++).
619 *
620 * @return (int) always returns 1
621 */
623{
626 nb_pas_dt_++;
627 // Compute next time step stability:
628 statistics().end_count(STD_COUNTERS::update_variables,0,0);
630 statistics().begin_count(STD_COUNTERS::update_variables,statistics().get_last_opened_counter_level()+1);
631 assert_parallel(dt_stab_);
632 assert_parallel(temps_courant_);
635
638
641
642 // Increment limite_cpu_sans_sauvegarde_
644 {
646 //Finally, we double the limit, so by default security backup at 10h, 20h, 40h, 80h, 160h, ...
647 //limite_cpu_sans_sauvegarde_ = 2 * limite_cpu_sans_sauvegarde_;
648 if (dt_sauv_ <= 0.)
649 Cerr << "NO next backup, by security, because dt_sauv = " << dt_sauv_ << finl;
650 else
651 Cerr << "The next backup, by security, will take place after " << limite_cpu_sans_sauvegarde_/3600 << " hours of calculation." << finl;
652 }
653// GF to ensure that all processes have the same elapsed time
654 if (je_suis_maitre())
655 {
656 temps_cpu_ecoule_ = statistics().get_time_since_last_open(STD_COUNTERS::total_execution_time);
657 }
658
659 envoyer_broadcast(temps_cpu_ecoule_,0);
660
661
662#ifdef LIBCCC_USER
663 if (je_suis_maitre() && limpr())
664 {
665 Cout << "[CCRT] ";
666 double second_remain;
667 int error = ccc_tremain(&second_remain);
668 if(!error)
669 {
670 int hour_remain = (int)(second_remain/3600);
671 second_remain-=hour_remain*3600;
672 int minute_remain = (int)(second_remain/60);
673 second_remain-=minute_remain*60;
674 Cout << hour_remain <<"h"<<minute_remain<<"mn"<<second_remain<<"s before job is killed on CCRT." << finl;
675 }
676 else
677 Cout << "Error." << finl;
678 }
679#endif
680 return 1;
681}
682// Makes a protection backup on 24h runs on CCRT machines
684{
685 if (dt_sauv_ <= 0.)
686 return 0;
687 else
688 {
690 {
691 Cerr << "After these " << limite_cpu_sans_sauvegarde_/3600 << " hours of calculation, a backup will be made by security." << finl;
692 return 1;
693 }
694 else
695 {
696 if (dt_sauv_<=dt_)
697 return 1;
698 else if (tmax_<=temps_courant_ || nb_pas_dt_max_<=nb_pas_dt_ || stationnaires_atteints_ || ind_temps_cpu_max_atteint || stop_lu())
699 return 1;
700 else
701 {
702 // See Schema_Temps_base::limpr for information on epsilon and modf
703 double i, j, epsilon = 1.e-8;
704 modf(temps_courant_/dt_sauv_ + epsilon, &i);
705 modf(temps_precedent_/dt_sauv_ + epsilon, &j);
706 return ( i>j ) ;
707 }
708 }
709 }
710}
711
718/*! @brief Prints the time step to an output stream if appropriate.
719 *
720 * @param (Sortie& os) the output stream
721 */
723{
724 if (limpr())
725 {
726 nb_impr_++;
727 if (je_suis_maitre() && schema_impr())
728 {
729 impr(os);
730 }
731 }
732}
733
734/*! @brief Prints the time step to an output stream if appropriate.
735 *
736 * @param (Sortie& os) the output stream
737 */
739{
740 if (limpr() && je_suis_maitre())
741 impr(os,pb);
742}
744{
745 if (limpr() && je_suis_maitre())
746 impr(os,pb);
747}
748
749/*! @brief Saves the current time and the number of time steps to an output stream.
750 *
751 * @param (Sortie& os) the output stream for the backup
752 */
754{
755 int bytes = 0;
757 {
758 int simple_checkpoint = ref_cast_non_const(Probleme_base, mon_probleme.valeur()).is_sauvegarde_simple();
759 int i = 0;
760 int i_max = 1;
761 if(!simple_checkpoint)
762 {
764 Cerr << "WARNING ! Overwriting the first " << nb_sauv_max_ << " backups..." << finl;
766 i_max = nb_sauv_max_;
767 }
768 TRUST_2_PDI pdi_interface;
769 pdi_interface.TRUST_start_sharing("iter", &i);
770 pdi_interface.TRUST_start_sharing("nb_iter_max", &i_max);
771 pdi_interface.TRUST_start_sharing("temps", &temps_courant_);
773 pdi_interface.trigger("time_scheme");
774 pdi_interface.stop_sharing_last_variable(); //temps
775 pdi_interface.stop_sharing_last_variable(); //nb_iter_max
776 pdi_interface.stop_sharing_last_variable(); //iter
777
778 bytes = 8+4; // one double and one int
779 }
780 nb_sauv_++;
781 return bytes;
782}
783
784/*! @brief Restarts (reads) the current time and the number of time steps performed from an input stream.
785 *
786 * @param (Entree& is) the input stream
787 * @return (int) always returns 1
788 */
790{
791 return 1;
792}
793
794/*! @brief Returns 1 if the .stop file contains a 1, returns 0 otherwise.
795 *
796 * @return (int) 1 if the .stop file contains 1, 0 otherwise
797 */
799{
800 int stop_lu_l = 0;
801 if (!get_disable_stop())
802 {
803 Nom nomfic(nom_du_cas());
804 nomfic += ".stop";
805 if (nb_pas_dt_ < 1)
806 {
807 if (je_suis_maitre())
808 {
809 SFichier ficstop(nomfic);
810 ficstop << stop_lu_l;
811 }
812 }
813 else
814 {
815 LecFicDiffuse ficstop(nomfic);
816 ficstop >> stop_lu_l;
817 }
818 }
819 return stop_lu_l;
820}
821
822/*! @brief Corrects the computed time step passed as parameter and verifies it is not "too" small (< dt_min_).
823 *
824 * The correction is:
825 * delta_t = min((security factor * dt_calc), dt_max)
826 * And verifies that delta_t is "sufficiently" larger than dt_min_.
827 *
828 * @param (double& dt_calc) the computed time step to verify
829 * @throws if the computed time step is less than dt_min
830 */
831bool Schema_Temps_base::corriger_dt_calcule(double& dt_calc) const
832{
833 // Print the RAM
834 if (limpr())
835 {
836 Cout << finl;
838 }
839
840 // proposed time step = stability time step (dt_stab) * security factor (facsec)
841 const double dt_propose = dt_stab_ * facsec_;
842
843 // Compute the time step dt as the minimal value between dt_max_ and proposed time step
844 double dt = std::min(dt_max_, dt_propose);
845
846 // if adapt_dt_tmax option is active ... cathare-style
847 bool adapt_dt_tmax = false;
848 if (adapt_dt_tmax_)
849 {
850 if (temps_courant_ + dt > tmax_)
851 {
852 dt = tmax_ - temps_courant_;
853 adapt_dt_tmax = true;
854 }
855 else if (temps_courant_ + 2. * dt > tmax_)
856 {
857 dt = 0.5 * (tmax_ - temps_courant_);
858 adapt_dt_tmax = true;
859 }
860 }
861
862 dt_calc = dt;
863
864 if ((dt - dt_min_) / (dt + DMINFLOAT) < -1.e-6 && !adapt_dt_tmax)
865 {
866 // Calculation stops if time step dt is less than dt_min
867 Cerr << "---------------------------------------------------------" << finl;
868 Cerr << "Problem with the time step " << dt << " which is less than dt_min " << dt_min_ << finl;
869 Cerr << "Lower dt_min value or check why the time step decreases..." << finl;
870 Cerr << "Results are saved to provide help." << finl;
871 Cerr << "---------------------------------------------------------" << finl;
872 Probleme_base& pb = ref_cast_non_const(Probleme_base, mon_probleme.valeur());
873 pb.postraiter(1);
874 pb.sauver();
876 }
877
878 return true;
879}
880
881
882/*! @brief Returns 1 if it is necessary to stop the computation for various reasons:
883 *
884 * - the final time has been reached
885 * - the maximum number of time steps has been exceeded
886 * - the steady state has been reached
887 * - file-based stop indicator (see int Schema_Temps_base::stop_lu())
888 * Returns 0 otherwise.
889 *
890 * @return (int) 1 if the computation should stop, 0 otherwise.
891 */
893{
895 {
896 Cerr << "---------------------------------------------------------"
897 << finl
898 << "The problem " << pb_base().le_nom()
899 << " wants to stop : final time reached"
900 << finl << finl;
901 return 1;
902 }
903
905 {
906 Cerr << "---------------------------------------------------------"
907 << finl
908 << "The problem " << pb_base().le_nom()
909 << " wants to stop : the maximum number of time steps reached"
910 << finl << finl;
911 return 1;
912 }
913
915 {
916 Cerr << "---------------------------------------------------------"
917 << finl
918 << "The problem " << pb_base().le_nom()
919 << " wants to stop : max cpu time reached"
920 << finl << finl;
921 return 1;
922 }
923
924 if (!get_disable_stop())
925 {
926 if (stop_lu())
927 {
928 Cerr << "---------------------------------------------------------"
929 << finl
930 << "The problem " << pb_base().le_nom()
931 << " wants to stop : stop file detected"
932 << finl << finl;
933 return 1;
934 }
935 }
936 return 0;
937}
938
939
941{
942 return mon_probleme.valeur();
943}
944
946{
947 return mon_probleme.valeur();
948}
949
950void Schema_Temps_base::ajouter_inertie(Matrice_Base& mat_morse,DoubleTab& secmem,const Equation_base& eqn) const
951{
952 // implementation for euler_implicite
953 double dt=pas_de_temps();
954 // We do not penalize the matrices and the right-hand sides even in the
955 // Dirichlet, symmetry cases
956 int pen=0;
957 eqn.solv_masse().ajouter_masse(dt,mat_morse,pen); //important order for PolyMAC_MPFA
958 const bool use_old_volumes = eqn.domaine_dis().domaine().deformable();
959 eqn.solv_masse().ajouter_masse(dt, secmem, eqn.inconnue().passe(), pen, use_old_volumes);
960}
961
962void Schema_Temps_base::ajouter_blocs(matrices_t matrices, DoubleTab& secmem, const Equation_base& eqn, const tabs_t& semi_impl) const
963{
964 eqn.solv_masse().ajouter_blocs(matrices, secmem, pas_de_temps(), semi_impl, 1);
965}
966
967/*! @brief Updates stationnaire_atteint_ and residu_ (criterion: residu_ < seuil_statio_).
968 *
969 * @param (double& t) the new current time
970 */
971void Schema_Temps_base::update_critere_statio(const DoubleTab& tab_critere, Equation_base& equation)
972{
973 DoubleVect& residu_equation = equation.get_residu();
974 // Depending on the size of the residu_equation array
975 // we take the max of tab_critere over the whole array or by column
976 int size = residu_equation.size_array();
977 if (size==0)
978 {
979 Cerr << "Error in Schema_Temps_base::update_critere_statio" << finl;
980 Cerr << "Array residu_equation has a null size" << finl;
981 for (int i=0; i<pb_base().nombre_d_equations(); i++)
982 if (pb_base().equation(i).get_residu().size_array()==0)
983 {
984 Cerr << "The equation of kind " << pb_base().equation(i).que_suis_je() << " didn't size the array." << finl;
985 Cerr << "Please, contact TRUST support." << finl;
986 exit();
987 }
988 }
989 else if (size==1)
990 {
991 if(norm_residu_ == "max")
992 residu_equation(0) = mp_max_abs_vect(tab_critere);
993 else if (norm_residu_ == "L2" || norm_residu_ == "l2")
994 residu_equation(0) = mp_norme_vect(tab_critere);
995 else
996 {
997 Cerr << "Schema_Temps_base::update_critere_statio : only norm max and norm L2 are allowed to compute residuals ("
998 << norm_residu_ << " not understood)" << finl;
1000 }
1001 }
1002 else
1003 {
1004 if(norm_residu_ == "max")
1005 mp_max_abs_tab(tab_critere, residu_equation);
1006 else if (norm_residu_ == "L2" || norm_residu_ == "l2")
1007 mp_norme_tab(tab_critere, residu_equation);
1008 else
1009 {
1010 Cerr << "Schema_Temps_base::update_critere_statio : only norm max and norm L2 are allowed to compute residuals ("
1011 << norm_residu_ << " not understood)" << finl;
1012 Process::exit();
1013 }
1014 }
1015 equation.set_residuals(tab_critere);
1016 // Compute residu_initial_equation over the first 5 time steps
1018 {
1019 DoubleVect& residu_initial_equation = equation.residu_initial();
1020 if (nb_pas_dt()<6)
1021 {
1022 for (int i=0; i<size; i++)
1023 residu_initial_equation(i) = residu_equation(i);
1024 // We no longer take the max since it can be large at the first time step:
1025 // residu_initial_equation(i) = std::max(residu_initial_equation(i), residu_equation(i));
1026 }
1027 // Normalize residu_equation by residu_initial_equation
1028 for (int i=0; i<size; i++)
1029 if (residu_initial_equation(i)>0)
1030 residu_equation(i) /= residu_initial_equation(i);
1031 }
1033 {
1034 const double max_var = mp_max_abs_vect(equation.inconnue().futur());
1035 const double min_var = mp_min_abs_vect(equation.inconnue().futur());
1036 residu_equation /= max_var - min_var + 1e-2;
1037 }
1038 if (!equation.disable_equation_residual())
1039 {
1040 //double equation_residual = mp_max_abs_vect(residu_equation);
1041 double equation_residual = local_max_abs_vect(residu_equation);
1042 residu_ = std::max(residu_, equation_residual);
1043 set_stationnaire_atteint() *= (equation_residual < seuil_statio_);
1044 }
1045}
1046
1047// Print the current time taking into account dt
1048// for the precision of the output (used in operators)
1050{
1051 int precision_actuelle=os.get_precision();
1052 int precision_temps;
1053 if (!est_egal(temps_courant(),0.))
1054 precision_temps=std::max( precision_actuelle, (int)(2+log10(1/std::fabs(pas_de_temps()))+(int)(log10(std::fabs(temps_courant())))) );
1055 else
1056 precision_temps=std::max( precision_actuelle, (int)(2+log10(1/std::fabs(pas_de_temps()))) );
1057 os.precision(precision_temps);
1058 os << temps_courant();
1059 os.precision(precision_actuelle);
1060}
1061
1062/*! @brief Writes the .progress file (estimated remaining CPU time).
1063 *
1064 */
1066{
1067 if (je_suis_maitre() && !disable_progress())
1068 {
1069 if (init)
1070 {
1071 if (!progress_.is_open())
1072 progress_.ouvrir(nom_du_cas() + ".progress");
1073 }
1074 else
1075 {
1076 if (schema_impr())
1077 {
1078 if ((residu_ > 0) && (residu_old_slope_ > 0))
1079 cumul_slope_ += (log(residu_) - log(residu_old_slope_)) / dt_;
1081 }
1082 if (schema_impr() && (nb_pas_dt() > 0 && pas_de_temps() > 0))
1083 {
1084 // Compute the average CPU time per time step; drawback: it can vary strongly over time in case of divergence or acceleration
1085 // But Statistiques does not allow retrieving the CPU time of the last time step (last_time called here would return the CPU time since the start of the time step)
1086 double nb_pas_selon_tmax = (temps_max() - temps_courant()) / pas_de_temps();
1087 double nb_pas_selon_nb_pas_dt_max = nb_pas_dt_max() - nb_pas_dt();
1088 double nb_pas_avant_fin = std::min(nb_pas_selon_tmax, nb_pas_selon_nb_pas_dt_max);
1089 //double seconds_to_finish = nb_pas_avant_fin * cpu_per_timestep;
1090 double dpercent = (1. - nb_pas_avant_fin /
1091 (nb_pas_avant_fin +
1092 nb_pas_dt())); // works even if it is tmax that limits
1093 // if the slope is >0 we are diverging ....
1094 if ((seuil_statio_ > 0) && (cumul_slope_ < -1e-20) &&
1096 residu_) // in a pb_couple one of the problems may have (seuil_statio_ > residu)
1097 {
1098 double distance = (-log(residu_ + 1e-20) + log(seuil_statio_)) / (cumul_slope_) * nb_pas_dt();
1099
1100 //Cerr<<distance<<" DDDDDD"<<finl;
1101 double dpercent2 = temps_courant() / (temps_courant() + distance);
1102 dpercent = std::max(dpercent, dpercent2);
1103 }
1104 int percent = int(dpercent * 100);
1105
1106 if (limpr())
1107 {
1108 double seconds_to_finish = statistics().get_time_since_last_open(STD_COUNTERS::total_execution_time) * (1. - dpercent) / dpercent;
1109 int integer_limit = (int) (pow(2.0, (double) ((sizeof(int) * 8) - 1)) - 1);
1110 if (seconds_to_finish < integer_limit)
1111 {
1112 int h = int(seconds_to_finish / 3600);
1113 int mn = int((seconds_to_finish - 3600 * h) / 60);
1114 int s = int(seconds_to_finish - 3600 * h - 60 * mn);
1115
1116 Cout << finl << "Estimated CPU time to finish the run (according to "
1117 << (nb_pas_selon_tmax < nb_pas_selon_nb_pas_dt_max ? "tmax" : "nb_pas_dt_max")
1118 << " value) : ";
1119 if (seconds_to_finish < 1)
1120 Cout << seconds_to_finish << " s";
1121 else
1122 Cout << h << "h" << mn << "mn" << s << "s";
1123
1124 Cout << ". Progress: " << (percent) << finl;
1125 }
1126 }
1128 progress_ << (percent) << finl;
1129 }
1130 }
1131 }
1132}
1133
1134/*! @brief Writes the .dt_ev file.
1135 *
1136 */
1137static SFichier dt_ev_;
1138static bool header_complete = false;
1139void open_dt_ev(IOS_OPEN_MODE mode)
1140{
1141 if (!dt_ev_.is_open())
1142 {
1143 Nom fichier(Objet_U::nom_du_cas() + ".dt_ev");
1144 dt_ev_.ouvrir(fichier, mode);
1145 dt_ev_.setf(ios::scientific);
1146 }
1147}
1149{
1150 if (je_suis_maitre() && !disable_dt_ev())
1151 {
1152 if (init)
1153 {
1154 Nom fichier(nom_du_cas() + ".dt_ev");
1155 struct stat f;
1156 // Initialize the .dt_ev file if it does not exist or if this is a fresh computation without restart
1157 if ((nb_pas_dt_ == 0) && ((stat(fichier, &f)) || !(pb_base().reprise_effectuee() == 1)))
1158 {
1159 if (schema_impr())
1160 {
1161 open_dt_ev(ios::out);
1162 dt_ev_ << "# temps\t\t dt\t\t facsec\t\t residu=max|Ri|\t dt_stab\t ";
1163 }
1164 open_dt_ev(ios::app);
1165 for (int i = 0; i < pb_base().nombre_d_equations(); i++)
1166 dt_ev_ << pb_base().equation(i).expression_residu();
1167 }
1168 else
1169 {
1170 if (schema_impr())
1171 open_dt_ev(ios::app);
1172 }
1173 }
1174 else
1175 {
1176 open_dt_ev(ios::app);
1177 if (schema_impr())
1178 {
1179 dt_ev_ << finl << temps_courant_ << "\t " << dt_ << "\t " << facsec_ << "\t " << residu_ << "\t "
1180 << dt_stab_ << "\t ";
1181 header_complete = true;
1182 }
1183 for (int i = 0; i < pb_base().nombre_d_equations(); i++)
1184 pb_base().equation(i).imprime_residu(dt_ev_);
1185 }
1186 }
1187}
1188
1189/*! @brief Closes the .dt_ev file.
1190 *
1191 */
1193{
1194 if (je_suis_maitre() && dt_ev_.is_open())
1195 {
1196 if (header_complete) dt_ev_ << finl;
1197 dt_ev_.close();
1198 header_complete = false;
1199 }
1200}
DoubleTab & futur(int i=1) override
Returns field values at instant t+i.
DoubleTab & passe(int i=1) override
Returns field values at instant t-i.
DoubleTab & valeurs() override
Returns the array of field values at the current time.
bool deformable() const
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
class Equation_base The role of an equation is the calculation of one or more fields....
virtual int equation_non_resolue() const
void set_residuals(const DoubleTab &residual)
Solveur_Masse_base & solv_masse()
Returns the mass solver associated with the equation.
virtual const Champ_Inc_base & inconnue() const =0
DoubleVect & get_residu()
virtual void abortTimeStep()
Reinitialize what must be.
virtual void imprime_residu(SFichier &)
virtual DoubleTab & derivee_en_temps_inco(DoubleTab &)
Returns the time derivative of the unknown I of the equation: dI/dt = M-1*(sum(operators(I) + sources...
DoubleVect & residu_initial()
Schema_Temps_base & schema_temps()
Returns the time scheme associated with the equation.
int disable_equation_residual() const
Domaine_dis_base & domaine_dis()
Returns the discretized domain associated with the equation.
virtual Nom expression_residu()
This class implements the operators and virtual methods of the EFichier class as follows: The file to...
Matrice_Base class - Base class of the matrix hierarchy.
A character string (Nom) in uppercase.
Definition Motcle.h:26
An array of Motcle objects.
Definition Motcle.h:63
int search(const Motcle &t) const
Definition Motcle.cpp:319
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
Base class for TRUST objects (Objet_U).
Definition Objet_U.h:68
friend class Entree
Definition Objet_U.h:71
friend class Sortie
Definition Objet_U.h:70
const Nom & que_suis_je() const
Returns the string identifying the class.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
static const Nom & nom_du_cas()
Returns a constant reference to the case name. This method is static.
Definition Objet_U.cpp:145
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
Helper class to factorize the readOn method of Objet_U classes.
Definition Param.h:112
void ajouter_flag(const char *keyword, const bool *value)
Register a boolean flag whose mere presence switches it to true.
Definition Param.cpp:474
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
Definition Param.cpp:364
void ajouter_non_std(const char *keyword, const Objet_U *value, Param::Nature nat=Param::OPTIONAL)
Register a keyword handled by Objet_U::lire_motcle_non_standard.
Definition Param.cpp:489
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
Definition Probleme_U.h:109
class Probleme_base It is a Probleme_U that is not a coupling.
int postraiter(int force=1) override
If force=1, performs post-processing regardless of the post-processing frequencies.
void sauver() const override
Writes to file for restart (backup).
virtual double calculer_pas_de_temps() const
Computes the value of the next time step for the problem.
virtual void mettre_a_jour(double temps)
Performs a time update of the problem.
const Schema_Temps_base & schema_temps() const
Returns the time scheme associated with the problem.
virtual int nombre_d_equations() const =0
virtual const Equation_base & equation(int) const =0
static int node_master()
Returns 1 if on the NUMA node master processor, 0 otherwise.
Definition Process.cpp:92
static void imprimer_ram_totale(int all_process=0)
Definition Process.cpp:655
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
static int je_suis_maitre()
Returns 1 if on the master processor of the current group (i.e. me() == 0), 0 otherwise.
Definition Process.cpp:82
SFichier is to the C++ ofstream class what Sortie is to the C++ ostream class.
Definition SFichier.h:29
class Schema_Temps_base
int seuil_statio_relatif_deconseille_
Flag to specify whether seuil_statio_ is an absolute (default) or relative value.
virtual Entree & lire_periode_sauvegarde_securite_en_heures(Entree &)
int precision_impr_
Number of significant digits for output.
int limpr() const
Returns 1 if there is a need to perform a print (cf dt_impr) Returns 0 otherwise.
virtual double computeTimeStep(bool &stop) const
virtual bool isStationary() const
Returns 1 if during the last time step, the problem has not evolved.
double temps_courant() const
Returns the current time.
virtual void resetTime(double time)
Nom dt_max_str_
setting of dt_max as a function of time
virtual bool corriger_dt_calcule(double &dt) const
Corrects the computed time step passed as parameter and verifies it is not "too" small (< dt_min_).
int sauvegarder(Sortie &) const override
Saves the current time and the number of time steps to an output stream.
int nb_pas_dt_max_atteint() const
Returns 1 if (the number of time steps >= maximum number of time steps).
Parser_U dt_max_fn_
Associated Parser_U.
virtual void set_param(Param &titi) const override
int nb_sauv_
how many checkpoints have we performed so far?
double dt_
Computation time step.
virtual void ajouter_inertie(Matrice_Base &mat_morse, DoubleTab &secmem, const Equation_base &eqn) const
bool disable_progress() const
double dt_failed_
Value of a time step if it failed.
virtual void associer_pb(const Probleme_base &)
void write_dt_ev(bool init)
double temps_max() const
Returns a reference to the maximum time.
double dt_max_
Maximum time step set by the user.
double mode_dt_start_
Mode for computing the initial time step - contains a double if dt_init option is used.
virtual void abortTimeStep()
double periode_cpu_sans_sauvegarde_
Default 23 hours;.
double limite_cpu_sans_sauvegarde_
Default 23 hours;.
int temps_final_atteint() const
Returns 1 if the final time has been reached (or exceeded).
virtual int stop() const
Returns 1 if it is necessary to stop the computation for various reasons:
Probleme_base & pb_base()
bool disable_dt_ev() const
virtual void validateTimeStep()
void imprimer_temps_courant(SFichier &) const
int lire_motcle_non_standard(const Motcle &, Entree &) override
Reads non-simple-type parameters of an Objet_U from an input stream.
virtual int impr(Sortie &os) const
Prints the time step number, the time step value, and the current time.
int niter_max_diff_impl_
Maximum iterations for CG diffusion implicitation - Above 1000 iterations, diffusion implicit algorit...
virtual void ajouter_blocs(matrices_t matrices, DoubleTab &secmem, const Equation_base &eqn, const tabs_t &semi_impl={}) const
double pas_de_temps() const
Returns the current time step (delta_t).
virtual void imprimer(Sortie &os) const
Prints the time step to an output stream if appropriate.
virtual void initialize()
virtual bool initTimeStep(double dt)
virtual Entree & lire_residuals(Entree &)
int nb_sauv_max_
Max number of checkpoints that will be performed (useful for PDI backup file).
virtual int faire_un_pas_de_temps_eqn_base(Equation_base &)=0
int nb_pas_dt() const
Returns the number of time steps performed.
double dt_impr_
Output time interval.
int stop_lu() const
Returns 1 if the .stop file contains a 1, returns 0 otherwise.
double dt_min_
Minimum time step set by the user.
int reprendre(Entree &) override
Restarts (reads) the current time and the number of time steps performed from an input stream.
virtual bool iterateTimeStep(bool &converged)
Calculate the U(n+1) unknown for each equation (if solved) of the problem with the selected time sche...
virtual int mettre_a_jour()
Updates the current time (t+=dt) and the number of time steps performed (nb_pas_dt_++).
double dt_stab_
Stability time step.
virtual Entree & lire_temps_cpu_max(Entree &)
virtual void mettre_a_jour_dt_stab()
int temps_cpu_max_atteint() const
virtual Entree & lire_nb_pas_dt_max(Entree &)
Reads the maximum number of time steps.
int nb_pas_dt_max() const
Returns a reference to the maximum number of time steps.
double seuil_diff_impl_
Threshold for implicit treatment of diffusion by CG.
void update_critere_statio(const DoubleTab &tab_critere, Equation_base &equation)
Updates stationnaire_atteint_ and residu_ (criterion: residu_ < seuil_statio_).
void write_progress(bool init)
Writes the .progress file (estimated remaining CPU time).
void finir() const
Closes the .dt_ev file.
virtual Matrice_Base & ajouter_masse(double dt, Matrice_Base &matrice, int penalisation=1) const
virtual void ajouter_blocs(matrices_t matrices, DoubleTab &secmem, double dt, const tabs_t &semi_impl, int resoudre_en_increments) const
void precision(int pre) override
Base class for output streams.
Definition Sortie.h:52
_SIZE_ size_array() const
TRUST_2_PDI Encapsulation of PDI methods (library used for IO operations). See the website pdi....
Definition TRUST_2_PDI.h:59
void stop_sharing_last_variable()
static int is_PDI_checkpoint()
void TRUST_start_sharing(const std::string &name, const void *data)
void trigger(const std::string &event)
static int nb_pas_dt_