TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Simpler.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 <Simpler.h>
17#include <Navier_Stokes_std.h>
18#include <EChaine.h>
19#include <Debog.h>
20#include <Matrice_Bloc.h>
21#include <Assembleur_base.h>
22#include <Schema_Temps_base.h>
23#include <TRUSTTrav.h>
24
25#include <Probleme_base.h>
26
27Implemente_instanciable(Simpler,"Simpler",Simple);
28// XD simpler solveur_implicite_base simpler BRACE Simpler method for incompressible systems.
29// XD attr seuil_convergence_implicite floattant seuil_convergence_implicite REQ Keyword to set the value of the
30// XD_CONT convergence criteria for the resolution of the implicit system build to solve either the Navier_Stokes
31// XD_CONT equation (only for Simple and Simpler algorithms) or a scalar equation. It is adviced to use the default
32// XD_CONT value (1e6) to solve the implicit system only once by time step. This value must be decreased when a coupling
33// XD_CONT between problems is considered.
34// XD attr seuil_convergence_solveur floattant seuil_convergence_solveur OPT value of the convergence criteria for the
35// XD_CONT resolution of the implicit system build by solving several times per time step the Navier_Stokes equation and
36// XD_CONT the scalar equations if any. This value MUST be used when a coupling between problems is considered (should
37// XD_CONT be set to a value typically of 0.1 or 0.01).
38// XD attr seuil_generation_solveur floattant seuil_generation_solveur OPT Option to create a GMRES solver and use vrel
39// XD_CONT as the convergence threshold (implicit linear system Ax=B will be solved if residual error ||Ax-B|| is lesser
40// XD_CONT than vrel).
41// XD attr seuil_verification_solveur floattant seuil_verification_solveur OPT Option to check if residual error
42// XD_CONT ||Ax-B|| is lesser than vrel after the implicit linear system Ax=B has been solved.
43// XD attr seuil_test_preliminaire_solveur floattant seuil_test_preliminaire_solveur OPT Option to decide if the
44// XD_CONT implicit linear system Ax=B should be solved by checking if the residual error ||Ax-B|| is bigger than vrel.
45// XD attr solveur solveur_sys_base solveur OPT Method (different from the default one, Gmres with diagonal
46// XD_CONT preconditioning) to solve the linear system.
47// XD attr no_qdm rien no_qdm OPT Keyword to not solve qdm equation (and turbulence models of these equation).
48// XD attr nb_it_max entier nb_it_max OPT Keyword to set the maximum iterations number for the Gmres.
49// XD attr controle_residu rien controle_residu OPT Keyword of Boolean type (by default 0). If set to 1, the convergence
50// XD_CONT occurs if the residu suddenly increases.
51
52
54{
55 return Simple::printOn(os);
56}
57
59{
60 return Simple::readOn(is);
61}
62
63// compute D correction_en_vitesse= E current + resu )
64// with D = diagonal of the matrix and E = D-matrix =-(matrix-D)
65int inverser_par_diagonale(const Matrice_Morse& matrice,const DoubleTrav& resu,const DoubleTab& current,DoubleTrav& correction_en_vitesse)
66{
67 const auto& tab1 = matrice.get_tab1();
68 const auto& tab2 = matrice.get_tab2();
69 const auto& coeff = matrice.get_coeff();
70
71 int deux_entrees=0;
72 int nb_comp=1;
73 if (resu.nb_dim()==2)
74 {
75 deux_entrees=1;
76 nb_comp=resu.dimension(1);
77 }
78 ConstDoubleTab_parts part(correction_en_vitesse);
79 int nb_ligne_reel=part[0].dimension(0);
80 // Determine U^
81 if (deux_entrees==0)
82 {
83 for(int i=0; i<nb_ligne_reel; i++)
84 {
85 for(int j=0; j<nb_comp; j++)
86 {
87 double t=resu(i);
88 for (auto k=tab1(i*nb_comp+j); k<tab1(i*nb_comp+j+1)-1; k++)
89 t -= coeff(k)*current(tab2(k)-1);
90
91 correction_en_vitesse(i) = t/matrice(i*nb_comp+j,i*nb_comp+j);
92 }
93 }
94 // verif
95 // test
96 if (0)
97 for(int i=0; i<nb_ligne_reel; i++)
98 {
99 for (int j=0; j<nb_comp; j++)
100 {
101 int ii=i*nb_comp+j;
102 double tmp=resu(i);
103 for (int k = 0; k<matrice.nb_colonnes(); k++)
104 if ((k/nb_comp)!=i)
105 {
106 if (matrice(ii,k))
107 tmp -= matrice(ii,k)*current((k/nb_comp));
108 }
109
110 double test=tmp/matrice(ii,ii);
111 if (!est_egal(test,correction_en_vitesse(i),1e-5))
112 {
113 Cerr<<i<<" "<<j<<" "<<resu(i)<<finl;
114 Cerr<<test<<" ici "<<correction_en_vitesse(i)-test<<finl;
115 return -1;
116 }
117 }
118 }
119 }
120
121 else
122 {
123 for(int i=0; i<nb_ligne_reel; i++)
124 {
125 for(int j=0; j<nb_comp; j++)
126 {
127 double t=resu(i,j);
128 for (auto k=tab1(i*nb_comp+j); k<tab1(i*nb_comp+j+1)-1; k++)
129 {
130 int i1 = (tab2(k)-1)/nb_comp;
131 int j1 = (tab2(k)-1)-i1*nb_comp;
132 t -= coeff(k)*current(i1,j1);
133 }
134 const double diagonal_coefficient = matrice(i*nb_comp+j,i*nb_comp+j);
135 assert(diagonal_coefficient!=0);
136 correction_en_vitesse(i,j) = t/diagonal_coefficient;
137 }
138 }
139 // test
140 if (0)
141 {
142 Cerr<<"milieu"<<finl;
143 DoubleTrav corr2(correction_en_vitesse);
144 matrice.multvect(current,corr2);
145 for(int i=0; i<nb_ligne_reel; i++)
146 {
147 for (int j=0; j<nb_comp; j++)
148 {
149 int ii = i*nb_comp+j;
150 corr2(i,j) = (resu(i,j)-corr2(i,j)+matrice(ii,ii)*current(i,j))/matrice(ii,ii);
151 double test = corr2(i,j);
152 if (!est_egal(test,correction_en_vitesse(i,j)))
153 {
154 Cerr<<i<<" "<<j<<" "<<resu(i,j)<<finl;
155 Cerr<<test<<" ici "<<correction_en_vitesse(i,j)<<" "<<current(i,j)<<" "<<matrice(ii,ii) <<finl;
156 return -1;
157 }
158 }
159 }
160 Cerr<<"fin"<<finl;
161 }
162 }
163 correction_en_vitesse.echange_espace_virtuel();
164 return 0;
165}
166
167
168//Input: Uk-1 ; Pk-1
169//Output: Uk ; Pk
170//k denotes an iteration
171
172void Simpler::iterer_NS(Equation_base& eqn,DoubleTab& current,DoubleTab& pression,double dt,Matrice_Morse& matrice,double seuil_resol,DoubleTrav& secmem,int nb_ite,int& converge, int& ok)
173{
174 if (eqn.probleme().is_dilatable())
175 {
176 Cerr<<" Simpler cannot be used with a quasi-compressible fluid."<<finl;
177 Cerr<<__FILE__<<(int)__LINE__<<" non code" <<finl;
178 exit();
179 }
180
182 SolveurSys& le_solveur_ = param.solveur();
183
184 Navier_Stokes_std& eqnNS = ref_cast(Navier_Stokes_std,eqn);
186 DoubleTrav gradP(current);
187 DoubleTrav correction_en_pression(pression);
188 DoubleTrav correction_en_vitesse(current);
189 DoubleTrav resu(current);
190
191 //int deux_entrees = 0;
192 //if (current.nb_dim()==2) deux_entrees = 1;
193 Operateur_Grad& gradient = eqnNS.operateur_gradient();
194 Operateur_Div& divergence = eqnNS.operateur_divergence();
195
196 // int nb_comp = 1;
197 //int nb_dim = current.nb_dim();
198
199 //if (nb_dim==2)
200 // nb_comp = current.dimension(1);
201
202 //Build matrix and residual
203 //matrice = A[Uk-1] = M/dt + CONV +DIFF
204 //resu = A[Uk-1]Uk-1 -(A[Uk-1]Uk-1-Ss) + Sv -BtPk-1
205 gradient.calculer(pression,gradP);
206 if (eqnNS.has_interface_blocs()) /* if assembler_blocs is available */
207 eqnNS.assembler_blocs_avec_inertie({{ "vitesse", &matrice }}, resu);
208 else
209 {
210 resu -= gradP;
211 eqnNS.assembler_avec_inertie(matrice,current,resu);
212 }
213
214 le_solveur_->reinit();
215
216 //Solve the system: D[Uk-1]UPk = E[Uk-1]Uk-1 + Sv + Ss -BtPk-1 + (M/dt)Uk-1
217 //matrice = A[Uk-1] = D - E with D the diagonal part of A
218 //correction_en_vitesse = UPk ; current = Uk-1 ; resu = Sv + Ss -BtPk-1
219 int status = inverser_par_diagonale(matrice,resu,current,correction_en_vitesse);
220 if (status!=0) exit();
221 Debog::verifier("Simpler::iterer_NS correction_en_vitesse",correction_en_vitesse);
222
223 //Build matrice_en_pression_2 = BD-1Bt[Uk-1]
224 Matrice& matrice_en_pression_2 = eqnNS.matrice_pression();
225 assembler_matrice_pression_implicite(eqnNS,matrice,matrice_en_pression_2);
226 SolveurSys& solveur_pression_ = eqnNS.solveur_pression();
227 solveur_pression_->reinit();
228
229 //Compute BUPk
230 divergence.calculer(correction_en_vitesse,secmem);
231 secmem *= -1;
232 secmem.echange_espace_virtuel();
233 if (nb_ite==1)
234 eqnNS.assembleur_pression()->modifier_secmem(secmem);
235
236 //Solve the system (BD-1Bt)P*_k = BUPk
237 //correction_en_pression = P*_k ; secmem = BUPk
238 solveur_pression_.resoudre_systeme(matrice_en_pression_2.valeur(),
239 secmem,correction_en_pression);
240
241 //Compute Pk = Pk-1 + P*_k
242 operator_add(pression, correction_en_pression, VECT_ALL_ITEMS);
243
244 eqnNS.assembleur_pression()->modifier_solution(pression);
245
246 //Compute Bt P*_k and adjust resu to -Bt Pk
247 gradient->multvect(correction_en_pression,gradP);
248 resu -= gradP;
250 Debog::verifier("Simpler::iterer_NS resu",resu);
251
252 //Solve the system: A[Uk-1]U*_k = -BtPk + Sv + Ss + (M/dt)Uk-1
253 //current = U*_k ; resu = A[Uk-1]Uk-1 - (A[Uk-1]Uk-1-Ss) + Sv -BtPk + (M/dt)Uk-1
254 le_solveur_.resoudre_systeme(matrice,resu,current);
255
256 //Compute BU*_k
257 divergence.calculer(current,secmem);
258 secmem *= -1;
259 secmem.echange_espace_virtuel();
260 Debog::verifier("Simpler::iterer_NS secmem",secmem);
261
262 //Solve the system (BD-1Bt)P'k = BU*_k
263 //correction_en_pression = P'k ; secmem = BU*_k
264 correction_en_pression = 0;
265 solveur_pression_.resoudre_systeme(matrice_en_pression_2.valeur(),
266 secmem,correction_en_pression);
267
268 //Solve the system D[Uk-1](Uk-U*_k) = -BtP'k
269 //correction_en_vitesse = U'k = Uk-U*_k ; correction_en_pression = P'k
270 calculer_correction_en_vitesse(correction_en_pression,gradP,correction_en_vitesse,matrice,gradient);
271
272 if (0)
273 {
274 Cerr<<" rr "<<mp_max_abs_vect(secmem)<<finl;
275 //Cerr<<secmem<<finl;
276 secmem*=-1;
277 divergence.ajouter(correction_en_vitesse, secmem);
278 Cerr<<" rr2 "<<mp_max_abs_vect(secmem)<<finl;
279
280 }
281
282 //Compute Uk = U*_k + U'k
283 current += correction_en_vitesse;
284 current.echange_espace_virtuel();
285 Debog::verifier("Simpler::iterer_NS current",current);
286
287 if (0)
288 {
289 divergence.calculer(current, secmem);
290 Cerr<<" apresdiv "<<mp_max_abs_vect(secmem)<<finl;;
291 }
292
293}
294
static void verifier(const char *const msg, double)
Definition Debog.cpp:21
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 void assembler_blocs_avec_inertie(matrices_t matrices, DoubleTab &secmem, const tabs_t &semi_impl={})
virtual void assembler_avec_inertie(Matrice_Morse &mat_morse, const DoubleTab &present, DoubleTab &secmem)
Probleme_base & probleme()
Returns the problem associated with the equation.
virtual DoubleVect & multvect(const DoubleVect &, DoubleVect &) const
Multiplication of a vector by the matrix.
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
const auto & get_tab2() const
const auto & get_tab1() const
int nb_colonnes() const override
Return local number of columns (=size on the current proc).
const auto & get_coeff() const
Matrice class - Generic class in the matrix hierarchy.
Definition Matrice.h:34
Navier_Stokes_std This class carries the terms of the momentum equation.
Operateur_Div & operateur_divergence()
Returns the divergence operator associated with the equation.
Operateur_Grad & operateur_gradient()
Returns the gradient operator associated with the equation.
int has_interface_blocs() const override
void reassembler_pression_si_necessaire()
Matrice & matrice_pression()
SolveurSys & solveur_pression()
Returns the pressure solver (const version).
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
Operateur_Div Generic class of the hierarchy of operators computing the divergence.
Classe Operateur_Grad Generic class of the hierarchy of operators computing the gradient.
class Parametre_implicite A Parametre_implicite object groups together the various
bool is_dilatable() const
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
void calculer_correction_en_vitesse(const DoubleTrav &correction_en_pression, DoubleTrav &gradP, DoubleTrav &correction_en_vitesse, const Matrice_Morse &matrice, const Operateur_Grad &gradient)
Definition Simple.cpp:535
void assembler_matrice_pression_implicite(Equation_base &eqn_NS, const Matrice_Morse &matrice, Matrice &matrice_en_pression_2)
void iterer_NS(Equation_base &, DoubleTab &current, DoubleTab &pression, double, Matrice_Morse &, double, DoubleTrav &, int nb_iter, int &converge, int &ok) override
Definition Simpler.cpp:172
class SolveurSys A SolveurSys represents any class
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)
Base class for output streams.
Definition Sortie.h:52
int nb_dim() const
Definition TRUSTTab.h:199
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")