TRUST 1.9.8
HPC thermohydraulic platform
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 non regle par l'utilisateur -> on demande sa preference au solveur */
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 == "{") // bloc d'equations resolues ensemble
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// Caracteristiques du schema //
204// //
205////////////////////////////////
206
207/*! @brief Renvoie le nombre de valeurs temporelles a conserver.
208 *
209 */
211{
212 return 3 ;
213}
214
215/*! @brief Renvoie le nombre de valeurs temporelles futures.
216 *
217 * Ici : n+1, donc 1.
218 *
219 */
221{
222 return 1 ;
223}
224
225/*! @brief Renvoie le le temps a la i-eme valeur future.
226 *
227 * Ici : t(n+1)
228 *
229 */
231{
232 assert(i==1);
233 return temps_courant()+pas_de_temps();
234}
235
236/*! @brief Renvoie le le temps le temps que doivent rendre les champs a l'appel de valeurs()
237 *
238 * Ici : t(n+1)
239 *
240 */
242{
243 return temps_courant()+pas_de_temps();
244}
245
246/////////////////////////////////////////
247// //
248// Fin des caracteristiques du schema //
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 //renverse l'ordre des equations si Faiblement compressible
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 sert pour la pression et pour les echanges entre pbs
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; //echec total -> on sort sans traiter les equations suivantes
297 convergence_pb = convergence_pb&&convergence_eqn;
298 futur=present;
300 present=futur;
301
302 // La ligne suivante (commentee) realise:
303 // MAJ NS (donc MAJ inc)
304 // MAJ modele de turbulence donc 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 // traitement de la convergence en temps
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(); // pour proposer un pas de temps plus bas au prochain essai
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 : prise en compte de la possibilite de modification du dt dans Itere_Pb
376 //cas du solveur pour compressible : division du pas de temps par 2
377 // si la convergence n'est pas atteinte en un nombre de pas de temps donne
378 // double temps = dt_ + temps_courant_;
379 test_stationnaire(prob);
380
381 return ok;
382}
383
385{
386 // Modif B.M. : Si on fait la sauvegarde entre derivee en temps inco et mettre a jour,
387 // un calcul avec reprise n'est pas equivalent au calcul ininterrompu
388 // (front-tracking notamment). Donc je mets la sauvegarde au debut du pas de temps.
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 sert pour la pression et pour les echanges entre pbs
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(); // pour proposer un pas de temps plus bas au prochain essai
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 // sert pour la pression et les couplages
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; //si echec total
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 // Reprise du facsec et du residu dans le fichier .dt_ev s'il existe
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 // Si en tete on lit
609 fichier >> chaine;
610 if (chaine=="#")
611 {
612 // On lit la ligne complete
613 std::getline(fichier.get_ifstream(), ligne);
614 } // Sinon on reouvre
615 else
616 {
617 fichier.ouvrir(nom_fichier);
618 }
619 // Recherche du pas de temps precedant 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 // On lit le reste de la ligne
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 // On prend le facsec lu uniquement s'il est entre les
655 // bornes specifiees dans le jeu de donnees
656 // En effet, on peut faire un calcul explicite puis une reprise en implicite
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
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.
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)
Calcul des coefficients d'echange pour les problemes couples thermiques.
virtual void imposer_cond_lim(Champ_Inc_base &, double)=0
Fichier en lecture Cette classe est a la classe C++ ifstream ce que la classe Entree est a la.
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
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
virtual int equation_non_resolue() const
virtual const Champ_Inc_base & inconnue() const =0
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Renvoie le domaine des conditions aux limite discretisee associee a l'equation.
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
virtual const Motcle & domaine_application() const
Renvoie "indetermine" Navier_Stokes_standard par exemple surcharge cette methode.
Cette classe implemente les operateurs et les methodes virtuelles de la classe EFichier de la facon s...
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
class Nom Une chaine de caractere pour nommer les objets de TRUST
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:319
Nom & majuscule()
Transforme le nom en majuscules Seules les lettres 'a'-'z' sont modifiees.
Definition Nom.cpp:180
const std::string & getString() const
Definition Nom.h:92
friend class Entree
Definition Objet_U.h:76
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
int lire_avec_accolades(Entree &is)
Alias of lire_avec_accolades_depuis.
Definition Param.h:577
classe Probleme_Couple C'est la classe historique de couplage de TRUST.
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Probleme_U.h:109
virtual bool updateGivenFields()
ATTENTION :
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
bool is_dilatable() const
bool updateGivenFields() override
ATTENTION :
virtual int nombre_d_equations() const =0
virtual const Equation_base & equation(int) const =0
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
double temps_futur(int i) const override
Renvoie le le temps a la i-eme valeur future.
int mettre_a_jour() override
Mise a jour du temps courant (t+=dt) et du nombre de pas de temps effectue (nb_pas_dt_++).
int reprendre(Entree &) override
Reprise d'un Objet_U sur un flot d'entree Methode a surcharger.
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
Renvoie le le temps le temps que doivent rendre les champs a l'appel de valeurs().
int nb_valeurs_futures() const override
Renvoie le nombre de valeurs temporelles futures.
int nb_valeurs_temporelles() const override
Renvoie le nombre de valeurs temporelles a conserver.
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
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
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 Classe de base pour tous les schemas en temps implicite
void set_param(Param &param) const override
int diffusion_implicite() const
Renvoie 1 si le schema en temps a ete lu diffusion_implicite.
double temps_courant() const
Renvoie le temps courant.
OBS_PTR(Probleme_base) mon_probleme
double dt_
Pas de temps de calcul.
Probleme_base & pb_base()
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.
double pas_de_temps() const
Renvoie le pas de temps (delta_t) courant.
virtual bool initTimeStep(double dt)
const double & residu() const
virtual int mettre_a_jour()
Mise a jour du temps courant (t+=dt) et du nombre de pas de temps effectue (nb_pas_dt_++).
void update_critere_statio(const DoubleTab &tab_critere, Equation_base &equation)
//Actualisation de stationnaire_atteint_ et residu_ (critere residu_<seuil_statio_)
Classe de base des flux de sortie.
Definition Sortie.h:52