TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Op_Dift_VEF_Face.cpp
1/****************************************************************************
2* Copyright (c) 2025, 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 <Check_espace_virtuel.h>
17#include <Discretisation_base.h>
18#include <Op_Dift_VEF_Face.h>
19#include <Milieu_base.h>
20#include <Debog.h>
21
22Implemente_instanciable_sans_constructeur(Op_Dift_VEF_Face, "Op_Dift_VEF_P1NC", Op_Dift_VEF_base);
23
24Op_Dift_VEF_Face::Op_Dift_VEF_Face()
25{
26 declare_support_masse_volumique(1); // pour FT ... BOF
27}
28
29Sortie& Op_Dift_VEF_Face::printOn(Sortie& s) const { return s << que_suis_je(); }
30
31Entree& Op_Dift_VEF_Face::readOn(Entree& s) { return s; }
32
33DoubleTab& Op_Dift_VEF_Face::ajouter(const DoubleTab& inconnue_org, DoubleTab& resu) const
34{
35 remplir_nu(nu_); // On remplit le tableau nu car ajouter peut se faire avant le premier pas de temps
36
37 const DoubleTab& nu_turb = diffusivite_turbulente().valeurs();
38 DoubleTrav nu, nu_turb_m, tab_inconnue;
39 const int nb_comp = resu.line_size();
40
41 // On dimensionne et initialise le tableau des bilans de flux:
42 flux_bords_.resize(le_dom_vef->nb_faces_bord(), nb_comp);
43 flux_bords_ = 0.;
44
45 int marq = phi_psi_diffuse(equation());
46 const DoubleVect& porosite_face = equation().milieu().porosite_face(), &porosite_elem = equation().milieu().porosite_elem();
47
48 // soit on a div(phi nu grad inco) OU on a div(nu grad phi inco) : cela depend si on diffuse phi_psi ou psi
49 modif_par_porosite_si_flag(nu_, nu, !marq, porosite_elem);
50 modif_par_porosite_si_flag(nu_turb, nu_turb_m, !marq, porosite_elem);
51 const DoubleTab& inconnue = modif_par_porosite_si_flag(inconnue_org, tab_inconnue, marq, porosite_face);
52
53 assert_espace_virtuel_vect(nu);
54 assert_espace_virtuel_vect(inconnue);
55 assert_espace_virtuel_vect(nu_turb_m);
56
57 Debog::verifier("Op_Dift_VEF_Face::ajouter nu", nu);
58 Debog::verifier("Op_Dift_VEF_Face::ajouter nu_turb", nu_turb_m);
59 Debog::verifier("Op_Dift_VEF_Face::ajouter inconnue_org", inconnue_org);
60 Debog::verifier("Op_Dift_VEF_Face::ajouter inconnue", inconnue);
61
62 if (equation().inconnue().nature_du_champ() == vectoriel)
63 {
64 fill_grad_Re<Type_Champ::VECTORIEL>(inconnue, resu, nu, nu_turb);
65 ajouter_bord_gen<Type_Champ::VECTORIEL>(inconnue, resu, flux_bords_, nu, nu_turb);
66 ajouter_interne_gen<Type_Champ::VECTORIEL>(inconnue, resu, flux_bords_, nu, nu_turb);
67 }
68 else
69 {
70 ajouter_bord_gen<Type_Champ::SCALAIRE>(inconnue, resu, flux_bords_, nu, nu_turb);
71 ajouter_interne_gen<Type_Champ::SCALAIRE>(inconnue, resu, flux_bords_, nu, nu_turb);
72 }
73
74 modifier_flux(*this);
75
76 return resu;
77}
78
79void Op_Dift_VEF_Face::contribuer_a_avec(const DoubleTab& inco, Matrice_Morse& matrice) const
80{
82 remplir_nu(nu_); // On remplit le tableau nu car l'assemblage d'une matrice avec ajouter_contribution peut se faire avant le premier pas de temps
83
84 const DoubleTab& nu_turb_ = diffusivite_turbulente().valeurs();
85 DoubleTrav nu, nu_turb;
86
87 int marq = phi_psi_diffuse(equation());
88 const DoubleVect& porosite_elem = equation().milieu().porosite_elem();
89
90 // soit on a div(phi nu grad inco) OU on a div(nu grad phi inco) : cela depend si on diffuse phi_psi ou psi
91 modif_par_porosite_si_flag(nu_, nu, !marq, porosite_elem);
92 modif_par_porosite_si_flag(nu_turb_, nu_turb, !marq, porosite_elem);
93
94 DoubleTrav porosite_eventuelle(equation().milieu().porosite_face());
95 porosite_eventuelle = equation().milieu().porosite_face();
96 if (!marq) porosite_eventuelle = 1;
97
98 if (equation().inconnue().nature_du_champ() == vectoriel)
99 {
100 ajouter_contribution_bord_gen<Type_Champ::VECTORIEL>(inco, matrice, nu, nu_turb, porosite_eventuelle);
101 ajouter_contribution_interne_gen<Type_Champ::VECTORIEL>(inco, matrice, nu, nu_turb, porosite_eventuelle);
102 }
103 else
104 {
105 ajouter_contribution_bord_gen<Type_Champ::SCALAIRE>(inco, matrice, nu, nu_turb, porosite_eventuelle);
106 ajouter_contribution_interne_gen<Type_Champ::SCALAIRE>(inco, matrice, nu, nu_turb, porosite_eventuelle);
107 }
108
110}
111
112// bientot a la poubelle// bientot a la poubelle
114{
115 const Domaine_Cl_VEF& domaine_Cl_VEF = domaine_cl_vef();
116 const Domaine_VEF& domaine_VEF = domaine_vef();
117 const IntTab& face_voisins = domaine_VEF.face_voisins();
118 const DoubleTab& face_normale = domaine_VEF.face_normales();
119 const int nb_faces = domaine_VEF.nb_faces(), nb_comp = resu.line_size();
120
121 // On traite les faces bord
122 if (equation().inconnue().nature_du_champ() == vectoriel)
123 {
124 const DoubleTab& nu_turb = diffusivite_turbulente().valeurs(), &inconnue_org = equation().inconnue().valeurs();
125 DoubleTrav nu, nu_turb_m, tab_inconnue;
126
127 int marq = phi_psi_diffuse(equation());
128
129 const DoubleVect& porosite_face = equation().milieu().porosite_face(), &porosite_elem = equation().milieu().porosite_elem();
130
131 // soit on a div(phi nu grad inco) OU on a div(nu grad phi inco) : cela depend si on diffuse phi_psi ou psi
132 modif_par_porosite_si_flag(nu_, nu, !marq, porosite_elem);
133 modif_par_porosite_si_flag(nu_turb, nu_turb_m, !marq, porosite_elem);
134
135 const DoubleTab& inconnue = modif_par_porosite_si_flag(inconnue_org, tab_inconnue, marq, porosite_face);
136
137 DoubleTab& grad = grad_;
138 grad = 0.;
139
140 Champ_P1NC::calcul_gradient(inconnue, grad, domaine_Cl_VEF);
141 DoubleTrav gradsa(grad);
142 gradsa = grad;
143
144 if (le_modele_turbulence->utiliser_loi_paroi())
145 Champ_P1NC::calcul_duidxj_paroi(grad, nu, nu_turb, tau_tan_, domaine_Cl_VEF);
146
147 grad -= gradsa;
149 ToDo_Kokkos("critical");
150 for (int num_face = 0; num_face < nb_faces; num_face++)
151 for (int kk = 0; kk < 2; kk++)
152 {
153 int elem = face_voisins(num_face, kk);
154 if (elem != -1)
155 {
156 int ori = 1 - 2 * kk;
157 for (int i = 0; i < nb_comp; i++)
158 for (int j = 0; j < nb_comp; j++)
159 resu(num_face, i) -= ori * face_normale(num_face, j) * ((nu[elem] + nu_turb[elem]) * grad(elem, i, j) + (nu_turb[elem]) * grad(elem, j, i) /* grad transpose */);
160 }
161 }
162 }
163
164 for (int n_bord = 0; n_bord < domaine_VEF.nb_front_Cl(); n_bord++)
165 {
166 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
167 if (sub_type(Neumann_paroi, la_cl.valeur()))
168 {
169 const Neumann_paroi& la_cl_paroi = ref_cast(Neumann_paroi, la_cl.valeur());
170 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
171 const int ndeb = le_bord.num_premiere_face(), nfin = ndeb + le_bord.nb_faces();
172 ToDo_Kokkos("critical");
173 for (int face = ndeb; face < nfin; face++)
174 for (int comp = 0; comp < nb_comp; comp++)
175 resu(face, comp) += la_cl_paroi.flux_impose(face - ndeb, comp) * domaine_VEF.face_surfaces(face);
176 }
177 else if (sub_type(Echange_externe_impose, la_cl.valeur()))
178 {
179 if (resu.line_size() == 1)
180 {
181 const Echange_externe_impose& la_cl_paroi = ref_cast(Echange_externe_impose, la_cl.valeur());
182 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
183 const int ndeb = le_bord.num_premiere_face(), nfin = ndeb + le_bord.nb_faces();
184 ToDo_Kokkos("critical");
185 for (int face = ndeb; face < nfin; face++)
186 resu[face] += la_cl_paroi.h_imp(face - ndeb) * (la_cl_paroi.T_ext(face - ndeb)) * domaine_VEF.face_surfaces(face);
187 }
188 else
189 Process::exit("Op_Dift_VEF_Face::contribuer_au_second_membre : Non code pour Echange_externe_impose !");
190 }
191 }
192}
DoubleTab & valeurs() override
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
static DoubleTab & calcul_gradient(const DoubleTab &, DoubleTab &, const Domaine_Cl_VEF &)
static DoubleTab & calcul_duidxj_paroi(DoubleTab &, const DoubleTab &, const DoubleTab &, const DoubleTab &, const Domaine_Cl_VEF &)
classe Cond_lim Classe generique servant a representer n'importe quelle classe
Definition Cond_lim.h:31
static void verifier(const char *const msg, double)
Definition Debog.cpp:21
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
class Domaine_VEF
Definition Domaine_VEF.h:54
virtual const DoubleVect & face_surfaces() const
Definition Domaine_VF.h:51
int nb_faces() const
renvoie le nombre global de faces.
Definition Domaine_VF.h:471
virtual double face_normales(int face, int comp) const
Definition Domaine_VF.h:47
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Definition Domaine_VF.h:418
int nb_front_Cl() const
Classe Echange_externe_impose: Cette classe represente le cas particulier de la classe.
virtual double h_imp(int num) const
Renvoie la valeur du coefficient d'echange de chaleur impose sur la i-eme composante.
virtual double T_ext(int num) const
Renvoie la valeur de la temperature imposee sur la i-eme composante du champ de frontiere.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
virtual const Milieu_base & milieu() const =0
virtual const Champ_Inc_base & inconnue() const =0
class Front_VF
Definition Front_VF.h:36
int nb_faces() const
Definition Front_VF.h:53
int num_premiere_face() const
Definition Front_VF.h:63
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
DoubleVect & porosite_elem()
Definition Milieu_base.h:58
DoubleVect & porosite_face()
Definition Milieu_base.h:62
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Definition MorEqn.h:62
Classe Neumann_paroi Cette condition limite correspond a un flux impose pour l'equation de.
virtual double flux_impose(int i) const
Renvoie la valeur du flux impose sur la i-eme composante du champ representant le flux a la frontiere...
Definition Neumann.cpp:35
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
const Champ_Fonc_base & diffusivite_turbulente() const
int phi_psi_diffuse(const Equation_base &eq) const
definit si on calcule div(phi nu grad Psi) ou div(nu grap Phi psi)
virtual void remplir_nu(DoubleTab &) const
const Domaine_VEF & domaine_vef() const
const Domaine_Cl_VEF & domaine_cl_vef() const
std::enable_if_t< _TYPE_==Type_Champ::VECTORIEL, void > ajouter_bord_gen(const DoubleTab &, DoubleTab &, DoubleTab &, const DoubleTab &, const DoubleTab &) const
void fill_grad_Re(const DoubleTab &, const DoubleTab &, const DoubleTab &, const DoubleTab &) const
void ajouter_contribution_bord_gen(const DoubleTab &, Matrice_Morse &, const DoubleTab &, const DoubleTab &, const DoubleVect &) const
std::enable_if_t< _TYPE_==Type_Champ::VECTORIEL, void > ajouter_interne_gen(const DoubleTab &, DoubleTab &, DoubleTab &, const DoubleTab &, const DoubleTab &) const
void ajouter_contribution_interne_gen(const DoubleTab &inco, Matrice_Morse &mat, const DoubleTab &nu, const DoubleTab &nu_turb, const DoubleVect &porosite_eventuelle) const
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
void contribuer_a_avec(const DoubleTab &, Matrice_Morse &) const override
DOES NOTHING - to override in derived classes.
void contribuer_au_second_membre(DoubleTab &resu) const override
DOES NOTHING - to override in derived classes.
void modifier_matrice_pour_periodique_apres_contribuer(Matrice_Morse &matrice, const Equation_base &) const
Somme les 2 lignes des faces periodiques associees permet de calculer dans le code sans se poser de q...
void modifier_matrice_pour_periodique_avant_contribuer(Matrice_Morse &matrice, const Equation_base &) const
divise les coefficients sur les ligne des faces periodiques par 2 en prevision de l'application modif...
void modifier_flux(const Operateur_base &) const
DoubleTab flux_bords_
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe de base des flux de sortie.
Definition Sortie.h:52
virtual void declare_support_masse_volumique(int ok)
Le constructeur d'une classe derivee qui se sert de la masse volumique doit appeler cette fonction av...
int line_size() const
Definition TRUSTVect.tpp:67
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")