TrioCFD 1.9.9_beta
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 // Some operators (Axi) have no iterators in VDF... another design anomaly to be fixed someday!
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 // Some operators (Axi) have no iterators in VDF... another design anomaly to be fixed someday!
60 return (bool(iter_)) ? iter_->impr(os) : 0;
61}
62
63/*! @brief Computes the diffusion contribution and stores it in 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 }; //the first op_ext is the local operator
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// Addition of the supplementary term V/(R*R) in the axisymmetric coordinate case
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")) // We are in the case of Navier_Stokes equations
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 << "Problem in Op_Diff_VDF_base::ajoute_terme_pour_axi with the equation type" << finl;
151 Cerr << "No other case than Navier_Stokes_std has been foreseen" << finl;
153 }
154 }
155 }
156}
157
159{
160 // Computation of the stability time step:
161 //
162 //
163 // - The diffusivity is not uniform, therefore:
164 //
165 // dt_stab = Min (1/(2*diffusivite(elem)*coeff(elem))
166 //
167 // where:
168 // coeff = 1/(dx*dx) + 1/(dy*dy) + 1/(dz*dz)
169 //
170 // i ranging over all mesh elements
171 //
172 // Note: in hydraulics the Max is sought over the initial mesh elements
173 // (as in thermics) and not over the momentum control volumes.
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 // If the diffusivity is variable, it must be an element-based field.
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}
Class Champ_Inc_base.
DoubleTab & valeurs() override
Returns the array of field values at the current time.
virtual DoubleTab & valeurs()=0
Champ_Uniforme Represents a field that is constant in space and time.
class Champ_base This class is the base of the fields hierarchy.
Definition Champ_base.h:43
class Champ_front_calc Derived class of Champ_front_var representing
const Equation_base & equation() const
Returns the equation associated with the unknown whose trace is taken.
class Cond_lim Generic class used to represent any class
Definition Cond_lim.h:31
class Domaine_Cl_VDF
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
class Domaine_VDF
Definition Domaine_VDF.h:61
double dim_elem(int, int) const
int orientation(int) const override
inline DoubleVect& Domaine_VDF::porosite_face() {
int nb_faces() const
Returns the total number of 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
Returns the neighbouring element of num_face in 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
class Equation_base The role of an equation is the calculation of one or more fields....
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
Returns the name of the field.
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
const Equation_base & equation() const
Returns the reference to the equation pointed to by MorEqn::mon_equation.
Definition MorEqn.h:62
A character string (Nom) in uppercase.
Definition Motcle.h:26
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
const std::string & getString() const
Definition Nom.h:92
static int dimension
Definition Objet_U.h:94
friend class Sortie
Definition Objet_U.h:70
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
static int bidim_axi
Definition Objet_U.h:97
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
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
Computes the diffusion contribution and stores it in resu.
void completer() override
Associates the operator with the domaine_dis, the domaine_Cl_dis, and the unknown of its equation.
Op_Diff_VDF_base(const Iterateur_VDF_base &iter_base)
Operateur_Diff_base This class is the base of the hierarchy of operators representing.
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
Returns the field corresponding to the true diffusivity of the medium used for the time step computat...
virtual void completer()
Associates the operator with the domaine_dis, the domaine_Cl_dis, and the unknown of its equation.
const std::string & nom_inconnue() const
virtual DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const
virtual Operateur_base & l_op_base()=0
Multiphase thermohydraulics problem of type "3*N equations":
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:391
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
virtual const Champ_base & get_champ_masse_volumique() const
Returns the density field.
virtual int has_champ_masse_volumique() const
Returns 1 if the density field has been associated, 0 otherwise.
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
_SIZE_ size() const
Definition TRUSTVect.tpp:45
int line_size() const
Definition TRUSTVect.tpp:67