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;
117 DoubleTrav secmem(press);
118 DoubleTrav inc_pre(press);
119 DoubleTrav rhoU(vit);
121 if (!
tab_W.get_md_vector())
123 tab_W.copy(secmem, RESIZE_OPTIONS::NOCOPY_NOINIT);
130 eqn.
has_champ(
"gradient_pression", gradient_pression);
132 if (!gradient_pression)
134 Cerr<<
"the equation does not include gradient_pression "<<finl;
138 DoubleTab& gradP = gradient_pression->valeurs();
139 DoubleTrav Mmoins1grad(gradP);
144 prepare_and_solve_u_star(eqn,fluide_dil,rhoU, vpoint);
148 solve_pressure_increment(eqn,fluide_dil,rhoU,secmem,inc_pre,vpoint);
151 correct_and_compute_u_np1(eqn,fluide_dil,rhoU,Mmoins1grad,inc_pre,gradP,vpoint);
157 const DoubleTab& present, DoubleTab& tab_secmem)
162 DoubleTrav rhovitesse(present);
170 const int nb_compo = present.
line_size();
172 auto tab1 = mat_morse.
get_tab1().view_ro();
173 CIntArrView tab2 = mat_morse.
get_tab2().view_ro();
174 CDoubleArrView rho_face_np1 =
static_cast<const ArrOfDouble&
>(tab_rho_face_np1).view_ro();
176 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), mat_morse.
nb_lignes(), KOKKOS_LAMBDA(
const int i)
178 for (
auto k=tab1(i)-1; k<tab1(i+1)-1; k++)
181 double rapport = rho_face_np1(j/nb_compo);
185 end_gpu_timer(__KERNEL_NAME__);
198 rho_vitesse_impl(tab_rho_face_np1,present,ref_cast_non_const(DoubleTab,present));
224 for (
auto& itr : lescl)
231 int nfin = ndeb + la_front_dis.
nb_faces();
233 DoubleTabView secmem = tab_secmem.
view_rw();
234 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(ndeb, nfin), KOKKOS_LAMBDA(
const int num_face)
236 for (
int dir=0; dir<dim; dir++)
237 secmem(num_face,dir)*=rho_face_np1(num_face);
239 end_gpu_timer(__KERNEL_NAME__);
247 statistics().begin_count(STD_COUNTERS::ajouter_blocs,statistics().get_last_opened_counter_level()+1);
249 Matrice_Morse *mat = matrices.count(nom_inco)?matrices.at(nom_inco):
nullptr;
255 DoubleTrav rhovitesse(present);
262 const int nb_compo = present.
line_size();
264 auto tab1 = mat->
get_tab1().view_ro();
265 CIntArrView tab2 = mat->
get_tab2().view_ro();
266 CDoubleArrView rho_face_np1 =
static_cast<const ArrOfDouble&
>(tab_rho_face_np1).view_ro();
268 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), mat->
nb_lignes(), KOKKOS_LAMBDA(
const int i)
270 for (
auto k=tab1(i)-1; k<tab1(i+1)-1; k++)
273 double rapport = rho_face_np1(j/nb_compo);
277 end_gpu_timer(__KERNEL_NAME__);
283 statistics().end_count(STD_COUNTERS::ajouter_blocs);
286 statistics().begin_count(STD_COUNTERS::source_terms,statistics().get_last_opened_counter_level()+1);
287 for (
int i = 0; i < eqn.
sources().size(); i++)
288 eqn.
sources()(i)->ajouter_blocs(matrices, tab_secmem, semi_impl);
289 statistics().end_count(STD_COUNTERS::source_terms);
291 statistics().begin_count(STD_COUNTERS::ajouter_blocs,statistics().get_last_opened_counter_level()+1);
293 rho_vitesse_impl(tab_rho_face_np1,present,ref_cast_non_const(DoubleTab,present));
319 for (
auto& itr : lescl)
327 int nfin = ndeb + la_front_dis.
nb_faces();
329 DoubleTabView secmem = tab_secmem.
view_rw();
330 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(ndeb, nfin), KOKKOS_LAMBDA(
const int num_face)
332 for (
int dir=0; dir<dim; dir++)
333 secmem(num_face,dir)*=rho_face_np1(num_face);
335 end_gpu_timer(__KERNEL_NAME__);
339 statistics().end_count(STD_COUNTERS::ajouter_blocs);
346 Cerr <<
"Navier_Stokes_Fluide_Dilatable_Proto::assembler is not coded ! You should use assembler_avec_inertie !" << finl;
355void Navier_Stokes_Fluide_Dilatable_Proto::prepare_and_solve_u_star(
Navier_Stokes_std& eqn,
357 DoubleTab& rhoU, DoubleTab& vpoint)
360 const DoubleTab& tab_rho = fluide_dil.
rho_discvit();
376 DoubleTrav trav(vpoint);
387 const Champ_base& rho_vit=eqn.
get_champ(
"rho_comme_v");
388 ref_cast_non_const(DoubleTab,rho_vit.
valeurs())=tab_rho_face_np1;
392 DoubleTrav secmemV(vpoint);
407 DoubleTrav dr(tab_rho_face_n);
409 CDoubleTabView tab_rho_face_n_v = tab_rho_face_n.
view_ro();
410 CDoubleTabView tab_rho_face_np1_v = tab_rho_face_np1.view_ro();
411 DoubleTabView dr_v = dr.view_rw();
412 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), dr.size_totale(),
416 dr_v(i, 0) = (tab_rho_face_n_v(i, 0) / tab_rho_face_np1_v(i, 0) - 1.) / dt;
418 end_gpu_timer(__KERNEL_NAME__);
437 vpoint -= rhovitesse;
443 update_vpoint_on_boundaries(eqn,fluide_dil,vpoint);
447void Navier_Stokes_Fluide_Dilatable_Proto::update_vpoint_on_boundaries(
const Navier_Stokes_std& eqn,
449 DoubleTab& tab_vpoint)
458 const int taille = tab_vpoint.
line_size();
463 for (
auto& itr : lescl)
465 const Cond_lim_base& la_cl_base = itr.valeur();
466 if (sub_type(Dirichlet,la_cl_base))
468 const Front_VF& la_front_dis = ref_cast(Front_VF,la_cl_base.
frontiere_dis());
469 const Dirichlet& diri=ref_cast(Dirichlet,la_cl_base);
474 ToDo_Kokkos(
"critical");
475 for (
int num_face=ndeb; num_face<nfin; num_face++)
477 int n0 = face_voisins(num_face, 0);
478 if (n0 == -1) n0 = face_voisins(num_face, 1);
482 tab_vit(num_face)*tab_rho_face_n(num_face))/dt_;
489 CDoubleArrView rho_face_np1 =
static_cast<const ArrOfDouble&
>(tab_rho_face_np1).view_ro();
490 CDoubleArrView rho_face_n =
static_cast<const ArrOfDouble&
>(tab_rho_face_n).view_ro();
491 CDoubleTabView vit = tab_vit.
view_ro();
492 DoubleTabView vpoint = tab_vpoint.
view_wo();
493 Kokkos::MDRangePolicy<Kokkos::Rank<2>> policy({ndeb, 0}, {nfin, dim});
494 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), policy, KOKKOS_LAMBDA(
const int num_face,
const int jj)
497 vpoint(num_face,jj)=(rho_face_np1(num_face)*val_imp(num_face-ndeb,jj)
498 -rho_face_n(num_face)*vit(num_face,jj))/dt_;
500 end_gpu_timer(__KERNEL_NAME__);
507void Navier_Stokes_Fluide_Dilatable_Proto::solve_pressure_increment(
Navier_Stokes_std& eqn,
509 DoubleTab& rhoU, DoubleTab& secmem,
510 DoubleTab& inc_pre, DoubleTab& vpoint)
524 DoubleTrav vpoint0(vpoint);
527 if (sub_type(Transport_Interfaces_base,prob.
equation(i)))
529 Transport_Interfaces_base& eq_transport = ref_cast(Transport_Interfaces_base,prob.
equation(i));
531 DoubleTab source_ibc(nb,m);
539 operator_negate(secmem);
546 Debog::verifier(
"Navier_Stokes_Fluide_Dilatable_base::derivee_en_temps_inco, secmem : ", secmem);
550 eqn.assembleur_pression()->modifier_secmem(secmem);
555void Navier_Stokes_Fluide_Dilatable_Proto::correct_and_compute_u_np1(
Navier_Stokes_std& eqn,
557 DoubleTab& rhoU,DoubleTab& Mmoins1grad,
558 DoubleTab& inc_pre,DoubleTab& gradP,
561 const DoubleTab& tab_rho_face_np1=fluide_dil.
rho_face_np1();
570 operator_add(press, inc_pre, VECT_ALL_ITEMS);
571 eqn.assembleur_pression()->modifier_solution(press);
585 vpoint -= Mmoins1grad;
592 tab_divide_any_shape(vpoint, tab_rho_face_np1);
599 Debog::verifier(
"Navier_Stokes_Fluide_Dilatable_base::derivee_en_temps_inco, vpoint : ", vpoint);
DoubleTab & futur(int i=1) override
Returns field values at instant t+i.
DoubleTab & passe(int i=1) override
Returns field values at instant t-i.
DoubleTab & valeurs() override
Returns the array of field values at the current time.
virtual DoubleTab & valeurs()=0
class Champ_base This class is the base of the fields hierarchy.
class Cond_lim_base Base class for the hierarchy of classes that represent the different boundary con...
virtual Frontiere_dis_base & frontiere_dis()
Returns the discretized boundary to which the boundary conditions apply.
class Conds_lim This class represents a vector of boundary conditions.
static void verifier(const char *const msg, double)
Dirichlet This class is the base class of the hierarchy of Dirichlet-type boundary conditions.
virtual double val_imp(int i) const
Returns the imposed value on the i-th component of the field at the boundary at the default time of c...
virtual const DoubleTab & tab_val_imp(double temps=DMAXFLOAT) const
double volume_total() const
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
virtual IntTab & face_voisins()
DoubleTab & derivee_en_temps_conv(DoubleTab &, const DoubleTab &)
Add convection term In: solution is the unknown I.
Sources & sources()
Returns the source terms associated with the equation.
Solveur_Masse_base & solv_masse()
Returns the mass solver associated with the equation.
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Returns the discretized boundary condition domain associated with the equation.
Probleme_base & probleme()
Returns the problem associated with the equation.
Schema_Temps_base & schema_temps()
Returns the time scheme associated with the equation.
void Gradient_conjugue_diff_impl(DoubleTrav &secmem, DoubleTab &solution)
Domaine_dis_base & domaine_dis()
Returns the discretized domain associated with the equation.
const Nom & le_nom() const override
Returns the name of the field.
Base class for a dilatable fluid, inheriting from Fluide_base.
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
Matrix-vector multiply-accumulate operation (saxpy).
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
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)
Computes the time derivative of the velocity unknown, i.e. the acceleration dU/dt,...
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)
Navier_Stokes_std This class carries the terms of the momentum equation.
virtual const Champ_Inc_base & rho_la_vitesse() const
const Milieu_base & milieu() const override
Returns the physical medium of the equation (Fluide_base upcast to Milieu_base).
const Champ_Inc_base & inconnue() const override
Returns the velocity (unknown field of the equation) (const version).
const Fluide_base & fluide() const
Returns the incompressible fluid (physical medium of the equation) associated with the equation.
virtual const Champ_Inc_base & vitesse() const
Operateur_Div & operateur_divergence()
Returns the divergence operator associated with the equation.
const Champ_base & get_champ(const Motcle &nom) const override
Operateur_Grad & operateur_gradient()
Returns the gradient operator associated with the equation.
DoubleTab & corriger_derivee_expl(DoubleTab &) override
Add a specific term for Navier Stokes (-gradP(n)) if necessary.
const Operateur & operateur(int) const override
Returns the i-th operator of the equation: - terme_diffusif if i = 0.
Matrice & matrice_pression()
SolveurSys & solveur_pression()
Returns the pressure solver (const version).
bool has_champ(const Motcle &nom, OBS_PTR(Champ_base) &ref_champ) const override
int nombre_d_operateurs() const override
Returns the number of operators in the equation: 2 for the standard Navier-Stokes equations.
Champ_Inc_base & pression()
const std::string & getString() const
void volumique(DoubleTab &) const
Initializes the array passed as parameter with the contribution of the operator.
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
Adds the contribution of the operator to the array passed as parameter.
DoubleTab & calculer(const DoubleTab &, DoubleTab &) const override
Initializes the array passed as parameter with the contribution of the operator.
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
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
const Domaine & domaine() const
Returns the domain associated with the problem.
const Schema_Temps_base & schema_temps() const
Returns the time scheme associated with the problem.
virtual int nombre_d_equations() const =0
virtual const Equation_base & equation(int) const =0
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
int diffusion_implicite() const
Returns 1 if the time scheme has been read with diffusion_implicite.
double temps_courant() const
Returns the current time.
double pas_de_temps() const
Returns the current time step (delta_t).
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
Returns appliquer_impl(x/temporal_coefficient) if a temporal coefficient is set, otherwise returns ap...
void set_name_of_coefficient_temporel(const Nom &)
Allows choosing the name of the temporal coefficient to use for apply.
Base class for output streams.
void contribuer_a_avec(const DoubleTab &, Matrice_Morse &) const
Contribution to the implicit matrix of source terms. By default, no contribution.
DoubleTab & ajouter(DoubleTab &) const
Adds the contribution of all sources in the list to the array passed as parameter,...
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