16#include <Navier_Stokes_Fluide_Dilatable_Proto.h>
17#include <Transport_Interfaces_base.h>
18#include <Fluide_Dilatable_base.h>
19#include <Navier_Stokes_std.h>
20#include <Schema_Temps_base.h>
21#include <Probleme_base.h>
24#include <Domaine_VF.h>
28#include <Perf_counters.h>
34 DoubleTab& rhovitesse)
const
37 CDoubleTabView tab_rho_v = tab_rho.
view_ro();
38 CDoubleTabView vit_v = vit.
view_ro();
39 DoubleTabView rhovitesse_v = rhovitesse.
view_wo();
40 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), n, KOKKOS_LAMBDA(
43 for (
int j=0 ; j<ncomp ; j++)
44 rhovitesse_v(i, j) = tab_rho_v(i, 0) * vit_v(i, j);
46 end_gpu_timer(__KERNEL_NAME__);
49 Debog::verifier(
"Navier_Stokes_Fluide_Dilatable_Proto::rho_vitesse : ", rhovitesse);
57 DoubleTrav mass_flux(vit);
61 if (
tab_W.get_md_vector())
63 operator_egal(array,
tab_W );
75 double LocalMassFlowRateError = mp_max_abs_vect(array);
77 os <<
"-------------------------------------------------------------------"<< finl;
78 os <<
"Cell balance mass flow rate control for the problem " << eqn.
probleme().
le_nom() <<
" : " << finl;
79 os <<
"Absolute value : " << LocalMassFlowRateError <<
" kg/s" << finl; ;
86 double bilan_massique_relatif = mp_max_abs_vect(array) * dt / rho_moyen;
87 os <<
"Relative value : " << bilan_massique_relatif << finl;
92 double local = LocalMassFlowRateError / ( TotalMass / dt ), global = mp_somme_vect(array) / ( TotalMass / dt );
93 cumulative_ += global;
95 os <<
"time step continuity errors : sum local = " << local <<
", global = " << global <<
", cumulative = " << cumulative_ << finl;
99 Cerr <<
"The mass balance is too bad (relative value > 1%)." << finl;
100 Cerr <<
"Please check and lower the convergence value of the pressure solver." << finl;
119 DoubleTrav secmem(press);
120 DoubleTrav inc_pre(press);
121 DoubleTrav rhoU(vit);
123 if (!
tab_W.get_md_vector())
125 tab_W.copy(secmem, RESIZE_OPTIONS::NOCOPY_NOINIT);
132 eqn.
has_champ(
"gradient_pression", gradient_pression);
134 if (!gradient_pression)
136 Cerr<<
"l'equation ne comprend pas gradient_pression "<<finl;
140 DoubleTab& gradP = gradient_pression->valeurs();
141 DoubleTrav Mmoins1grad(gradP);
146 prepare_and_solve_u_star(eqn,fluide_dil,rhoU, vpoint);
150 solve_pressure_increment(eqn,fluide_dil,rhoU,secmem,inc_pre,vpoint);
153 correct_and_compute_u_np1(eqn,fluide_dil,rhoU,Mmoins1grad,inc_pre,gradP,vpoint);
159 const DoubleTab& present, DoubleTab& tab_secmem)
164 DoubleTrav rhovitesse(present);
172 const int nb_compo = present.
line_size();
174 auto tab1 = mat_morse.
get_tab1().view_ro();
175 CIntArrView tab2 = mat_morse.
get_tab2().view_ro();
176 CDoubleArrView rho_face_np1 =
static_cast<const ArrOfDouble&
>(tab_rho_face_np1).view_ro();
178 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), mat_morse.
nb_lignes(), KOKKOS_LAMBDA(
const int i)
180 for (
auto k=tab1(i)-1; k<tab1(i+1)-1; k++)
183 double rapport = rho_face_np1(j/nb_compo);
187 end_gpu_timer(__KERNEL_NAME__);
200 rho_vitesse_impl(tab_rho_face_np1,present,ref_cast_non_const(DoubleTab,present));
226 for (
auto& itr : lescl)
233 int nfin = ndeb + la_front_dis.
nb_faces();
235 DoubleTabView secmem = tab_secmem.
view_rw();
236 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(ndeb, nfin), KOKKOS_LAMBDA(
const int num_face)
238 for (
int dir=0; dir<dim; dir++)
239 secmem(num_face,dir)*=rho_face_np1(num_face);
241 end_gpu_timer(__KERNEL_NAME__);
249 statistics().begin_count(STD_COUNTERS::ajouter_blocs,statistics().get_last_opened_counter_level()+1);
251 Matrice_Morse *mat = matrices.count(nom_inco)?matrices.at(nom_inco):
nullptr;
257 DoubleTrav rhovitesse(present);
264 const int nb_compo = present.
line_size();
266 auto tab1 = mat->
get_tab1().view_ro();
267 CIntArrView tab2 = mat->
get_tab2().view_ro();
268 CDoubleArrView rho_face_np1 =
static_cast<const ArrOfDouble&
>(tab_rho_face_np1).view_ro();
270 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), mat->
nb_lignes(), KOKKOS_LAMBDA(
const int i)
272 for (
auto k=tab1(i)-1; k<tab1(i+1)-1; k++)
275 double rapport = rho_face_np1(j/nb_compo);
279 end_gpu_timer(__KERNEL_NAME__);
285 statistics().end_count(STD_COUNTERS::ajouter_blocs);
288 statistics().begin_count(STD_COUNTERS::source_terms,statistics().get_last_opened_counter_level()+1);
289 for (
int i = 0; i < eqn.
sources().size(); i++)
290 eqn.
sources()(i)->ajouter_blocs(matrices, tab_secmem, semi_impl);
291 statistics().end_count(STD_COUNTERS::source_terms);
293 statistics().begin_count(STD_COUNTERS::ajouter_blocs,statistics().get_last_opened_counter_level()+1);
295 rho_vitesse_impl(tab_rho_face_np1,present,ref_cast_non_const(DoubleTab,present));
321 for (
auto& itr : lescl)
329 int nfin = ndeb + la_front_dis.
nb_faces();
331 DoubleTabView secmem = tab_secmem.
view_rw();
332 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(ndeb, nfin), KOKKOS_LAMBDA(
const int num_face)
334 for (
int dir=0; dir<dim; dir++)
335 secmem(num_face,dir)*=rho_face_np1(num_face);
337 end_gpu_timer(__KERNEL_NAME__);
341 statistics().end_count(STD_COUNTERS::ajouter_blocs);
348 Cerr <<
"Navier_Stokes_Fluide_Dilatable_Proto::assembler is not coded ! You should use assembler_avec_inertie !" << finl;
357void Navier_Stokes_Fluide_Dilatable_Proto::prepare_and_solve_u_star(
Navier_Stokes_std& eqn,
359 DoubleTab& rhoU, DoubleTab& vpoint)
362 const DoubleTab& tab_rho = fluide_dil.
rho_discvit();
378 DoubleTrav trav(vpoint);
389 const Champ_base& rho_vit=eqn.
get_champ(
"rho_comme_v");
390 ref_cast_non_const(DoubleTab,rho_vit.
valeurs())=tab_rho_face_np1;
394 DoubleTrav secmemV(vpoint);
409 DoubleTrav dr(tab_rho_face_n);
411 CDoubleTabView tab_rho_face_n_v = tab_rho_face_n.
view_ro();
412 CDoubleTabView tab_rho_face_np1_v = tab_rho_face_np1.view_ro();
413 DoubleTabView dr_v = dr.view_rw();
414 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), dr.size_totale(),
418 dr_v(i, 0) = (tab_rho_face_n_v(i, 0) / tab_rho_face_np1_v(i, 0) - 1.) / dt;
420 end_gpu_timer(__KERNEL_NAME__);
439 vpoint -= rhovitesse;
445 update_vpoint_on_boundaries(eqn,fluide_dil,vpoint);
449void Navier_Stokes_Fluide_Dilatable_Proto::update_vpoint_on_boundaries(
const Navier_Stokes_std& eqn,
451 DoubleTab& tab_vpoint)
460 const int taille = tab_vpoint.
line_size();
465 for (
auto& itr : lescl)
467 const Cond_lim_base& la_cl_base = itr.valeur();
468 if (sub_type(Dirichlet,la_cl_base))
470 const Front_VF& la_front_dis = ref_cast(Front_VF,la_cl_base.
frontiere_dis());
471 const Dirichlet& diri=ref_cast(Dirichlet,la_cl_base);
476 ToDo_Kokkos(
"critical");
477 for (
int num_face=ndeb; num_face<nfin; num_face++)
479 int n0 = face_voisins(num_face, 0);
480 if (n0 == -1) n0 = face_voisins(num_face, 1);
484 tab_vit(num_face)*tab_rho_face_n(num_face))/dt_;
491 CDoubleArrView rho_face_np1 =
static_cast<const ArrOfDouble&
>(tab_rho_face_np1).view_ro();
492 CDoubleArrView rho_face_n =
static_cast<const ArrOfDouble&
>(tab_rho_face_n).view_ro();
493 CDoubleTabView vit = tab_vit.
view_ro();
494 DoubleTabView vpoint = tab_vpoint.
view_wo();
495 Kokkos::MDRangePolicy<Kokkos::Rank<2>> policy({ndeb, 0}, {nfin, dim});
496 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), policy, KOKKOS_LAMBDA(
const int num_face,
const int jj)
499 vpoint(num_face,jj)=(rho_face_np1(num_face)*val_imp(num_face-ndeb,jj)
500 -rho_face_n(num_face)*vit(num_face,jj))/dt_;
502 end_gpu_timer(__KERNEL_NAME__);
509void Navier_Stokes_Fluide_Dilatable_Proto::solve_pressure_increment(
Navier_Stokes_std& eqn,
511 DoubleTab& rhoU, DoubleTab& secmem,
512 DoubleTab& inc_pre, DoubleTab& vpoint)
526 DoubleTrav vpoint0(vpoint);
529 if (sub_type(Transport_Interfaces_base,prob.
equation(i)))
531 Transport_Interfaces_base& eq_transport = ref_cast(Transport_Interfaces_base,prob.
equation(i));
533 DoubleTab source_ibc(nb,m);
541 operator_negate(secmem);
548 Debog::verifier(
"Navier_Stokes_Fluide_Dilatable_base::derivee_en_temps_inco, secmem : ", secmem);
552 eqn.assembleur_pression()->modifier_secmem(secmem);
557void Navier_Stokes_Fluide_Dilatable_Proto::correct_and_compute_u_np1(
Navier_Stokes_std& eqn,
559 DoubleTab& rhoU,DoubleTab& Mmoins1grad,
560 DoubleTab& inc_pre,DoubleTab& gradP,
563 const DoubleTab& tab_rho_face_np1=fluide_dil.
rho_face_np1();
572 operator_add(press, inc_pre, VECT_ALL_ITEMS);
573 eqn.assembleur_pression()->modifier_solution(press);
587 vpoint -= Mmoins1grad;
594 tab_divide_any_shape(vpoint, tab_rho_face_np1);
601 Debog::verifier(
"Navier_Stokes_Fluide_Dilatable_base::derivee_en_temps_inco, vpoint : ", vpoint);
DoubleTab & futur(int i=1) override
Renvoie les valeurs du champs a l'instant t+i.
DoubleTab & passe(int i=1) override
Renvoie les valeurs du champs a l'instant t-i.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
virtual DoubleTab & valeurs()=0
classe Champ_base Cette classe est la base de la hierarchie des champs.
classe Cond_lim_base Classe de base pour la hierarchie des classes qui representent les differentes c...
virtual Frontiere_dis_base & frontiere_dis()
Renvoie la frontiere discretisee a laquelle les conditions aux limites s'appliquent.
classe Conds_lim Cette classe represente un vecteur de conditions aux limites.
static void verifier(const char *const msg, double)
classe Dirichlet Cette classe est la classe de base de la hierarchie des conditions aux limites de ty...
virtual double val_imp(int i) const
Renvoie la valeur imposee sur la i-eme composante du champ a la frontiere au temps par defaut du cham...
virtual const DoubleTab & tab_val_imp(double temps=DMAXFLOAT) const
double volume_total() const
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
virtual IntTab & face_voisins()
DoubleTab & derivee_en_temps_conv(DoubleTab &, const DoubleTab &)
Add convection term In: solution is the unknown I.
Sources & sources()
Renvoie les termes sources asssocies a l'equation.
Solveur_Masse_base & solv_masse()
Renvoie le solveur de masse associe a l'equation.
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Renvoie le domaine des conditions aux limite discretisee associee a l'equation.
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
Schema_Temps_base & schema_temps()
Renvoie le schema en temps associe a l'equation.
void Gradient_conjugue_diff_impl(DoubleTrav &secmem, DoubleTab &solution)
Domaine_dis_base & domaine_dis()
Renvoie le domaine discretise 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,
const DoubleTab & rho_face_n() const
const DoubleTab & rho_discvit() const
virtual void secmembre_divU_Z(DoubleTab &) const =0
const DoubleTab & rho_face_np1() const
int num_premiere_face() const
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_tab2() const
const auto & get_tab1() const
int nb_lignes() const override
Return local number of lines (=size on the current proc).
void assembler_avec_inertie_impl(const Navier_Stokes_std &eqn, Matrice_Morse &mat_morse, const DoubleTab &present, DoubleTab &secmem)
DoubleTab & rho_vitesse_impl(const DoubleTab &tab_rho, const DoubleTab &vit, DoubleTab &rhovitesse) const
int impr_impl(const Navier_Stokes_std &eqn, Sortie &os) const
Navier_Stokes_Fluide_Dilatable_Proto()
DoubleTab & derivee_en_temps_inco_impl(Navier_Stokes_std &, DoubleTab &res)
Calcule la derivee en temps de l'inconnue vitesse, i.
void assembler_blocs_avec_inertie(const Navier_Stokes_std &eqn, matrices_t matrices, DoubleTab &secmem, const tabs_t &semi_impl)
void assembler_impl(Matrice_Morse &mat_morse, const DoubleTab &present, DoubleTab &secmem)
classe Navier_Stokes_std Cette classe porte les termes de l'equation de la dynamique
virtual const Champ_Inc_base & rho_la_vitesse() const
const Milieu_base & milieu() const override
Renvoie le milieu physique de l'equation (le Fluide_base upcaste en Milieu_base).
const Champ_Inc_base & inconnue() const override
Renvoie la vitesse (champ inconnue de l'equation) (version const).
const Fluide_base & fluide() const
Renvoie le fluide incompressible (milieu physique de l'equation) associe a l'equation.
virtual const Champ_Inc_base & vitesse() const
Operateur_Div & operateur_divergence()
Renvoie l'operateur de calcul de la divergence associe a l'equation.
const Champ_base & get_champ(const Motcle &nom) const override
Operateur_Grad & operateur_gradient()
Renvoie l'operateur de calcul du gradient associe a l'equation.
DoubleTab & corriger_derivee_expl(DoubleTab &) override
Add a specific term for Navier Stokes (-gradP(n)) if necessary.
const Operateur & operateur(int) const override
Renvoie le i-eme operateur de l'equation: - le terme_diffusif si i = 0.
Matrice & matrice_pression()
SolveurSys & solveur_pression()
Renvoie le solveur en pression (version const).
bool has_champ(const Motcle &nom, OBS_PTR(Champ_base) &ref_champ) const override
int nombre_d_operateurs() const override
Renvoie le nombre d'operateurs de l'equation: Pour Navier Stokes Standard c'est 2.
Champ_Inc_base & pression()
const std::string & getString() const
void volumique(DoubleTab &) const
Initialise le tableau passe en parametre avec la contribution de l'operateur.
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
Ajoute la contribution de l'operateur au tableau passe en parametre.
DoubleTab & calculer(const DoubleTab &, DoubleTab &) const override
Initialise le tableau passe en parametre avec la contribution de l'operateur.
virtual void modifier_pour_Cl(Matrice_Morse &, DoubleTab &) const
DOES NOTHING - to override in derived classes.
virtual void contribuer_a_avec(const DoubleTab &, Matrice_Morse &) const
DOES NOTHING - to override in derived classes.
virtual void ajouter_blocs(matrices_t matrices, DoubleTab &secmem, const tabs_t &semi_impl={ }) const
virtual Operateur_base & l_op_base()=0
virtual DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const =0
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
const Domaine & domaine() const
Renvoie le domaine associe au probleme.
const Schema_Temps_base & schema_temps() const
Renvoie le schema en temps associe au probleme.
virtual int nombre_d_equations() const =0
virtual const Equation_base & equation(int) const =0
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
int diffusion_implicite() const
Renvoie 1 si le schema en temps a ete lu diffusion_implicite.
double temps_courant() const
Renvoie le temps courant.
double pas_de_temps() const
Renvoie le pas de temps (delta_t) courant.
int resoudre_systeme(const Matrice_Base &matrice, const DoubleVect &secmem, DoubleVect &solution)
virtual Matrice_Base & ajouter_masse(double dt, Matrice_Base &matrice, int penalisation=1) const
virtual DoubleTab & appliquer(DoubleTab &) const
renvoie appliquer_impl(x/coeffient_temporelle) si on a un coefficient temporel sinon renvoie applique...
void set_name_of_coefficient_temporel(const Nom &)
permet de choisir le nom du coefficient temporelle que l'on veut utiliser pour appliquer
Classe de base des flux de sortie.
void contribuer_a_avec(const DoubleTab &, Matrice_Morse &) const
contribution a la matrice implicite des termes sources par defaut pas de contribution
DoubleTab & ajouter(DoubleTab &) const
Ajoute la contribution de toutes les sources de la liste au tableau passe en parametre,...
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, View< _TYPE_, _SHAPE_ > > view_wo()
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, ConstView< _TYPE_, _SHAPE_ > > view_ro() const
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, View< _TYPE_, _SHAPE_ > > view_rw()
_SIZE_ dimension(int d) const
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
virtual void modifier_vpoint_pour_imposer_vit(const DoubleTab &inco_val, DoubleTab &vpoint0, DoubleTab &vpoint, const DoubleTab &rho_faces, DoubleTab &source_val, const double temps, const double dt, const int is_explicite=1, const double eta=1.)=0