TrioCFD 1.9.8
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// calcul D correction_en_vitesse= E current + resu )
64// avec D diagonale de la matrice et E = D-matrice =-(matrice-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//Entree : Uk-1 ; Pk-1
169//Sortie Uk ; Pk
170//k designe une 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 //Construction de matrice et resu
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()) /* si assembler_blocs est disponible */
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 //Resolution du systeme : D[Uk-1]UPk = E[Uk-1]Uk-1 + Sv + Ss -BtPk-1 + (M/dt)Uk-1
217 //matrice = A[Uk-1] = D - E avec D partie diagonale de 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 //Construction de 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 //Calcul de 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 //Resolution du systeme (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 //Calcul de 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 //Calcul de Bt P*_k et ajustement de resu a -Bt Pk
247 gradient->multvect(correction_en_pression,gradP);
248 resu -= gradP;
250 Debog::verifier("Simpler::iterer_NS resu",resu);
251
252 //Resolution du systeme : 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 //Calcul de 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 //Resolution du systeme (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 //Resolution du systeme 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 //Calcul de 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
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
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()
Renvoie le probleme associe a l'equation.
virtual DoubleVect & multvect(const DoubleVect &, DoubleVect &) const
Multiplication d'un vecteur par la matrice.
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
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
Classe Matrice Classe generique de la hierarchie des matrices.
Definition Matrice.h:34
classe Navier_Stokes_std Cette classe porte les termes de l'equation de la dynamique
Operateur_Div & operateur_divergence()
Renvoie l'operateur de calcul de la divergence associe a l'equation.
Operateur_Grad & operateur_gradient()
Renvoie l'operateur de calcul du gradient associe a l'equation.
int has_interface_blocs() const override
void reassembler_pression_si_necessaire()
Matrice & matrice_pression()
SolveurSys & solveur_pression()
Renvoie le solveur en pression (version const).
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
classe Operateur_Div Classe generique de la hierarchie des operateurs calculant la divergence
Classe Operateur_Grad Classe generique de la hierarchie des operateurs calculant le gradient.
classe Parametre_implicite Un objet Parametre_implicite est un objet regroupant les differentes
bool is_dilatable() const
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
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 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)
Classe de base des flux de sortie.
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")