TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Equation_IBM_proto.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 <Discretisation_base.h>
17#include <Equation_IBM_proto.h>
18#include <Schema_Temps_base.h>
19#include <Source_PDF_base.h>
20#include <Operateur_base.h>
21#include <Probleme_base.h>
22#include <Equation_base.h>
23#include <Operateur.h>
24#include <Param.h>
25#include <Nom.h>
26#include <Perf_counters.h>
27
29{
30 param.ajouter("correction_variable_initiale",&correction_variable_initiale_,Param::OPTIONAL);
31}
32
34{
35 eq_IBM_ = eq;
36
37 int i_source = -1;
38 int nb_source_pdf = 0;
39 int nb_source = eq.sources().size();
40 Cerr << "nb_source : " << nb_source << finl;
41 for(int i = 0; i<nb_source; i++)
42 {
43 //Cerr << (sources())[i]->que_suis_je() << ", " << (sources())[i]->que_suis_je().find("gne") << finl;
44 if ((eq.sources())[i]->que_suis_je().find("Source_PDF") > -1)
45 {
46 i_source = i;
47 nb_source_pdf++;
48 }
49 }
50 if (nb_source_pdf>1)
51 {
52 Cerr<<"(IBM) More than one Source_PDF_base detected."<<finl;
53 Cerr<<"(IBM) Case not supported."<<finl;
54 Cerr<<"Aborting..."<<finl;
55 abort();
56 }
57 i_source_pdf_ = i_source;
58 if (i_source_pdf_ != -1)
59 {
60 Cerr<<"(IBM) Immersed Interface with Source_PDF_base for equation : "<< eq_IBM_->le_nom()<<finl;
61 eq.sources()[i_source_pdf_]->set_description((Nom)"Sum of the PDF source term on the obstacle (~= force/power induced by the obstacle under some assumptions)");
62 Nom the_suffix = eq_IBM_->le_nom().getSuffix(eq_IBM_->probleme().le_nom());
63 eq.sources()[i_source_pdf_]->set_fichier((Nom)the_suffix+"_Bilan_term_induced_by_obstacle");
64 }
65
66 // XXX Elie Saikali
67 // ok pour temperature pour le moment (cas test Comte_Bellot_EF_IBC dans trio ! a corrriger plus tard Michel !)
68 if (i_source_pdf_ == -1 && eq_IBM_->que_suis_je().debute_par("Navier_Stokes"))
69 {
70 Cerr << "No PDF source term read in your equation " << eq_IBM_->que_suis_je() << " !!!"<< finl;
71 Cerr << "Either add this source term or use a non_IBM problem !!!"<< finl;
73 }
74
75 return is;
76}
77
79{
80 if (i_source_pdf_ == -1) return false;
81 Cerr<<"(IBM) initTimeStep_IBM: update of immersed values for equation : "<< eq_IBM_->le_nom() <<finl;
82 Source_PDF_base& src = dynamic_cast<Source_PDF_base&>((eq_IBM_->sources())[i_source_pdf_].valeur());
84
86 {
87 Cerr<<"(IBM) PDF_mobile : updating the shape following shape velocity"<<finl;
88 const Probleme_base& pb = eq_IBM_->probleme();
89 const Domaine_dis_base& le_dom_dis = pb.domaine_dis();
90 const DoubleTab& coords = le_dom_dis.domaine().coord_sommets();
91 Domaine_VF& le_dom_VF = ref_cast_non_const(Domaine_VF, pb.domaine_dis());
92 double delta_t = eq_IBM_->schema_temps().pas_de_temps();
93 double temps= eq_IBM_->schema_temps().temps_courant();
94
95 // Deplacement de la frontiere
96 PDF_model& my_model = ref_cast_non_const(PDF_model, src.get_modele());
97 my_model.affecter_vitesse_shape_IBM(le_dom_VF, coords, temps);
98 DoubleTab& vitesse = ref_cast_non_const(DoubleTab, src.get_modele().get_vitesse_shape_IBM()) ;
99 double raid = my_model.raid();
100 src.update_elem_IBM(vitesse, delta_t,raid);
101 }
102 return true;
103}
104
106{
107 if (i_source_pdf_ == -1) return derivee;
108 Cerr<<"(IBM) Immersed Interface: Dirichlet value in Equation for PDF (if any)."<<finl;
109 Source_PDF_base& src = dynamic_cast<Source_PDF_base&>((eq_IBM_->sources())[i_source_pdf_].valeur());
110
111 // Terme PDF IB value : -rho/delta_t ksi_gamma/epsilon U_gamma
112 DoubleTab secmem_pdf(derivee);
113 src.calculer_pdf(secmem_pdf);
114 derivee -= secmem_pdf;
115 derivee.echange_espace_virtuel();
116
117 // Terme en temps : -rho/delta_t ksi_gamma Un
118 int pdf_bilan = src.get_modele().pdf_bilan();
119 if (pdf_bilan == 1|| pdf_bilan == 2)
120 {
121 int i_traitement_special = 101;
122 int nb_comp = derivee.dimension(1);
123 if (nb_comp == Objet_U::dimension)
124 {
125 //vector; NS
126 // Navier_Stokes_std& eq_NS = ref_cast_non_const(Navier_Stokes_std, eq_IBM);
127 if (eq_IBM_->nombre_d_operateurs() > 1)
128 {
129 // if (eq_NS.vitesse_pour_transport().le_nom()=="rho_u") i_traitement_special = 1;
130 i_traitement_special = 101;
131 }
132 }
133 else if (nb_comp == 1)
134 {
135 //scalar; terme temps en rho
136 i_traitement_special = 1;
137 }
138 else
139 {
140 Cerr << "Equation_IBM_proto: for scalar or vector only; dim = " <<nb_comp<< finl;
142 }
143
144 DoubleTrav secmem_pdf_time(derivee);
145 src.calculer(secmem_pdf_time, i_traitement_special);
146 secmem_pdf += secmem_pdf_time;
147 }
148 else if(pdf_bilan != 0 )
149 {
150 Cerr<<"Source_PDF_EF: Model pdf_bilan must be 0; 1 or 2 only"<<finl;
152 }
153
154 // Sauvegarde de secmem_pdf
155 secmem_pdf.echange_espace_virtuel();
156 src.set_sec_mem_pdf(secmem_pdf);
157
158 return derivee;
159}
160
162{
163 if (i_source_pdf_ == -1) return;
164
165 Source_PDF_base& src = dynamic_cast<Source_PDF_base&>((eq_IBM_->sources())[i_source_pdf_].valeur());
166 src.updateChampRho();
167 DoubleTab coeff;
168 coeff = src.compute_coeff_matrice();
170 Cerr<<"(IBM) preparer_calcul_IBM: Min/max coeff : "<< mp_min_vect(coeff) << " " << mp_max_vect(coeff) <<finl;
171 champ_coeff_pdf_som_ = coeff;
172 modify_initial_variable_ibm_proto(eq_IBM_->inconnue().valeurs());
173}
174
176{
178 {
179 Cerr<<"(IBM) Immersed Interface: modified initial variable."<<finl;
180 const Source_PDF_base& src = dynamic_cast<Source_PDF_base&>((eq_IBM_->sources())[i_source_pdf_].valeur());
182 variable.echange_espace_virtuel();
183 }
184}
185
186// ajoute les contributions des operateurs et des sources
187void Equation_IBM_proto::assembler_ibm_proto(Matrice_Morse& matrice, const DoubleTab& inco, DoubleTab& resu)
188{
189 const double rhoCp = eq_IBM_->get_time_factor();
190 int size_s = eq_IBM_->sources().size();
191
192 // Test de verification de la methode contribuer_a_avec
193 for (int op=0; op<eq_IBM_->nombre_d_operateurs(); op++)
194 eq_IBM_->operateur(op).l_op_base().tester_contribuer_a_avec(inco, matrice);
195
196 // Contribution des operateurs et des sources:
197 // [Vol/dt+A]Inco(n+1)=somme(residu)+Vol/dt*Inco(n)
198 // Typiquement: si Op=flux(Inco) alors la matrice implicite A contient une contribution -dflux/dInco
199 // Exemple: Op flux convectif en VDF:
200 // Op=T*u*S et A=-d(T*u*S)/dT=-u*S
201 const Discretisation_base::type_calcul_du_residu& type_codage=eq_IBM_->probleme().discretisation().codage_du_calcul_du_residu();
203 {
204 if ( eq_IBM_->probleme().discretisation().que_suis_je() == "EF")
205 {
206 // On calcule somme(residu) par contribuer_au_second_membre (typiquement CL non implicitees)
207 // Cette approche necessite de coder 3 methodes (contribuer_a_avec, contribuer_au_second_membre et ajouter pour l'explicite)
208 if (!is_IBM())
209 eq_IBM_->sources().contribuer_a_avec(inco, matrice);
210 else
211 {
212 for (int i = 0; i < size_s; i++)
213 {
214 if (eq_IBM_->sources()(i).valeur().que_suis_je().find("Source_PDF") <= -1)
215 {
216 const Source_base& src_base = eq_IBM_->sources()(i).valeur();
217 src_base.contribuer_a_avec(inco, matrice);
218 }
219 }
220 }
221 statistics().end_count(STD_COUNTERS::matrix_assembly);
222 if (!is_IBM())
223 eq_IBM_->sources().ajouter(resu);
224 else
225 {
226 for (int i = 0; i < size_s; i++)
227 if (eq_IBM_->sources()(i).valeur().que_suis_je().find("Source_PDF") <= -1)
228 eq_IBM_->sources()(i).ajouter(resu);
229 }
230 statistics().begin_count(STD_COUNTERS::matrix_assembly,statistics().get_last_opened_counter_level()+1);
231 matrice.ajouter_multvect(inco, resu); // Add source residual first
232 for (int op = 0; op < eq_IBM_->nombre_d_operateurs(); op++)
233 {
234 eq_IBM_->operateur(op).l_op_base().contribuer_a_avec(inco, matrice);
235 eq_IBM_->operateur(op).l_op_base().contribuer_au_second_membre(resu);
236 }
237 }
238 else
239 {
240 Cerr << "VIA_CONTRIBUER_AU_SECOND_MEMBRE not coded for " << eq_IBM_->que_suis_je() << ":assembler" << finl;
241 Cerr << "with discretisation " << eq_IBM_->probleme().discretisation().que_suis_je() << "" << finl;
243 }
244 // // On calcule somme(residu) par contribuer_au_second_membre (typiquement CL non implicitees)
245 // // Cette approche necessite de coder 3 methodes (contribuer_a_avec, contribuer_au_second_membre et ajouter pour l'explicite)
246 // sources().contribuer_a_avec(inco,matrice);
247 // sources().ajouter(resu);
248 // matrice.ajouter_multvect(inco, resu); // Add source residual first
249 // for (int op = 0; op < nombre_d_operateurs(); op++)
250 // {
251 // operateur(op).l_op_base().contribuer_a_avec(inco, matrice);
252 // operateur(op).l_op_base().contribuer_au_second_membre(resu);
253 // }
254 }
255 else if (type_codage==Discretisation_base::VIA_AJOUTER)
256 {
257 // On calcule somme(residu) par somme(operateur)+sources+A*Inco(n)
258 // Cette approche necessite de coder seulement deux methodes (contribuer_a_avec et ajouter)
259 // Donc un peu plus couteux en temps de calcul mais moins de code a ecrire/maintenir
260 for (int op=0; op<eq_IBM_->nombre_d_operateurs(); op++)
261 {
262 Matrice_Morse mat(matrice);
263 mat.get_set_coeff() = 0.0;
264 eq_IBM_->operateur(op).l_op_base().contribuer_a_avec(inco, mat);
265 if (op == 1) mat *= rhoCp; // la derivee est multipliee par rhoCp pour la convection
266 matrice += mat;
267 statistics().end_count(STD_COUNTERS::matrix_assembly);
268 {
269 DoubleTab resu_tmp(resu);
270 resu_tmp = 0.;
271 eq_IBM_->operateur(op).ajouter(inco, resu_tmp);
272 if (op == 1) resu_tmp *= rhoCp;
273 resu += resu_tmp;
274 }
275 statistics().begin_count(STD_COUNTERS::matrix_assembly,statistics().get_last_opened_counter_level()+1);
276 }
277 if (! is_IBM() )
278 eq_IBM_->sources().contribuer_a_avec(inco,matrice);
279 else
280 {
281 for (int i = 0; i < size_s; i++)
282 if (eq_IBM_->sources()(i).valeur().que_suis_je().find("Source_PDF") <= -1)
283 {
284 const Source_base& src_base = eq_IBM_->sources()(i).valeur();
285 src_base.contribuer_a_avec(inco, matrice);
286 }
287 }
288 statistics().end_count(STD_COUNTERS::matrix_assembly);
289 if (!is_IBM())
290 eq_IBM_->sources().ajouter(resu);
291 else
292 {
293 for (int i = 0; i < size_s; i++)
294 if (eq_IBM_->sources()(i).valeur().que_suis_je().find("Source_PDF") <= -1)
295 eq_IBM_->sources()(i).ajouter(resu);
296 }
297 statistics().begin_count(STD_COUNTERS::matrix_assembly,statistics().get_last_opened_counter_level()+1);
298 matrice.ajouter_multvect(inco, resu); // Ajout de A*Inco(n)
299 // PL (11/04/2018): On aimerait bien calculer la contribution des sources en premier
300 // comme dans le cas VIA_CONTRIBUER_AU_SECOND_MEMBRE mais le cas Canal_perio_3D (keps
301 // periodique plante: il y'a une erreur de periodicite dans les termes sources du modele KEps...
302 }
303 else
304 {
305 Cerr << "Unknown value in Convection_Diffusion_Temperature_IBM::assembler for " << (int)type_codage << finl;
307 }
308
309 // pour ne pas avoir des termes PDF infinis lors de l'ajout de A*Inco(n)
310 if ( is_IBM() )
311 for (int i = 0; i < size_s; i++)
312 {
313 if (eq_IBM_->sources()(i).valeur().que_suis_je().find("Source_PDF") > -1)
314 {
315 const Source_base& src_base = eq_IBM_->sources()(i).valeur();
316 src_base.contribuer_a_avec(inco,matrice);
317 }
318 }
319 // ajouter source PDF avec le bon signe
321}
const DoubleTab_t & coord_sommets() const
Definition Domaine.h:112
class Domaine_VF
Definition Domaine_VF.h:44
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
bool initTimeStep_ibm_proto(double ddt)
void modify_initial_variable_ibm_proto(DoubleTab &)
Entree & readOn_ibm_proto(Entree &is, Equation_base &eq)
void assembler_ibm_proto(Matrice_Morse &mat_morse, const DoubleTab &present, DoubleTab &secmem)
void set_param_ibm_proto(Param &param) const
DoubleTab & derivee_en_temps_inco_ibm_proto(DoubleTab &)
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
Sources & sources()
Renvoie les termes sources asssocies a l'equation.
virtual DoubleVect & ajouter_multvect(const DoubleVect &x, DoubleVect &r) const
Operation de multiplication-accumulation (saxpy) matrice vecteur.
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
auto & get_set_coeff()
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
const Nom getSuffix(const char *const) const
Definition Nom.cpp:281
const Nom & le_nom() const override
Renvoie *this;.
Definition Nom.cpp:563
static int dimension
Definition Objet_U.h:99
: class PDF_model
Definition PDF_model.h:34
int pdf_bilan() const
Definition PDF_model.h:41
void affecter_vitesse_shape_IBM(Domaine_VF &, const DoubleTab &, double)
const DoubleTab & get_vitesse_shape_IBM() const
Definition PDF_model.h:46
bool get_PDF_mobile() const
Definition PDF_model.h:42
double raid() const
Definition PDF_model.h:49
int is_vitesse_PDF_donnee() const
Definition PDF_model.h:48
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
@ OPTIONAL
Definition Param.h:115
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
const Domaine_dis_base & domaine_dis() const
Renvoie le domaine discretise associe au probleme.
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
class Source_PDF_base Base class for the source terms for the penalisation of the momentum in the Imm...
const PDF_model & get_modele() const
void set_sec_mem_pdf(DoubleTab &it)
void update_elem_IBM(DoubleTab &, double, double)
DoubleTab & calculer_pdf(DoubleTab &) const
virtual DoubleTab compute_coeff_matrice() const
virtual void correct_variable(const DoubleTab &, DoubleTab &) const
DoubleTab & calculer(DoubleTab &) const override
classe Source_base Un objet Source_base est un terme apparaissant au second membre d'une
Definition Source_base.h:42
virtual void contribuer_a_avec(const DoubleTab &, Matrice_Morse &) const
contribution a la matrice implicite des termes sources par defaut pas de contribution
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")