TrioCFD 1.9.9_beta
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// assembly of the pressure system
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 on restart, keep the pressure value
121 // previously it was only used to initialize the Lagrange multiplier for the projection
122 // it is important for Simpler/Piso to restart correctly from the saved pressure
123 //la_pression->valeurs()=0.;
124 Debog::verifier("Navier_Stokes_std::preparer_calcul, la_pression av projeter", la_pression->valeurs());
125 if (projection_a_faire())
126 projeter();
127
128 // In case a pressure BC depends on u that was just modified
129 le_dom_Cl_dis->mettre_a_jour(temps);
130 Debog::verifier("Navier_Stokes_std::preparer_calcul, la_pression ap projeter", la_pression->valeurs());
131
132 // Initialise the pressure field (solve Laplacian(P)=0 with pressure boundary conditions)
133 // Allows starting the solve with a good pressure approximation (important for Piso where P!=0)
134 if (!probleme().reprise_effectuee() && methode_calcul_pression_initiale_ != 3)
135 {
136 Cout << "Estimating the pressure field at startup:" << finl;
137 DoubleTrav secmem(la_pression->valeurs());
138 DoubleTrav vpoint(gradient_P->valeurs());
139 gradient.calculer(la_pression->valeurs(), gradient_P->valeurs());
140 vpoint -= gradient_P->valeurs();
142 {
143 Cerr << "(IBM) Immersed Interface: modified pressure gradient for initial pressure computation." << finl;
144 vpoint /= champ_coeff_pdf_som_;
145 }
147 for (int op = 0; op < nombre_d_operateurs(); op++)
148 operateur(op).ajouter(vpoint);
150 {
151 int mod = 0;
152 if (le_schema_en_temps->pas_de_temps() == 0)
153 {
154 double dt = std::max(le_schema_en_temps->pas_temps_min(), calculer_pas_de_temps());
155 dt = std::min(dt, le_schema_en_temps->pas_temps_max());
156 le_schema_en_temps->set_dt() = (dt);
157 mod = 1;
158 }
159 for (int i = 0; i < sources().size(); i++)
160 {
161 if (sources()(i).valeur().que_suis_je().find("Source_PDF") <= -1)
162 {
163 sources()(i).ajouter(vpoint);
164 }
165 }
166 if (projection_initiale == 0)
167 {
169 {
170 Cerr << "(IBM) Immersed Interface: Dirichlet velocity in initial pressure computation for PDF (if any)." << finl;
171 DoubleTrav secmem_pdf(vpoint);
172 src.calculer_pdf(secmem_pdf);
173 vpoint -= secmem_pdf;
174
175 DoubleTrav secmem_pdf_calculer(vpoint);
176 src.calculer(secmem_pdf_calculer);
177 vpoint += secmem_pdf_calculer;
178
179 vpoint.echange_espace_virtuel();
180 }
181 }
182
183 if (mod)
184 le_schema_en_temps->set_dt() = 0;
185 }
186
187 solveur_masse->appliquer(vpoint);
188 vpoint.echange_espace_virtuel();
189 divergence.calculer(vpoint, secmem);
190 secmem *= -1;
191 secmem.echange_espace_virtuel();
192
193 assembleur_pression_->modifier_secmem_pour_incr_p(la_pression->valeurs(), 1, secmem);
194 DoubleTrav inc_pre(la_pression->valeurs());
195 solveur_pression_.resoudre_systeme(matrice_pression_.valeur(), secmem, inc_pre);
196 Cerr << "Pressure increment computed successfully" << finl;
197
199 {
200 Cerr << "(IBM) Immersed Interface: correction of initial pressure." << finl;
202 inc_pre.echange_espace_virtuel();
203 }
204
205 // Ensure the virtual space is up to date, hence all_items
206 operator_add(la_pression->valeurs(), inc_pre, VECT_ALL_ITEMS);
207 }
208 // Update pressure
209 la_pression->changer_temps(temps);
211 // Compute pressure forces:
212 gradient->calculer_flux_bords();
213
214 // Compute gradient_P (ToDo make consistent with ::mettre_a_jour()):
215 gradient.calculer(la_pression->valeurs(), gradient_P->valeurs());
216 gradient_P->changer_temps(temps);
217
218 // Compute divergence_U
219 divergence.calculer(la_vitesse->valeurs(), divergence_U->valeurs());
220 divergence_U->changer_temps(temps);
221
222 if (le_traitement_particulier)
223 le_traitement_particulier->preparer_calcul_particulier();
224
225 Debog::verifier("Navier_Stokes_std::preparer_calcul, vitesse", inconnue());
226 Debog::verifier("Navier_Stokes_std::preparer_calcul, pression", la_pression);
227
228 DoubleTab coeff(champ_coeff_pdf_som_);
229 coeff = 1.;
231 {
232 Cerr << "(IBM) Immersed Interface: H1 penalty of pressure matrix." << finl;
233 coeff /= champ_coeff_pdf_som_;
234 }
235 else if (correction_matrice_pression_ == 1)
236 {
237 Cerr << "(IBM) Immersed Interface: modification of pressure matrix." << finl;
238 coeff *= champ_coeff_pdf_som_;
239 //Cerr<<"Min/max of coefficients: "<< mp_min_vect(champ_coeff_pdf_som_) << " " << mp_max_vect(champ_coeff_pdf_som_) <<finl;
240 }
241 src.multiply_coeff_volume(coeff);
242 coeff.echange_espace_virtuel();
243 assembleur_pression()->assembler_mat(matrice_pression(), coeff, 1, 1);
244
245 return 1;
246}
247
249{
250 bool ddt = Navier_Stokes_std::initTimeStep(dt);
251
253
254 Source_PDF_base& src = dynamic_cast<Source_PDF_base&>((sources())[i_source_pdf_].valeur());
255 src.updateChampRho();
256 bool mat_var = src.get_matrice_pression_variable_bool_();
257 if (mat_var == false)
258 return ddt;
259 Cerr << "(IBM) Immersed Interface: update of pressure matrix coefficents." << finl;
260 DoubleTab coeff;
261 coeff = src.compute_coeff_matrice();
264 //Cerr<<"Min/max of coefficients: "<< mp_min_vect(coeff) << " " << mp_max_vect(coeff) <<finl;
265
267 {
268 Cerr << "(IBM) Immersed Interface: update of pressure matrix." << finl;
269 DoubleTrav inv_coeff(champ_coeff_pdf_som_);
270 inv_coeff = 1.;
271 inv_coeff *= champ_coeff_pdf_som_;
272 src.multiply_coeff_volume(inv_coeff);
273 inv_coeff.echange_espace_virtuel();
274 assembleur_pression()->assembler_mat(matrice_pression(), inv_coeff, 1, 1);
275 }
276
277 return ddt;
278}
279
280// adds contributions from operators and sources
281void Navier_Stokes_IBM::assembler(Matrice_Morse& matrice, const DoubleTab& inco, DoubleTab& resu)
282{
283 assembler_ibm_proto(matrice, inco, resu);
284}
285
286// for IBM methods; adds PDF source to RHS
291
293{
294 // for IBM methods
295 if ( equation_non_resolue() == 0)
296 {
297 Cerr<<"*******(IBM) Use an explicit time scheme (at least Euler explicit + diffusion) with Source_PDF_base.*******"<<finl;
298 abort();
299 }
300}
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()
Returns the source terms associated with the equation.
virtual int preparer_calcul()
Everything that does not depend on other possible problems.
Probleme_base & probleme()
Returns the problem associated with the equation.
Schema_Temps_base & schema_temps()
Returns the time scheme associated with the equation.
virtual double calculer_pas_de_temps() const
Calculation of the next time step.
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
bool initTimeStep(double dt) override
Allocation and initialization of the unknown and boundary conditions until 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
Everything that does not depend on other possible problems.
void verify_scheme() override
void modify_initial_variable() override
void derivee_en_temps_inco_sources(DoubleTrav &) override
int correction_matrice_projection_initiale_
Navier_Stokes_std This class carries the terms of the momentum equation.
Operateur_Grad gradient
const Champ_Inc_base & inconnue() const override
Returns the velocity (unknown field of the equation) (const version).
const Fluide_base & fluide() const
Returns the incompressible fluid (physical medium of the equation) associated with the equation.
virtual void projeter()
Computes the solution U of the equations: | M(U-V)/dt + BtP = 0.
bool initTimeStep(double dt) override
Allocation and initialization of the unknown and boundary conditions until present+dt.
Operateur_Div divergence
void set_param(Param &titi) const override
virtual int projection_a_faire()
const Operateur & operateur(int) const override
Returns the i-th operator of the equation: - terme_diffusif if i = 0.
Matrice & matrice_pression()
virtual void calculer_la_pression_en_pa()
Computes "la_pression_en_pa" from "la_pression".
int nombre_d_operateurs() const override
Returns the number of operators in the equation: 2 for the standard Navier-Stokes equations.
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 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()
Abort routine for TRUST on a fatal error.
Definition Process.cpp:573
double temps_courant() const
Returns the current time.
Base class for output streams.
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)
Time update of all sources in the list.
Definition Sources.cpp:109
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")