TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Convection_Diffusion_Espece_Multi_QC.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_Espece_Multi_QC.h>
17#include <Navier_Stokes_Turbulent_QC.h>
18#include <Fluide_Quasi_Compressible.h>
19#include <Neumann_sortie_libre.h>
20#include <Loi_Etat_Multi_GP_QC.h>
21#include <Discretisation_base.h>
22#include <Navier_Stokes_QC.h>
23#include <Probleme_base.h>
24#include <Dirichlet.h>
25#include <TRUSTTrav.h>
26#include <EChaine.h>
27#include <Param.h>
28#include <Perf_counters.h>
29
30Implemente_instanciable(Convection_Diffusion_Espece_Multi_QC,"Convection_Diffusion_Espece_Multi_QC",Convection_Diffusion_Espece_Multi_base);
31// XD convection_diffusion_espece_multi_QC eqn_base convection_diffusion_espece_multi_QC INHERITS_BRACE Species
32// XD_CONT conservation equation for a multi-species quasi-compressible fluid.
33
35{
37}
38
40{
42}
43
45{
47 param.ajouter("espece",&mon_espece_); // XD_ADD_P espece
48 // XD_CONT Assosciate a species (with its properties) to the equation
49}
50
52{
53 if (mot=="diffusion")
54 {
55 Cerr << "Reading and typing of the diffusion operator : " << finl;
56 //associate mu_sur_Sc in the diffusivity
57 terme_diffusif.associer_diffusivite(diffusivite_pour_transport());
58 ref_cast_non_const(Champ_base,terme_diffusif.diffusivite()).nommer("mu_sur_Schmidt");
59 is >> terme_diffusif;
60 // Must call associer_diffusivite_pour_pas_de_temps
61 terme_diffusif.associer_diffusivite_pour_pas_de_temps(diffusivite_pour_pas_de_temps());
62 return 1;
63 }
64 else if (mot=="convection")
65 {
66 const Probleme_base& pb = probleme();
67 const Champ_Inc_base& vit_transportante = (pb.que_suis_je() == "Pb_Thermohydraulique_Especes_Turbulent_QC") ? ref_cast(Navier_Stokes_Turbulent_QC,pb.equation(0)).rho_la_vitesse() :
68 ref_cast(Navier_Stokes_QC,pb.equation(0)).rho_la_vitesse();
69 associer_vitesse(vit_transportante);
70 terme_convectif.associer_vitesse(vit_transportante);
71 is >> terme_convectif;
72 terme_convectif.associer_vitesse(vit_transportante);
73 return 1;
74 }
75 else
77}
78
80{
81 // TODO : FIXME : currently passing mu_sur_Schmidt as parameter; should be replaced by nu_sur_Schmidt
82 return le_fluide->mu_sur_Schmidt();
83}
84
85/*! @brief Associe l inconnue de l equation a la loi d etat,
86 *
87 */
89{
91 Fluide_Quasi_Compressible& le_fluideQC = ref_cast(Fluide_Quasi_Compressible, fluide());
92 Loi_Etat_Multi_GP_QC& loi_etat = ref_cast_non_const(Loi_Etat_Multi_GP_QC, le_fluideQC.loi_etat().valeur());
93 loi_etat.associer_inconnue(l_inco_ch.valeur());
94 loi_etat.associer_espece(*this);
95
96 // fill the modified boundary condition domain with 1 everywhere at the boundary...
97 zcl_modif_ = domaine_Cl_dis();
98
99 Conds_lim& condlims = zcl_modif_->les_conditions_limites();
100 int nb = condlims.size();
101 for (int i = 0; i < nb; i++)
102 {
103 // for each boundary condition we retrieve the front field and set it to 1 even if the BC is a flux (in that case convection will remain zero)
104 if (sub_type(Neumann_sortie_libre, condlims[i].valeur()))
105 {
106 ref_cast(Neumann_sortie_libre,condlims[i].valeur()).tab_ext() = 1;
107 }
108 if (sub_type(Dirichlet, condlims[i].valeur()))
109 {
110 const Frontiere_dis_base& frdis = condlims[i]->frontiere_dis();
111 EChaine toto(" Champ_front_uniforme 1 1");
112 toto >> condlims[i].valeur();
113 condlims[i]->associer_fr_dis_base(frdis);
114 }
115 DoubleTab& T = condlims[i]->champ_front().valeurs();
116 T = 1.;
117 }
118}
119
120/*! @brief Renvoie la derivee en temps de l'inconnue de l'equation.
121 *
122 * Le calcul est le suivant:
123 * d(inconnue)/dt = M^{-1} * (sources - somme(Op_{i}(inconnue))) / rho
124 *
125 * @param (DoubleTab& derivee) le tableau des valeurs de la derivee en temps du champ inconnu
126 * @return (DoubleTab&) le tableau des valeurs de la derivee en temps du champ inconnu
127 */
129{
130 derivee = 0;
131
132 les_sources.ajouter(derivee);
133 solveur_masse->appliquer(derivee);
134 DoubleTrav derivee_bis(derivee);
135
136 // first subtract phi*div(1 U)
137 const DoubleTab& frac_mass = inconnue().valeurs();
138
140
141 int n = frac_mass.dimension_tot(0);
142 for (int i = 0; i < n; i++)
143 derivee_bis(i) = -derivee_bis(i) * frac_mass(i);
144
145 // suite + standard
146 operateur(1).ajouter(derivee_bis);
147 operateur(0).ajouter(derivee_bis);
148
149 solveur_masse->set_name_of_coefficient_temporel("masse_volumique");
150 solveur_masse->appliquer(derivee_bis);
151 solveur_masse->set_name_of_coefficient_temporel("no_coeff");
152 derivee += derivee_bis;
153 return derivee;
154}
155
156void Convection_Diffusion_Espece_Multi_QC::assembler(Matrice_Morse& matrice, const DoubleTab& inco, DoubleTab& resu)
157{
158 resu = 0;
159 const auto& tab1 = matrice.get_tab1();
160 auto& coeff = matrice.get_set_coeff();
161
162 const DoubleTab& rho = get_champ("masse_volumique").valeurs();
163 operateur(0).l_op_base().contribuer_a_avec(inco, matrice);
164 operateur(0).ajouter(resu);
165 int ndl = rho.dimension(0);
166
167 // subtract Divu1 *inco
168 DoubleTrav divu1(inco);
170
171 // add convection
172 operateur(1).l_op_base().contribuer_a_avec(inco, matrice);
173 operateur(1).ajouter(resu);
174
175 for (int i = 0; i < ndl; i++)
176 {
177 resu(i) -= divu1(i) * inco(i);
178 matrice(i, i) += divu1(i);
179 }
180 // divide each row by rho
181 for (int som = 0; som < ndl; som++)
182 {
183 double inv_rho = 1 / rho(som);
184 for (auto k = tab1(som) - 1; k < tab1(som + 1) - 1; k++)
185 coeff(k) *= inv_rho;
186 resu(som) *= inv_rho;
187 }
188
189 les_sources.contribuer_a_avec(inco, matrice);
190 les_sources.ajouter(resu);
191
192 int test_op = 0;
193 {
194 char *theValue = getenv("TRUST_TEST_OPERATEUR_IMPLICITE_BLOQUANT");
195 if (theValue != nullptr)
196 test_op = 1;
197 }
198
199 if (test_op)
200 {
201 DoubleTab test(resu);
202 DoubleTab test2(resu);
203 DoubleTrav resu2(resu);
205 solveur_masse->appliquer(test2);
206 resu2 -= test2;
207 Cerr << " here " << mp_max_abs_vect(resu2) << finl;
208 matrice.ajouter_multvect(inco, test);
209 solveur_masse->appliquer(test);
210 const double max_test = mp_max_abs_vect(test);
211 Cerr << "iii " << max_test << finl;
212
213 if (max_test > 0)
214 {
215
216 for (int i = 0; i < resu.size(); i++)
217 if (std::fabs(test(i)) > 1e-5)
218 Cerr << i << " " << test(i) << finl;
220 }
221 }
222 matrice.ajouter_multvect(inco, resu);
223}
224
225void Convection_Diffusion_Espece_Multi_QC::assembler_blocs_avec_inertie(matrices_t matrices, DoubleTab& secmem, const tabs_t& semi_impl)
226{
227 statistics().begin_count(STD_COUNTERS::ajouter_blocs,statistics().get_last_opened_counter_level()+1);
228 const std::string& nom_inco = inconnue().le_nom().getString();
229 const DoubleTab& inco = inconnue().valeurs();
230 Matrice_Morse *mat = matrices.count(nom_inco) ? matrices.at(nom_inco) : nullptr;
231
232 secmem = 0;
233 const auto& tab1 = mat->get_tab1();
234
235 auto& coeff = mat->get_set_coeff();
236
237 const DoubleTab& rho = get_champ("masse_volumique").valeurs();
238 operateur(0).l_op_base().ajouter_blocs(matrices, secmem, semi_impl);
239
240 int ndl = rho.dimension(0);
241 // divide each row by rho
242 for (int som = 0; som < ndl; som++)
243 {
244 double inv_rho = 1 / rho(som);
245 for (auto k = tab1(som) - 1; k < tab1(som + 1) - 1; k++)
246 coeff(k) *= inv_rho;
247 secmem(som) *= inv_rho;
248 }
249
250 // add convection
251 operateur(1).l_op_base().ajouter_blocs(matrices, secmem, semi_impl);
252
253 // subtract Divu1 *inco
254 DoubleTrav divu1(inco);
256
257 for (int i = 0; i < ndl; i++)
258 {
259 secmem(i) -= divu1(i) * inco(i);
260 if (mat)
261 (*mat)(i, i) += divu1(i);
262 }
263 statistics().end_count(STD_COUNTERS::ajouter_blocs);
264
265 statistics().begin_count(STD_COUNTERS::source_terms,statistics().get_last_opened_counter_level()+1);
266 for (int i = 0; i < sources().size(); i++)
267 sources()(i)->ajouter_blocs(matrices, secmem, semi_impl);
268 statistics().end_count(STD_COUNTERS::source_terms);
269
270 statistics().begin_count(STD_COUNTERS::ajouter_blocs,statistics().get_last_opened_counter_level()+1);
271 if (mat)
272 mat->ajouter_multvect(inco, secmem);
273
274 schema_temps().ajouter_blocs(matrices, secmem, *this);
275
276 if (!discretisation().is_poly_family())
277 modifier_pour_Cl(*mat, secmem);
278
279 statistics().end_count(STD_COUNTERS::ajouter_blocs);
280}
DoubleTab & valeurs() override
Returns the array of field values at the current time.
virtual DoubleTab & valeurs()=0
class Champ_base This class is the base of the fields hierarchy.
Definition Champ_base.h:43
Particular case of Convection_Diffusion_Espece_Multi_base for a quasi-compressible fluid when the tra...
int lire_motcle_non_standard(const Motcle &, Entree &) override
Reads non-simple-type parameters of an Objet_U from an input stream.
void assembler_blocs_avec_inertie(matrices_t matrices, DoubleTab &secmem, const tabs_t &semi_impl) override
DoubleTab & derivee_en_temps_inco(DoubleTab &) override
Renvoie la derivee en temps de l'inconnue de l'equation.
void completer() override
Associe l inconnue de l equation a la loi d etat,.
const Champ_base & diffusivite_pour_pas_de_temps() const override
void assembler(Matrice_Morse &mat_morse, const DoubleTab &present, DoubleTab &secmem) override
Particular case of Convection_Diffusion_Espece_Fluide_Dilatable_base for a quasi-compressible fluid w...
const Champ_base & get_champ(const Motcle &nom) const override
void calculer_div_rho_u_impl(DoubleTab &res, const Convection_Diffusion_Fluide_Dilatable_base &eqn) const
void associer_vitesse(const Champ_base &)
Associates the transporting velocity with the equation.
const Operateur & operateur(int) const override
Returns the operator at the given index: returns terme_diffusif if i = 0,.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Sources & sources()
Returns the source terms associated with the equation.
const Discretisation_base & discretisation() const
Returns the discretization associated with the equation.
virtual void completer()
Completes the construction (initialization) of objects associated with the equation.
Sources les_sources
virtual void modifier_pour_Cl(Matrice_Morse &mat_morse, DoubleTab &secmem) const
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Returns the discretized boundary condition domain associated with the equation.
Probleme_base & probleme()
Returns the problem associated with the equation.
int lire_motcle_non_standard(const Motcle &, Entree &) override
Reads non-simple-type parameters of an Objet_U from an input stream.
Schema_Temps_base & schema_temps()
Returns the time scheme associated with the equation.
const Nom & le_nom() const override
Returns the name of the field.
void associer_espece(const Convection_Diffusion_Espece_Multi_QC &eq)
Associates the physical properties of a species with the state law.
virtual void associer_inconnue(const Champ_Inc_base &inconnue)
Associates the unknown of each mass fraction equation with the state law.
virtual DoubleVect & ajouter_multvect(const DoubleVect &x, DoubleVect &r) const
Matrix-vector multiply-accumulate operation (saxpy).
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
const auto & get_tab1() const
auto & get_set_coeff()
A character string (Nom) in uppercase.
Definition Motcle.h:26
const std::string & getString() const
Definition Nom.h:92
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
virtual void contribuer_a_avec(const DoubleTab &, Matrice_Morse &) const
DOES NOTHING - to override in derived classes.
virtual void ajouter_blocs(matrices_t matrices, DoubleTab &secmem, const tabs_t &semi_impl={ }) const
virtual Operateur_base & l_op_base()=0
virtual DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const =0
Helper class to factorize the readOn method of Objet_U classes.
Definition Param.h:112
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
Definition Param.cpp:364
void begin_count(const STD_COUNTERS &std_cnt, int counter_lvl=-100000)
void end_count(const std::string &custom_count_name, int count_increment=1, long int quantity_increment=0)
End the count of a counter and update the counter values.
virtual const Equation_base & equation(int) const =0
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
virtual void ajouter_blocs(matrices_t matrices, DoubleTab &secmem, const Equation_base &eqn, const tabs_t &semi_impl={}) const
Base class for output streams.
Definition Sortie.h:52
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
_SIZE_ size() const
Definition TRUSTVect.tpp:45