TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Diffusion_croisee_echelle_temp_taux_diss_turb_PolyMAC_MPFA.cpp
1/****************************************************************************
2* Copyright (c) 2021, 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 <Diffusion_croisee_echelle_temp_taux_diss_turb_PolyMAC_MPFA.h>
17
18#include <Dissipation_type_helpers.h>
19#include <Energie_cinetique_turbulente.h>
20#include <Champ_Elem_PolyMAC_MPFA.h>
21#include <Echange_impose_base.h>
22#include <Domaine_PolyMAC_MPFA.h>
23#include <Domaine_Cl_PolyMAC_family.h>
24#include <Probleme_base.h>
25#include <Neumann_paroi.h>
26#include <Dirichlet.h>
27
28Implemente_instanciable(Diffusion_croisee_echelle_temp_taux_diss_turb_PolyMAC_MPFA, "Diffusion_croisee_echelle_temp_taux_diss_turb_Elem_PolyMAC_MPFA", Source_Diffusion_croisee_echelle_temp_taux_diss_turb);
29
31
33
35{
36 const Probleme_base& pb = equation().probleme();
37
38 for (int i = 0; i < pb.nombre_d_equations(); i++)
39 {
40 const Equation_base& eq_i = pb.equation(i);
41 for (int j = 0; j < eq_i.domaine_Cl_dis().nb_cond_lim(); j++)
42 {
43 const Cond_lim& cond_lim_loc = eq_i.domaine_Cl_dis().les_conditions_limites(j);
44 if (sub_type(Echange_impose_base, cond_lim_loc.valeur()))
45 {
46 if (sub_type(Energie_cinetique_turbulente, eq_i))
48 else if (sub_type(Echelle_temporelle_turbulente, eq_i) || sub_type(Taux_dissipation_turbulent, eq_i))
50 }
51 }
52 }
53}
54
55/*! @brief Compute the face gradient of a PolyMAC_MPFA cell field using fgrad tables.
56 *
57 * Handles element contributions and boundary conditions (Echange_impose_base,
58 * Neumann_paroi, Dirichlet) via the fcl dispatch table.
59 *
60 * @param ch the PolyMAC_MPFA cell field whose fgrad tables are used
61 * @param field_passe values at the previous time step
62 * @param grad_fixe if true, use init_grad (fixed stencil); otherwise calc_grad (recomputed each step)
63 * @param nf number of faces
64 * @param N line size (number of components)
65 * @param nb_elem_tot total number of elements (real + virtual)
66 * @param grad_f [out] face gradient array (nf, N)
67 */
68static void compute_face_gradient(const Champ_Elem_PolyMAC_MPFA& ch,
69 const DoubleTab& field_passe,
70 const bool grad_fixe,
71 const int nf, const int N, const int nb_elem_tot,
72 DoubleTrav& grad_f)
73{
74 if (grad_fixe)
75 ch.init_grad(0);
76 else
77 ch.calc_grad(0);
78
79 const IntTab& f_d = ch.fgrad_d;
80 const IntTab& f_e = ch.fgrad_e;
81 const DoubleTab& f_w = ch.fgrad_w;
82 const IntTab& fcl = ch.fcl();
84
85 for (int f = 0; f < nf; f++)
86 for (int n = 0; n < N; n++)
87 {
88 grad_f(f, n) = 0;
89 for (int j = f_d(f); j < f_d(f + 1); j++)
90 {
91 const int e = f_e(j);
92 const int f_bord = e - nb_elem_tot;
93 if (f_bord < 0) // contribution d'un element
94 grad_f(f, n) += f_w(j) * field_passe(e, n);
95 else if (fcl(f_bord, 0) == 1 || fcl(f_bord, 0) == 2) // Echange_impose_base
96 grad_f(f, n) += (f_w(j) ? f_w(j, n) * ref_cast(Echange_impose_base, cls[fcl(f_bord, 1)].valeur()).T_ext(fcl(f_bord, 2), n) : 0);
97 else if (fcl(f_bord, 0) == 4) // Neumann non homogene
98 grad_f(f, n) += (f_w(j) ? f_w(j, n) * ref_cast(Neumann_paroi, cls[fcl(f_bord, 1)].valeur()).flux_impose(fcl(f_bord, 2), n) : 0);
99 else if (fcl(f_bord, 0) == 6) // Dirichlet
100 grad_f(f, n) += f_w(j) * ref_cast(Dirichlet, cls[fcl(f_bord, 1)].valeur()).val_imp(fcl(f_bord, 2), n);
101 }
102 }
103}
104
105void Diffusion_croisee_echelle_temp_taux_diss_turb_PolyMAC_MPFA::ajouter_blocs(matrices_t matrices, DoubleTab& secmem, const tabs_t& semi_impl) const
106{
107 const Domaine_PolyMAC_MPFA& domaine = ref_cast(Domaine_PolyMAC_MPFA, equation().domaine_dis());
108 const Champ_Elem_PolyMAC_MPFA& ch_k = ref_cast(Champ_Elem_PolyMAC_MPFA, equation().probleme().get_champ("k"));
109 const DoubleTab& k_passe = ch_k.passe();
110 const DoubleTab& xp = domaine.xp();
111 const DoubleTab& xv = domaine.xv();
112
113 const IntTab& e_f = domaine.elem_faces();
114 const IntTab& f_e = domaine.face_voisins();
115 const DoubleVect& pe = equation().milieu().porosite_elem();
116 const DoubleVect& ve = domaine.volumes();
117 const DoubleVect& fs = domaine.face_surfaces();
118
119 const Champ_Elem_PolyMAC_MPFA& ch_diss = ref_cast(Champ_Elem_PolyMAC_MPFA, equation().inconnue());
120 const DoubleTab& diss_passe = ch_diss.passe();
121 const DoubleTab& diss = ch_diss.valeurs();
122
123 const int nf = domaine.nb_faces();
124 const int D = dimension;
125 const int nb_elem = domaine.nb_elem();
126 const int nb_elem_tot = domaine.nb_elem_tot();
127 const int N = diss_passe.line_size();
128
129 const std::string Type_diss = get_dissipation_type(equation());
130
131 assert(N == 1 || k_passe.line_size() == 1); // si Ntau > 1 il vaut mieux iterer sur les id_composites des phases turbulentes decrites par un modele k-tau
132
133 /* Calcul de grad de tau/omega et de k aux faces */
134
135 DoubleTrav grad_f_diss(nf, N);
136 compute_face_gradient(ch_diss, diss_passe, f_grad_tau_omega_fixe_, nf, N, nb_elem_tot, grad_f_diss);
137
138 DoubleTrav grad_f_k(nf, N);
139 compute_face_gradient(ch_k, k_passe, f_grad_k_fixe_, nf, N, nb_elem_tot, grad_f_k);
140
141 /* Calcul de grad(tau/omega).grad(k) */
142
143 DoubleTrav grad_f_diss_dot_grad_f_k(nb_elem, N);
144 for (int e = 0; e < nb_elem; e++)
145 for (int n = 0; n < N; n++)
146 {
147 std::array grad_diss = {0., 0., 0.};
148 std::array grad_k = {0., 0., 0.};
149
150 int f {0};
151 for (int j = 0; j < e_f.dimension(1) && (f = e_f(e, j)) >= 0; j++)
152 {
153 const double coeff = (e == f_e(f, 0) ? 1 : -1) * fs(f) / ve(e);
154 for (int d = 0; d < D; d++)
155 {
156 const double w = coeff * (xv(f, d) - xp(e, d));
157 grad_diss.at(d) += w * grad_f_diss(f, n);
158 grad_k.at(d) += w * grad_f_k(f, n);
159 }
160 }
161
162 double dot = 0.;
163 for (int d = 0; d < D; d++)
164 dot += grad_diss.at(d) * grad_k.at(d);
165 grad_f_diss_dot_grad_f_k(e, n) = dot;
166 }
167
168 /* Remplissage des matrices et du second membre */
169
170 Matrice_Morse* const M = matrices.count(ch_diss.le_nom().getString()) ? matrices.at(ch_diss.le_nom().getString()) : nullptr;
171
172 for (int e = 0; e < nb_elem; e++)
173 for (int n = 0; n < N; n++)
174 {
175 const double peve = pe(e) * ve(e);
176
177 if (Type_diss == "tau")
178 {
179 const double dot_min = std::min(grad_f_diss_dot_grad_f_k(e, n), 0.);
180 secmem(e, n) += peve * sigma_d_ * diss(e, n) * dot_min;
181 if (M)
182 (*M)(N * e + n, N * e + n) -= peve * sigma_d_ * dot_min;
183 }
184 else if (Type_diss == "omega")
185 {
186 if (diss(e, n) > 1.e-8)
187 {
188 const double dp = std::max(diss_passe(e, n), 1.e-6);
189 const double dot_max = std::max(grad_f_diss_dot_grad_f_k(e, n), 0.);
190 secmem(e, n) += peve * sigma_d_ / dp * (2 - diss(e, n) / dp) * dot_max;
191 if (M)
192 (*M)(N * e + n, N * e + n) -= peve * sigma_d_ * (-1. / (dp * dp)) * dot_max;
193 }
194 }
195 }
196}
: class Champ_Elem_PolyMAC_MPFA
void calc_grad(int full_stencil) const
void init_grad(int full_stencil) const
const IntTab & fcl() const
DoubleTab & passe(int i=1) override
Renvoie les valeurs du champs a l'instant t-i.
const Domaine_Cl_dis_base & domaine_Cl_dis() const
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
classe Cond_lim Classe generique servant a representer n'importe quelle classe
Definition Cond_lim.h:31
classe Conds_lim Cette classe represente un vecteur de conditions aux limites.
Definition Conds_lim.h:32
void ajouter_blocs(matrices_t matrices, DoubleTab &secmem, const tabs_t &semi_impl={}) const override
void completer() override
Met a jour les references internes a l'objet Source_base.
classe Dirichlet Cette classe est la classe de base de la hierarchie des conditions aux limites de ty...
Definition Dirichlet.h:31
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
classe Echange_impose_base: Cette condition limite sert uniquement pour l'equation d'energie.
classe Echelle_temporelle_turbulente Equation de transport de l'echelle temporelle turbulente (modele...
classe Energie_cinetique_turbulente Equation de transport d'une energie cinetique turbulente (modeles...
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
virtual const Milieu_base & milieu() const =0
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.
const Nom & le_nom() const override
Renvoie le nom du champ.
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
DoubleVect & porosite_elem()
Definition Milieu_base.h:58
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.
const std::string & getString() const
Definition Nom.h:92
static int dimension
Definition Objet_U.h:99
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 Probleme_base C'est un Probleme_U qui n'est pas un couplage.
virtual int nombre_d_equations() const =0
virtual const Equation_base & equation(int) const =0
Classe de base des flux de sortie.
Definition Sortie.h:52
const Champ_base & get_champ(const Motcle &nom) const override
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
int line_size() const
Definition TRUSTVect.tpp:67
classe Taux_dissipation_turbulent Equation de transport du taux de dissipation turbulen (modele k-ome...