TrioCFD 1.9.9_beta
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
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 Conds_lim This class represents a vector of boundary conditions.
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
Dirichlet This class is the base class of the hierarchy of Dirichlet-type boundary conditions.
Definition Dirichlet.h:31
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
Echange_impose_base: This boundary condition is used only for the energy equation.
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()
Returns the problem associated with the equation.
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
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
Returns the reference to the equation pointed to by MorEqn::mon_equation.
Definition MorEqn.h:62
static int dimension
Definition Objet_U.h:94
const Nom & que_suis_je() const
Returns the string identifying the class.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
const Champ_base & get_champ(const Motcle &nom) const override
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
Base class for output streams.
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