TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Piso.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 <Fluide_Dilatable_base.h>
17#include <MD_Vector_composite.h>
18#include <Discretisation_base.h>
19#include <Navier_Stokes_IBM.h>
20#include <Schema_Temps_base.h>
21#include <MD_Vector_tools.h>
22#include <Source_PDF_base.h>
23#include <Assembleur_base.h>
24#include <TRUSTTab_parts.h>
25#include <Probleme_base.h>
26#include <MD_Vector_std.h>
27#include <Matrice_Bloc.h>
28#include <TRUSTTrav.h>
29#include <EChaine.h>
30#include <Debog.h>
31#include <Piso.h>
32
33Implemente_instanciable(Piso,"Piso",Simpler);
34// XD piso simpler piso INHERITS_BRACE Piso (Pressure Implicit with Split Operator) - method to solve N_S.
35// XD attr seuil_convergence_implicite floattant seuil_convergence_implicite OPT Convergence criteria.
36// XD attr nb_corrections_max entier nb_corrections_max OPT Maximum number of corrections performed by the PISO
37// XD_CONT algorithm to achieve the projection of the velocity field. The algorithm may perform less corrections then
38// XD_CONT nb_corrections_max if the accuracy of the projection is sufficient. (By default nb_corrections_max is set to
39// XD_CONT 21).
40
41Implemente_instanciable_sans_constructeur(Implicite,"Implicite",Piso);
42// XD implicite piso implicite INHERITS_BRACE similar to PISO, but as it looks like a simplified solver, it will use
43// XD_CONT fewer timesteps. But it may run faster because the pressure matrix is not re-assembled and thus provides CPU
44// XD_CONT gains.
45
46Implicite::Implicite()
47{
49}
50
51Sortie& Piso::printOn(Sortie& os ) const { return Simpler::printOn(os); }
52
53Entree& Piso::readOn(Entree& is ) { return Simpler::readOn(is); }
54
55Sortie& Implicite::printOn(Sortie& os ) const { return Piso::printOn(os); }
56
57Entree& Implicite::readOn(Entree& is ) { return Piso::readOn(is); }
58
59
60Entree& Piso::lire(const Motcle& motlu,Entree& is)
61{
62 Motcles les_mots(2);
63 {
64 les_mots[0] = "nb_corrections_max";
65 les_mots[1] = "with_sources";
66 }
67
68 int rang = les_mots.search(motlu);
69 switch(rang)
70 {
71 case 0:
72 {
74 if (nb_corrections_max_ < 2)
75 {
76 Cerr<<"There should be at least two corrections steps for the PISO algorithm."<<finl;
77 }
78 break;
79 }
80 case 1:
81 {
82 is >> with_sources_;
83 break;
84 }
85 default :
86 {
87 return Simpler::lire(motlu, is);
88 }
89 }
90 return is;
91}
92
93
94
95void test_imposer_cond_lim(Equation_base& eqn,DoubleTab& current2,const char * msg,int flag)
96{
97 return;
98 /*
99 DoubleTab& present = eqn.inconnue().futur();
100 DoubleTab sauv(present);
101 const Schema_Temps_base& sch = eqn.probleme().schema_temps();
102 eqn.domaine_Cl_dis().imposer_cond_lim(eqn.inconnue(),sch.temps_courant()+sch.pas_de_temps());
103 present -= sauv;
104 // BM, je remplace max_abs par mp_pax_abs: du coup la methode doit etre appelee simultanement par tous les procs.
105 double ecart_max=mp_max_abs_vect(present);
106 Cout<<msg <<" "<<ecart_max<<finl;
107
108 if ((ecart_max>1e-10))
109 abort();
110 present = sauv;
111 */
112}
113
114//Entree Un ; Pn
115//Sortie Un+1 = U***_k ; Pn+1 = P**_k
116//n designe une etape temporelle
117
118void Piso::iterer_NS(Equation_base& eqn,DoubleTab& current,DoubleTab& pression,
119 double dt,Matrice_Morse& matrice,double seuil_resol,DoubleTrav& secmem,int nb_ite,int& converge, int& ok)
120{
121 converge = 1;
122 if (nb_ite>1) return;
123 Navier_Stokes_std& eqnNS = ref_cast(Navier_Stokes_std,eqn);
125 const bool is_NS_IBM = sub_type(Navier_Stokes_IBM, eqnNS);
126
127 eqnNS.setPressureTimeN(); //sometimes we need a second special treatement like for ALE for example
128
129 if (eqnNS.discretisation().que_suis_je() == "PolyMAC_CDO")
130 return iterer_NS_PolyMAC_CDO(eqnNS, current, pression, dt, matrice, ok);
131
133 SolveurSys& le_solveur_ = param_eqn.solveur();
134
135 DoubleTrav gradP(current);
136 DoubleTrav correction_en_pression(pression);
137 DoubleTrav resu(current);
138
139
140 int is_dilat = eqn.probleme().is_dilatable();
141
142 double vitesse_norme,vitesse_norme_old ;
143 double pression_norme,pression_norme_old ;
144 vitesse_norme_old = 1.e10 ;
145 pression_norme_old = 1.e10 ;
146
147 // int deux_entrees = 0;
148 //if (current.nb_dim()==2) deux_entrees = 1;
149 Operateur_Grad& gradient = eqnNS.operateur_gradient();
150 Operateur_Div& divergence = eqnNS.operateur_divergence();
151
152 //int nb_comp = 1;
153 //int nb_dim = current.nb_dim();
154
155 // if(nb_dim==2) nb_comp = current.dimension(1);
156
157 //Construction de matrice et resu
158 //matrice = A[Un] = M/delta_t + CONV +DIFF
159 //resu = A[Un]Un -(A[Un]Un-Ss) + Sv -BtPn
160
161 if (is_NS_IBM)
162 add_penality_term(eqnNS, resu, gradP);
163
164 gradient->calculer(pression,gradP);
165 if (eqnNS.has_interface_blocs()) //si l'interface blocs est disponible, on l'utilise
166 {
167 eqnNS.assembler_blocs_avec_inertie({{ "vitesse", &matrice }}, resu);
168 if (eqnNS.discretisation().is_poly_family())
169 matrice.ajouter_multvect(current, resu); //pour ne pas etre en increment
170 }
171 else //sinon, on passe par ajouter/contribuer
172 {
173 resu -= gradP;
174 eqnNS.assembler_avec_inertie(matrice,current,resu);
175 }
176
177 le_solveur_->reinit();
178
179 //Construction de matrice_en_pression_2 = BD-1Bt[Un]
180 //Assemblage reeffectue seulement pour algorithme Piso (avancement_crank_==0)
181 Matrice& matrice_en_pression_2 = eqnNS.matrice_pression();
182 SolveurSys& solveur_pression_ = eqnNS.solveur_pression();
183
185 {
186 assembler_matrice_pression_implicite(eqnNS,matrice,matrice_en_pression_2);
187 solveur_pression_->reinit();
188 }
189
190 //Etape predicteur
191 //Resolution du systeme A[Un]U* = -BtPn + Sv + Ss
192 //current = U*
193 le_solveur_.resoudre_systeme(matrice,resu,current);
194
195 test_imposer_cond_lim(eqn,current,"apres resolution ",0);
196 current.echange_espace_virtuel();
197 Debog::verifier("Piso::iterer_NS current apres solveur",current);
198
199 if (with_sources_)
200 {
201 matrice.get_set_coeff() = 0;
202 eqnNS.sources().contribuer_a_avec(current, matrice);
203 eqnNS.solv_masse().ajouter_masse(dt, matrice, 1);
204 assembler_matrice_pression_implicite(eqnNS,matrice,matrice_en_pression_2);
205 solveur_pression_->reinit();
206 }
207
208 //Calcul de secmem = BU* (en incompressible) BU* -drho/dt (en quasi-compressible)
209 if (is_dilat)
210 {
211 if (with_d_rho_dt_)
212 {
213 Fluide_Dilatable_base& fluide_dil = ref_cast(Fluide_Dilatable_base,eqn.milieu());
214 fluide_dil.secmembre_divU_Z(secmem);
215 secmem *= -1;
216 }
217 else secmem = 0;
218 divergence.ajouter(current,secmem);
219 }
220 else
221 divergence.calculer(current,secmem);
222 secmem *= -1;
223
224 if (is_NS_IBM)
225 correct_incr_pressure(eqnNS, secmem);
226
227 secmem.echange_espace_virtuel();
228 Debog::verifier("Piso::iterer_NS secmem",secmem);
229
230 // GF il ne faut pas modifier le scd membre le terme en du/dt au bord a deja ete pris en compte dans la resolution precedente
231 // eqnNS.assembleur_pression()->modifier_secmem(secmem);
232
233 //Etape de correction 1
234 Cout << "Solving mass equation :" << finl;
235 //Description du cas implicite
236 //Resolution du systeme (BD-1Bt)P' = Bu* (D-1 = M-1 pour le cas implicite)
237 //correction_en_pression = P' pour Piso et correction_en_pression = delta_t*P' pour implicite
238 eqnNS.assembleur_pression()->modifier_secmem_pour_incr_p(pression, 1. / dt, secmem);
239 //si la matrice varie, passage increments -> valeurs pour aider les solveurs iteratifs
240 if (with_sources_)
241 matrice_en_pression_2->ajouter_multvect(pression, secmem);
242 solveur_pression_.resoudre_systeme(matrice_en_pression_2.valeur(),
243 secmem,correction_en_pression);
244 if (with_sources_)
245 correction_en_pression -= pression;
246 correction_en_pression.echange_espace_virtuel();
247 Debog::verifier("Piso::iterer_NS apres correction_pression",correction_en_pression);
248
249 if (avancement_crank_==1)
250 {
251 //calcul de Un+1
252 //Calcul de Bt(delta_t*delta_P)
253 gradient->multvect(correction_en_pression,gradP);
254
255 if (with_sources_)
256 for (int i = 0, N = gradP.nb_dim() == 2 ? gradP.dimension(1) : 1; i < gradP.dimension_tot(0); i++)
257 for (int n = 0; n < N; n++)
258 gradP(i, n) = matrice.get_tab1()(N * i + n + 1) > matrice.get_tab1()(N * i + n) && matrice(N * i + n, N * i + n) ? gradP(i, n) / matrice(N * i + n, N * i + n) : 0;
259 else
260 eqn.solv_masse().appliquer(gradP);
261
262 if (is_NS_IBM)
263 correct_gradP(eqnNS, gradP);
264
265 //Calcul de Un+1 = U* -delta_t*delta_P
266 current -= gradP;
267 eqn.solv_masse().corriger_solution(current, current); //pour PolyMAC_MPFA : sert a corriger ve
268 current.echange_espace_virtuel();
269 divergence.calculer(current,secmem);
270
271 //Calcul de Pn+1 = Pn + (delta_t*delta_P)/delat_t
272 Debog::verifier("Piso::iterer_NS correction avant dt",correction_en_pression);
273 if (!with_sources_)
274 correction_en_pression /= dt;
275
276 if (is_NS_IBM)
277 correct_pressure(eqnNS, pression, correction_en_pression);
278 else
279 pression += correction_en_pression;
280 // </IBM>
281 eqnNS.assembleur_pression()->modifier_solution(pression);
282 pression.echange_espace_virtuel();
283
284 Debog::verifier("Piso::iterer_NS pression finale",pression);
285 Debog::verifier("Piso::iterer_NS current final",current);
286 if (is_dilat)
287 {
288 // on redivise par rho_np_1 avant de sortir
289 diviser_par_rho_np1_face(eqn,current);
290 }
291
292 eqnNS.updateFluidForce(current);
293
294 return;
295 }
296
297 // calcul de la correction en vitesse premiere etape (DU' =-Bt P)
298
299 //Calcul de P* = Pn + P'
300 pression += correction_en_pression;
301 eqnNS.assembleur_pression()->modifier_solution(pression);
302 //Resolution du systeme D[Un]U' = -BtP'
303 DoubleTrav correction_en_vitesse(current);
304 calculer_correction_en_vitesse(correction_en_pression,gradP,correction_en_vitesse,matrice,gradient);
305
306 //Calcul de U** = U* + U'
307 current += correction_en_vitesse;
308 test_imposer_cond_lim(eqn,current,"apres premiere correction ",0);
309 Debog::verifier("Piso::iterer_NS arpes cor pression",pression);
310 Debog::verifier("Piso::iterer_NS arpes cor vitesse",current);
311
312 //Etape correcteur 2
313 for (int compt=0; compt<nb_corrections_max_-1; compt++)
314 {
315 correction_en_vitesse.echange_espace_virtuel();
316 //Resolution du systeme D resu = EU' + (resu2=0) pour stocker resu = D-1EU'
317 DoubleTrav resu2(resu);
318 int status = inverser_par_diagonale(matrice,resu2,correction_en_vitesse,resu);
319
320 if (status!=0) exit();
321 // calcul de P'' BD-1Bt P''= -div(D-1EU')
322
324 //Calcul de B(D-1EU')
325 divergence.calculer(resu,secmem);
326 secmem *= -1;
327 secmem.echange_espace_virtuel();
328
329 //Resolution du systeme (BD-1Bt)P'' = (BD-1E)U'
330 //correction_en_pression = P''
331 correction_en_pression = 0;
332 solveur_pression_.resoudre_systeme(matrice_en_pression_2.valeur(),
333 secmem,correction_en_pression);
334
335#ifdef DEBUG
336 // Pour verifier que le calcul du gradient ne modifie pas la pression
337 DoubleTrav correction_en_pression_mod(pression);
338 correction_en_pression_mod = correction_en_pression;
339#endif
340 //Resolution du systeme D[Un]U'' = -BtP''
341 //correction_en_vitesse = U''
342 calculer_correction_en_vitesse(correction_en_pression,gradP,correction_en_vitesse,matrice,gradient);
343
344#ifdef DEBUG
345 correction_en_pression_mod -= correction_en_pression;
346 assert(max_abs(correction_en_pression_mod)==0);
347#endif
348
349 //Calcul de U'' = U'' + D-1EU'
350 correction_en_vitesse += resu;
351 // ajout des increments
352
353 // Optimization: combine 2 mp_norme_vect into 1 collective call
354 double vitesse_carre = local_carre_norme_vect(correction_en_vitesse);
355 double pression_carre = local_carre_norme_vect(correction_en_pression);
356 mp_sum_for_each(vitesse_carre, pression_carre);
357 vitesse_norme = sqrt(vitesse_carre);
358 pression_norme = sqrt(pression_carre);
359
360 if ( (vitesse_norme>vitesse_norme_old) || (pression_norme>pression_norme_old) )
361 {
362 Cout <<"PISO : "<< compt+1 <<" corrections to perform the projection."<< finl;
363 if (is_dilat)
364 {
365 // on redivise par rho_np_1 avant de sortir
366 diviser_par_rho_np1_face(eqn,current);
367 }
368 return ;
369 }
370
371 vitesse_norme_old = vitesse_norme;
372 pression_norme_old = pression_norme;
373 //Calcul de P** = P* + P''
374 pression += correction_en_pression;
375 eqnNS.assembleur_pression()->modifier_solution(pression);
376
377 //Calcul de U*** = U** + U''
378 current += correction_en_vitesse;
379 test_imposer_cond_lim(eqn,current,"apres correction (int)__LINE__",0);
380
381 Debog::verifier("Piso::iterer_NS apres correction pression",pression);
382 Debog::verifier("Piso::iterer_NS apres correction vitesse",current);
383 }
384 if (is_dilat)
385 {
386 diviser_par_rho_np1_face(eqn,current);
387 //ref_cast(Navier_Stokes_QC,eqn).impr_impl(eqnNS, Cout);
388 }
389 current.echange_espace_virtuel();
390 // divergence.calculer(current, secmem); Cerr<<" ici DIVU "<<mp_max_abs_vect(secmem)<<finl;;
391 Cout <<"PISO : "<<nb_corrections_max_<<" corrections to perform the projection."<< finl;
392}
393
394//version PolyMAC_CDO de la fonction ci-dessus
395void Piso::iterer_NS_PolyMAC_CDO(Navier_Stokes_std& eqn, DoubleTab& current, DoubleTab& pression, double dt, Matrice_Morse& matrice, int& ok)
396{
397 if (avancement_crank_ == 0)
398 Process::exit("sorry, the PISO solver is not implemented with PolyMAC_CDO! Please use Implicite instead");
400 SolveurSys& le_solveur_ = param_eqn.solveur();
401
402 Navier_Stokes_std& eqnNS = ref_cast(Navier_Stokes_std, eqn);
403 Operateur_Grad& op_grad = eqnNS.operateur_gradient();
404 Operateur_Div& op_div = eqnNS.operateur_divergence();
405
406 DoubleTrav dv(current); //, dP(pression); //corrections en vitesse / pression
407
408 /* etape de prediction : current <- v(0) ne verifiant pas div = 0 */
409 DoubleTrav secmem_NS(current), v_new(current);
410 op_grad.ajouter(pression, secmem_NS);
411 secmem_NS *= -1;
412 eqnNS.assembler_avec_inertie(matrice, current, secmem_NS);
413 le_solveur_->reinit();
414 le_solveur_.resoudre_systeme(matrice, secmem_NS, v_new);
415 v_new.echange_espace_virtuel();
416
417 Matrice& mat_press_orig = eqn.matrice_pression(), mat_press;
418
419 /* etapes de correction : current <- v(i) verifiant div = 0 mais approche pour NS, pression <- p(i) correspondant a v(i) */
420 for (int i = 0; i < 1; i++)
421 {
422 DoubleTrav sol_M(pression), secmem_M(pression);
423 /* resolution en (dt * dp(i), dv(i)) */
424 //second membre : divergence, NS
425 DoubleTab_parts p_sec(secmem_M), p_sol(sol_M); //p_sec/sol[0] -> elements, p_sec/sol[1] -> faces
426 //bloc superieur : div v(i-1)
427 op_div.ajouter(v_new, p_sec[0]);
428 //bloc inferieur : residu de l'etape de prediction
429 p_sec[1] = 0; //p_res[0];
430
431 //matrice (sauf si avancement_crank_ == 1) : prise en compte des contributions des sources (et pas des operateurs!)
433 {
434 matrice.get_set_coeff() = 0, eqn.sources().contribuer_a_avec(current, matrice);
435 DoubleTrav diag(p_sec[1]);
436 for (int j = 0; j < p_sec[1].dimension(0); j++)
437 diag(j) = dt * matrice(j, j);
438 diag.echange_espace_virtuel();
439 eqn.assembleur_pression()->assembler_mat(mat_press, diag, 1, 1);
440 eqn.solveur_pression()->reinit();
441 }
442
443 //resolution
444 Cerr << "PISO : |sec dp| < " << mp_max_abs_vect(p_sec[0]) << " |sec dv| < " << mp_max_abs_vect(p_sec[1]) << finl;
445 eqn.solveur_pression().resoudre_systeme(avancement_crank_ == 1 ? mat_press_orig.valeur() : mat_press.valeur(), secmem_M, sol_M);
446 //mises a jour : v^(i) = v^(i-1)+dv^(i), p^(i) = p^(i-1) + dp^(i)
447 eqn.assembleur_pression()->corriger_vitesses(sol_M, dv);
448 Cerr << "PISO : |dp| < " << mp_max_abs_vect(p_sol[0]) / dt << " |dv| < " << mp_max_abs_vect(dv);
449 v_new += dv, sol_M /= dt, pression -= sol_M;
450 //
451 p_sec[0] = 0, op_div.ajouter(v_new, p_sec[0]);
452 Cerr << " |div v| < " << mp_max_abs_vect(p_sec[0]) << finl;
453 pression.echange_espace_virtuel();
454 }
455 current = v_new;
456}
457
458void Piso::add_penality_term(Navier_Stokes_std& eqnNS, DoubleTrav& resu , DoubleTrav& gradP)
459{
460 // <IBM> Taking into account penality term for Immersed Boundary Method
461 Navier_Stokes_IBM& eqnNS_IBM = ref_cast(Navier_Stokes_IBM, eqnNS);
462 const int i_source_PDF = eqnNS_IBM.get_i_source_pdf();
463 if (i_source_PDF != -1)
464 {
465 Source_PDF_base& src = dynamic_cast<Source_PDF_base&>((eqnNS.sources())[i_source_PDF].valeur());
466 DoubleTab secmem_pdf(resu);
467 src.calculer_pdf(secmem_pdf);
468
469 // Terme en temps : -rho/delta_t ksi_gamma Un
470 int pdf_bilan = src.get_modele().pdf_bilan();
471 if (pdf_bilan == 1)
472 {
473 int i_traitement_special = 101;
474 if (eqnNS.nombre_d_operateurs() > 1)
475 {
476 if (eqnNS.vitesse_pour_transport().le_nom() == "rho_u")
477 i_traitement_special = 1;
478 }
479 DoubleTrav secmem_pdf_time(resu);
480 src.calculer(secmem_pdf_time, i_traitement_special);
481 secmem_pdf += secmem_pdf_time;
482 }
483
484 // Sauvegarde de secmem_pdf
485 secmem_pdf.echange_espace_virtuel();
486 src.set_sec_mem_pdf(secmem_pdf);
487
488 const DoubleTab& coeff = eqnNS_IBM.get_champ_coeff_pdf_som();
489 if (eqnNS_IBM.get_gradient_pression_qdm_modifie() == 1)
490 {
491 Cerr << "(IBM) Immersed Interface: modified pressure gradient in momentum equation." << finl;
492 gradP /= coeff;
493 }
495 }
496}
497
498void Piso::correct_gradP(Navier_Stokes_std& eqnNS, DoubleTrav& gradP)
499{
500 Navier_Stokes_IBM& eqnNS_IBM = ref_cast(Navier_Stokes_IBM, eqnNS);
501 const int i_source_PDF = eqnNS_IBM.get_i_source_pdf();
502 if ((i_source_PDF != -1) && (eqnNS_IBM.get_correction_vitesse_modifie() == 1))
503 {
504 Cerr << "(IBM) Immersed Interface: modified velocity correction." << finl;
505 const DoubleTab& coeff = eqnNS_IBM.get_champ_coeff_pdf_som();
506 gradP /= coeff;
508 }
509}
510
511void Piso::correct_incr_pressure(Navier_Stokes_std& eqnNS, DoubleTrav& secmem)
512{
513 // <IBM> Taking into account zero velocity divergence for Immersed Boundary Method
514 Navier_Stokes_IBM& eqnNS_IBM = ref_cast(Navier_Stokes_IBM, eqnNS);
515 const int i_source_PDF = eqnNS_IBM.get_i_source_pdf();
516 if ((i_source_PDF != -1) && (eqnNS_IBM.get_correction_matrice_pression() == 1))
517 {
518 Cerr << "(IBM) Immersed Interface: velocity divergence is zero for crossed elements." << finl;
519 const DoubleTab& coeff = eqnNS_IBM.get_champ_coeff_pdf_som();
520 Source_PDF_base& src = dynamic_cast<Source_PDF_base&>((eqnNS.sources())[i_source_PDF].valeur());
521 src.correct_incr_pressure(coeff, secmem);
522 }
523}
524
525void Piso::correct_pressure(Navier_Stokes_std& eqnNS, DoubleTab& pression, DoubleTab& correction_en_pression)
526{
527 // <IBM> Immersed Interface: modified pressure correction.
528 Navier_Stokes_IBM& eqnNS_IBM = ref_cast(Navier_Stokes_IBM, eqnNS);
529 const int i_source_PDF = eqnNS_IBM.get_i_source_pdf();
530 if ((i_source_PDF != -1) && (eqnNS_IBM.get_correction_pression_modifie()==1))
531 {
532 Cerr<<"Immersed Interface: modified pressure correction."<<finl;
533 const DoubleTab& coeff = eqnNS_IBM.get_champ_coeff_pdf_som();
534 const Source_PDF_base& src = dynamic_cast<Source_PDF_base&>((eqnNS.sources())[i_source_PDF].valeur());
535 src.correct_pressure(coeff,pression,correction_en_pression);
536 }
537 else
538 pression += correction_en_pression;
539}
static void verifier(const char *const msg, double)
Definition Debog.cpp:21
virtual bool is_poly_family() const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
const DoubleTab & get_champ_coeff_pdf_som() const
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
virtual const Milieu_base & milieu() const =0
Sources & sources()
Renvoie les termes sources asssocies a l'equation.
virtual void assembler_blocs_avec_inertie(matrices_t matrices, DoubleTab &secmem, const tabs_t &semi_impl={})
const Discretisation_base & discretisation() const
Renvoie la discretisation associee a l'equation.
Solveur_Masse_base & solv_masse()
Renvoie le solveur de masse associe a l'equation.
virtual void assembler_avec_inertie(Matrice_Morse &mat_morse, const DoubleTab &present, DoubleTab &secmem)
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
const Nom & le_nom() const override
Renvoie le nom du champ.
classe Fluide_Dilatable_base Cette classe represente un d'un fluide dilatable,
virtual void secmembre_divU_Z(DoubleTab &) const =0
virtual DoubleVect & ajouter_multvect(const DoubleVect &x, DoubleVect &r) const
Operation de multiplication-accumulation (saxpy) matrice vecteur.
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
const auto & get_tab1() const
auto & get_set_coeff()
Classe Matrice Classe generique de la hierarchie des matrices.
Definition Matrice.h:34
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
int get_gradient_pression_qdm_modifie() const
int get_correction_vitesse_modifie() const
int get_correction_pression_modifie() const
int get_correction_matrice_pression() const
classe Navier_Stokes_std Cette classe porte les termes de l'equation de la dynamique
virtual void updateFluidForce(DoubleTab &)
virtual const Champ_base & vitesse_pour_transport() const
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).
int nombre_d_operateurs() const override
Renvoie le nombre d'operateurs de l'equation: Pour Navier Stokes Standard c'est 2.
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
classe Operateur_Div Classe generique de la hierarchie des operateurs calculant la divergence
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
Ajoute la contribution de l'operateur au tableau passe en parametre.
Classe Operateur_Grad Classe generique de la hierarchie des operateurs calculant le gradient.
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
Ajoute la contribution de l'operateur au tableau passe en parametre.
int pdf_bilan() const
Definition PDF_model.h:41
classe Parametre_implicite Un objet Parametre_implicite est un objet regroupant les differentes
Definition Piso.h:82
int avancement_crank_
Definition Piso.h:89
int nb_corrections_max_
Definition Piso.h:88
Entree & lire(const Motcle &, Entree &) override
Definition Piso.cpp:60
int with_sources_
Definition Piso.h:90
void iterer_NS(Equation_base &, DoubleTab &current, DoubleTab &pression, double, Matrice_Morse &, double, DoubleTrav &, int nb_iter, int &converge, int &ok) override
Definition Piso.cpp:118
bool is_dilatable() const
static void mp_sum_for_each(T &arg1, T &arg2)
C++14 compatible mp_sum_for_each: combine multiple mp_sum calls into one collective operation Usage: ...
Definition Process.cpp:207
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
int with_d_rho_dt_
Definition Simple.h:81
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)
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)
virtual Entree & lire(const Motcle &, Entree &)
Parametre_implicite & get_and_set_parametre_implicite(Equation_base &eqn)
virtual Matrice_Base & ajouter_masse(double dt, Matrice_Base &matrice, int penalisation=1) const
virtual DoubleTab & corriger_solution(DoubleTab &x, const DoubleTab &y, int incr=0) const
virtual DoubleTab & appliquer(DoubleTab &) const
renvoie appliquer_impl(x/coeffient_temporelle) si on a un coefficient temporel sinon renvoie applique...
Classe de base des flux de sortie.
Definition Sortie.h:52
const PDF_model & get_modele() const
void set_sec_mem_pdf(DoubleTab &it)
DoubleTab & calculer_pdf(DoubleTab &) const
virtual void correct_pressure(const DoubleTab &, DoubleTab &, const DoubleTab &) const
DoubleTab & calculer(DoubleTab &) const override
virtual void correct_incr_pressure(const DoubleTab &, DoubleTab &) const
void contribuer_a_avec(const DoubleTab &, Matrice_Morse &) const
contribution a la matrice implicite des termes sources par defaut pas de contribution
Definition Sources.cpp:201
int nb_dim() const
Definition TRUSTTab.h:199
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
_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")