TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Milieu_Phase_field.cpp
1/****************************************************************************
2* Copyright (c) 2025, 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 <Milieu_Phase_field.h>
17#include <Pb_Phase_field.h>
18#include <Discret_Thyd.h>
19#include <EChaine.h>
20#include <Param.h>
21
22Implemente_instanciable(Milieu_Phase_field, "Milieu_Phase_field", Fluide_Incompressible);
23
24// XD approx_boussinesq objet_lecture nul NO_BRACE different mass density formulation are available depending if the
25// XD_CONT Boussinesq approximation is made or not
26// XD attr yes_or_no chaine(into=["oui","non"]) yes_or_no REQ To use or not the Boussinesq approximation.
27// XD attr bloc_bouss bloc_boussinesq bloc_bouss REQ to choose the rho formulation
28
29// XD bloc_boussinesq objet_lecture nul BRACE choice of rho formulation
30// XD attr probleme ref_Pb_base probleme OPT Name of problem.
31// XD attr rho_1 floattant rho_1 OPT value of rho
32// XD attr rho_2 floattant rho_2 OPT value of rho
33// XD attr rho_fonc_c bloc_rho_fonc_c rho_fonc_c_ OPT to use for define a general form for rho
34
35// XD bloc_rho_fonc_c objet_lecture nul NO_BRACE if rho has a general form
36// XD attr Champ_Fonc_Fonction chaine(into=["Champ_Fonc_Fonction"]) Champ_Fonc_Fonction OPT Champ_Fonc_Fonction
37// XD attr problem_name ref_Pb_base problem_name OPT Name of problem.
38// XD attr concentration chaine(into=["concentration"]) concentration OPT concentration
39// XD attr dim entier dim OPT dimension of the problem
40// XD attr val chaine val OPT function of rho
41// XD attr Champ_Uniforme chaine(into=["Champ_Uniforme"]) Champ_Uniforme OPT Champ_Uniforme
42// XD attr fielddim entier fielddim OPT dimension of the problem
43// XD attr val2 chaine val2 OPT function of rho
44
45// XD visco_dyn_cons objet_lecture nul NO_BRACE different treatment of the kinematic viscosity could be done depending
46// XD_CONT of the use of the Boussinesq approximation or the constant dynamic viscosity approximation
47// XD attr yes_or_no chaine(into=["oui","non"]) yes_or_no REQ To use or not the constant dynamic viscosity
48// XD attr bloc_visco bloc_visco2 bloc_visco REQ to choose the mu formulation
49
50// XD bloc_visco2 objet_lecture nul BRACE choice of mu formulation
51// XD attr probleme ref_Pb_base probleme OPT Name of problem.
52// XD attr mu_1 floattant mu_1 OPT value of mu
53// XD attr mu_2 floattant mu_2 OPT value of mu
54// XD attr mu_fonc_c bloc_mu_fonc_c mu_fonc_c_ OPT to use for define a general form for mu
55
56// XD bloc_mu_fonc_c objet_lecture nul NO_BRACE if mu has a general form
57// XD attr Champ_Fonc_Fonction chaine(into=["Champ_Fonc_Fonction"]) Champ_Fonc_Fonction OPT Champ_Fonc_Fonction
58// XD attr problem_name ref_Pb_base problem_name OPT Name of problem.
59// XD attr concentration chaine(into=["concentration"]) concentration OPT concentration
60// XD attr dim entier dim OPT dimension of the problem
61// XD attr val chaine val OPT function of mu
62
64{
65 return os << que_suis_je() << " " << le_nom() << finl;
66}
67
69{
71}
72
74{
75 // XD milieu_phase_field fluide_incompressible milieu_phase_field INHERITS_BRACE Class for Phase_field fluid.
77 param.ajouter("Fermeture|Closure", &fermeture_, Param::REQUIRED);
78 param.ajouter_non_std("approximation_de_boussinesq", (this), Param::REQUIRED); // XD_ADD_P approx_boussinesq
79 // XD_CONT To use or not the Boussinesq approximation.
80 param.ajouter_non_std("viscosite_dynamique_constante", (this), Param::OPTIONAL); // XD_ADD_P visco_dyn_cons
81 // XD_CONT To use or not a viscosity which will depends on concentration C (in fact, C is the unknown of Cahn-Hilliard
82 // XD_CONT equation).
83}
84
86{
87 Motcle motlu;
88 if (mot == "approximation_de_boussinesq")
89 {
90 Motcle temp_boussi_;
91 is >> temp_boussi_;
92 bool fonctionsALire = false;
93 if (temp_boussi_ == "oui")
94 {
95 boussi_ = 1;
96 diff_boussi_ = 0;
97 if (!has_beta_c())
98 {
99 fonctionsALire = true;
100 Cerr << "Approximation de Boussinesq utilisee mais beta_co non defini comme propriete du fluide" << finl;
101 Cerr << "On s'attend donc a lire les fonctions rho(c) et drho/dc" << finl;
102 }
103 }
104 else
105 {
106 boussi_ = 0;
107 fonctionsALire = true;
108 }
109 is >> motlu;
110 if (motlu != "{")
111 {
112 Cerr << "Error while reading approximation_de_boussinesq" << finl;
113 Cerr << "We expected a { instead of " << motlu << finl;
115 }
116 is >> motlu;
117 if (fonctionsALire)
118 {
119 if (motlu == "rho_fonc_c")
120 {
121 Cerr << motlu << finl;
122 is >> rho_;
123 is >> drhodc_;
124 is >> motlu;
125 }
126 else
127 {
128 double rho1, rho2;
129 Nom prob;
130 while (motlu != "}")
131 {
132 if (motlu == "probleme")
133 is >> prob;
134 if (motlu == "rho_1")
135 is >> rho1;
136 if (motlu == "rho_2")
137 is >> rho2;
138 is >> motlu;
139 }
140 Nom chaine("Champ_Fonc_Fonction ");
141 chaine += prob;
142 chaine += " concentration 1 ";
143 Nom rhoM(0.5 * (rho1 + rho2));
144 Nom drho(rho2 - rho1);
145 chaine += rhoM;
146 chaine += "+val*(";
147 chaine += drho;
148 chaine += ")";
149 EChaine echaine(chaine);
150 echaine >> rho_;
151 Nom chaine2("Champ_Uniforme 1 ");
152 chaine2 += drho;
153 EChaine echaine2(chaine2);
154 Cerr << "@@@ " << chaine2 << finl;
155 echaine2 >> drhodc_;
156 }
157 }
158 if (motlu != "}")
159 {
160 Cerr << "Error while reading approximation_de_boussinesq" << finl;
161 Cerr << "We expected a } instead of " << motlu << finl;
163 }
164 return 1;
165 }
166 else if (mot == "viscosite_dynamique_constante")
167 {
168 Motcle temp_diffbou_;
169 is >> temp_diffbou_;
170 if (temp_diffbou_ == "oui")
171 {
172 diff_boussi_ = 1;
173 }
174 else
175 {
176 diff_boussi_ = 0;
177 is >> motlu;
178 assert(motlu == "{");
179 is >> motlu;
180 if (motlu == "mu_fonc_c")
181 {
182 Cerr << motlu << finl;
183 is >> mu_;
184 is >> motlu;
185 }
186 else
187 {
188 double mu1, mu2;
189 Nom prob;
190 while (motlu != "}")
191 {
192 if (motlu == "probleme")
193 is >> prob;
194 if (motlu == "mu_1")
195 is >> mu1;
196 if (motlu == "mu_2")
197 is >> mu2;
198 is >> motlu;
199 }
200 Nom chaine("Champ_Fonc_Fonction ");
201 chaine += prob;
202 chaine += " concentration 1 ";
203 Nom muM(0.5 * (mu1 + mu2));
204 Nom dmu(mu2 - mu1);
205 chaine += muM;
206 chaine += "+val*(";
207 chaine += dmu;
208 chaine += ")";
209 EChaine echaine(chaine);
210 echaine >> mu_;
211 }
212 assert(motlu == "}");
213 }
214 if (diff_boussi_ == 1)
215 {
216 // RLT: pas sur de tout a fait comprendre si c'est encore d'actualite mais, en tout cas, en lien avec modification
217 // commentee dans Navier_Stokes_phase_field::calculer_pas_de_temps
218 Cerr << "LE PAS DE TEMPS DE STABILITE (DE DIFFUSION) DOIT ETRE FORCE DANS VDF/Operateurs/OpDifVDFFaCs.cpp : ligne 115" << finl;
219 Cerr << "ATTENTION : LE PAS DE TEMPS DE DIFFUSION SERA ALORS FORCE A LA VALEUR DE 1 SECONDE !!!" << finl;
220 // Ceci est utile car normalement dans ce cas le pas de temps de diffusion ne depend pas de rho
221 // car la viscosite dynamique est constante (on prend alors mu/rho0)
222 // Or dans ce cas TRUST semble calculer ce pas temps avec une influence venant de rho (Debug ?)
223 }
224 return 1;
225 }
226 else
228}
229
231{
232 pb_pf_ = ref_cast(Pb_Phase_field, pb);
234
235 if (mu_)
236 {
237 dis.nommer_completer_champ_physique(pb.domaine_dis(), "viscosite_dynamique", "Pa.s", mu_, pb);
238 champs_compris_.ajoute_champ(mu_);
239 }
240
241 const DoubleTab& rho0Tab = masse_volumique().valeurs();
242 int dim = rho0Tab.nb_dim();
243 switch(dim)
244 {
245 case 2:
246 rho0_ = rho0Tab(0, 0);
247 break;
248 case 3:
249 rho0_ = rho0Tab(0, 0, 0);
250 break;
251 default:
252 Cerr << "Milieu_Phase_field : Problem with rho0 dimension:" << dim << finl;
254 break;
255 }
256
257// if (has_beta_c())
258// betac_ = beta_c();
259
260 if (!rho_)
261 {
262 if (boussi_ != 1)
263 Process::exit("Milieu_Phase_field::discretiser : should not be here (1)");
264
265 dis.discretiser_champ("CHAMP_ELEM", pb.domaine_dis(), "masse_volumique", "kg/m3", 1, 0., rho_);
266 champs_compris_.ajoute_champ(rho_);
267 dis.discretiser_champ("CHAMP_ELEM", pb.domaine_dis(), "derivee_masse_volumique", "kg/m3", 1, 0., drhodc_);
268 champs_compris_.ajoute_champ(drhodc_);
269 }
270 if (rho_->le_nom() == "anonyme")
271 {
272 if (boussi_ == 1 && has_beta_c())
273 Process::exit("Milieu_Phase_field::discretiser : should not be here (2)");
274
275 dis.nommer_completer_champ_physique(pb.domaine_dis(), "masse_volumique", "kg/m3", rho_, pb);
276 champs_compris_.ajoute_champ(rho_);
277 dis.nommer_completer_champ_physique(pb.domaine_dis(), "derivee_masse_volumique", "kg/m3", drhodc_, pb);
278 champs_compris_.ajoute_champ(drhodc_);
279 }
280
281}
282
283/*! @brief Calcule rho_n+1 pour utilisation dans la pression
284 *
285 */
287{
288 const Convection_Diffusion_Phase_field& eq_c = ref_cast(Convection_Diffusion_Phase_field, pb_pf_->equation(1));
289 Sources& list_sources = ref_cast_non_const(Sources, eq_c.sources());
290 int type_systeme_naire = fermeture_->get_type_systeme_naire();
291
292 int i = 1;
293 double temps = pb_pf_->schema_temps().temps_futur(i);
294 if (init)
295 {
296 i = 0;
297 temps = pb_pf_->schema_temps().temps_courant();
298 }
299 if (boussi_ == 0 || !has_beta_c())
300 {
301 // normalement, quelque chose comme 'rho_->mettre_a_jour(schema_temps().temps_futur(i))' devrait faire l'affaire
302 // probleme, cette evaluation se fait avec c(n) alors que l'on veut evaluer avec c(n+1)
303 // on introduit une methode specifique (qui depend de la discretisation) que l'on met arbitrairement dans Source_Con_Phase_field_base
304 Source_Con_Phase_field_base& source_pf_base = ref_cast(Source_Con_Phase_field_base, list_sources(0).valeur());
305 source_pf_base.calculer_champ_fonc_c(temps, rho_, eq_c.inconnue().futur(i));
306 source_pf_base.calculer_champ_fonc_c(temps, drhodc_, eq_c.inconnue().futur(i));
307 }
308 else
309 {
310 const DoubleTab& c = eq_c.inconnue().futur(i);
311 //Mirantsoa 264902
312 DoubleTab& rhoTab = rho_->valeurs(); /**/
313 DoubleTab& drhodcTab = drhodc_->valeurs();/**/
314 DoubleTab rho0Tab(rhoTab);
315
316 if (type_systeme_naire == 0)
317 {
318 drhodcTab = rho0_;
319 tab_multiply_any_shape(drhodcTab, beta_c().valeurs());
320 rhoTab = c;
321 tab_multiply_any_shape(rhoTab, drhodcTab);
322 rhoTab += rho0_;
323 //Cerr << "c = "<< c<<finl;
324
325 }
326 else if (type_systeme_naire == 1)
327 {
328 DoubleTab beta_(rhoTab);
329 DoubleTab betacTab(c);
330
331 //calcul de drhodcTab comme rho0*somme(betac)
332 drhodcTab = rho0_;
333 for (i = 0; i < beta_.dimension(0); i++)
334 {
335 for (int j = 0; j < betacTab.line_size(); j++)
336 {
337 betacTab(i, j) = beta_c().valeurs()(0, j);
338 beta_(i) += betacTab(i, j);
339 }
340 }
341 tab_multiply_any_shape(drhodcTab, beta_);
342
343 //calcul de rhoTab comme rho0+rho0*somme(betac*c)
344 rhoTab = 0;
345 tab_multiply_any_shape(betacTab, c);
346 for (i = 0; i < betacTab.dimension(0); i++)
347 {
348 for (int j = 0; j < betacTab.line_size(); j++)
349 {
350 rhoTab(i) += betacTab(i, j);
351 }
352 }
353 rho0Tab = rho0_;
354 tab_multiply_any_shape(rhoTab, rho0Tab);
355 rhoTab += rho0_;
356 }
357 }
358 rho_->valeurs().echange_espace_virtuel();
359 drhodc_->valeurs().echange_espace_virtuel();
360}
361
363{
364 if (boussi_ == 0 && diff_boussi_ == 0)
365 {
366 const Convection_Diffusion_Phase_field& eq_c = ref_cast(Convection_Diffusion_Phase_field, pb_pf_->equation(1));
367 int i = 1;
368 double temps = pb_pf_->schema_temps().temps_futur(i);
369 if (init)
370 {
371 i = 0;
372 temps = pb_pf_->schema_temps().temps_courant();
373 }
374 // normalement, quelque chose comme 'mu_->mettre_a_jour(schema_temps().temps_futur(i))' devrait faire l'affaire
375 // probleme, cette evaluation se fait avec c(n) alors que l'on veut evaluer avec c(n+1)
376 // on introduit une methode specifique (qui depend de la discretisation) que l'on met arbitrairement dans Source_Con_Phase_field_base
377 Sources& list_sources = ref_cast_non_const(Sources, eq_c.sources());
378 Source_Con_Phase_field_base& source_pf = ref_cast(Source_Con_Phase_field_base, list_sources(0).valeur());
379 source_pf.calculer_champ_fonc_c(temps, mu_, eq_c.inconnue().futur(i));
380 mu_->valeurs().echange_espace_virtuel();
381 }
382}
383
384int Milieu_Phase_field::initialiser(const double temps)
385{
387 Cerr << "Milieu_Phase_field::initialiser()" << finl;
388 // Calcul de la masse volumique
389 rho_->initialiser(temps);
390
391 drhodc_->initialiser(temps);
392
393 calculer_rho(true); // RLT: cette minitialisation etait incorrecte dans TrioCFD 1.8.0 car on utilisait c.futur()
394 // Calcul de la viscosite dynamique dans le cas boussi_==0 et diff_boussi_==0
395 if (mu_)
396 {
397 mu_->initialiser(temps);
398 calculer_mu(true); // RLT: cette minitialisation etait incorrecte dans dans TrioCFD 1.8.0 car on utilisait c.futur()
399 }
400
401 rho_->changer_temps(temps);
402 drhodc_->changer_temps(temps);
403
404 if (mu_)
405 mu_->changer_temps(temps);
406
407 return 1;
408}
409
414
415/*
416 * A voir si l'ordre est pas important, on fait ca dans mettre_a_jour ...
417 */
419{
420 calculer_rho();
421 rho_->changer_temps(temps);
422 drhodc_->changer_temps(temps);
423 if (mu_)
424 {
425 calculer_mu(); // RLT: cette mise a jour etait manquante dans TrioCFD 1.8.0
426 mu_->changer_temps(temps);
427 }
428}
DoubleTab & valeurs() override
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
DoubleTab & futur(int i=1) override
Renvoie les valeurs du champs a l'instant t+i.
virtual DoubleTab & valeurs()=0
const Champ_Inc_base & inconnue() const override
Renvoie le champ inconnue de l'equation: la concentration.
classe Convection_Diffusion_Phase_field Cas particulier de Convection_Diffusion_Concentration
classe Discretisation_base Cette classe represente un schema de discretisation en espace,...
void nommer_completer_champ_physique(const Domaine_dis_base &domaine_vdf, const Nom &nom_champ, const Nom &unite, Champ_base &champ, const Probleme_base &pbi) const
void discretiser_champ(const Motcle &directive, const Domaine_dis_base &z, const Nom &nom, const Nom &unite, int nb_comp, int nb_pas_dt, double temps, OWN_PTR(Champ_Inc_base)&champ, const Nom &sous_type=NOM_VIDE) const
Une entree dont la source est une chaine de caracteres.
Definition EChaine.h:31
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Sources & sources()
Renvoie les termes sources asssocies a l'equation.
classe Fluide_Incompressible Cette classe represente un d'un fluide incompressible ainsi que
void set_param(Param &param) const override
bool has_beta_c() const
Definition Fluide_base.h:67
const Champ_Don_base & beta_c() const
Definition Fluide_base.h:65
void calculer_rho(const bool init=false)
Calcule rho_n+1 pour utilisation dans la pression.
void mettre_a_jour(double temps) override
Effectue une mise a jour en temps du milieu, et donc de ses parametres caracteristiques.
int lire_motcle_non_standard(const Motcle &, Entree &) override
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
void calculer_mu(const bool init=false)
void set_param(Param &param) const override
int initialiser(const double temps) override
Initialise les parametres du fluide.
void discretiser(const Probleme_base &pb, const Discretisation_base &dis) override
void update_rho_mu(double temps)
virtual int initialiser(const double temps)
virtual void mettre_a_jour(double temps)
virtual void discretiser(const Probleme_base &pb, const Discretisation_base &dis)
virtual const Champ_base & masse_volumique() const
Renvoie la masse volumique du milieu.
int lire_motcle_non_standard(const Motcle &, Entree &) override
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
Champs_compris champs_compris_
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
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
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
@ REQUIRED
Definition Param.h:115
void ajouter_non_std(const char *keyword, const Objet_U *value, Param::Nature nat=Param::OPTIONAL)
Register a keyword handled by Objet_U::lire_motcle_non_standard.
Definition Param.cpp:489
Classe Pb_Phase_field Cette classe represente un probleme d'hydraulique avec transport.
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
Classe de base des flux de sortie.
Definition Sortie.h:52
class Source_Con_Phase_field_base
virtual void calculer_champ_fonc_c(const double t, Champ_Don_base &champ_fonc_c, const DoubleTab &val_c) const =0
class Sources Sources represente une liste de Source.
Definition Sources.h:31
int nb_dim() const
Definition TRUSTTab.h:199
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
int line_size() const
Definition TRUSTVect.tpp:67