TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Op_Dift_EF_Q1.h
1/****************************************************************************
2* Copyright (c) 2024, 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#ifndef Op_Dift_EF_Q1_included
17#define Op_Dift_EF_Q1_included
18
19#include <Op_Dift_EF_base.h>
20#include <Op_EF_base.h>
21#include <TRUST_Ref.h>
22
23
24class Champ_Uniforme;
25class Matrice_Morse;
26class Domaine_Cl_EF;
27class Domaine_EF;
28
29/*! @brief class Op_Dift_EF_Q1 Cette classe represente l'operateur de diffusion
30 *
31 * La discretisation est EF
32 * Le champ diffuse est scalaire
33 * Le champ de diffusivite est uniforme
34 *
35 */
37{
38 Declare_instanciable(Op_Dift_EF_Q1);
39public:
40
41 void associer_diffusivite(const Champ_base& ) override;
42 inline const Champ_base& diffusivite() const override { return diffusivite_; }
43 inline double diffusivite(int) const
44 {
45 return (diffusivite().valeurs().nb_dim() == 1) ? (diffusivite().valeurs())(0) : (diffusivite().valeurs())(0, 0);
46 }
47
48 DoubleTab& ajouter(const DoubleTab& , DoubleTab& ) const override;
49 DoubleTab& ajouter_new(const DoubleTab& , DoubleTab& ) const;
50 DoubleTab& calculer(const DoubleTab& , DoubleTab& ) const override;
51 double calculer_dt_stab() const override;
52 void calculer_pour_post(Champ_base& espace_stockage,const Nom& option,int comp) const override;
53 void verifier() const;
54 void remplir_nu(DoubleTab&) const override;
55 void remplir_marqueur_elem_CL_paroi(ArrOfInt& ,const Domaine_EF& ,const Domaine_Cl_EF& ) const;
56
57 // Methodes pour l implicite.
58 inline void dimensionner(Matrice_Morse& matrice) const override { Op_EF_base::dimensionner(le_dom_EF.valeur(), la_zcl_EF.valeur(), matrice); }
59 inline void modifier_pour_Cl(Matrice_Morse& matrice, DoubleTab& secmem) const override { Op_EF_base::modifier_pour_Cl(le_dom_EF.valeur(),la_zcl_EF.valeur(), matrice, secmem); }
60 inline void contribuer_a_avec(const DoubleTab& inco, Matrice_Morse& matrice) const override { ajouter_contribution(inco, matrice); }
61 void contribuer_au_second_membre(DoubleTab& ) const override;
62 void ajouter_bords(const DoubleTab&, DoubleTab& ,int contrib_interne=1) const;
63 void ajouter_contribution(const DoubleTab&, Matrice_Morse& ) const;
64 void ajouter_contributions_bords(Matrice_Morse& matrice) const;
65 void ajouter_contribution_new(const DoubleTab&, Matrice_Morse&) const;
66 void ajouter_cas_scalaire(const DoubleTab& inconnue, DoubleTab& resu, DoubleTab& flux_bords, DoubleTab& nu, const Domaine_Cl_EF& domaine_Cl_EF, const Domaine_EF& domaine_EF) const;
67 void ajouter_cas_vectoriel(const DoubleTab& inconnue, DoubleTab& resu, DoubleTab& flux_bords, DoubleTab& nu, const Domaine_Cl_EF& domaine_Cl_EF, const Domaine_EF& domaine_EF, int nb_comp) const;
68
69
70protected :
71 int transpose_; // vaurt zero si on ne veut pas calculer grad u transpose
72 int transpose_partout_; // vaut 1 si on veut calculer grad_u_transpose meme au bord
74 OBS_PTR(Champ_base) diffusivite_;
75
76 DoubleTab& ajouter_scalaire_dim3_nbn_8(const DoubleTab&, DoubleTab&) const;
77 DoubleTab& ajouter_scalaire_dim2_nbn_4(const DoubleTab&, DoubleTab&) const;
78 DoubleTab& ajouter_scalaire_gen(const DoubleTab&, DoubleTab&) const;
79
80 template<AJOUTE_SCAL _T_>
81 DoubleTab& ajouter_scalaire_template(const DoubleTab&, DoubleTab&) const;
82
83 DoubleTab& ajouter_vectoriel_dim3_nbn_8(const DoubleTab&, DoubleTab&) const;
84 DoubleTab& ajouter_vectoriel_dim2_nbn_4(const DoubleTab&, DoubleTab&) const;
85 DoubleTab& ajouter_vectoriel_gen(const DoubleTab&, DoubleTab&) const;
86
87 template<AJOUTE_VECT _T_>
88 DoubleTab& ajouter_vectoriel_template(const DoubleTab&, DoubleTab&) const;
89};
90
92{
93 Declare_instanciable(Op_Dift_EF_Q1_option);
94};
95
96template<AJOUTE_SCAL _T_>
97DoubleTab& Op_Dift_EF_Q1::ajouter_scalaire_template(const DoubleTab& tab_inconnue, DoubleTab& resu) const
98{
99 static constexpr bool IS_GEN = (_T_ == AJOUTE_SCAL::GEN), IS_D3_8 = (_T_ == AJOUTE_SCAL::D3_8), IS_D2_4 = (_T_ == AJOUTE_SCAL::D2_4);
100
101 const Domaine_EF& domaine_ef = ref_cast(Domaine_EF, equation().domaine_dis());
102
103 const int N = IS_GEN ? resu.line_size() : 1;
104 const int nb_som_elem = IS_D3_8 ? 8 : ( IS_D2_4 ? 4 : domaine_ef.domaine().nb_som_elem() /* IS_GEN */);
105 const int const_dimension = IS_D3_8 ? 3 : ( IS_D2_4 ? 2 : Objet_U::dimension /* IS_GEN */);
106 const int dim_fois_nbn = nb_som_elem * const_dimension;
107
108 const DoubleVect& volumes_thilde = domaine_ef.volumes_thilde(), &volumes = domaine_ef.volumes();
109
110 const DoubleTab& bij = domaine_ef.Bij();
111 int nb_elem_tot = domaine_ef.domaine().nb_elem_tot();
112 const IntTab& elems = domaine_ef.domaine().les_elems();
113
115 DoubleVect diffu_turb(diffusivite_turbulente().valeurs());
116 DoubleTab diffu(nu_);
117
118 const double *bij_ptr = bij.addr();
119 const double *inco_ptr = tab_inconnue.addr();
120
121#define bij_(elem,i,j) bij_ptr[elem*dim_fois_nbn+i*const_dimension+j]
122#define inconnue_(som,a) inco_ptr[som * N + a]
123#define resu_(som,a) resu_ptr[som * N + a]
124
125 ArrOfDouble pr(N);
126 for (int elem = 0; elem < nb_elem_tot; elem++)
127 if (elem_contribue(elem))
128 {
129 double pond = volumes_thilde(elem) / volumes(elem) / volumes(elem) * (diffu[elem] + diffu_turb[elem]);
130
131 for (int i1 = 0; i1 < nb_som_elem; i1++)
132 {
133 int glob = elems(elem, i1);
134 for (int yy = 0; yy < N; yy++) pr[yy] = 0;
135
136 for (int i2 = 0; i2 < nb_som_elem; i2++)
137 {
138 int glob2 = elems(elem, i2);
139
140 {
141 double prod = 0;
142 for (int b = 0; b < const_dimension; b++)
143 {
144 prod += bij_(elem,i1,b)*bij_(elem,i2,b);
145 }
146 for (int n = 0; n < N; n++) pr[n] += prod * inconnue_(glob2, n);
147 }
148 }
149 resu(glob) -= pr[0] * pond;
150 }
151 }
152
153 // on ajoute la contribution des bords
154 ajouter_bords(tab_inconnue, resu);
155 return resu;
156
157#undef bij_
158#undef inconnue_
159#undef resu_
160}
161
162template<AJOUTE_VECT _T_>
163DoubleTab& Op_Dift_EF_Q1::ajouter_vectoriel_template(const DoubleTab& tab_inconnue, DoubleTab& resu) const
164{
165 static constexpr bool IS_GEN = (_T_ == AJOUTE_VECT::GEN), IS_D3_8 = (_T_ == AJOUTE_VECT::D3_8), IS_D2_4 = (_T_ == AJOUTE_VECT::D2_4);
166
167 const Domaine_EF& domaine_ef = ref_cast(Domaine_EF, equation().domaine_dis());
168
169 const int N = IS_D3_8 ? 3 : (IS_D2_4 ? 2 : resu.line_size() /* IS_GEN */);
170 const int const_dimension = IS_GEN ? Objet_U::dimension : N;
171 const int nb_som_elem = IS_D3_8 ? 8 : (IS_D2_4 ? 4 : domaine_ef.domaine().nb_som_elem() /* IS_GEN */);
172 const int dim_fois_nbn = nb_som_elem * const_dimension;
173
174 ArrOfInt marqueur_neuman;
175 remplir_marqueur_sommet_neumann(marqueur_neuman, domaine_ef, la_zcl_EF.valeur(), transpose_partout_);
176 ArrOfInt marqueur_paroi;
177 remplir_marqueur_elem_CL_paroi(marqueur_paroi, domaine_ef, la_zcl_EF.valeur());
178
179 const DoubleVect& volumes_thilde = domaine_ef.volumes_thilde(), &volumes = domaine_ef.volumes();
180
181 const DoubleTab& bij = domaine_ef.Bij();
182 int nb_elem_tot = domaine_ef.domaine().nb_elem_tot();
183 const IntTab& elems = domaine_ef.domaine().les_elems();
184
186 DoubleVect diffu_turb(diffusivite_turbulente().valeurs());
187 DoubleTab diffu(nu_);
188
189 const double *bij_ptr = bij.addr();
190 const double *inco_ptr = tab_inconnue.addr();
191 double *resu_ptr = resu.addr();
192
193#define bij_(elem,i,j) bij_ptr[elem*dim_fois_nbn+i*const_dimension+j]
194#define inconnue_(som,a) inco_ptr[som * N + a]
195#define resu_(som,a) resu_ptr[som * N + a]
196
197 ArrOfDouble pr(N);
198
199 for (int elem = 0; elem < nb_elem_tot; elem++)
200 if (elem_contribue(elem))
201 {
202 double pond = volumes_thilde(elem) / volumes(elem) / volumes(elem) * (diffu[elem] + diffu_turb[elem]);
203
204 for (int i1 = 0; i1 < nb_som_elem; i1++)
205 {
206 int glob = elems(elem, i1);
207 for (int yy = 0; yy < N; yy++)
208 pr[yy] = 0;
209 int transpose = (marqueur_neuman[glob] == 1 || N == 1) ? 0 : transpose_;
210 for (int i2 = 0; i2 < nb_som_elem; i2++)
211 {
212 int glob2 = elems(elem, i2);
213
214 {
215 double prod = 0;
216 double prod2 = 0;
217 for (int b = 0; b < const_dimension; b++)
218 {
219 prod += bij_(elem,i1,b)*bij_(elem,i2,b);
220 if (transpose)
221 prod2+=bij_(elem,i1,b)*inconnue_(glob2,b);
222 }
223 for (int n = 0; n < N; n++) pr[n] += prod * inconnue_(glob2, n) + prod2 * bij_(elem, i2, n);
224 }
225 }
226 for (int n = 0; n < N; n++) resu_(glob, n)-= pr[n] * pond;
227 }
228 }
229
230 // on ajoute la contribution des bords
231 ajouter_bords(tab_inconnue, resu);
232 return resu;
233
234#undef bij_
235#undef inconnue_
236#undef resu_
237}
238
239#endif
virtual DoubleTab & valeurs()=0
classe Champ_Uniforme Represente un champ constant dans l'espace et dans le temps.
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
int_t nb_elem_tot() const
Definition Domaine.h:132
IntTab_t & les_elems()
Definition Domaine.h:129
class Domaine_EF
Definition Domaine_EF.h:59
const DoubleTab & Bij() const
Definition Domaine_EF.h:92
const DoubleVect & volumes_thilde() const
Definition Domaine_EF.h:85
double volumes(int i) const
Definition Domaine_VF.h:113
const Domaine & domaine() const
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Definition MorEqn.h:62
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
static int dimension
Definition Objet_U.h:99
const Champ_Fonc_base & diffusivite_turbulente() const
class Op_Dift_EF_Q1 Cette classe represente l'operateur de diffusion
void calculer_pour_post(Champ_base &espace_stockage, const Nom &option, int comp) const override
const Champ_base & diffusivite() const override
DoubleTab & ajouter_vectoriel_template(const DoubleTab &, DoubleTab &) const
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
void verifier() const
DoubleTab & ajouter_scalaire_dim2_nbn_4(const DoubleTab &, DoubleTab &) const
DoubleTab & ajouter_scalaire_template(const DoubleTab &, DoubleTab &) const
void ajouter_cas_scalaire(const DoubleTab &inconnue, DoubleTab &resu, DoubleTab &flux_bords, DoubleTab &nu, const Domaine_Cl_EF &domaine_Cl_EF, const Domaine_EF &domaine_EF) const
void ajouter_bords(const DoubleTab &, DoubleTab &, int contrib_interne=1) const
void ajouter_contribution_new(const DoubleTab &, Matrice_Morse &) const
void ajouter_contribution(const DoubleTab &, Matrice_Morse &) const
OBS_PTR(Champ_base) diffusivite_
double calculer_dt_stab() const override
Calcul dt_stab.
void ajouter_contributions_bords(Matrice_Morse &matrice) const
void associer_diffusivite(const Champ_base &) override
associe le champ de diffusivite
void contribuer_au_second_membre(DoubleTab &) const override
DOES NOTHING - to override in derived classes.
DoubleTab & ajouter_vectoriel_dim2_nbn_4(const DoubleTab &, DoubleTab &) const
void remplir_nu(DoubleTab &) const override
DoubleTab & ajouter_vectoriel_gen(const DoubleTab &, DoubleTab &) const
double diffusivite(int) const
void ajouter_cas_vectoriel(const DoubleTab &inconnue, DoubleTab &resu, DoubleTab &flux_bords, DoubleTab &nu, const Domaine_Cl_EF &domaine_Cl_EF, const Domaine_EF &domaine_EF, int nb_comp) const
DoubleTab & ajouter_scalaire_gen(const DoubleTab &, DoubleTab &) const
DoubleTab & calculer(const DoubleTab &, DoubleTab &) const override
void dimensionner(Matrice_Morse &matrice) const override
DOES NOTHING - to override in derived classes.
DoubleTab & ajouter_new(const DoubleTab &, DoubleTab &) const
DoubleTab & ajouter_scalaire_dim3_nbn_8(const DoubleTab &, DoubleTab &) const
void remplir_marqueur_elem_CL_paroi(ArrOfInt &, const Domaine_EF &, const Domaine_Cl_EF &) const
DoubleTab & ajouter_vectoriel_dim3_nbn_8(const DoubleTab &, DoubleTab &) const
void modifier_pour_Cl(Matrice_Morse &matrice, DoubleTab &secmem) const override
DOES NOTHING - to override in derived classes.
void contribuer_a_avec(const DoubleTab &inco, Matrice_Morse &matrice) const override
DOES NOTHING - to override in derived classes.
void dimensionner(const Domaine_EF &, const Domaine_Cl_EF &, Matrice_Morse &) const
Dimensionnement de la matrice qui devra recevoir les coefficients provenant de la convection,...
int elem_contribue(const int elem) const
void modifier_pour_Cl(const Domaine_EF &, const Domaine_Cl_EF &, Matrice_Morse &, DoubleTab &) const
Modification des coef de la matrice et du second membre pour les conditions de Dirichlet.
DoubleTab & flux_bords()
_TYPE_ * addr()
int line_size() const
Definition TRUSTVect.tpp:67