TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Diffusion_supplementaire_echelle_temp_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_supplementaire_echelle_temp_turb_PolyMAC_MPFA.h>
17
18#include <Op_Diff_Turbulent_PolyMAC_MPFA_Elem.h>
19#include <Echelle_temporelle_turbulente.h>
20#include <Viscosite_turbulente_k_tau.h>
21#include <Champ_Elem_PolyMAC_MPFA.h>
22#include <Echange_impose_base.h>
23#include <Domaine_PolyMAC_MPFA.h>
24#include <Domaine_Cl_PolyMAC_family.h>
25#include <Navier_Stokes_std.h>
26#include <Pb_Multiphase.h>
27#include <Matrix_tools.h>
28#include <Array_tools.h>
29#include <Dirichlet.h>
30
31#include <cmath>
32#include <vector>
33
34Implemente_instanciable(Diffusion_supplementaire_echelle_temp_turb_PolyMAC_MPFA,"Diffusion_supplementaire_lin_echelle_temp_turb_Elem_PolyMAC_MPFA|Diffusion_supplementaire_echelle_temp_turb_Elem_PolyMAC_MPFA", Source_Diffusion_supplementaire_echelle_temp_turb);
35
37
39
40void Diffusion_supplementaire_echelle_temp_turb_PolyMAC_MPFA::dimensionner_blocs(matrices_t matrices, const tabs_t& semi_impl) const
41{
43
44 const Domaine_PolyMAC_MPFA& domaine = ref_cast(Domaine_PolyMAC_MPFA, equation().domaine_dis());
45 const Champ_Elem_PolyMAC_MPFA& tau = ref_cast(Champ_Elem_PolyMAC_MPFA, equation().inconnue());
46
47 if (!matrices.count("tau") || semi_impl.count("tau"))
48 return;
49
50 const int N = equation().inconnue().valeurs().line_size();
51 const int ne = domaine.nb_elem();
52 const int ne_tot = domaine.nb_elem_tot();
53
54 tau.init_grad(0);
55 const IntTab& fg_d = tau.fgrad_d;
56 const IntTab& fg_e = tau.fgrad_e;
57 const IntTab& e_f = domaine.elem_faces(); // Tables used in domaine_PolyMAC_MPFA::fgrad
58
59 for (auto &&i_m : matrices)
60 if (i_m.first == "tau")
61 {
62 Matrice_Morse mat;
63 Stencil stencil(0, 2);
64
65 for(int e = 0 ; e < ne ; e++)
66 for (int n=0 ; n<N ; n++)
67 for (int i = 0, f; i < e_f.dimension(1) && (f = e_f(e, i)) >= 0; i++)
68 for (int j = fg_d(f); j < fg_d(f+1) ; j++)
69 {
70 const int ed = fg_e(j);
71 if (ed < ne_tot) //contrib d'un element ; contrib d'un bord : pas de derivee
72 stencil.append_line(N * e + n, N * ed + n);
73 }
74 tableau_trier_retirer_doublons(stencil);
75 Matrix_tools::allocate_morse_matrix(ne_tot, ne_tot, stencil, mat);
76 i_m.second->nb_colonnes() ? *i_m.second += mat : *i_m.second = mat;
77 }
78}
79
80void Diffusion_supplementaire_echelle_temp_turb_PolyMAC_MPFA::ajouter_blocs(matrices_t matrices, DoubleTab& secmem, const tabs_t& semi_impl) const
81{
82 const Domaine_PolyMAC_MPFA& domaine = ref_cast(Domaine_PolyMAC_MPFA, equation().domaine_dis());
83 const Domaine_Cl_PolyMAC_family& zcl = ref_cast(Domaine_Cl_PolyMAC_family, equation().domaine_Cl_dis());
84// const Echelle_temporelle_turbulente& eq = ref_cast(Echelle_temporelle_turbulente, equation());
85 const Champ_Elem_PolyMAC_MPFA& tau = ref_cast(Champ_Elem_PolyMAC_MPFA, equation().inconnue());
86 const DoubleTab& tab_tau = semi_impl.count("tau") ? semi_impl.at("tau") : tau.valeurs();
87 const DoubleTab& tab_tau_passe = tau.passe();
88 const DoubleTab& k = equation().probleme().get_champ("k").valeurs();
89
90 const IntTab& fcl = tau.fcl();
91 const IntTab& e_f = domaine.elem_faces();
92 const IntTab& f_e = domaine.face_voisins();
93 const Conds_lim& cls = zcl.les_conditions_limites();
94// const Op_Diff_Turbulent_PolyMAC_MPFA_Elem& Op_diff_loc = ref_cast(Op_Diff_Turbulent_PolyMAC_MPFA_Elem, eq.operateur(0).l_op_base());
95// const DoubleTab& nu_tot = Op_diff_loc.nu();
96 const DoubleTab& xp = domaine.xp();
97 const DoubleTab& xv = domaine.xv();
98
99 const DoubleVect& pe = equation().milieu().porosite_elem();
100 const DoubleVect& ve = domaine.volumes();
101 const DoubleVect& fs = domaine.face_surfaces();
102
103 const int N = tab_tau.dimension(1);
104 const int nf = domaine.nb_faces();
105 const int ne = domaine.nb_elem();
106 const int ne_tot = domaine.nb_elem_tot();
107 const int D = dimension;
108
109 Matrice_Morse *Mtau = matrices.count("tau") ? matrices.at("tau") : nullptr;
110 Matrice_Morse *Mk = matrices.count("k") ? matrices.at("k") : nullptr;
111
112 DoubleTrav grad_sqrt_tau_faces(nf, N);
113 DoubleTrav grad_sqrt_tau_elems(ne, N*D);
114 DoubleTrav grad_tau_sqrt_tau_faces;
115 DoubleTrav grad_tau_sqrt_tau_elems;
116 if (!semi_impl.count("tau") && (Mtau))
117 {
118 grad_tau_sqrt_tau_faces = DoubleTrav(nf, N);
119 grad_tau_sqrt_tau_elems = DoubleTrav(ne, N*D);
120 }
121
123 tau.init_grad(0); // Initialisation des tables fgrad_d, fgrad_e, fgrad_w qui dependent de la discretisation et du type de conditions aux limites --> pas de mises a jour necessaires
124 else
125 tau.calc_grad(0); // Si on a des CAL qui evoluent avec les lois de paroi, on recalcule le fgrad a chaque pas de temps
126 //
127 const IntTab& fg_d = tau.fgrad_d;
128 const IntTab& fg_e = tau.fgrad_e; // Tables used in domaine_PolyMAC_MPFA::fgrad
129 DoubleTab f_w = tau.fgrad_w;
130
131 // Calculation of grad of root of tau at faces in the past
132
133 for (int f = 0; f < nf; f++)
134 for (int n = 0; n < N; n++)
135 {
136 grad_sqrt_tau_faces(f, n) = 0;
137 for (int j = fg_d(f); j < fg_d(f+1) ; j++)
138 {
139 const int e = fg_e(j);
140 int f_bord {0};
141 if ( (f_bord = e-ne_tot) < 0) //contrib d'un element
142 grad_sqrt_tau_faces(f, n) += f_w(j) * std::sqrt(std::max(limiter_tau_, tab_tau_passe(e, n))) ; // Si implicite ou pas
143 else if (fcl(f_bord, 0) == 1 || fcl(f_bord, 0) == 2) //Echange_impose_base
144 grad_sqrt_tau_faces(f, n) += f_w(j, n) ? f_w(j, n) * ref_cast(Echange_impose_base, cls[fcl(f_bord, 1)].valeur()).T_ext(fcl(f_bord, 2), n) / std::sqrt(std::max(limiter_tau_, tab_tau_passe(domaine.face_voisins(f_bord, 0), n))) : 0;
145 else if (fcl(f_bord, 0) == 4) //Neumann non homogene
146 Process::exit(que_suis_je() + " : Inhomogeneous Neumann BC not allowed when calculating sqrt(tau) !") ;
147 else if (fcl(f_bord, 0) == 6) // Dirichlet
148 grad_sqrt_tau_faces(f, n) += f_w(j) * std::sqrt(ref_cast(Dirichlet, cls[fcl(f_bord, 1)].valeur()).val_imp(fcl(f_bord, 2), n));
149 }
150 }
151
152 if (!semi_impl.count("tau") && (Mtau))
153 for (int f = 0; f < nf; f++)
154 for (int n = 0 ; n < N; n++)
155 {
156 grad_tau_sqrt_tau_faces(f, n) = 0;
157 for (int j = fg_d(f); j < fg_d(f+1) ; j++)
158 {
159 const int e = fg_e(j);
160 int f_bord {0};
161 if ((f_bord = e-ne_tot) < 0) //contrib d'un element
162 grad_tau_sqrt_tau_faces(f, n) += f_w(j) * tab_tau(e, n) / std::sqrt(std::max(limiter_tau_, tab_tau_passe(e, n))) ; // Si implicite ou pas
163 // same bc as sqrt
164 else if (fcl(f_bord, 0) == 1 || fcl(f_bord, 0) == 2) //Echange_impose_base
165 grad_tau_sqrt_tau_faces(f, n) += f_w(j, n) ? f_w(j, n) * ref_cast(Echange_impose_base, cls[fcl(f_bord, 1)].valeur()).T_ext(fcl(f_bord, 2), n) /std::sqrt(std::max(limiter_tau_, tab_tau_passe(domaine.face_voisins(f_bord, 0), n))) : 0;
166 else if (fcl(f_bord, 0) == 4) //Neumann non homogene
167 Process::exit(que_suis_je() + " : Inhomogeneous Neumann BC not allowed when calculating sqrt(tau) !") ;
168 else if (fcl(f_bord, 0) == 6) // Dirichlet
169 grad_tau_sqrt_tau_faces(f, n) += f_w(j) * std::sqrt(ref_cast(Dirichlet, cls[fcl(f_bord, 1)].valeur()).val_imp(fcl(f_bord, 2), n));
170 }
171 }
172
173 // Calculation of grad of root of tau at elements ; same if implicit or explicit
174 for (int e = 0; e < ne; e++)
175 for (int n = 0; n < N ; n++)
176 for (int d = 0; d < D; d++)
177 for (int j = 0, f; j < e_f.dimension(1) && (f = e_f(e, j)) >= 0; j++)
178 grad_sqrt_tau_elems(e, N*d+n) += (e == f_e(f, 0) ? 1 : -1) * fs(f) * (xv(f, d) - xp(e, d)) / ve(e) * grad_sqrt_tau_faces(f, n);
179
180 if (!semi_impl.count("tau") && (Mtau))
181 for (int e = 0; e < ne; e++)
182 for (int n = 0 ; n < N ; n++)
183 for (int d = 0; d < D; d++)
184 for (int j = 0, f; j < e_f.dimension(1) && (f = e_f(e, j)) >= 0; j++)
185 grad_tau_sqrt_tau_elems(e, N*d+n) += (e == f_e(f, 0) ? 1 : -1) * fs(f) * (xv(f, d) - xp(e, d)) / ve(e) * grad_tau_sqrt_tau_faces(f, n);
186
187 for(int e = 0 ; e < ne ; e++)
188 for (int n=0 ; n<N ; n++)
189 {
190 // Second membre
191 double fac = 0 ;
192 for (int d = 0; d<D; d++)
193 fac += grad_sqrt_tau_elems(e, N*d+n)* ((!semi_impl.count("tau") && (Mtau)) ? grad_tau_sqrt_tau_elems(e, N*d+n) :grad_sqrt_tau_elems(e, N*d+n));
194 fac *= pe(e)*ve(e);
195
196 secmem(e, n) += fac * -8 * sigma_tau_ * tab_tau(e,n) * k(e,n);
197
198 if (Mtau)
199 (*Mtau)(N * e + n, N * e + n) += fac * 8 * sigma_tau_ * k(e,n);
200 if (Mk)
201 (*Mk)(N * e + n, N * e + n) += fac * 8 * sigma_tau_ * tab_tau(e,n);
202
203 if (!semi_impl.count("tau") && (Mtau))
204 {
205 for (int i = 0, f; i < e_f.dimension(1) && (f = e_f(e, i)) >= 0; i++)
206 for (int j = fg_d(f); j < fg_d(f+1) ; j++)
207 {
208 const int ed = fg_e(j);
209 if (ed < ne_tot)
210 for (int d = 0; d < D ; d++) //contrib d'un element ; contrib d'un bord : pas de derivee
211 {
212 const double inv_sqrt_tau = (tab_tau_passe(ed, n) > limiter_tau_) ? std::sqrt(1/tab_tau_passe(ed, n)) : std::sqrt(1/limiter_tau_);
213 (*Mtau)(N * e + n, N * ed + n) += pe(e)*ve(e) * 8 * sigma_tau_ * tab_tau(e,n) * k(e,n) * grad_sqrt_tau_elems(e, N*d+n) * (e == f_e(f, 0) ? 1 : -1) * fs(f) * (xv(f, d) - xp(e, d)) / ve(e) * f_w(j) * inv_sqrt_tau ;
214 }
215 }
216 }
217 }
218}
: 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.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
virtual DoubleTab & valeurs()=0
classe Conds_lim Cette classe represente un vecteur de conditions aux limites.
Definition Conds_lim.h:32
Classe Diffusion_supplementaire_echelle_temp_turb_PolyMAC_MPFA Cette classe implemente dans PolyMAC_M...
void dimensionner_blocs(matrices_t matrices, const tabs_t &semi_impl={}) const override
void ajouter_blocs(matrices_t matrices, DoubleTab &secmem, const tabs_t &semi_impl={}) const override
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.
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
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
static void allocate_morse_matrix(const int nb_lines, const int nb_columns, const Stencil &stencil, Matrice_Morse &matrix, const bool &attach_stencil_to_matrix=false)
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
static int dimension
Definition Objet_U.h:99
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_base & get_champ(const Motcle &nom) const override
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
Classe Source_Diffusion_supplementaire_echelle_temp_turb Cette classe implemente la diffusion supplem...
void dimensionner_blocs(matrices_t matrices, const tabs_t &semi_impl={}) const override
void append_line(_TYPE_)
Definition TRUSTTab.tpp:213
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
int line_size() const
Definition TRUSTVect.tpp:67