TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Op_Diff_VDF_Elem_base.cpp
1/****************************************************************************
2* Copyright (c) 2026, 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 <Op_Diff_VDF_Elem_base.h>
17#include <Echange_contact_VDF.h>
18#include <Champ_P0_VDF.h>
19#include <Matrix_tools.h>
20#include <Array_tools.h>
21#include <Perf_counters.h>
22
23Implemente_base_sans_constructeur(Op_Diff_VDF_Elem_base,"Op_Diff_VDF_Elem_base",Op_Diff_VDF_base);
24
25Sortie& Op_Diff_VDF_Elem_base::printOn(Sortie& s ) const { return s << que_suis_je() ; }
27
29{
30 // Calcul du pas de temps de stabilite :
31 //
32 // - La diffusivite est uniforme donc :
33 //
34 // dt_stab = 1/(2*diffusivite*Max(coef(elem)))
35 //
36 // avec:
37 // coef = 1/(dx*dx) + 1/(dy*dy) + 1/(dz*dz)
38 //
39 // i decrivant l'ensemble des elements du maillage
40 //
41 // Rq : On ne balaie pas l'ensemble des elements puisque
42 // le max de coeff est atteint sur l'element qui realise
43 // a la fois le min de dx le min de dy et le min de dz
44 double dt_stab = DMAXFLOAT;
45 const Domaine_VDF& domaine_VDF = iter_->domaine();
47
49 {
50 double alpha = -123.;
51 if (equation().diffusion_multi_scalaire())
52 {
53 const int nb_comp = static_cast<int>(std::sqrt(diffu.line_size()));
54 std::vector<double> diff_vect(nb_comp);
55
56 for (int i = 0; i < nb_comp; i++)
57 for (int j = 0; j < nb_comp; j++)
58 diff_vect[i] += std::abs(diffu(0, nb_comp * i + j));
59
60 alpha = *std::max_element(diff_vect.begin(), diff_vect.end());
61 }
62 else
63 {
64 // GF le max permet de traiter le multi_inco
65 alpha = max_array(diffu);
66 }
67
68 double coef = 1 / (domaine_VDF.h_x() * domaine_VDF.h_x()) + 1 / (domaine_VDF.h_y() * domaine_VDF.h_y());
69
70 if (dimension == 3)
71 coef += 1 / (domaine_VDF.h_z() * domaine_VDF.h_z());
72
73 if (alpha == 0)
74 dt_stab = DMAXFLOAT;
75 else
76 dt_stab = 0.5 / (alpha * coef);
77
78 return Process::mp_min(dt_stab);
79 }
80
81 if (equation().diffusion_multi_scalaire())
82 return 1e30;
83
84 return Op_Diff_VDF_base::calculer_dt_stab_(domaine_VDF);
85}
86
87void Op_Diff_VDF_Elem_base::contribuer_termes_croises(const DoubleTab& inco, const Probleme_base& autre_pb, const DoubleTab& autre_inco, Matrice_Morse& matrice) const
88{
89 const Domaine_VDF& domaine = iter_->domaine();
90 const IntTab& f_e = domaine.face_voisins();
91 const Domaine_Cl_VDF& zcl = iter_->domaine_Cl();
92 int l;
93
94 // boucle sur les cl pour trouver un paroi_contact
95 for (int i = 0; i < domaine.nb_front_Cl(); i++)
96 {
97 const Cond_lim& la_cl = zcl.les_conditions_limites(i);
98 if (!la_cl->que_suis_je().debute_par("Paroi_Echange_contact")) continue; //pas un Echange_contact
99 const Echange_contact_VDF& cl = ref_cast(Echange_contact_VDF, la_cl.valeur());
100 if (cl.nom_autre_pb() != autre_pb.le_nom()) continue; //not our problem
101
102 std::map<int, std::pair<int, int>> f2e;
103 const Front_VF& fvf = ref_cast(Front_VF, cl.frontiere_dis());
104 for (int j = 0; j < cl.item.dimension(0); j++)
105 if ((l = cl.item(j)) >= 0)
106 {
107 int f = fvf.num_face(j);
108 int e = f_e(f, 0) == -1 ? f_e(f, 1) : f_e(f, 0);
109 f2e[f] = std::make_pair(e, l);
110 }
111 iter_->ajouter_contribution_autre_pb(inco, matrice, la_cl, f2e);
112 }
113}
114
115void Op_Diff_VDF_Elem_base::dimensionner_termes_croises(Matrice_Morse& matrice, const Probleme_base& autre_pb, int nl, int nc) const
116{
117 const Champ_P0_VDF& ch = ref_cast(Champ_P0_VDF, equation().inconnue());
118 const Domaine_VDF& domaine = iter_->domaine();
119 const IntTab& f_e = domaine.face_voisins();
120 const Conds_lim& cls = iter_->domaine_Cl().les_conditions_limites();
121 int i, j, l, f, n, N = ch.valeurs().line_size();
122
123 Stencil stencil(0, 2);
124
125 for (i = 0; i < cls.size(); i++)
126 if (sub_type(Echange_contact_VDF, cls[i].valeur()))
127 {
128 const Echange_contact_VDF& cl = ref_cast(Echange_contact_VDF, cls[i].valeur());
129 if (cl.nom_autre_pb() != autre_pb.le_nom()) continue; //not our problem
130
131 /* stencil */
132 const Front_VF& fvf = ref_cast(Front_VF, cl.frontiere_dis());
133 for (j = 0; j < cl.item.dimension(0); j++)
134 if ((l = cl.item(j)) >= 0)
135 {
136 f = fvf.num_face(j);
137 int e = f_e(f, 0) == -1 ? f_e(f, 1) : f_e(f, 0);
138 for (n = 0; n < N; n++) stencil.append_line(N * e + n, N * l + n);
139 }
140 }
141
142 tableau_trier_retirer_doublons(stencil);
143 Matrix_tools::allocate_morse_matrix(nl, nc, stencil, matrice);
144}
145
146void Op_Diff_VDF_Elem_base::dimensionner_blocs(matrices_t matrices, const tabs_t& semi_impl) const
147{
148 const std::string nom_inco = equation().inconnue().le_nom().getString();
149 if (semi_impl.count(nom_inco)) return; //semi-implicite -> rien a dimensionner
150
152 int n_ext = (int)op_ext.size(); //pour la thermique monolithique
153
154 std::vector<Matrice_Morse *> mat(n_ext);
155 std::vector<int> N(n_ext); //nombre de composantes par probleme de op_ext
156 for (int i = 0; i < n_ext; i++)
157 {
158 N[i] = op_ext[i]->equation().inconnue().valeurs().line_size();
159
160 std::string nom_mat = i ? nom_inco + "/" + op_ext[i]->equation().probleme().le_nom().getString() : nom_inco;
161 mat[i] = matrices.count(nom_mat) ? matrices.at(nom_mat) : nullptr;
162 if(!mat[i]) continue;
163 Matrice_Morse mat2;
164 if(i==0) Op_VDF_Elem::dimensionner(iter_->domaine(), iter_->domaine_Cl(), mat2, equation().diffusion_multi_scalaire());
165 else
166 {
167 int nl = N[0] * iter_->domaine().nb_elem_tot();
168 int nc = N[i] * op_ext[i]->equation().domaine_dis().nb_elem_tot();
169 dimensionner_termes_croises(mat2, op_ext[i]->equation().probleme(),nl, nc);
170 }
171 mat[i]->nb_colonnes() ? *mat[i] += mat2 : *mat[i] = mat2;
172 }
173}
174
175void Op_Diff_VDF_Elem_base::ajouter_blocs(matrices_t matrices, DoubleTab& secmem, const tabs_t& semi_impl) const
176{
178
179 // On commence par l'operateur locale; i.e. *this !
180 iter_->ajouter_blocs(matrices, secmem, semi_impl);
181
182 // On ajoute des termes si axi ...
183 Op_Diff_VDF_base::ajoute_terme_pour_axi(matrices, secmem, semi_impl);
184
185 // On ajoute contribution si monolithique
186 if ((int) op_ext.size() > 1) ajouter_blocs_pour_monolithique(matrices, secmem, semi_impl);
187}
188
189void Op_Diff_VDF_Elem_base::ajouter_blocs_pour_monolithique(matrices_t matrices, DoubleTab& secmem, const tabs_t& semi_impl) const
190{
191 const std::string& nom_inco = equation().inconnue().le_nom().getString();
192 int n_ext = (int)op_ext.size() - 1; // pour la thermique monolithique, -1 car 1er (i.e. *this) est deja fait via ajouter_blocs
193 std::vector<Matrice_Morse *> mat(n_ext);
194 std::vector<const DoubleTab *> inco(n_ext); //inconnues
195
196 for (int i = 0; i < n_ext; i++)
197 {
198 std::string nom_mat = nom_inco + "/" + op_ext[i + 1]->equation().probleme().le_nom().getString();
199 mat[i] = matrices.count(nom_mat) ? matrices.at(nom_mat) : nullptr;
200 if(mat[i])
201 {
202 inco[i] = semi_impl.count(nom_mat) ? &semi_impl.at(nom_mat) : &op_ext[i + 1]->equation().inconnue().valeurs();
203 contribuer_termes_croises(*inco[i], op_ext[i + 1]->equation().probleme(), op_ext[i + 1]->equation().inconnue().valeurs(), *mat[i]);
204 }
205 }
206}
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
classe Champ_P0_VDF Classe qui represente un champ discret P0 par element associe a un domaine discre...
virtual DoubleTab & valeurs()=0
classe Champ_Uniforme Represente un champ constant dans l'espace et dans le temps.
virtual Frontiere_dis_base & frontiere_dis()
Renvoie la frontiere discretisee a laquelle les conditions aux limites s'appliquent.
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
class Domaine_Cl_VDF
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
class Domaine_VDF
Definition Domaine_VDF.h:64
double h_y() const
double h_x() const
double h_z() const
const Domaine & domaine() const
const Nom & nom_autre_pb() const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
virtual const Champ_Inc_base & inconnue() const =0
const Nom & le_nom() const override
Renvoie le nom du champ.
class Front_VF
Definition Front_VF.h:36
int num_face(const int) const
Definition Front_VF.h:68
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)
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Definition MorEqn.h:62
const std::string & getString() const
Definition Nom.h:92
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
class Op_Diff_VDF_Elem_base Cette classe represente l'operateur de diffusion associe a une equation d...
void dimensionner_blocs(matrices_t matrices, const tabs_t &semi_impl) const override
void contribuer_termes_croises(const DoubleTab &inco, const Probleme_base &autre_pb, const DoubleTab &autre_inco, Matrice_Morse &matrice) const override
void dimensionner_termes_croises(Matrice_Morse &, const Probleme_base &autre_pb, int nl, int nc) const override
void ajouter_blocs(matrices_t matrices, DoubleTab &secmem, const tabs_t &semi_impl) const override
double calculer_dt_stab() const override
Calcul dt_stab.
class Op_Diff_VDF_base Classe de base des operateurs de diffusion VDF
double calculer_dt_stab_(const Domaine_VDF &zone_VDF) const
void init_op_ext() const override
void ajoute_terme_pour_axi(matrices_t, DoubleTab &, const tabs_t &) const
void dimensionner(const Domaine_VDF &, const Domaine_Cl_VDF &, Matrice_Morse &, const bool) const
std::vector< const Operateur_Diff_base * > op_ext
virtual const Champ_base & diffusivite() const =0
virtual const Champ_base & diffusivite_pour_pas_de_temps() const
Renvoie le champ_don correspondant a la vraie diffusivite du milieu qui sert pour le calcul du pas de...
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Probleme_U.h:109
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
static double mp_min(double)
Definition Process.cpp:386
Classe de base des flux de sortie.
Definition Sortie.h:52
virtual int has_champ_masse_volumique() const
Renvoie 1 si la masse volumique a ete associee, 0 sinon.
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