TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Navier_Stokes_IBM.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#include <Navier_Stokes_IBM.h>
16#include <Navier_Stokes_std.h>
17#include <Schema_Temps_base.h>
18#include <Source_PDF_base.h>
19#include <Assembleur_base.h>
20#include <Probleme_base.h>
21#include <Fluide_base.h>
22#include <Debog.h>
23#include <Param.h>
24#include <Nom.h>
25
26Implemente_instanciable(Navier_Stokes_IBM, "Navier_Stokes_IBM", Navier_Stokes_std);
27// XD navier_stokes_ibm navier_stokes_standard navier_stokes_ibm INHERITS_BRACE IBM Navier-Stokes equations.
28// XD attr correction_matrice_projection_initiale entier correction_matrice_projection_initiale OPT (IBM advanced) fix
29// XD_CONT matrix of initial projection for PDF
30// XD attr correction_calcul_pression_initiale entier correction_calcul_pression_initiale OPT (IBM advanced) fix initial
31// XD_CONT pressure computation for PDF
32// XD attr correction_vitesse_projection_initiale entier correction_vitesse_projection_initiale OPT (IBM advanced) fix
33// XD_CONT initial velocity computation for PDF
34// XD attr correction_matrice_pression entier correction_matrice_pression OPT (IBM advanced) fix pressure matrix for PDF
35// XD attr matrice_pression_penalisee_H1 entier matrice_pression_penalisee_H1 OPT (IBM advanced) fix pressure matrix for
36// XD_CONT PDF
37// XD attr correction_vitesse_modifie entier correction_vitesse_modifie OPT (IBM advanced) fix velocity for PDF
38// XD attr correction_pression_modifie entier correction_pression_modifie OPT (IBM advanced) fix pressure for PDF
39// XD attr gradient_pression_qdm_modifie entier gradient_pression_qdm_modifie OPT (IBM advanced) fix pressure gradient
40// XD attr correction_variable_initiale entier correction_variable_initiale OPT Modify initial variable
41
43{
45}
46
48{
50 readOn_ibm_proto(is, *this);
51 return is;
52}
53
55{
56 param.ajouter("correction_matrice_projection_initiale", &correction_matrice_projection_initiale_, Param::OPTIONAL);
57 param.ajouter("correction_calcul_pression_initiale", &correction_calcul_pression_initiale_, Param::OPTIONAL);
58 param.ajouter("correction_vitesse_projection_initiale", &correction_vitesse_projection_initiale_, Param::OPTIONAL);
59 param.ajouter("correction_matrice_pression", &correction_matrice_pression_, Param::OPTIONAL);
60 param.ajouter("matrice_pression_penalisee_H1", &matrice_pression_penalisee_H1_, Param::OPTIONAL);
61 param.ajouter("correction_vitesse_modifie", &correction_vitesse_modifie_, Param::OPTIONAL);
62 param.ajouter("correction_pression_modifie", &correction_pression_modifie_, Param::OPTIONAL);
63 param.ajouter("gradient_pression_qdm_modifie", &gradient_pression_qdm_modifie_, Param::OPTIONAL);
66}
67
73
75{
77 {
78 Cerr << "(IBM) Immersed Interface: modified velocity corrector for initial projection." << finl;
79 gradP /= champ_coeff_pdf_som_;
80 }
81}
82
83// assemblage du systeme en pression
85{
86 const double temps = schema_temps().temps_courant();
87 sources().mettre_a_jour(temps);
89
91
92 bool is_dilatable = probleme().is_dilatable();
93 Cerr << "(IBM) Immersed Interface: compute pressure matrix coefficients." << finl;
94 Source_PDF_base& src = dynamic_cast<Source_PDF_base&>((sources())[i_source_pdf_].valeur());
95 // if (src.getInterpolationBool())
96 // {
97 // src.calculer_variable_imposee();
98 // }
100 {
101 Cerr << "(IBM) Immersed Interface: modified pressure matrix for initial projection." << finl;
102 DoubleTab inv_coeff(champ_coeff_pdf_som_);
103 inv_coeff = 1.;
104 inv_coeff *= champ_coeff_pdf_som_;
105 src.multiply_coeff_volume(inv_coeff);
106 inv_coeff.echange_espace_virtuel();
107 assembleur_pression()->assembler_mat(matrice_pression_, inv_coeff, 1, 1);
108 }
109 else
110 {
111 if (!is_dilatable)
112 assembleur_pression()->assembler(matrice_pression_);
113 else
114 {
115 Cerr << "Assembling for quasi-compressible" << finl;
116 assembleur_pression()->assembler_QC(fluide().masse_volumique().valeurs(), matrice_pression_);
117 }
118 }
119
120 // GF en cas de reprise on conserve la valeur de la pression
121 // avant elle ne servait qu' a initialiser le lagrange pour la projection
122 // C'est important pour le Simpler/Piso de bien repartir de la pression
123 // sauvegardee...
124 //la_pression->valeurs()=0.;
125 Debog::verifier("Navier_Stokes_std::preparer_calcul, la_pression av projeter", la_pression->valeurs());
126 if (projection_a_faire())
127 projeter();
128
129 // Au cas ou une cl de pression depend de u que l'on vient de modifier
130 le_dom_Cl_dis->mettre_a_jour(temps);
131 Debog::verifier("Navier_Stokes_std::preparer_calcul, la_pression ap projeter", la_pression->valeurs());
132
133 // Initialisation du champ de pression (resolution de Laplacien(P)=0 avec les conditions limites en pression)
134 // Permet de demarrer la resolution avec une bonne approximation de la pression (important pour le Piso ou P!=0)
135 if (!probleme().reprise_effectuee() && methode_calcul_pression_initiale_ != 3)
136 {
137 Cout << "Estimation du champ de pression au demarrage:" << finl;
138 DoubleTrav secmem(la_pression->valeurs());
139 DoubleTrav vpoint(gradient_P->valeurs());
140 gradient.calculer(la_pression->valeurs(), gradient_P->valeurs());
141 vpoint -= gradient_P->valeurs();
143 {
144 Cerr << "(IBM) Immersed Interface: modified pressure gradient for initial pressure computation." << finl;
145 vpoint /= champ_coeff_pdf_som_;
146 }
148 for (int op = 0; op < nombre_d_operateurs(); op++)
149 operateur(op).ajouter(vpoint);
151 {
152 int mod = 0;
153 if (le_schema_en_temps->pas_de_temps() == 0)
154 {
155 double dt = std::max(le_schema_en_temps->pas_temps_min(), calculer_pas_de_temps());
156 dt = std::min(dt, le_schema_en_temps->pas_temps_max());
157 le_schema_en_temps->set_dt() = (dt);
158 mod = 1;
159 }
160 for (int i = 0; i < sources().size(); i++)
161 {
162 if (sources()(i).valeur().que_suis_je().find("Source_PDF") <= -1)
163 {
164 sources()(i).ajouter(vpoint);
165 }
166 }
167 if (projection_initiale == 0)
168 {
170 {
171 Cerr << "(IBM) Immersed Interface: Dirichlet velocity in initial pressure computation for PDF (if any)." << finl;
172 DoubleTrav secmem_pdf(vpoint);
173 src.calculer_pdf(secmem_pdf);
174 vpoint -= secmem_pdf;
175
176 DoubleTrav secmem_pdf_calculer(vpoint);
177 src.calculer(secmem_pdf_calculer);
178 vpoint += secmem_pdf_calculer;
179
180 vpoint.echange_espace_virtuel();
181 }
182 }
183
184 if (mod)
185 le_schema_en_temps->set_dt() = 0;
186 }
187
188 solveur_masse->appliquer(vpoint);
189 vpoint.echange_espace_virtuel();
190 divergence.calculer(vpoint, secmem);
191 secmem *= -1;
192 secmem.echange_espace_virtuel();
193
194 assembleur_pression_->modifier_secmem_pour_incr_p(la_pression->valeurs(), 1, secmem);
195 DoubleTrav inc_pre(la_pression->valeurs());
196 solveur_pression_.resoudre_systeme(matrice_pression_.valeur(), secmem, inc_pre);
197 Cerr << "Pressure increment computed successfully" << finl;
198
200 {
201 Cerr << "(IBM) Immersed Interface: correction of initial pressure." << finl;
203 inc_pre.echange_espace_virtuel();
204 }
205
206 // On veut que l'espace virtuel soit a jour, donc all_items
207 operator_add(la_pression->valeurs(), inc_pre, VECT_ALL_ITEMS);
208 }
209 // Mise a jour pression
210 la_pression->changer_temps(temps);
212 // Calcul des forces de pression:
213 gradient->calculer_flux_bords();
214
215 // Calcul gradient_P (ToDo rendre coherent avec ::mettre_a_jour()):
216 gradient.calculer(la_pression->valeurs(), gradient_P->valeurs());
217 gradient_P->changer_temps(temps);
218
219 // Calcul divergence_U
220 divergence.calculer(la_vitesse->valeurs(), divergence_U->valeurs());
221 divergence_U->changer_temps(temps);
222
223 if (le_traitement_particulier)
224 le_traitement_particulier->preparer_calcul_particulier();
225
226 Debog::verifier("Navier_Stokes_std::preparer_calcul, vitesse", inconnue());
227 Debog::verifier("Navier_Stokes_std::preparer_calcul, pression", la_pression);
228
229 DoubleTab coeff(champ_coeff_pdf_som_);
230 coeff = 1.;
232 {
233 Cerr << "(IBM) Immersed Interface: H1 penalty of pressure matrix." << finl;
234 coeff /= champ_coeff_pdf_som_;
235 }
236 else if (correction_matrice_pression_ == 1)
237 {
238 Cerr << "(IBM) Immersed Interface: modification of pressure matrix." << finl;
239 coeff *= champ_coeff_pdf_som_;
240 //Cerr<<"Min/max of coefficients: "<< mp_min_vect(champ_coeff_pdf_som_) << " " << mp_max_vect(champ_coeff_pdf_som_) <<finl;
241 }
242 src.multiply_coeff_volume(coeff);
243 coeff.echange_espace_virtuel();
244 assembleur_pression()->assembler_mat(matrice_pression(), coeff, 1, 1);
245
246 return 1;
247}
248
250{
251 bool ddt = Navier_Stokes_std::initTimeStep(dt);
252
254
255 Source_PDF_base& src = dynamic_cast<Source_PDF_base&>((sources())[i_source_pdf_].valeur());
256 src.updateChampRho();
257 bool mat_var = src.get_matrice_pression_variable_bool_();
258 if (mat_var == false)
259 return ddt;
260 Cerr << "(IBM) Immersed Interface: update of pressure matrix coefficents." << finl;
261 DoubleTab coeff;
262 coeff = src.compute_coeff_matrice();
265 //Cerr<<"Min/max of coefficients: "<< mp_min_vect(coeff) << " " << mp_max_vect(coeff) <<finl;
266
268 {
269 Cerr << "(IBM) Immersed Interface: update of pressure matrix." << finl;
270 DoubleTrav inv_coeff(champ_coeff_pdf_som_);
271 inv_coeff = 1.;
272 inv_coeff *= champ_coeff_pdf_som_;
273 src.multiply_coeff_volume(inv_coeff);
274 inv_coeff.echange_espace_virtuel();
275 assembleur_pression()->assembler_mat(matrice_pression(), inv_coeff, 1, 1);
276 }
277
278 return ddt;
279}
280
281// ajoute les contributions des operateurs et des sources
282void Navier_Stokes_IBM::assembler(Matrice_Morse& matrice, const DoubleTab& inco, DoubleTab& resu)
283{
284 assembler_ibm_proto(matrice, inco, resu);
285}
286
287// for IBM methods; on ajoute source PDF au RHS
292
294{
295 // for IBM methods
296 if ( equation_non_resolue() == 0)
297 {
298 Cerr<<"*******(IBM) Use an explicit time scheme (at least Euler explicit + diffusion) with Source_PDF_base.*******"<<finl;
299 abort();
300 }
301}
static void verifier(const char *const msg, double)
Definition Debog.cpp:21
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_champ_coeff_pdf_som(DoubleTab &coeff)
void set_param_ibm_proto(Param &param) const
DoubleTab & derivee_en_temps_inco_ibm_proto(DoubleTab &)
virtual int equation_non_resolue() const
Sources & sources()
Renvoie les termes sources asssocies a l'equation.
virtual int preparer_calcul()
Tout ce qui ne depend pas des autres problemes eventuels.
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
Schema_Temps_base & schema_temps()
Renvoie le schema en temps associe a l'equation.
virtual double calculer_pas_de_temps() const
Calcul du prochain pas de temps.
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
bool initTimeStep(double dt) override
Allocation et initialisation de l'inconnue et des CLs jusqu'a present+dt.
void assembler(Matrice_Morse &mat_morse, const DoubleTab &present, DoubleTab &secmem) override
void set_param(Param &titi) const override
void modify_initial_gradP(DoubleTrav &) override
int correction_vitesse_projection_initiale_
int preparer_calcul() override
Tout ce qui ne depend pas des autres problemes eventuels.
void verify_scheme() override
void modify_initial_variable() override
void derivee_en_temps_inco_sources(DoubleTrav &) override
int correction_matrice_projection_initiale_
classe Navier_Stokes_std Cette classe porte les termes de l'equation de la dynamique
Operateur_Grad gradient
const Champ_Inc_base & inconnue() const override
Renvoie la vitesse (champ inconnue de l'equation) (version const).
const Fluide_base & fluide() const
Renvoie le fluide incompressible (milieu physique de l'equation) associe a l'equation.
virtual void projeter()
Calcule la solution U des equations: | M(U-V)/dt + BtP = 0.
bool initTimeStep(double dt) override
Allocation et initialisation de l'inconnue et des CLs jusqu'a present+dt.
Operateur_Div divergence
void set_param(Param &titi) const override
virtual int projection_a_faire()
const Operateur & operateur(int) const override
Renvoie le i-eme operateur de l'equation: - le terme_diffusif si i = 0.
Matrice & matrice_pression()
virtual void calculer_la_pression_en_pa()
Calcul de "la_pression_en_pa" en fonction de "la_pression".
int nombre_d_operateurs() const override
Renvoie le nombre d'operateurs de l'equation: Pour Navier Stokes Standard c'est 2.
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
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
@ OPTIONAL
Definition Param.h:115
bool is_dilatable() const
static void abort()
Routine de sortie de Trio-U sur une erreur abort().
Definition Process.cpp:570
double temps_courant() const
Renvoie le temps courant.
Classe de base des flux de sortie.
Definition Sortie.h:52
class Source_PDF_base Base class for the source terms for the penalisation of the momentum in the Imm...
const bool & get_matrice_pression_variable_bool_() const
DoubleTab & calculer_pdf(DoubleTab &) const
virtual DoubleTab compute_coeff_matrice() const
virtual void multiply_coeff_volume(DoubleTab &) const
DoubleTab & calculer(DoubleTab &) const override
virtual void correct_incr_pressure(const DoubleTab &, DoubleTab &) const
void mettre_a_jour(double temps)
Mise a jour en temps, de toute les sources de la liste.
Definition Sources.cpp:109
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")