TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Schema_Euler_Implicite.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_Euler_Implicite.h>
17#include <Domaine_Cl_dis_base.h>
18#include <Probleme_Couple.h>
19#include <communications.h>
20#include <Equation_base.h>
21#include <Probleme_base.h>
22#include <LecFicDiffuse.h>
23#include <Milieu_base.h>
24#include <Param.h>
25#include <string>
26
27Implemente_instanciable(Schema_Euler_Implicite,"Schema_euler_implicite|Scheme_euler_implicit",Schema_Implicite_base);
28
30{
32}
33
35{
37 if (facsec_max_ == DMAXFLOAT) /* facsec_max not set by the user -> ask the solver for its preferred value */
38 facsec_max_ = le_solveur->get_default_facsec_max();
39 dt_gf_ = le_solveur->get_default_growth_factor();
40 if(!le_solveur)
41 {
42 Cerr << "A solver must be selected." << finl;
43 Cerr << "Syntax : " << finl
44 << "Solveur solver_name [ solver parameters ] " << finl;
45 exit();
46 }
47 if (resolution_monolithique_.size() && !le_solveur->est_compatible_avec_th_mono())
48 Cerr << que_suis_je() << " : deactivating thermique_monolithique for the implicit solver " << le_solveur->que_suis_je() << finl, resolution_monolithique_.clear();
50 {
51 Cerr << "diffusion_implicite option cannot be used with an implicit time scheme." << finl;
52 exit();
53 }
54 return s;
55}
56
57void Schema_Euler_Implicite::calcul_fac_sec(double& residu,double& residu_old,double& facsec)
58{
59 if (residu_old==0)
60 {
63 }
64 else if (facsec_func_)
65 {
66 // facsec=f(t)
67 facsec_fn_.setVar(0, temps_courant());
68 facsec = facsec_fn_.eval();
69 facsec = std::min(facsec,facsec_max_);
70 }
72 {
73 // Dynamic facsec=f(residual)
74 facsec*=sqrt(rapport_residus_);
76 facsec = std::min(facsec,facsec_max_);
78 }
80}
81
82
84{
85 if (mot == "resolution_monolithique")
86 {
87 Motcle m;
88 is >> m;
89 assert (m == "{");
90 is >> m;
91 while (m != "}")
92 {
93 if (m == "{") // block of equations solved together
94 {
95 std::set<std::string> bloc_domap;
96 is >> m;
97 while (m != "}")
98 {
99 bloc_domap.insert(m.getString());
100 is >> m;
101 }
102 resolution_monolithique_.push_back(bloc_domap);
103 }
104 else
105 {
106 resolution_monolithique_.push_back({m.getString()});
107 is >> m;
108 }
109 }
110 }
111 else if (mot == "facsec_max") //old syntax
112 is >> facsec_max_;
113 else if (mot == "facsec_expert")
115 else if (mot == "facsec_func")
118 return 1;
119}
120
121
122// XD facsec_expert interprete nul BRACE To parameter the safety factor for the time step during the simulation.
124{
125 Param param("facsec_expert");
126 param.ajouter("facsec_ini",&facsec_); // XD_ADD_P floattant
127 // XD_CONT Initial facsec taken into account at the beginning of the simulation.
128 param.ajouter("facsec_max",&facsec_max_); // XD_ADD_P floattant
129 // XD_CONT Maximum ratio allowed between time step and stability time returned by CFL condition. The initial ratio
130 // XD_CONT given by facsec keyword is changed during the calculation with the implicit scheme but it couldn\'t be
131 // XD_CONT higher than facsec_max value.NL2 Warning: Some implicit schemes do not permit high facsec_max, example
132 // XD_CONT Schema_Adams_Moulton_order_3 needs facsec=facsec_max=1. NL2 Advice:NL2 The calculation may start with a
133 // XD_CONT facsec specified by the user and increased by the algorithm up to the facsec_max limit. But the user can
134 // XD_CONT also choose to specify a constant facsec (facsec_max will be set to facsec value then). Faster convergence
135 // XD_CONT has been seen and depends on the kind of calculation: NL2-Hydraulic only or thermal hydraulic with forced
136 // XD_CONT convection and low coupling between velocity and temperature (Boussinesq value beta low), facsec between
137 // XD_CONT 20-30NL2-Thermal hydraulic with forced convection and strong coupling between velocity and temperature
138 // XD_CONT (Boussinesq value beta high), facsec between 90-100 NL2-Thermohydralic with natural convection, facsec
139 // XD_CONT around 300NL2 -Conduction only, facsec can be set to a very high value (1e8) as if the scheme was
140 // XD_CONT unconditionally stableNL2These values can also be used as rule of thumb for initial facsec with a
141 // XD_CONT facsec_max limit higher.
142 param.ajouter("rapport_residus",&rapport_residus_); // XD_ADD_P floattant
143 // XD_CONT Ratio between the residual at time n and the residual at time n+1 above which the facsec is increased by
144 // XD_CONT multiplying by sqrt(rapport_residus) (1.2 by default).
145 param.ajouter("nb_ite_sans_accel_max",&nb_ite_sans_accel_max_); // XD_ADD_P entier
146 // XD_CONT Maximum number of iterations without facsec increases (20000 by default): if facsec does not increase with
147 // XD_CONT the previous condition (ration between 2 consecutive residuals too high), we increase it by force after
148 // XD_CONT nb_ite_sans_accel_max iterations.
149
150 param.lire_avec_accolades(is);
151
152 return is;
153}
154
156{
157 Nom facsec_str;
158
159 is >> facsec_str;
160
161 facsec_fn_.setNbVar(1);
162 facsec_fn_.setString(facsec_str);
163 facsec_fn_.addVar("t");
164 facsec_fn_.parseString();
165 facsec_ = facsec_fn_.eval();
166 if(facsec_str.majuscule().contient("T"))
167 facsec_func_ = true;
168}
169
171{
172 // XD schema_euler_implicite schema_implicite_base schema_euler_implicite INHERITS_BRACE This is the Euler implicit
173 // XD_CONT scheme.
174 param.ajouter("max_iter_implicite",&nb_ite_max);
175 param.ajouter_flag("facsec_cfl",&facsec_cfl_); // XD_ADD_P rien
176 // XD_CONT Flag to compute time step based on CFL: dt=min(facsec,facsec_max)*dt(convection)X/
177 param.ajouter_non_std("facsec_max", (this)); // XD_ADD_P floattant
178 // XD_CONT For old syntax, see the complete parameters of facsec for details
179 param.ajouter_non_std("facsec_expert", (this)); // XD_ADD_P facsec_expert
180 // XD_CONT Advanced facsec specification
181 param.ajouter_non_std("facsec_func", (this)); // XD_ADD_P chaine
182 // XD_CONT Advanced facsec specification as a function
183 param.ajouter_non_std("resolution_monolithique", (this)); // XD_ADD_P bloc_lecture
184 // XD_CONT Activate monolithic resolution for coupled problems. Solves together the equations corresponding to the
185 // XD_CONT application domains in the given order. All aplication domains of the coupled equations must be given to
186 // XD_CONT determine the order of resolution. If the monolithic solving is not wanted for a specific application
187 // XD_CONT domain, an underscore can be added as prefix. For example, resolution_monolithique { dom1 { dom2 dom3 }
188 // XD_CONT _dom4 } will solve in a single matrix the equations having dom1 as application domain, then the equations
189 // XD_CONT having dom2 or dom3 as application domain in a single matrix, then the equations having dom4 as application
190 // XD_CONT domain in a sequential way (not in a single matrix).
192}
193
194
196{
198 residu_=0;
199 return true;
200}
201////////////////////////////////
202// //
203// Schema characteristics //
204// //
205////////////////////////////////
206
207/*! @brief Returns the number of temporal values to keep.
208 *
209 */
211{
212 return 3 ;
213}
214
215/*! @brief Returns the number of future temporal values.
216 *
217 * Here: n+1, so 1.
218 *
219 */
221{
222 return 1 ;
223}
224
225/*! @brief Returns the time at the i-th future value.
226 *
227 * Here: t(n+1)
228 *
229 */
231{
232 assert(i==1);
233 return temps_courant()+pas_de_temps();
234}
235
236/*! @brief Returns the time that fields must return when valeurs() is called.
237 *
238 * Here: t(n+1)
239 *
240 */
242{
243 return temps_courant()+pas_de_temps();
244}
245
246/////////////////////////////////////////
247// //
248// End of schema characteristics //
249// //
250/////////////////////////////////////////
251
253{
254 int i;
255 for( i=0; i<pb.nombre_d_equations(); i++)
256 {
257 DoubleTab& passe = pb.equation(i).inconnue().passe();
258 DoubleTab& present = pb.equation(i).inconnue().valeurs();
259 if ( (pb.equation(i).que_suis_je()!="Euler") || temps_courant_==0.)
260 passe = present;
261 }
262}
263
269
271{
272 int ii;
273 bool convergence_pb = true;
274 bool convergence_eqn = false;
275 int drap = pb.is_dilatable();
276 Cout << "=======================================================================================" << finl;
277 Cout << "Schema_Euler_Implicite: Implicit iteration " << compteur << " on the " << pb.que_suis_je() << " problem " << pb.le_nom() << " :" << finl;
278 Cout << "=======================================================================================" << finl;
279 for(int i=0; i<pb.nombre_d_equations(); i++)
280 {
281 // reverse the order of equations for weakly compressible flow
282 if ((drap)&&(i<2))
283 ii = 1-i;
284 else
285 ii = i;
286 Equation_base& eqn= pb.equation(ii);
287 DoubleTab& present = eqn.inconnue().valeurs();
288 DoubleTab& futur = eqn.inconnue().futur();
289 double temps=temps_courant_+dt_;
290
291 // imposer_cond_lim is used for the pressure and for inter-problem exchanges
293 Cout<<"Solving " << eqn.que_suis_je() << " equation :" << finl;
294 const DoubleTab& inut=futur;
295 convergence_eqn=le_solveur->iterer_eqn(eqn, inut, present, dt_, compteur, ok);
296 if (!ok) return false; // total failure -> exit without processing the following equations
297 convergence_pb = convergence_pb&&convergence_eqn;
298 futur=present;
300 present=futur;
301
302 // The following (commented-out) line performs:
303 // Update NS (hence update unknowns)
304 // Update turbulence model (k-eps)
305 // eqn.inconnue().mettre_a_jour(temps);
306
307 // eqn.inconnue().reculer();
308 eqn.inconnue().Champ_base::changer_temps(temps);
309 Cout << finl;
310 }
311 return (convergence_pb==true);
312}
313
315{
316 for(int i=0; i<pb.nombre_d_equations(); i++)
317 {
318 // time convergence processing
319 DoubleTab& passe = pb.equation(i).inconnue().passe();
320 DoubleTab& present = pb.equation(i).inconnue().valeurs();
321 DoubleTab& futur = pb.equation(i).inconnue().futur();
322 futur = present;
324 present -= passe;
325 present/=dt_;
326 update_critere_statio(present, pb.equation(i));
327 present = passe;
328 }
329}
330
331void recommencer_pb(Probleme_base& pb)
332{
333 for(int i=0; i<pb.nombre_d_equations(); i++)
334 {
335 DoubleTab& passe = pb.equation(i).inconnue().passe();
336 DoubleTab& present = pb.equation(i).inconnue().valeurs();
337 present=passe;
338 }
339}
340
341
343{
344 Probleme_base& prob=pb_base();
345
346 converged = false;
347 Initialiser_Champs(prob);
348
349 int ok=1;
350 int compteur;
351 while (!converged)
352 {
353 compteur=0;
354 Cout<<" "<<finl;
355 //Cout<<"Schema_Euler_Implicite : solving of problem "<<prob.que_suis_je()<<finl;
356 while (ok && !converged && compteur < nb_ite_max)
357 {
358 compteur++;
359 prob.updateGivenFields();
360 converged = Iterer_Pb(prob,compteur, ok);
361 Cout<<" "<<finl;;
362 }
363 if (!ok || (!converged && compteur == nb_ite_max))
364 {
365 Cout<<"!!! Schema_Euler_Implicite has not converged at t="<< temps_courant_ << " with dt =" << dt_<< " !!!" << finl;
366 converged = false;
367 notify_failed_timestep(); // to propose a lower time step on the next attempt
368 return false;
369 }
370 else
371 {
372 Cout<<"The "<<prob.que_suis_je()<<" problem " << prob.le_nom() << " has converged after "<<compteur<<" implicit iterations."<<finl;
373 }
374 }
375 // modification: account for the possibility of modifying dt in Itere_Pb
376 // for the compressible solver: divide the time step by 2
377 // if convergence is not reached within a given number of time steps
378 // double temps = dt_ + temps_courant_;
379 test_stationnaire(prob);
380
381 return ok;
382}
383
385{
386 // Modif B.M.: If the save is done between derivee_en_temps_inco and mettre_a_jour,
387 // a restarted calculation is not equivalent to an uninterrupted one
388 // (especially for front-tracking). So the save is placed at the beginning of the time step.
389 //if (lsauv())
390 // for (int i=0;i<pbc.nb_problemes();i++)
391 // ref_cast(Probleme_base,pbc.probleme(i)).sauver();
392
393 int convergence_pbc = 0;
394 int i;
395
396 for(i=0; i<pbc.nb_problemes(); i++)
397 Initialiser_Champs(ref_cast(Probleme_base,pbc.probleme(i)));
398
399
400 int cv = 0;
401 int compteur;
402
403 while (!cv)
404 {
405 compteur=0;
406
407 while ((!convergence_pbc )&&(compteur<nb_ite_max))
408 {
409 compteur++;
410 convergence_pbc=1;
411
412
413 for(i=0; i<pbc.nb_problemes()*1; i++)
414 {
415 Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
416 const int nb_eqn=pb.nombre_d_equations();
417 for(int ii=0; ii<nb_eqn; ii++)
418 {
420 }
421
422 }
423
424 if (resolution_monolithique_.size())
425 {
426 //make sure all application domains are in resolution_monolithique_
427 std::set<std::string> doms_app, doms_mono;
428 for(i = 0; i < pbc.nb_problemes(); i++)
429 for(int j = 0; j < ref_cast(Probleme_base,pbc.probleme(i)).nombre_d_equations(); j++)
430 doms_app.insert(ref_cast(Probleme_base,pbc.probleme(i)).equation(j).domaine_application().getString());
431 for (auto && s : resolution_monolithique_)
432 for (auto &&d : s) doms_mono.insert((Nom(d)).getSuffix("-").getString());
433
434 if (doms_mono != doms_app)
435 {
436 Cerr << "Error : all the application domains should be given in the resolution_monolitique block to impose the order of resolution" << finl;
437 Cerr << "and some are missing among :";
438 for (auto &&n: doms_app) Cerr << Nom(" ") + n;
439 Cerr << finl << "(an underscore can be put at the begining of the application domains for which a standard resolution is wanted)" << finl;
441 }
442
443 for (auto && s : resolution_monolithique_)
444 {
445 // serach all equations of this dom app
446 LIST(OBS_PTR(Equation_base)) eqs;
447 for(i = 0; i < pbc.nb_problemes(); i++)
448 for(int j = 0; j < ref_cast(Probleme_base,pbc.probleme(i)).nombre_d_equations(); j++)
449 {
450 const Probleme_base& pb = ref_cast(Probleme_base,pbc.probleme(i));
451 const Motcle type = pb.equation(j).domaine_application();
452 if ((s.count(type.getString()) || s.count((Nom("-") + type).getString())) && !pb.equation(j).equation_non_resolue()) eqs.add(pb.equation(j));
453 }
454 if (eqs.size() == 0) continue; // equations non resolues
455
456 Cout << "RESOLUTION {";
457 for (auto &&d : s) Cout << Nom(" ") + d;
458 Cout << " }" << finl;
459 Cout << "-------------------------" << finl;
460 const bool mono = !(s.size() == 1 && Nom((*s.begin())).debute_par("-"));
461 if (mono)
462 {
463 Cout << "Resolution monolithique! the equations {";
464 for (int k = 0; k < eqs.size(); k++)
465 {
466 Cout << " " << eqs[k]->que_suis_je();
467 eqs[k]->probleme().updateGivenFields();
468 }
469 Cout << " } are solved by assembling a single matrix." << finl;
470 bool convergence_eqs = le_solveur->iterer_eqs(eqs, compteur, ok);
471 convergence_pbc = convergence_pbc && convergence_eqs;
472 }
473 else
474 {
475 for (int k = 0; k < eqs.size(); k++)
476 {
477 Equation_base& eqn = eqs[k].valeur();
479
480 DoubleTab& present = eqn.inconnue().valeurs();
481 DoubleTab& futur = eqn.inconnue().futur();
482 double temps = temps_courant_ + dt_;
483
484 // imposer_cond_lim is used for the pressure and for inter-problem exchanges
486 Cout<<"Solving " << eqn.que_suis_je() << " equation :" << finl;
487 const DoubleTab& inut=futur;
488 bool convergence_eqn=le_solveur->iterer_eqn(eqn, inut, present, dt_, compteur, ok);
489 if (!ok) break;
490 convergence_pbc = convergence_pbc && convergence_eqn;
491 futur = present;
493 present = futur;
494
495 eqn.inconnue().Champ_base::changer_temps(temps);
496 Cout << finl;
497 }
498 }
499 }
500 }
501 else
502 {
503 for(i=0; ok && i<pbc.nb_problemes(); i++)
504 {
506 int convergence_pb = Iterer_Pb(ref_cast(Probleme_base,pbc.probleme(i)),compteur, ok);
507 convergence_pbc = convergence_pbc * convergence_pb ;
508 }
509
510 }
511 }
512 if (!ok || (!convergence_pbc && compteur==nb_ite_max))
513 {
514 Cout << pbc.le_nom() << (ok ? " : failure" : " : non-convergence") << " at t = "<< temps_courant_ << " with dt = " << dt_<< " !!!" << finl;
515 notify_failed_timestep(); // to propose a lower time step on the next attempt
516 return 0;
517 }
518 else
519 {
520 Cout<<"The "<<pbc.que_suis_je()<<" problem " << pbc.le_nom() << " has converged after "<<compteur<<" implicit iterations."<<finl;
521 cv=1;
522 }
523 }
524
525 double residu_1=0;
526 for(i=0; i<pbc.nb_problemes(); i++)
527 {
528 residu_1=residu_;
529 test_stationnaire(ref_cast(Probleme_base,pbc.probleme(i)));
530 residu_=std::max(residu_,residu_1);
531 }
532
533 return 1;
534}
535
537{
538 DoubleTab& passe = eqn.inconnue().passe();
539 DoubleTab& present = eqn.inconnue().valeurs();
540 DoubleTab& futur = eqn.inconnue().futur();
541 int compteur = 0, ok = 1;
542 bool convergence_eqn = false;
543 passe = present;
544 // futur=present;
545 // used for the pressure and inter-problem couplings
547 //present=futur;
548
549 compteur=0;
550 Cout << finl;
551 while ((!convergence_eqn)&&(compteur<nb_ite_max))
552 {
553 compteur++;
554 Cout<<"==================================================================================" << finl;
555 Cout<<"Schema_Euler_Implicite: Implicit iteration " << compteur << " on the "<<eqn.que_suis_je() << " equation of the problem "<< eqn.probleme().le_nom()<< " :" <<finl;
556 Cout<<"==================================================================================" << finl;
557 const DoubleTab& inut=futur;
558 convergence_eqn=le_solveur->iterer_eqn(eqn, inut, present, dt_, compteur, ok);
559 if (!ok) return 0; // total failure
560 futur=present;
562 present=futur;
563 }
564 present -= passe;
565 present/=dt_;
566
567 update_critere_statio(present, eqn);
568
569
570 present = passe;
571
572 return 1;
573}
574
576{
577 Nom nom_fichier(nom_du_cas());
578 nom_fichier+=".dt_ev";
579 LecFicDiffuse test;
580 if (!test.ouvrir(nom_fichier))
581 {
582 Cerr << "*****************************************" << finl;
583 Cerr << "***************** WARNING ***************" << finl;
584 Cerr << "File " << nom_fichier << " does not exist." << finl;
585 Cerr << "In order to restart a calculation carried out with an implicit time scheme" << finl;
586 Cerr << "it is preferable to re-read the .dt_ev file to pick up some informations" << finl;
587 Cerr << "and in particular the facsec of the previous calculation." << finl;
588 Cerr << "TRUST will use facsec= " << facsec_ << "." << finl;
589 Cerr << "Else specify the facsec wanted value in your data file." << finl;
590 Cerr << "*****************************************" << finl;
591 return 1;
592 }
593
594 // Reading facsec and residual from the .dt_ev file if it exists
595 double facsec_lu=1.;
596 double residu_lu=0;
597 double facsec_lu_old;
598
599 // Test ouverture du fichier
600 if (je_suis_maitre())
601 {
602 EFichier fichier;
603 fichier.ouvrir(nom_fichier);
604 Nom chaine;
605 double temps=0;
606 double dt;
607 std::string ligne;
608 // Read the header if present
609 fichier >> chaine;
610 if (chaine=="#")
611 {
612 // Read the full line
613 std::getline(fichier.get_ifstream(), ligne);
614 } // Otherwise reopen
615 else
616 {
617 fichier.ouvrir(nom_fichier);
618 }
619 // Search for the time step preceding tinit_
620 fichier >> temps;
621 double residu_old_old=0;
622 while (!fichier.eof() && temps<tinit_)
623 {
624
625 facsec_lu_old = facsec_lu;
626 fichier >> dt;
627 fichier >> facsec_lu;
628 fichier >> residu_lu;
629 if (residu_old_==0)
630 residu_old_=residu_lu;
631 if (residu_old_old==0)
632 residu_old_old=residu_lu;
633 // Read the rest of the line
634 std::getline(fichier.get_ifstream(), ligne);
635 fichier >> temps;
636
637 if (facsec_lu_old != facsec_lu)
638 {
639 residu_old_ = residu_old_old;
640
642 }
643 residu_old_old = residu_lu;
645 }
646 }
647// GF
648 calcul_fac_sec(residu_lu,residu_old_,facsec_lu);
649 envoyer_broadcast(facsec_lu, 0 /* pe source */);
650 envoyer_broadcast(residu_lu, 0 /* pe source */);
651 envoyer_broadcast(nb_ite_sans_accel_, 0 /* pe source */);
652 envoyer_broadcast(residu_old_, 0 /* pe source */);
653
654 // The read facsec is used only if it is within the bounds
655 // specified in the data set.
656 // Indeed, one may run an explicit calculation and then restart with an implicit scheme.
657 residu_ = residu_lu;
658 if (facsec_lu>=facsec_)
659 {
660 if (facsec_lu<=facsec_max_)
661 facsec_ = facsec_lu;
662 else
664 Cerr << "Facsec after reading in " << nom_fichier << " : " << facsec_ << finl;
665 Cerr << "Residu after reading in " << nom_fichier << " : " << residu_ << finl;
666 }
667 else
668 {
669 Cerr << "The readen facsec in " << nom_fichier << " : " << facsec_lu << finl;
670 Cerr << "is not used since it is lower than the facsec from the data set : " << facsec_ << finl;
671 }
672 return 1;
673}
674
676{
677 for (auto &&s : resolution_monolithique_)
678 if (s.count(nom.getString())) return 1;
679 return 0;
680}
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.
const Probleme_U & probleme(int i) const
Definition Couplage_U.h:127
int nb_problemes() const
Definition Couplage_U.h:117
virtual int calculer_coeffs_echange(double temps)
Computes the exchange coefficients for thermally coupled problems.
virtual void imposer_cond_lim(Champ_Inc_base &, double)=0
File for reading. This class is to the C++ ifstream class what the Entree class is to the.
Definition EFichier.h:29
virtual int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::in)
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
virtual const Champ_Inc_base & inconnue() const =0
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Returns the discretized boundary condition domain associated with the equation.
Probleme_base & probleme()
Returns the problem associated with the equation.
virtual const Motcle & domaine_application() const
Returns "indeterminate" Navier_Stokes_standard for example overrides this method.
This class implements the operators and virtual methods of the EFichier class as follows: The file to...
A character string (Nom) in uppercase.
Definition Motcle.h:26
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
bool contient(const Nom &nom) const
Definition Nom.h:86
virtual int debute_par(const char *const n) const
Definition Nom.cpp:314
Nom & majuscule()
Converts the name to uppercase. Only letters 'a'-'z' are modified.
Definition Nom.cpp:176
const std::string & getString() const
Definition Nom.h:92
friend class Entree
Definition Objet_U.h:71
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
int lire_avec_accolades(Entree &is)
Alias of lire_avec_accolades_depuis.
Definition Param.h:577
Probleme_Couple This is the historical coupling class of TRUST.
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
virtual bool updateGivenFields()
WARNING:
class Probleme_base It is a Probleme_U that is not a coupling.
bool is_dilatable() const
bool updateGivenFields() override
WARNING:
virtual int nombre_d_equations() const =0
virtual const Equation_base & equation(int) const =0
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
double temps_futur(int i) const override
Returns the time at the i-th future value.
int mettre_a_jour() override
Updates the current time (t+=dt) and the number of time steps performed (nb_pas_dt_++).
int reprendre(Entree &) override
Restores an Objet_U from an input stream. Virtual method to override.
virtual int faire_un_pas_de_temps_pb_couple(Probleme_Couple &, int &ok)
void set_param(Param &) const override
void Initialiser_Champs(Probleme_base &)
int Iterer_Pb(Probleme_base &, int ite, int &ok)
bool iterateTimeStep(bool &converged) override
Calculate the U(n+1) unknown for each equation (if solved) of the problem with the selected time sche...
int resolution_monolithique(const Nom &nom) const
double temps_defaut() const override
Returns the time that fields must return when valeurs() is called.
int nb_valeurs_futures() const override
Returns the number of future temporal values.
int nb_valeurs_temporelles() const override
Returns the number of temporal values to keep.
const double & residu_old() const
void calcul_fac_sec(double &residu_, double &residu_old, double &facsec_)
int lire_motcle_non_standard(const Motcle &mot, Entree &is) override
Reads non-simple-type parameters of an Objet_U from an input stream.
std::vector< std::set< std::string > > resolution_monolithique_
Entree & lire_facsec_expert(Entree &)
void test_stationnaire(Probleme_base &)
int faire_un_pas_de_temps_eqn_base(Equation_base &) override
bool initTimeStep(double dt) override
class Schema_Implicite_base Base class for all implicit time schemes.
void set_param(Param &param) const override
int diffusion_implicite() const
Returns 1 if the time scheme has been read with diffusion_implicite.
double temps_courant() const
Returns the current time.
OBS_PTR(Probleme_base) mon_probleme
double dt_
Computation time step.
Probleme_base & pb_base()
int lire_motcle_non_standard(const Motcle &, Entree &) override
Reads non-simple-type parameters of an Objet_U from an input stream.
double pas_de_temps() const
Returns the current time step (delta_t).
virtual bool initTimeStep(double dt)
const double & residu() const
virtual int mettre_a_jour()
Updates the current time (t+=dt) and the number of time steps performed (nb_pas_dt_++).
void update_critere_statio(const DoubleTab &tab_critere, Equation_base &equation)
Updates stationnaire_atteint_ and residu_ (criterion: residu_ < seuil_statio_).
Base class for output streams.
Definition Sortie.h:52