TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Op_Diff_VDF_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 <Convection_Diffusion_Temperature_base.h>
17#include <Echange_contact_VDF.h>
18#include <Op_Diff_VDF_base.h>
19#include <Champ_front_calc.h>
20#include <Eval_Diff_VDF.h>
21#include <Pb_Multiphase.h>
22#include <TRUSTTrav.h>
23#include <Operateur.h>
24#include <Motcle.h>
25
26Implemente_base(Op_Diff_VDF_base, "Op_Diff_VDF_base", Operateur_Diff_base);
27
28Sortie& Op_Diff_VDF_base::printOn(Sortie& s) const { return s << que_suis_je(); }
29Entree& Op_Diff_VDF_base::readOn(Entree& s) { return s; }
30
32{
34 // Certains operateurs (Axi) n'ont pas d'iterateurs en VDF... Encore une anomalie dans la conception a corriger un jour !
35 if (iter_)
36 {
37 const bool is_pb_multi = sub_type(Pb_Multiphase, equation().probleme());
38
39 iter_->completer_();
40 const Champ_Inc_base& cc = le_champ_inco ? le_champ_inco.valeur() : equation().inconnue();
41 iter_->associer_champ_convecte_ou_inc(cc, nullptr);
42 iter_->set_name_champ_inco(le_champ_inco ? nom_inconnue() : cc.le_nom().getString());
43 iter_->set_convective_op_pb_type(false /* diff op */, is_pb_multi);
44 iter_->set_multiscalar_diff(equation().diffusion_multi_scalaire());
45 if (is_pb_multi && sub_type(Convection_Diffusion_Temperature_base, equation()))
46 {
47 const Pb_Multiphase& pbm = ref_cast(Pb_Multiphase, equation().probleme());
48 if (pbm.has_correlation("Flux_parietal"))
49 {
50 iter_->associer_correlation_flux_parietal(pbm.get_correlation("Flux_parietal"));
51 iter_->creer_champ_T_paroi_pour_flux_parietal();
52 }
53 }
54 }
55}
56
58{
59 // Certains operateurs (Axi) n'ont pas d'iterateurs en VDF... Encore une anomalie dans la conception a corriger un jour !
60 return (bool(iter_)) ? iter_->impr(os) : 0;
61}
62
63/*! @brief calcule la contribution de la diffusion, la range dans resu
64 *
65 */
66DoubleTab& Op_Diff_VDF_base::calculer(const DoubleTab& inco, DoubleTab& resu) const
67{
68 resu = 0.;
69 return ajouter(inco, resu);
70}
71
73{
74 const Domaine_VDF& zvdf = iter_->domaine();
75 const Domaine_Cl_VDF& zclvdf = iter_->domaine_Cl();
76 op_ext = { this }; //le premier op_ext est l'operateur local
77
78 for (int n_bord = 0; n_bord < zvdf.nb_front_Cl(); n_bord++)
79 {
80 const Cond_lim& la_cl = zclvdf.les_conditions_limites(n_bord);
81 if (sub_type(Echange_contact_VDF, la_cl.valeur()))
82 {
83 const Echange_contact_VDF& cl = ref_cast(Echange_contact_VDF, la_cl.valeur());
84 const Champ_front_calc& ch = ref_cast(Champ_front_calc, cl.T_autre_pb());
85 const Equation_base& o_eqn = ch.equation();
86 const Op_Diff_VDF_base *o_diff = &ref_cast(Op_Diff_VDF_base, o_eqn.operateur(0).l_op_base());
87
88 if (std::find(op_ext.begin(), op_ext.end(), o_diff) == op_ext.end())
89 op_ext.push_back(o_diff);
90 }
91 }
92 op_ext_init_ = 1;
93}
94
95// Ajout du terme supplementaire en V/(R*R) dans le cas des coordonnees axisymetriques
96void Op_Diff_VDF_base::ajoute_terme_pour_axi(matrices_t matrices, DoubleTab& secmem, const tabs_t& semi_impl) const
97{
98 if (equation().domaine_application() == Motcle("Hydraulique")) // On est dans le cas des equations de Navier_Stokes
99 {
100 const std::string& nom_inco = equation().inconnue().le_nom().getString();
101 Matrice_Morse* mat = matrices.count(nom_inco) ? matrices.at(nom_inco) : nullptr;
102 const DoubleTab& inco = semi_impl.count(nom_inco) ? semi_impl.at(nom_inco) : equation().inconnue().valeurs();
103
104 if (Objet_U::bidim_axi == 1)
105 {
106 const Domaine_VDF& zvdf = iter_->domaine();
107 const DoubleTab& xv = zvdf.xv();
108 const IntVect& ori = zvdf.orientation();
109 const IntTab& face_voisins = zvdf.face_voisins();
110 const DoubleVect& volumes_entrelaces = zvdf.volumes_entrelaces();
111 int face, nb_faces = zvdf.nb_faces(); //, cst;
112 double db_diffusivite;
113 Nom nom_eq = equation().que_suis_je();
114 if ((nom_eq == "Navier_Stokes_standard") || (nom_eq == "Navier_Stokes_QC") || (nom_eq == "Navier_Stokes_FT_Disc") || (nom_eq == "QDM_Multiphase"))
115 {
116 const Eval_Diff_VDF& eval = dynamic_cast<const Eval_Diff_VDF&>(iter_->evaluateur());
117 const Champ_base& ch_diff = eval.get_diffusivite();
118 const DoubleTab& tab_diffusivite = ch_diff.valeurs();
119
120 const int N = tab_diffusivite.dimension(1);
121 DoubleTrav diffu_tot(zvdf.nb_elem_tot(), N);
122 if (tab_diffusivite.size() == 1) diffu_tot = tab_diffusivite(0, 0);
123 else diffu_tot = tab_diffusivite;
124
125 for (face = 0; face < nb_faces; face++)
126 for (int n = 0; n < N; n++)
127 if (ori(face) == 0)
128 {
129 const int elem1 = face_voisins(face, 0), elem2 = face_voisins(face, 1);
130
131 if (elem1 == -1) db_diffusivite = diffu_tot(elem2, n);
132 else if (elem2 == -1) db_diffusivite = diffu_tot(elem1, n);
133 else db_diffusivite = 0.5 * (diffu_tot(elem2, n) + diffu_tot(elem1, n));
134
135 double r = xv(face, 0);
136 if (r >= 1.e-24)
137 {
138 if (mat) (*mat)(N * face + n, N * face + n) += db_diffusivite * volumes_entrelaces(face) / (r * r);
139 secmem(face, n) -= inco(face, n) * db_diffusivite * volumes_entrelaces(face) / (r * r);
140 }
141 }
142 }
143 else if (equation().que_suis_je() == "Navier_Stokes_Interface_avec_trans_masse" || equation().que_suis_je() == "Navier_Stokes_Interface_sans_trans_masse"
144 || equation().que_suis_je() == "Navier_Stokes_Front_Tracking" || equation().que_suis_je() == "Navier_Stokes_Front_Tracking_BMOL" /* c'est quoi ce truc ???? un truc de 1900 ? */)
145 {
146 /* Voir le terme source axi dans Interfaces/VDF */
147 }
148 else
149 {
150 Cerr << "Probleme dans Op_Diff_VDF_base::ajoute_terme_pour_axi avec le type de l'equation" << finl;
151 Cerr << "on n'a pas prevu d'autre cas que Navier_Stokes_std" << finl;
153 }
154 }
155 }
156}
157
159{
160 // Calcul du pas de temps de stabilite :
161 //
162 //
163 // - La diffusivite n'est pas uniforme donc:
164 //
165 // dt_stab = Min (1/(2*diffusivite(elem)*coeff(elem))
166 //
167 // avec :
168 // coeff = 1/(dx*dx) + 1/(dy*dy) + 1/(dz*dz)
169 //
170 // i decrivant l'ensemble des elements du maillage
171 //
172 // Rq: en hydraulique on cherche le Max sur les elements du maillage
173 // initial (comme en thermique) et non le Max sur les volumes de Qdm.
174 double dt_stab = DMAXFLOAT;
176 const DoubleTab& diffu = ch_diffu.valeurs(), *alp = sub_type(Pb_Multiphase, equation().probleme()) ? &ref_cast(Pb_Multiphase, equation().probleme()).equation_masse().inconnue().passe() : nullptr;
177 const bool Cdiffu = sub_type(Champ_Uniforme, ch_diffu);
178
179 // Si la diffusivite est variable, ce doit etre un champ aux elements.
180 assert(Cdiffu || diffu.size() == diffu.line_size() * zone_VDF.nb_elem());
181
182 int rho_comme_diff = 0;
184 {
185 const DoubleTab& rho = get_champ_masse_volumique().valeurs();
186 rho_comme_diff = (rho.dimension(1) == diffu.dimension(1));
187 }
188
189 for (int elem = 0; elem < zone_VDF.nb_elem(); elem++)
190 {
191 double h = 0;
192 for (int d = 0 ; d < dimension; d++)
193 {
194 const double l = zone_VDF.dim_elem(elem, d);
195 h += 1. / (l * l);
196 }
197 for (int n = 0; n < diffu.dimension(1); n++)
198 {
199 double alpha_loc = diffu(Cdiffu ? 0 : elem, n);
201 {
202 const DoubleTab& rho = get_champ_masse_volumique().valeurs();
203 alpha_loc/= rho(elem, rho_comme_diff * n);
204 }
205 const double dt_loc = (alp ? (*alp)(elem, n) : 1.0) * 0.5 / ((alpha_loc + DMINFLOAT) * h);
206 if (dt_loc < dt_stab) dt_stab = dt_loc;
207 }
208 }
209
210 return Process::mp_min(dt_stab);
211}
Classe Champ_Inc_base.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
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
classe Champ_front_calc Classe derivee de Champ_front_var qui represente les
const Equation_base & equation() const
Renvoie l'equation associee a l'inconnue dont on prend la trace.
classe Cond_lim Classe generique servant a representer n'importe quelle classe
Definition Cond_lim.h:31
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 dim_elem(int, int) const
int orientation(int) const override
inline DoubleVect& Domaine_VDF::porosite_face() {
int nb_faces() const
renvoie le nombre global de faces.
Definition Domaine_VF.h:471
DoubleVect & volumes_entrelaces()
Definition Domaine_VF.h:99
double xv(int num_face, int k) const
Definition Domaine_VF.h:76
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Definition Domaine_VF.h:418
int nb_elem_tot() const
int nb_front_Cl() const
const Domaine & domaine() const
virtual Champ_front_base & T_autre_pb()
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 Champ_Inc_base & inconnue() const =0
virtual const Operateur & operateur(int) const =0
virtual const Champ_base & get_diffusivite() const final
const Nom & le_nom() const override
Renvoie le nom du champ.
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
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
const std::string & getString() const
Definition Nom.h:92
static int dimension
Definition Objet_U.h:99
friend class Sortie
Definition Objet_U.h:75
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
static int bidim_axi
Definition Objet_U.h:102
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_base Classe de base des operateurs de diffusion VDF
int impr(Sortie &os) const override
DOES NOTHING - to override in derived classes.
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
DoubleTab & calculer(const DoubleTab &, DoubleTab &) const override
calcule la contribution de la diffusion, la range dans resu
void completer() override
Associe l'operateur au domaine_dis, le domaine_Cl_dis, et a l'inconnue de son equation.
Op_Diff_VDF_base(const Iterateur_VDF_base &iter_base)
classe Operateur_Diff_base Cette classe est la base de la hierarchie des operateurs representant
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...
virtual void completer()
Associe l'operateur au domaine_dis, le domaine_Cl_dis, et a l'inconnue de son equation.
const std::string & nom_inconnue() const
virtual DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const
virtual Operateur_base & l_op_base()=0
classe Pb_Multiphase Cette classe represente un probleme de thermohydraulique multiphase de type "3*N...
int has_correlation(std::string nom_correlation) const
const Correlation_base & get_correlation(std::string nom_correlation) const
static double mp_min(double)
Definition Process.cpp:386
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
virtual const Champ_base & get_champ_masse_volumique() const
Renvoie le champ de masse volumique.
virtual int has_champ_masse_volumique() const
Renvoie 1 si la masse volumique a ete associee, 0 sinon.
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
_SIZE_ size() const
Definition TRUSTVect.tpp:45
int line_size() const
Definition TRUSTVect.tpp:67