TrioCFD 1.9.8
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> // necessaire pour 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 Constructeur par defaut d'un schema en temps.
48 *
49 * Initialise differents membres de la classe.
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 je remets le calculer_pas_de_temps car des schemas en temps implicites s'en servent pour dimensionner (en particulier ovap)
64 // je le mets une deuxieme fois pour alternant....
66
67 // Ecritures:
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 //On divise par facsec_ car multiplication par facsec_ dans corriger_dt_calcule()
75 //quel que soit le mode d initialisation de dt_
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 //reevaluation de dt_max_ si fonction du temps
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 // Correction en premier du pas de temps
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)); //pour provoquer une baisse de dt en cas d'echec a la resolution precedente
106 dt = std::min(dt, (temps_courant_ - temps_precedent_) * dt_gf_); //pour ne pas remonter dt trop vite (comme 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 // Mise a jour immediate de l'attribut dt_ afin que pas_de_temps()
126 // soit a jour tout le temps (en particulier au moment du postraitement)
127 // Ce n'etait pas le cas pour les versions <= 1.6.3 et les champs dependant
128 // de dt n'etaient pas juste si 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 // On calcule une fois la derivee pour avoir les flux bord
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 Renvoie 1 s'il y a lieu d'effectuer une impression (cf dt_impr) Renvoie 0 sinon
182 *
183 * @return (int) 1 si il y lieu d'effectuer une impression 0 sinon
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 : On utilise desormais la fonction "modf(operation , & partie entiere)" de math.h
199 // Cette fonction decompose le resultat de "operation" en une partie entiere et une partie decimale.
200 // Ainsi, on ne transforme plus un double en int avec tout les risques que cela comporte.
201 // ex : modf(9/7,&i) donne 1.000000 pour la partie entiere et 0.285714 pour le partie decimale
202 //
203 // epsilon permet d'assurer que le resultat de l'operation est independant de la precision machine :
204 // ex : 0.99999999/1.00000000 peut donner 0.99999999 ou 1.00000000 suivant les machines
205 // alors que
206 // ex : 0.99999999/1.00000000 + 1.e-8 donne tjrs 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 // Ecritures
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 Retourne 1 si lors du dernier pas de temps, le probleme n'a pas evolue.
237 *
238 * @param (temps) le temps a atteindre
239 * @return (1 si le probleme n'a pas evolue, 0 sinon.)
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 Surcharge Objet_U::printOn(Sortie&) Imprime le schema en temps sur un flot de sortie.
371 *
372 * !! Attention n'est pas symetrique de la lecture !!
373 * On ecrit les differents parametres du schema en temps.
374 *
375 * @param (Sortie& os) le flot de sortie
376 * @return (Sortie&) le flot de sortie modifie
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 Lecture d'un schema en temps a partir d'un flot d'entree.
414 *
415 * Le format de lecture attendu est le suivant:
416 * {
417 * [Motcle valeur_reelle]
418 * }
419 * Les mots clefs peuvent etre:
420 * tinit, tmax, nb_pas_dt_max, dt_min, dt_max,
421 * dt_sauv, dt_impr, facsec, seuil_statio,
422 *
423 * @param (Entree& is) le flot d'entree
424 * @return (Entree&) le flot d'entree modifie
425 * @throws accolade ouvrante attendue
426 * @throws motclef inconnu a cet endroit
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 Lecture du nombre de pas de temps maximal
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 en secondes
529 return is;
530}
531
533{
534 Cerr << "Reading the max cpu time allowed" << finl;
535 is >> tcpumax_;
536 tcpumax_*=3600; // Conversion en secondes
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 Impression du numero du pas de temps, la valeur du pas de temps.
575 *
576 * et du temps courant.
577 *
578 * @param (Sortie& os) le flot de sortie
579 * @return (int) renvoie toujours 0
580 */
582{
583 os << finl;
584 os << "-------------------------------------------------------------------" << finl;
585 os << "We finished treating the time step number "<< nb_pas_dt_ << " , for the time scheme ..." << finl
586 << " stable dt used = " << dt_ << finl /* dt_stab_ peut etre ? c'est pareil je pense */
587 << " time achieved (in seconds) = " << temps_courant_ << finl;
588 return 0;
589}
590
591/*! @brief Impression du numero du pas de temps, la valeur du pas de temps.
592 *
593 * et du temps courant.
594 *
595 * @param (Sortie& os) le flot de sortie
596 * @return (int) renvoie toujours 0
597 */
599{
600 os << finl;
601 os << " Problem : " << pb.le_nom() << finl;
602 os << "We treat the time step number "<< nb_pas_dt_ << finl;
603 os << " dt = " << dt_ << finl;
604 os << " time = " << temps_courant_ << finl;
605 os << " time scheme : " << pb.schema_temps() << finl;
606 return 0;
607}
609{
610 os << finl;
611 os << " Problem : " << pb.le_nom() << finl;
612 os << "We treat the time step number "<< nb_pas_dt_ << finl;
613 os << " dt = " << dt_ << finl;
614 os << " time = " << temps_courant_ << finl;
615 os << " time scheme : " << pb.schema_temps() << finl;
616 return 0;
617}
618
619extern "C" {
620 int ccc_tremain(double*);
621}
622/*! @brief Mise a jour du temps courant (t+=dt) et du nombre de pas de temps effectue (nb_pas_dt_++).
623 *
624 * @return (int) retourne toujours 1
625 */
627{
630 nb_pas_dt_++;
631 // Compute next time step stability:
632 statistics().end_count(STD_COUNTERS::update_variables,0,0);
634 statistics().begin_count(STD_COUNTERS::update_variables,statistics().get_last_opened_counter_level()+1);
635 assert_parallel(dt_stab_);
636 assert_parallel(temps_courant_);
639
642
645
646 // On incremente limite_cpu_sans_sauvegarde_
648 {
650 //Finalement, on double la limite, ainsi par defaut sauvegarde de securite 10h, 20h, 40h, 80h, 160h,....
651 //limite_cpu_sans_sauvegarde_ = 2 * limite_cpu_sans_sauvegarde_;
652 if (dt_sauv_ <= 0.)
653 Cerr << "NO next backup, by security, because dt_sauv = " << dt_sauv_ << finl;
654 else
655 Cerr << "The next backup, by security, will take place after " << limite_cpu_sans_sauvegarde_/3600 << " hours of calculation." << finl;
656 }
657// GF pour etre sur que tous les proc aient le meme temps ecoule
658 if (je_suis_maitre())
659 {
660 temps_cpu_ecoule_ = statistics().get_time_since_last_open(STD_COUNTERS::total_execution_time);
661 }
662
663 envoyer_broadcast(temps_cpu_ecoule_,0);
664
665
666#ifdef LIBCCC_USER
667 if (je_suis_maitre() && limpr())
668 {
669 Cout << "[CCRT] ";
670 double second_remain;
671 int error = ccc_tremain(&second_remain);
672 if(!error)
673 {
674 int hour_remain = (int)(second_remain/3600);
675 second_remain-=hour_remain*3600;
676 int minute_remain = (int)(second_remain/60);
677 second_remain-=minute_remain*60;
678 Cout << hour_remain <<"h"<<minute_remain<<"mn"<<second_remain<<"s before job is killed on CCRT." << finl;
679 }
680 else
681 Cout << "Error." << finl;
682 }
683#endif
684 return 1;
685}
686// Fait une sauvegarde de protection sur des runs de 24h sur machines du CCRT
688{
689 if (dt_sauv_ <= 0.)
690 return 0;
691 else
692 {
694 {
695 Cerr << "After these " << limite_cpu_sans_sauvegarde_/3600 << " hours of calculation, a backup will be made by security." << finl;
696 return 1;
697 }
698 else
699 {
700 if (dt_sauv_<=dt_)
701 return 1;
702 else if (tmax_<=temps_courant_ || nb_pas_dt_max_<=nb_pas_dt_ || stationnaires_atteints_ || ind_temps_cpu_max_atteint || stop_lu())
703 return 1;
704 else
705 {
706 // Voir Schema_Temps_base::limpr pour information sur epsilon et modf
707 double i, j, epsilon = 1.e-8;
708 modf(temps_courant_/dt_sauv_ + epsilon, &i);
709 modf(temps_precedent_/dt_sauv_ + epsilon, &j);
710 return ( i>j ) ;
711 }
712 }
713 }
714}
715
722/*! @brief Imprime le pas de temps sur un flot de sortie s'il y a lieu.
723 *
724 * @param (Sortie& os) le flot de sortie
725 */
727{
728 if (limpr())
729 {
730 nb_impr_++;
731 if (je_suis_maitre() && schema_impr())
732 {
733 impr(os);
734 }
735 }
736}
737
738/*! @brief Imprime le pas de temps sur un flot de sortie s'il y a lieu.
739 *
740 * @param (Sortie& os) le flot de sortie
741 */
743{
744 if (limpr() && je_suis_maitre())
745 impr(os,pb);
746}
748{
749 if (limpr() && je_suis_maitre())
750 impr(os,pb);
751}
752
753/*! @brief Sauvegarde le temps courant et le nombre de pas de temps sur un flot de sortie.
754 *
755 * @param (Sortie& os) le flot de sortie pour la sauvegarde
756 */
758{
759 int bytes = 0;
761 {
762 int simple_checkpoint = ref_cast_non_const(Probleme_base, mon_probleme.valeur()).is_sauvegarde_simple();
763 int i = 0;
764 int i_max = 1;
765 if(!simple_checkpoint)
766 {
768 Cerr << "WARNING ! Overwriting the first " << nb_sauv_max_ << " backups..." << finl;
770 i_max = nb_sauv_max_;
771 }
772 TRUST_2_PDI pdi_interface;
773 pdi_interface.TRUST_start_sharing("iter", &i);
774 pdi_interface.TRUST_start_sharing("nb_iter_max", &i_max);
775 pdi_interface.TRUST_start_sharing("temps", &temps_courant_);
777 pdi_interface.trigger("time_scheme");
778 pdi_interface.stop_sharing_last_variable(); //temps
779 pdi_interface.stop_sharing_last_variable(); //nb_iter_max
780 pdi_interface.stop_sharing_last_variable(); //iter
781
782 bytes = 8+4; // one double and one int
783 }
784 nb_sauv_++;
785 return bytes;
786}
787
788/*! @brief Reprise (lecture) du temps courant et du nombre de pas de temps effectues a partir d'un flot d'entree.
789 *
790 * @param (Entree& is) le flot d'entree
791 * @return (int) renvoie toujours 1
792 */
794{
795 return 1;
796}
797
798/*! @brief Renvoie 1 si le fichier (d'extension) .
799 *
800 * stop contient un 1 Renvoie 0 sinon
801 *
802 * @return (int) 1 si le fichier (d'extension) .stop contient 1, 0 sinon
803 */
805{
806 int stop_lu_l = 0;
807 if (!get_disable_stop())
808 {
809 Nom nomfic(nom_du_cas());
810 nomfic += ".stop";
811 if (nb_pas_dt_ < 1)
812 {
813 if (je_suis_maitre())
814 {
815 SFichier ficstop(nomfic);
816 ficstop << stop_lu_l;
817 }
818 }
819 else
820 {
821 LecFicDiffuse ficstop(nomfic);
822 ficstop >> stop_lu_l;
823 }
824 }
825 return stop_lu_l;
826}
827
828/*! @brief Corrige le pas de temps calcule que l'on passe en parametre et verifie qu'il n'est pas "trop" petit (< dt-min_).
829 *
830 * La correction est la suivante:
831 * delta_t = min((facteur de securite * dt_calc), dt_max)
832 * Et on verifie que delta_t est "suffisamment" plus grand que dt_min_.
833 *
834 * @param (double& dt_calc) le pas de temps calcule a verifier
835 * @throws le pas de temps calcule est inferieur a dt_min
836 */
837bool Schema_Temps_base::corriger_dt_calcule(double& dt_calc) const
838{
839 // Print the RAM
840 if (limpr())
841 {
842 Cout << finl;
844 }
845
846 // proposed time step = stability time step (dt_stab) * security factor (facsec)
847 const double dt_propose = dt_stab_ * facsec_;
848
849 // Compute the time step dt as the minimal value between dt_max_ and proposed time step
850 double dt = std::min(dt_max_, dt_propose);
851
852 // si option adapt_dt_tmax active ... a la cathare
853 bool adapt_dt_tmax = false;
854 if (adapt_dt_tmax_)
855 {
856 if (temps_courant_ + dt > tmax_)
857 {
858 dt = tmax_ - temps_courant_;
859 adapt_dt_tmax = true;
860 }
861 else if (temps_courant_ + 2. * dt > tmax_)
862 {
863 dt = 0.5 * (tmax_ - temps_courant_);
864 adapt_dt_tmax = true;
865 }
866 }
867
868 dt_calc = dt;
869
870 if ((dt - dt_min_) / (dt + DMINFLOAT) < -1.e-6 && !adapt_dt_tmax)
871 {
872 // Calculation stops if time step dt is less than dt_min
873 Cerr << "---------------------------------------------------------" << finl;
874 Cerr << "Problem with the time step " << dt << " which is less than dt_min " << dt_min_ << finl;
875 Cerr << "Lower dt_min value or check why the time step decreases..." << finl;
876 Cerr << "Results are saved to provide help." << finl;
877 Cerr << "---------------------------------------------------------" << finl;
878 Probleme_base& pb = ref_cast_non_const(Probleme_base, mon_probleme.valeur());
879 pb.postraiter(1);
880 pb.sauver();
882 }
883
884 return true;
885}
886
887
888/*! @brief Renvoie 1 si il y lieu de stopper le calcul pour differente raisons: - le temps final est atteint
889 *
890 * - le nombre de pas de temps maximum est depasse
891 * - l'etat stationnaire est atteint
892 * - indicateur d'arret fichier (voir int Schema_Temps_base::stop_lu())
893 * Renvoie 0 sinon
894 *
895 * @return (int) 1 si il y a lieu de stopper le calcul 0 sinon.
896 */
898{
900 {
901 Cerr << "---------------------------------------------------------"
902 << finl
903 << "The problem " << pb_base().le_nom()
904 << " wants to stop : final time reached"
905 << finl << finl;
906 return 1;
907 }
908
910 {
911 Cerr << "---------------------------------------------------------"
912 << finl
913 << "The problem " << pb_base().le_nom()
914 << " wants to stop : the maximum number of time steps reached"
915 << finl << finl;
916 return 1;
917 }
918
920 {
921 Cerr << "---------------------------------------------------------"
922 << finl
923 << "The problem " << pb_base().le_nom()
924 << " wants to stop : max cpu time reached"
925 << finl << finl;
926 return 1;
927 }
928
929 if (!get_disable_stop())
930 {
931 if (stop_lu())
932 {
933 Cerr << "---------------------------------------------------------"
934 << finl
935 << "The problem " << pb_base().le_nom()
936 << " wants to stop : stop file detected"
937 << finl << finl;
938 return 1;
939 }
940 }
941 return 0;
942}
943
944
946{
947 return mon_probleme.valeur();
948}
949
951{
952 return mon_probleme.valeur();
953}
954
955void Schema_Temps_base::ajouter_inertie(Matrice_Base& mat_morse,DoubleTab& secmem,const Equation_base& eqn) const
956{
957 // codage pour euler_implicite
958 double dt=pas_de_temps();
959 // On ne penalise pas les matrices et les secmems meme dans les cas
960 // dirichlet , symetrie
961 int pen=0;
962 eqn.solv_masse().ajouter_masse(dt,mat_morse,pen); //ordre important pour PolyMAC_MPFA
963 const bool use_old_volumes = eqn.domaine_dis().domaine().deformable();
964 eqn.solv_masse().ajouter_masse(dt, secmem, eqn.inconnue().passe(), pen, use_old_volumes);
965}
966
967void Schema_Temps_base::ajouter_blocs(matrices_t matrices, DoubleTab& secmem, const Equation_base& eqn, const tabs_t& semi_impl) const
968{
969 eqn.solv_masse().ajouter_blocs(matrices, secmem, pas_de_temps(), semi_impl, 1);
970}
971
972/*! @brief //Actualisation de stationnaire_atteint_ et residu_ (critere residu_<seuil_statio_)
973 *
974 * @param (double& t) le nouveau temps courant
975 */
976void Schema_Temps_base::update_critere_statio(const DoubleTab& tab_critere, Equation_base& equation)
977{
978 DoubleVect& residu_equation = equation.get_residu();
979 // En fonction de la taille du tableau residu_equation
980 // on prend le max de tab_critere sur tout le tableau ou par colonne
981 int size = residu_equation.size_array();
982 if (size==0)
983 {
984 Cerr << "Error in Schema_Temps_base::update_critere_statio" << finl;
985 Cerr << "Array residu_equation has a null size" << finl;
986 for (int i=0; i<pb_base().nombre_d_equations(); i++)
987 if (pb_base().equation(i).get_residu().size_array()==0)
988 {
989 Cerr << "The equation of kind " << pb_base().equation(i).que_suis_je() << " didn't size the array." << finl;
990 Cerr << "Please, contact TRUST support." << finl;
991 exit();
992 }
993 }
994 else if (size==1)
995 {
996 if(norm_residu_ == "max")
997 residu_equation(0) = mp_max_abs_vect(tab_critere);
998 else if (norm_residu_ == "L2" || norm_residu_ == "l2")
999 residu_equation(0) = mp_norme_vect(tab_critere);
1000 else
1001 {
1002 Cerr << "Schema_Temps_base::update_critere_statio : only norm max and norm L2 are allowed to compute residuals ("
1003 << norm_residu_ << " not understood)" << finl;
1004 Process::exit();
1005 }
1006 }
1007 else
1008 {
1009 if(norm_residu_ == "max")
1010 mp_max_abs_tab(tab_critere, residu_equation);
1011 else if (norm_residu_ == "L2" || norm_residu_ == "l2")
1012 mp_norme_tab(tab_critere, residu_equation);
1013 else
1014 {
1015 Cerr << "Schema_Temps_base::update_critere_statio : only norm max and norm L2 are allowed to compute residuals ("
1016 << norm_residu_ << " not understood)" << finl;
1017 Process::exit();
1018 }
1019 }
1020 equation.set_residuals(tab_critere);
1021 // On calcule le residu_initial_equation sur les 5 premiers pas de temps
1023 {
1024 DoubleVect& residu_initial_equation = equation.residu_initial();
1025 if (nb_pas_dt()<6)
1026 {
1027 for (int i=0; i<size; i++)
1028 residu_initial_equation(i) = residu_equation(i);
1029 // On ne prend plus le max car celui ci est parfois grand au premier pas de temps:
1030 // residu_initial_equation(i) = std::max(residu_initial_equation(i), residu_equation(i));
1031 }
1032 // On normalise residu_equation par residu_initial_equation
1033 for (int i=0; i<size; i++)
1034 if (residu_initial_equation(i)>0)
1035 residu_equation(i) /= residu_initial_equation(i);
1036 }
1038 {
1039 const double max_var = mp_max_abs_vect(equation.inconnue().futur());
1040 const double min_var = mp_min_abs_vect(equation.inconnue().futur());
1041 residu_equation /= max_var - min_var + 1e-2;
1042 }
1043 if (!equation.disable_equation_residual())
1044 {
1045 //double equation_residual = mp_max_abs_vect(residu_equation);
1046 double equation_residual = local_max_abs_vect(residu_equation);
1047 residu_ = std::max(residu_, equation_residual);
1048 set_stationnaire_atteint() *= (equation_residual < seuil_statio_);
1049 }
1050}
1051
1052// Impression du temps courant en tenant compte du dt
1053// pour la precision de l'impression (utilise dans les operateurs)
1055{
1056 int precision_actuelle=os.get_precision();
1057 int precision_temps;
1058 if (!est_egal(temps_courant(),0.))
1059 precision_temps=std::max( precision_actuelle, (int)(2+log10(1/std::fabs(pas_de_temps()))+(int)(log10(std::fabs(temps_courant())))) );
1060 else
1061 precision_temps=std::max( precision_actuelle, (int)(2+log10(1/std::fabs(pas_de_temps()))) );
1062 os.precision(precision_temps);
1063 os << temps_courant();
1064 os.precision(precision_actuelle);
1065}
1066
1067/*! @brief Ecriture du fichier .progress (temps CPU estime restant)
1068 *
1069 */
1071{
1072 if (je_suis_maitre() && !disable_progress())
1073 {
1074 if (init)
1075 {
1076 if (!progress_.is_open())
1077 progress_.ouvrir(nom_du_cas() + ".progress");
1078 }
1079 else
1080 {
1081 if (schema_impr())
1082 {
1083 if ((residu_ > 0) && (residu_old_slope_ > 0))
1084 cumul_slope_ += (log(residu_) - log(residu_old_slope_)) / dt_;
1086 }
1087 if (schema_impr() && (nb_pas_dt() > 0 && pas_de_temps() > 0))
1088 {
1089 // On calcule le temps CPU moyen par pas de temps, inconvenient il peut varier fortement au cours du temps si divergence du calcul ou au contraire acceleration
1090 // Mais Statistiques ne permet pas d'avoir le temps CPU du dernier pas de temps (last_time appele ici renverrait le temps CPU depuis le debut du pas de temps)
1091 double nb_pas_selon_tmax = (temps_max() - temps_courant()) / pas_de_temps();
1092 double nb_pas_selon_nb_pas_dt_max = nb_pas_dt_max() - nb_pas_dt();
1093 double nb_pas_avant_fin = std::min(nb_pas_selon_tmax, nb_pas_selon_nb_pas_dt_max);
1094 //double seconds_to_finish = nb_pas_avant_fin * cpu_per_timestep;
1095 double dpercent = (1. - nb_pas_avant_fin /
1096 (nb_pas_avant_fin +
1097 nb_pas_dt())); // marche meme si c'est ltemps max qui limite
1098 // si la pente est >0 on diverge ....
1099 if ((seuil_statio_ > 0) && (cumul_slope_ < -1e-20) &&
1101 residu_) // dans un pb_couple on peut avoir (seuil_statio_ > residu) pour un des problemes
1102 {
1103 double distance = (-log(residu_ + 1e-20) + log(seuil_statio_)) / (cumul_slope_) * nb_pas_dt();
1104
1105 //Cerr<<distance<<" DDDDDD"<<finl;
1106 double dpercent2 = temps_courant() / (temps_courant() + distance);
1107 dpercent = std::max(dpercent, dpercent2);
1108 }
1109 int percent = int(dpercent * 100);
1110
1111 if (limpr())
1112 {
1113 double seconds_to_finish = statistics().get_time_since_last_open(STD_COUNTERS::total_execution_time) * (1. - dpercent) / dpercent;
1114 int integer_limit = (int) (pow(2.0, (double) ((sizeof(int) * 8) - 1)) - 1);
1115 if (seconds_to_finish < integer_limit)
1116 {
1117 int h = int(seconds_to_finish / 3600);
1118 int mn = int((seconds_to_finish - 3600 * h) / 60);
1119 int s = int(seconds_to_finish - 3600 * h - 60 * mn);
1120 Cout << finl << "Estimated CPU time to finish the run (according to "
1121 << (nb_pas_selon_tmax < nb_pas_selon_nb_pas_dt_max ? "tmax" : "nb_pas_dt_max")
1122 << " value) : ";
1123 if (seconds_to_finish < 1)
1124 Cout << seconds_to_finish << " s";
1125 else
1126 Cout << h << "h" << mn << "mn" << s << "s";
1127
1128 Cout << ". Progress: " << (percent) << finl;
1129 }
1130 }
1132 progress_ << (percent) << finl;
1133 }
1134 }
1135 }
1136}
1137
1138/*! @brief Ecriture du fichier .dt_ev
1139 *
1140 */
1141static SFichier dt_ev_;
1142static bool header_complete = false;
1143void open_dt_ev(IOS_OPEN_MODE mode)
1144{
1145 if (!dt_ev_.is_open())
1146 {
1147 Nom fichier(Objet_U::nom_du_cas() + ".dt_ev");
1148 dt_ev_.ouvrir(fichier, mode);
1149 dt_ev_.setf(ios::scientific);
1150 }
1151}
1153{
1154 if (je_suis_maitre() && !disable_dt_ev())
1155 {
1156 if (init)
1157 {
1158 Nom fichier(nom_du_cas() + ".dt_ev");
1159 struct stat f;
1160 // On initialise le fichier .dt_ev s'il n'existe pas ou si c'est un demarrage de calcul sans reprise
1161 if ((nb_pas_dt_ == 0) && ((stat(fichier, &f)) || !(pb_base().reprise_effectuee() == 1)))
1162 {
1163 if (schema_impr())
1164 {
1165 open_dt_ev(ios::out);
1166 dt_ev_ << "# temps\t\t dt\t\t facsec\t\t residu=max|Ri|\t dt_stab\t ";
1167 }
1168 open_dt_ev(ios::app);
1169 for (int i = 0; i < pb_base().nombre_d_equations(); i++)
1170 dt_ev_ << pb_base().equation(i).expression_residu();
1171 }
1172 else
1173 {
1174 if (schema_impr())
1175 open_dt_ev(ios::app);
1176 }
1177 }
1178 else
1179 {
1180 open_dt_ev(ios::app);
1181 if (schema_impr())
1182 {
1183 dt_ev_ << finl << temps_courant_ << "\t " << dt_ << "\t " << facsec_ << "\t " << residu_ << "\t "
1184 << dt_stab_ << "\t ";
1185 header_complete = true;
1186 }
1187 for (int i = 0; i < pb_base().nombre_d_equations(); i++)
1188 pb_base().equation(i).imprime_residu(dt_ev_);
1189 }
1190 }
1191}
1192
1193/*! @brief Fermeture du fichier .dt_ev
1194 *
1195 */
1197{
1198 if (je_suis_maitre() && dt_ev_.is_open())
1199 {
1200 if (header_complete) dt_ev_ << finl;
1201 dt_ev_.close();
1202 header_complete = false;
1203 }
1204}
DoubleTab & futur(int i=1) override
Renvoie les valeurs du champs a l'instant t+i.
DoubleTab & passe(int i=1) override
Renvoie les valeurs du champs a l'instant t-i.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
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
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
virtual int equation_non_resolue() const
void set_residuals(const DoubleTab &residual)
Solveur_Masse_base & solv_masse()
Renvoie le solveur de masse associe a l'equation.
virtual const Champ_Inc_base & inconnue() const =0
DoubleVect & get_residu()
virtual void abortTimeStep()
Reinitialiser ce qui doit l'etre.
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()
Renvoie le schema en temps associe a l'equation.
int disable_equation_residual() const
Domaine_dis_base & domaine_dis()
Renvoie le domaine discretise associe a l'equation.
virtual Nom expression_residu()
Cette classe implemente les operateurs et les methodes virtuelles de la classe EFichier de la facon s...
Classe Matrice_Base Classe de base de la hierarchie des matrices.
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
Un tableau d'objets de la classe Motcle.
Definition Motcle.h:63
int search(const Motcle &t) const
Definition Motcle.cpp:321
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
classe Objet_U Cette classe est la classe de base des Objets de TRUST
Definition Objet_U.h:73
friend class Entree
Definition Objet_U.h:76
friend class Sortie
Definition Objet_U.h:75
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
static const Nom & nom_du_cas()
Renvoie une reference constante vers le nom du cas.
Definition Objet_U.cpp:146
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
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
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Probleme_U.h:109
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
int postraiter(int force=1) override
Si force=1, effectue le postraitement sans tenir compte des frequences de postraitement.
void sauver() const override
Ecriture sur fichier en vue d'une reprise (sauvegarde).
virtual double calculer_pas_de_temps() const
Calcul la valeur du prochain pas de temps du probleme.
virtual void mettre_a_jour(double temps)
Effectue une mise a jour en temps du probleme.
const Schema_Temps_base & schema_temps() const
Renvoie le schema en temps associe au probleme.
virtual int nombre_d_equations() const =0
virtual const Equation_base & equation(int) const =0
static int node_master()
renvoie 1 si on est sur le processeur maitre du noeud numa, 0 sinon.
Definition Process.cpp:95
static void imprimer_ram_totale(int all_process=0)
Definition Process.cpp:651
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
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
Cette classe est a la classe C++ ofstream ce que la classe Sortie est a la classe C++ ostream Elle re...
Definition SFichier.h:27
class Schema_Temps_base
int seuil_statio_relatif_deconseille_
Drapeau pour specifier si seuil_statio_ est une valeur absolue (defaut) ou relative.
virtual Entree & lire_periode_sauvegarde_securite_en_heures(Entree &)
int precision_impr_
Nombre de chiffres significatifs impression.
int limpr() const
Renvoie 1 s'il y a lieu d'effectuer une impression (cf dt_impr) Renvoie 0 sinon.
virtual double computeTimeStep(bool &stop) const
virtual bool isStationary() const
Retourne 1 si lors du dernier pas de temps, le probleme n'a pas evolue.
double temps_courant() const
Renvoie le temps courant.
virtual void resetTime(double time)
Nom dt_max_str_
reglage de dt_max comme une fonction du temps
virtual bool corriger_dt_calcule(double &dt) const
Corrige le pas de temps calcule que l'on passe en parametre et verifie qu'il n'est pas "trop" petit (...
int sauvegarder(Sortie &) const override
Sauvegarde le temps courant et le nombre de pas de temps sur un flot de sortie.
int nb_pas_dt_max_atteint() const
Renvoie 1 si (le nombre de pas de temps >= nombre de pas de temps maximum).
Parser_U dt_max_fn_
Parser_U associe.
virtual void set_param(Param &titi) const override
int nb_sauv_
how many checkpoints have we performed so far?
double dt_
Pas de temps de calcul.
virtual void ajouter_inertie(Matrice_Base &mat_morse, DoubleTab &secmem, const Equation_base &eqn) const
bool disable_progress() const
double dt_failed_
Si on a rate un pas de temps, sa valeur.
virtual void associer_pb(const Probleme_base &)
void write_dt_ev(bool init)
double temps_max() const
Renvoie une reference sur le temps maximum.
double dt_max_
Pas de temps max fixe par l'utilisateur.
double mode_dt_start_
Mode calcul du pas de temps de depart - contient un double si option dt_init.
virtual void abortTimeStep()
double periode_cpu_sans_sauvegarde_
Par defaut 23 heures;.
double limite_cpu_sans_sauvegarde_
Par defaut 23 heures;.
int temps_final_atteint() const
Renvoie 1 si le temps final est atteint (ou depasse).
virtual int stop() const
Renvoie 1 si il y lieu de stopper le calcul pour differente raisons: - le temps final est atteint.
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
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
virtual int impr(Sortie &os) const
Impression du numero du pas de temps, la valeur du pas de temps.
int niter_max_diff_impl_
Iterations maximale pour GC implicitation - Above 1000 iterations, diffusion implicit algorithm may b...
virtual void ajouter_blocs(matrices_t matrices, DoubleTab &secmem, const Equation_base &eqn, const tabs_t &semi_impl={}) const
double pas_de_temps() const
Renvoie le pas de temps (delta_t) courant.
virtual void imprimer(Sortie &os) const
Imprime le pas de temps sur un flot de sortie s'il y a lieu.
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
Renvoie le nombre de pas de temps effectues.
double dt_impr_
Pas de temps d'impression.
int stop_lu() const
Renvoie 1 si le fichier (d'extension) .
double dt_min_
Pas de temps min fixe par l'utilisateur.
int reprendre(Entree &) override
Reprise (lecture) du temps courant et du nombre de pas de temps effectues a partir d'un flot d'entree...
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()
Mise a jour du temps courant (t+=dt) et du nombre de pas de temps effectue (nb_pas_dt_++).
double dt_stab_
Pas de temps de stabilite.
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 &)
Lecture du nombre de pas de temps maximal.
int nb_pas_dt_max() const
Renvoie une reference sur le nombre de pas maxi.
double seuil_diff_impl_
Seuil pour implicitation de la diffusion par GC.
void update_critere_statio(const DoubleTab &tab_critere, Equation_base &equation)
//Actualisation de stationnaire_atteint_ et residu_ (critere residu_<seuil_statio_)
void write_progress(bool init)
Ecriture du fichier .progress (temps CPU estime restant).
void finir() const
Fermeture du fichier .dt_ev.
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
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ size_array() const
classe 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_