TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Solveur_Newmark.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 <Solveur_Newmark.h>
17#include <Equation_Navier_Cauchy.h>
18
19Implemente_instanciable(Solveur_Newmark, "Newmark", Solveur_non_lineaire);
20// XD newmark solveur_implicite_base newmark BRACE Newmark implicit solver for the resolution of the linear
21// XD_CONT elastodynamic equation.
22// XD attr seuil_convergence_implicite floattant seuil_convergence_implicite REQ Keyword to set the value of the
23// XD_CONT convergence criteria for the resolution of the implicit system build to solve either the Navier_Stokes
24// XD_CONT equation (only for Simple and Simpler algorithms) or a scalar equation. It is adviced to use the default
25// XD_CONT value (1e6) to solve the implicit system only once by time step. This value must be decreased when a coupling
26// XD_CONT between problems is considered.
27// XD attr seuil_convergence_solveur floattant seuil_convergence_solveur OPT value of the convergence criteria for the
28// XD_CONT resolution of the implicit system build by solving several times per time step the Navier_Stokes equation and
29// XD_CONT the scalar equations if any. This value MUST be used when a coupling between problems is considered (should
30// XD_CONT be set to a value typically of 0.1 or 0.01).
31// XD attr seuil_generation_solveur floattant seuil_generation_solveur OPT Option to create a GMRES solver and use vrel
32// XD_CONT as the convergence threshold (implicit linear system Ax=B will be solved if residual error ||Ax-B|| is lesser
33// XD_CONT than vrel).
34// XD attr seuil_verification_solveur floattant seuil_verification_solveur OPT Option to check if residual error
35// XD_CONT ||Ax-B|| is lesser than vrel after the implicit linear system Ax=B has been solved.
36// XD attr seuil_test_preliminaire_solveur floattant seuil_test_preliminaire_solveur OPT Option to decide if the
37// XD_CONT implicit linear system Ax=B should be solved by checking if the residual error ||Ax-B|| is bigger than vrel.
38// XD attr solveur solveur_sys_base solveur OPT Method (different from the default one, Gmres with diagonal
39// XD_CONT preconditioning) to solve the linear system.
40// XD attr nb_it_max entier nb_it_max OPT Keyword to set the maximum iterations number for the Gmres.
41// XD attr controle_residu rien controle_residu OPT Keyword of Boolean type (by default 0). If set to 1, the convergence
42// XD_CONT occurs if the residu suddenly increases.
43// XD attr alpha floattant alpha OPT Damping coefficient for Rayleigh damping: C = alpha * M
44// XD attr beta floattant beta OPT Newmark parameter beta (default value 0.25 for average acceleration method).
45// XD attr gamma floattant gamma OPT Newmark parameter gamma (default value 0.5 for average acceleration method).
46
49
51{
52 Motcles les_mots(3);
53 {
54 les_mots[0] = "beta";
55 les_mots[1] = "gamma";
56 les_mots[2] = "alpha"; // C = alpha * M damping
57 }
58
59 int rang = les_mots.search(motlu);
60 switch(rang)
61 {
62 case 0:
63 {
64 is >> beta_;
65 break;
66 }
67 case 1:
68 {
69 is >> gamma_;
70 break;
71 }
72 case 2:
73 {
74 is >> alpha_;
75 break;
76 }
77 default :
78 {
79 Cerr << "Keyword : " << motlu << " is not understood in " << que_suis_je() << finl;
80 exit();
81 }
82 }
83 return is;
84}
85
86bool Solveur_Newmark::iterer_eqn(Equation_base& eqn, const DoubleTab& inut, DoubleTab& current, double dt, int nb_iter, int& ok)
87{
88 if (!sub_type(Equation_Navier_Cauchy, eqn))
89 {
90 Cerr << que_suis_je() << " cannot be used with equation type " << eqn.que_suis_je() << ". Expected Equation_Navier_Cauchy." << finl;
92 }
93
94 DoubleTab u_old(current); // previous implicit iterate (u^k-1)
96
97 // Storage for v and a across calls (shape-matched to 'current')
98 // (Kept local-static to avoid touching headers; reset if size changes)
99 if ((v_n_.size_totale() != current.size_totale()) || (a_n_.size_totale() != current.size_totale()))
100 {
101 v_n_ = current;
102 v_n_ = 0.;
103 a_n_ = current;
104 a_n_ = 0.;
105 v_kp1_ = current;
106 v_kp1_ = 0.;
107 a_kp1_ = current;
108 a_kp1_ = 0.;
109 u_pred_ = current;
110 v_pred_ = current;
111 }
112
113 // Newmark coefficients
114 const double a0 = 1.0 / (beta_ * dt * dt); // scales M on LHS
115 const double a1 = gamma_ / (beta_ * dt); // scales C on LHS (Rayleigh with C = alpha_*M)
116
117 const int N = current.size_totale();
118 if (nb_iter == 1)
119 {
120 v_n_ = v_kp1_;
121 a_n_ = a_kp1_;
122 // u_pred = u_n + dt*v_n + dt^2*(0.5 - beta_)*a_n
123 for (int i = 0; i < N; i++)
124 u_pred_.addr()[i] = eqn.inconnue().passe().addr()[i] + dt * v_n_.addr()[i] + dt * dt * (0.5 - beta_) * a_n_.addr()[i];
125
126 for (int i = 0; i < N; i++)
127 v_pred_.addr()[i] = v_n_.addr()[i] + dt * (1.0 - gamma_) * a_n_.addr()[i];
128 }
129
130// Effective mass scaling handled by Solveur_Masse: ajouter_masse(dt_eff, ...)
131// In TRUST, ajouter_masse(dt_eff, M, ...) adds (M / dt_eff) to the matrix.
132// We need a0*M on the LHS, hence choose dt_eff = 1 / a0 = beta_ * dt^2.
133 const double dt_eff = 1.0 / a0; // = beta_ * dt^2
134
135// Assemble stiffness and external forces at the Newmark-predicted state
136// Use 'current' as linearization point set to u_pred before assembly
137 if (current.dimension_tot(0) > 0) current = u_pred_;
138 Matrice_Morse matrice;
139 eqn.dimensionner_matrice(matrice);
140 matrice.get_set_coeff() = 0;
141
142 DoubleTrav rhs(current);
143 rhs = 0.;
144 statistics().begin_count(STD_COUNTERS::matrix_assembly,statistics().get_last_opened_counter_level()+1);
145 eqn.assembler(matrice, current, rhs); // K and external terms at u_pred
146 statistics().end_count(STD_COUNTERS::matrix_assembly);
147
148// Add effective mass to matrix and RHS (M*a0*u_pred)
149 eqn.solv_masse().ajouter_masse(dt_eff, matrice, 0 /*implicit*/);
150 eqn.solv_masse().ajouter_masse(dt_eff, rhs, u_pred_, 0 /*implicit*/);
151
152// Add damping contributions if alpha_ != 0: K_eff += a1 * C = a1 * alpha_ * M
153// and RHS += C * (a1 * u_pred - v_pred) = alpha_ * M * (a1 * u_pred - v_pred)
154 if (alpha_ != 0.)
155 {
156 // Matrix: add (a1 * alpha_) * M -> achieved with dt_eff_C_mat = 1 / (a1 * alpha_)
157 if (a1 != 0.)
158 {
159 const double dt_eff_C_mat = 1.0 / (a1 * alpha_);
160 eqn.solv_masse().ajouter_masse(dt_eff_C_mat, matrice, 0 /*implicit*/);
161 }
162 // RHS: add alpha_ * M * (a1 * u_pred - v_pred) -> use dt_eff_C_rhs = 1 / alpha_
163 DoubleTrav w(current);
164 // w = a1 * u_pred - v_pred
165 for (int i = 0; i < N; i++)
166 w.addr()[i] = a1 * u_pred_.addr()[i] - v_pred_.addr()[i];
167 const double dt_eff_C_rhs = 1.0 / alpha_;
168 eqn.solv_masse().ajouter_masse(dt_eff_C_rhs, rhs, w, 0 /*implicit*/);
169 }
170
171// Apply boundary conditions
172 eqn.modifier_pour_Cl(matrice, rhs);
173
174// Solve for u_{n+1}
175 solveur->reinit();
176 solveur.resoudre_systeme(matrice, rhs, current); // current := u_{n+1}
177
178// Recover a_{n+1} and v_{n+1}
179// a_{n+1} = a0*(u_{n+1} - u_pred)
180 for (int i = 0; i < N; i++)
181 a_kp1_.addr()[i] = a0 * (current.addr()[i] - u_pred_.addr()[i]);
182// v_{n+1} = v_pred + gamma_*dt*a_{n+1}
183 for (int i = 0; i < N; i++)
184 v_kp1_.addr()[i] = v_pred_.addr()[i] + gamma_ * dt * a_kp1_.addr()[i];
185
186
187 DoubleTab dudt(current);
188 dudt -= u_old; // dudt = u^k - u^{k-1}
189 double dudt_norme = mp_norme_vect(dudt);
190 const double seuil_convg = get_and_set_parametre_implicite(eqn).seuil_convergence_implicite();
191
192 const bool converge = (dudt_norme < seuil_convg);
193 Cout << eqn.que_suis_je() << (converge ? " is " : " is not ") << "converged at the implicit iteration " << nb_iter << " ( ||uk-uk-1|| = " << dudt_norme << (converge ? "<" : ">") << " implicit threshold " << seuil_convg << " )" << finl;
194
195 eqn.valider_iteration();
196 ok = 1;
197 solveur->reinit();
198 return converge ? 1 : 0;
199}
DoubleTab & passe(int i=1) override
Renvoie les valeurs du champs a l'instant t-i.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Navier–Cauchy equation for small-strain linear elasticity.
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
Solveur_Masse_base & solv_masse()
Renvoie le solveur de masse associe a l'equation.
virtual void valider_iteration()
methode virtuelle permettant de corriger l'onconnue lors d'iterations implicites par exemple K-eps do...
virtual const Champ_Inc_base & inconnue() const =0
virtual void assembler(Matrice_Morse &mat_morse, const DoubleTab &present, DoubleTab &secmem)
virtual void modifier_pour_Cl(Matrice_Morse &mat_morse, DoubleTab &secmem) const
virtual void dimensionner_matrice(Matrice_Morse &mat_morse)
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
auto & get_set_coeff()
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
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
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
double & seuil_convergence_implicite()
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
class SolveurSys Un SolveurSys represente n'importe qu'elle classe
Definition SolveurSys.h:32
int resoudre_systeme(const Matrice_Base &matrice, const DoubleVect &secmem, DoubleVect &solution)
Parametre_implicite & get_and_set_parametre_implicite(Equation_base &eqn)
virtual Matrice_Base & ajouter_masse(double dt, Matrice_Base &matrice, int penalisation=1) const
Newmark time integration scheme for linear elasticity.
Entree & lire(const Motcle &, Entree &) override
bool iterer_eqn(Equation_base &equation, const DoubleTab &inconnue, DoubleTab &result, double dt, int numero_iteration, int &ok) override
class Solveur_non_lineaire
Classe de base des flux de sortie.
Definition Sortie.h:52
_TYPE_ * addr()
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
_SIZE_ size_totale() const
Definition TRUSTVect.tpp:61