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>
41Implemente_instanciable_sans_constructeur(
Implicite,
"Implicite",
Piso);
64 les_mots[0] =
"nb_corrections_max";
65 les_mots[1] =
"with_sources";
68 int rang = les_mots.
search(motlu);
76 Cerr<<
"There should be at least two corrections steps for the PISO algorithm."<<finl;
95void test_imposer_cond_lim(
Equation_base& eqn,DoubleTab& current2,
const char * msg,
int flag)
119 double dt,
Matrice_Morse& matrice,
double seuil_resol,DoubleTrav& secmem,
int nb_ite,
int& converge,
int& ok)
122 if (nb_ite>1)
return;
130 return iterer_NS_PolyMAC_CDO(eqnNS, current, pression, dt, matrice, ok);
135 DoubleTrav gradP(current);
136 DoubleTrav correction_en_pression(pression);
137 DoubleTrav resu(current);
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 ;
162 add_penality_term(eqnNS, resu, gradP);
164 gradient->calculer(pression,gradP);
177 le_solveur_->reinit();
187 solveur_pression_->reinit();
195 test_imposer_cond_lim(eqn,current,
"apres resolution ",0);
205 solveur_pression_->reinit();
218 divergence.ajouter(current,secmem);
221 divergence.calculer(current,secmem);
225 correct_incr_pressure(eqnNS, secmem);
234 Cout <<
"Solving mass equation :" << finl;
238 eqnNS.assembleur_pression()->modifier_secmem_pour_incr_p(pression, 1. / dt, secmem);
241 matrice_en_pression_2->ajouter_multvect(pression, secmem);
243 secmem,correction_en_pression);
245 correction_en_pression -= pression;
247 Debog::verifier(
"Piso::iterer_NS apres correction_pression",correction_en_pression);
253 gradient->multvect(correction_en_pression,gradP);
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;
263 correct_gradP(eqnNS, gradP);
269 divergence.calculer(current,secmem);
272 Debog::verifier(
"Piso::iterer_NS correction avant dt",correction_en_pression);
274 correction_en_pression /= dt;
277 correct_pressure(eqnNS, pression, correction_en_pression);
279 pression += correction_en_pression;
281 eqnNS.assembleur_pression()->modifier_solution(pression);
282 pression.echange_espace_virtuel();
289 diviser_par_rho_np1_face(eqn,current);
300 pression += correction_en_pression;
301 eqnNS.assembleur_pression()->modifier_solution(pression);
303 DoubleTrav correction_en_vitesse(current);
307 current += correction_en_vitesse;
308 test_imposer_cond_lim(eqn,current,
"apres premiere correction ",0);
317 DoubleTrav resu2(resu);
318 int status = inverser_par_diagonale(matrice,resu2,correction_en_vitesse,resu);
320 if (status!=0)
exit();
325 divergence.calculer(resu,secmem);
331 correction_en_pression = 0;
333 secmem,correction_en_pression);
337 DoubleTrav correction_en_pression_mod(pression);
338 correction_en_pression_mod = correction_en_pression;
345 correction_en_pression_mod -= correction_en_pression;
346 assert(max_abs(correction_en_pression_mod)==0);
350 correction_en_vitesse += resu;
354 double vitesse_carre = local_carre_norme_vect(correction_en_vitesse);
355 double pression_carre = local_carre_norme_vect(correction_en_pression);
357 vitesse_norme = sqrt(vitesse_carre);
358 pression_norme = sqrt(pression_carre);
360 if ( (vitesse_norme>vitesse_norme_old) || (pression_norme>pression_norme_old) )
362 Cout <<
"PISO : "<< compt+1 <<
" corrections to perform the projection."<< finl;
366 diviser_par_rho_np1_face(eqn,current);
371 vitesse_norme_old = vitesse_norme;
372 pression_norme_old = pression_norme;
374 pression += correction_en_pression;
375 eqnNS.assembleur_pression()->modifier_solution(pression);
378 current += correction_en_vitesse;
379 test_imposer_cond_lim(eqn,current,
"apres correction (int)__LINE__",0);
386 diviser_par_rho_np1_face(eqn,current);
398 Process::exit(
"sorry, the PISO solver is not implemented with PolyMAC_CDO! Please use Implicite instead");
406 DoubleTrav dv(current);
409 DoubleTrav secmem_NS(current), v_new(current);
410 op_grad.
ajouter(pression, secmem_NS);
413 le_solveur_->reinit();
415 v_new.echange_espace_virtuel();
420 for (
int i = 0; i < 1; i++)
422 DoubleTrav sol_M(pression), secmem_M(pression);
425 DoubleTab_parts p_sec(secmem_M), p_sol(sol_M);
427 op_div.
ajouter(v_new, p_sec[0]);
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);
444 Cerr <<
"PISO : |sec dp| < " << mp_max_abs_vect(p_sec[0]) <<
" |sec dv| < " << mp_max_abs_vect(p_sec[1]) << finl;
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;
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();
458void Piso::add_penality_term(
Navier_Stokes_std& eqnNS, DoubleTrav& resu , DoubleTrav& gradP)
461 Navier_Stokes_IBM& eqnNS_IBM = ref_cast(Navier_Stokes_IBM, eqnNS);
463 if (i_source_PDF != -1)
465 Source_PDF_base& src =
dynamic_cast<Source_PDF_base&
>((eqnNS.
sources())[i_source_PDF].valeur());
466 DoubleTab secmem_pdf(resu);
473 int i_traitement_special = 101;
477 i_traitement_special = 1;
479 DoubleTrav secmem_pdf_time(resu);
480 src.
calculer(secmem_pdf_time, i_traitement_special);
481 secmem_pdf += secmem_pdf_time;
485 secmem_pdf.echange_espace_virtuel();
491 Cerr <<
"(IBM) Immersed Interface: modified pressure gradient in momentum equation." << finl;
500 Navier_Stokes_IBM& eqnNS_IBM = ref_cast(Navier_Stokes_IBM, eqnNS);
504 Cerr <<
"(IBM) Immersed Interface: modified velocity correction." << finl;
514 Navier_Stokes_IBM& eqnNS_IBM = ref_cast(Navier_Stokes_IBM, eqnNS);
518 Cerr <<
"(IBM) Immersed Interface: velocity divergence is zero for crossed elements." << finl;
520 Source_PDF_base& src =
dynamic_cast<Source_PDF_base&
>((eqnNS.
sources())[i_source_PDF].valeur());
525void Piso::correct_pressure(
Navier_Stokes_std& eqnNS, DoubleTab& pression, DoubleTab& correction_en_pression)
528 Navier_Stokes_IBM& eqnNS_IBM = ref_cast(Navier_Stokes_IBM, eqnNS);
532 Cerr<<
"Immersed Interface: modified pressure correction."<<finl;
534 const Source_PDF_base& src =
dynamic_cast<Source_PDF_base&
>((eqnNS.
sources())[i_source_PDF].valeur());
538 pression += correction_en_pression;
static void verifier(const char *const msg, double)
virtual bool is_poly_family() const
Class defining operators and methods for all reading operation in an input flow (file,...
int get_i_source_pdf() const
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
Classe Matrice Classe generique de la hierarchie des matrices.
Une chaine de caractere (Nom) en majuscules.
Un tableau d'objets de la classe Motcle.
int search(const Motcle &t) const
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.
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
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.
classe Parametre_implicite Un objet Parametre_implicite est un objet regroupant les differentes
Entree & lire(const Motcle &, Entree &) override
void iterer_NS(Equation_base &, DoubleTab ¤t, DoubleTab &pression, double, Matrice_Morse &, double, DoubleTrav &, int nb_iter, int &converge, int &ok) override
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: ...
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
void calculer_correction_en_vitesse(const DoubleTrav &correction_en_pression, DoubleTrav &gradP, DoubleTrav &correction_en_vitesse, const Matrice_Morse &matrice, const Operateur_Grad &gradient)
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
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.
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
_SIZE_ dimension_tot(int) const override
_SIZE_ dimension(int d) const
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")