TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Echange_contact_VDF_FT_Disc.cpp
1/****************************************************************************
2* Copyright (c) 2015 - 2016, 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 <Echange_contact_VDF_FT_Disc.h>
17
18#include <Champ_front_calc.h>
19#include <Probleme_base.h>
20#include <Champ_Uniforme.h>
21#include <Schema_Temps_base.h>
22#include <Milieu_base.h>
23#include <Modele_turbulence_scal_base.h>
24#include <Domaine_VDF.h>
25#include <Equation_base.h>
26#include <Conduction.h>
27#include <Param.h>
28#include <Probleme_FT_Disc_gen.h>
29#include <Triple_Line_Model_FT_Disc.h>
30#include <Domaine_VF.h>
31#include <Front_VF.h>
32
33
34// XD paroi_echange_contact_vdf_ft paroi_echange_contact_vdf paroi_echange_contact_vdf_ft INHERITS_BRACE This boundary
35// XD_CONT condition is used between a conduction problem and a thermohydraulic problem with two phases flow
36// XD_CONT (Front-Tracking method) to modelize heat exchange.
37Implemente_instanciable( Echange_contact_VDF_FT_Disc, "Echange_contact_VDF_FT_Disc", Echange_contact_VDF ) ;
38// XD echange_contact_vdf_ft_disc condlim_base echange_contact_vdf_ft_disc BRACE echange_conatct_vdf en prescisant la
39// XD_CONT phase
40
42{
44 return os;
45}
46
48{
49 if (app_domains.size() == 0) app_domains = { Motcle("Thermique") };
50
51 // Echange_contact_VDF::readOn( is );
52 Cerr<<"Lecture des parametres du contact (Echange_contact_VDF_FT_Disc::readOn)"<<finl;
53 Param param("Echange_contact_VDF_FT_Disc::readOn");
54 param.ajouter("autre_probleme",&nom_autre_pb_,Param::REQUIRED); // XD_ADD_P chaine
55 // XD_CONT name of other problem
56 param.ajouter("autre_bord",&nom_bord,Param::REQUIRED); // XD_ADD_P chaine
57 // XD_CONT name of other boundary
58 param.ajouter("autre_champ_temperature",&nom_champ,Param::REQUIRED); // XD_ADD_P chaine
59 // XD_CONT name of other field
60 param.ajouter("nom_mon_indicatrice",&nom_champ_indicatrice_,Param::REQUIRED); // XD_ADD_P chaine
61 // XD_CONT name of indicatrice
62 param.ajouter("Ri_liq",&Ri_); // XD_ADD_P double
63 // XD_CONT interficial thermal resitence of liquid
64 int phase = INT_MAX; // should be overriden after reading. see next line
65 param.ajouter("phase",&phase,Param::REQUIRED); // XD_ADD_P int
66 // XD_CONT phase
67 param.lire_avec_accolades(s);
68 indicatrice_ref_ = double(phase);
70
71 h_paroi=1e10; // why not git 1/h_paroi = 0....?
72 // T_autre_pb(): temp type front from other calculation/OWN_PTR(Champ_base) dans le domaine
73 T_autre_pb_.typer("Champ_front_calc");
74 // T_ext(): mettre_a_jour utilise des donnees externes,
75 // Peut aussi initialized by a champ dans le domaine.
76 le_champ_front.typer("Ch_front_var_instationnaire_dep");
78
79 return s;
80}
82{
83 // Champ_front_calc:: mettre_a_jour()
84 // par default distant_= 1
85 // trace the value corresponding from champ inconnu
86 // Champ_Inc_P0_base::trace(), trace the element from distant
88 indicatrice_->mettre_a_jour(temps);
89
90 const DoubleTab& I = indicatrice_->valeurs_au_temps(temps);
91
93 // le_milieu = SOLID
94 const Milieu_base& le_milieu=ch.milieu();
95 int nb_comp = le_milieu.conductivite().nb_comp();
96 assert(nb_comp==1);
97
98
99 int is_pb_fluide=0;
100
101
102 DoubleTab& mon_h= h_imp_->valeurs();
103 int opt=0;
104 calculer_h_autre_pb( autre_h, 0., opt);
105 // Here, compute h_diff in the fluid side
106 calculer_h_mon_pb(mon_h,Ri_,opt);
107
108 // juste acceder la valeur..., et les remplir
109 // pas forcement des chose dedans et valable.
110 DoubleTab& mon_Tex= T_ext(). valeurs();
111 calculer_Teta_equiv(mon_Tex,mon_h,autre_h,is_pb_fluide,temps);
112
113 // Attention: Ti_wall_ should be updated after TCL model
114 // AS it will be used in TCL model, in particular,
115 // influence the heat flux in MESO zone
116 // OK here: TCL model is called in UpdateField
117 DoubleTab& mon_Ti= Ti_wall_-> valeurs();
118 DoubleTab Twalltmp(mon_Ti);
119 Twalltmp.detach_vect();
120 calculer_Teta_paroi(Twalltmp,mon_h,autre_h,is_pb_fluide,temps);
121
122 int taille=mon_h.dimension(0);
123
124 for (int ii=0; ii<taille; ii++)
125 for (int jj=0; jj<nb_comp; jj++)
126 {
127 if (est_egal(I(ii,0),indicatrice_ref_))
128 {
129 mon_h(ii,jj)=1./(1./autre_h(ii,jj)+1./mon_h(ii,jj));
130 mon_Ti(ii, jj) = Twalltmp(ii, jj);
131 }
132 else
133 {
134 // Using Ghost Fluid Method, mon_h and T in pure-L/pure-G cells are NO-PHYSICAL
135 // the BC here are not important
136 // Setting mon_h = 0 => isothermal BC
137 mon_h(ii,jj) = 0.;
138 // Update mon_Ti in the same way (to have a good convergence)
139 mon_Ti(ii, jj) = Twalltmp(ii, jj);
140 }
141 }
142
143
144 Nom nom_pb=mon_dom_cl_dis->equation().probleme().le_nom();
145 Probleme_base& pb_gen=ref_cast(Probleme_base, Interprete::objet(nom_pb));
146 Probleme_FT_Disc_gen *pbft = dynamic_cast<Probleme_FT_Disc_gen*>(&pb_gen);
147
148 const Domaine_VF& le_dom=ref_cast(Domaine_VF, mon_dom_cl_dis -> domaine_dis());
149 const DoubleVect& surface= le_dom.face_surfaces();
150
151
152 if (pbft-> tcl().is_activated())
153 {
154
155 // phi_ext_ used in *Eval_Diff_VDF_Elem_Gen.tpp* L97
156 DoubleTab& mon_phi = phi_ext_-> valeurs();
157 mon_phi = 0;
158// **************************************To be implemented*******************
159 // 2 - phase cells at pb-Boundary when solving T-eq at Liquid side
160 //mixed mesh => Text, Twall, mon_h
161 if (indicatrice_ref_ == 1)
162 {
163 Triple_Line_Model_FT_Disc *tcl = pbft ? &pbft->tcl() : nullptr;
164 const ArrOfDouble& Q_from_CL = tcl->Q();
165 const ArrOfInt& faces_with_CL_contrib = tcl-> boundary_faces();
166 const IntTab& face_voisins = le_dom.face_voisins();
167
168
169 const int nb_contact_line_contribution = faces_with_CL_contrib.size_array();
170
171
172 for (int jj = 0; jj < nb_comp; jj++)
173 {
174 // In case of parallelization:
175 // raccord in liquid domain and faces_with_CL_contrib are in the same processeur
176 // => have the same face Number in the same position
177 // use face number to check correspondence
178 // fill mon_phi
179 for (int idx = 0; idx < nb_contact_line_contribution; idx++)
180 {
181 const int facei = faces_with_CL_contrib[idx];
182 bool Not_find_ = true;
183
184 int ii;
185 for (ii=0; ii<taille; ii++)
186 {
187 const int face = ii + frontiere_dis ().frontiere ().num_premiere_face ();
188 if (facei == face)
189 {
190 Not_find_ = false;
191 break;
192 }
193 }
194
195 const double sign = (face_voisins (facei, 0) == -1) ? -1. : 1.;
196 const double TCL_wall_flux = Q_from_CL[idx] / surface (facei);
197 const double val = -sign * TCL_wall_flux;
198
199 if (!Not_find_)
200 mon_phi(ii, jj) += val;
201 else
202 Process::exit(Nom("Echange_contact_VDF_FT_Disc : missing element corresponding") + Nom(facei) + " ! Check all faces number in TCL are at BC?" );
203 }
204
205 // replace mon_h and mon_Ti;
206 for (int ii=0; ii<taille; ii++)
207 {
208 if (!est_egal(mon_phi(ii, jj), 0.))
209 {
210 mon_Ti(ii, jj) = T_ext().valeurs()(ii, jj) - mon_phi(ii, jj) /autre_h(ii) ;
211 mon_h(ii,jj) = 0.;
212 }
213 }
214 }
215 }
216 }
217
218 // put in the end: to make sure to update the *modified* h_imp_, phi_ext_, and T_ext
221 mon_Ti.echange_espace_virtuel();
222 Ti_wall_->mettre_a_jour(temps);
223
224
225 // check if to inject a new nuclateion seed
226 // only check in the liquid - equation
227
228 if ((pbft->tcl ().reinjection_tcl ()) && (indicatrice_ref_ == 1) )
229 {
230 bool& ready_inject = pbft->tcl ().ready_inject_tcl ();
231 ready_inject = false;
232
233 int BC_has_tcl = 0;
234
235 for (int ii = 0; ii < taille; ii++)
236 if (!est_egal (I (ii, 0), indicatrice_ref_))
237 {
238 BC_has_tcl = 1;
239 break;
240 }
241 BC_has_tcl = Process::mp_max (BC_has_tcl);
242
243 if (BC_has_tcl == 0)
244 {
245 double sum_T = 0;
246 double sum_surface = 0;
247
248 for (int ii = 0; ii < taille; ii++)
249 {
250 const int face = ii
252 if (le_dom.xv (face, 0) <= pbft->tcl ().Rc_inject ())
253 {
254 sum_surface += surface (face);
255 sum_T += surface (face) * mon_Ti (ii, 0);
256 }
257 }
258
259 sum_T = Process::mp_sum (sum_T);
260 sum_surface = Process::mp_sum (sum_surface);
261
262 sum_T = (sum_surface > DMINFLOAT) ? sum_T / sum_surface : 0;
263
264 ready_inject = (sum_T >= pbft->tcl ().tempC_tcl ()) ? true : false;
265 }
266
267 ready_inject = Process::mp_max ((int)ready_inject);
268 }
269
270}
271
273{
275
276 indicatrice_.typer("Champ_front_calc");
277 Champ_front_calc& ch=ref_cast(Champ_front_calc, indicatrice_.valeur());
278
279 Nom nom_bord_=frontiere_dis().frontiere().le_nom();
280 Nom nom_pb = mon_dom_cl_dis->equation ().probleme ().le_nom ();
281
282 int distant=0;
283 // when solving pure condution pb for solid
284 if (sub_type(Conduction,domaine_Cl_dis().equation()))
285 {
286 nom_pb=nom_autre_pb_;
287 nom_bord_=nom_bord_oppose_;
288 distant=1;
289 }
290 // check the coherance and fixer nb of component
291 ch.creer(nom_pb, nom_bord_, nom_champ_indicatrice_);
292 // changer distant = 0; for indicatrice_...
293 // par default, 1;
294 ch.set_distant(distant);
296 ch.completer();
298 ch.fixer_nb_valeurs_temporelles(nb_cases);
299
300 Probleme_base& pb_gen = ref_cast(Probleme_base, Interprete::objet (nom_pb));
301
302 //ONCE phi_ext_lu_ true, will be completer in father classes
303
304 const Probleme_FT_Disc_gen *pbft =
305 dynamic_cast<const Probleme_FT_Disc_gen*> (&pb_gen);
306
307 int nb_faces_raccord1 = frontiere_dis().frontiere().nb_faces ();
308
309 if (pbft->tcl ().is_activated () && phi_ext_lu_ == false)
310 {
311 phi_ext_lu_ = true;
312
313 derivee_phi_ext_.typer ("Champ_front_fonc");
314 derivee_phi_ext_->fixer_nb_comp (1);
315 derivee_phi_ext_->associer_fr_dis_base (frontiere_dis ());
316 derivee_phi_ext_->valeurs ().resize (nb_faces_raccord1, 1);
317
318 phi_ext_.typer ("Champ_front_fonc");
319 phi_ext_->fixer_nb_comp (1);
320 phi_ext_->associer_fr_dis_base (frontiere_dis ());
321 phi_ext_->valeurs ().resize (nb_faces_raccord1, 1);
322 }
323
324
325
326 Ti_wall_.typer ("Champ_front_fonc");
327 Ti_wall_->fixer_nb_comp (1);
328 Ti_wall_->associer_fr_dis_base (frontiere_dis ());
329 Ti_wall_->valeurs().resize (nb_faces_raccord1, 1);
330 Ti_wall_-> fixer_nb_valeurs_temporelles(nb_cases);
331
332}
333
334
335
336/*! @brief Change le i-eme temps futur de la CL.
337 *
338 */
340{
342 indicatrice_->changer_temps_futur(temps,i);
343 Ti_wall_ -> changer_temps_futur(temps,i);
344}
345
346/*! @brief Tourne la roue de la CL
347 *
348 */
350{
351 int ok=Echange_contact_VDF::avancer(temps);
352 ok = ok && indicatrice_->avancer(temps);
353 ok = ok && Ti_wall_ -> avancer(temps);
354 return ok;
355}
356
357/*! @brief Tourne la roue de la CL
358 *
359 */
361{
362 int ok=Echange_contact_VDF::reculer(temps);
363 ok = ok && indicatrice_->reculer(temps);
364 ok = ok && Ti_wall_ -> reculer(temps);
365 return ok;
366}
367
369{
370
371 // T_autre_pb is ALSO created and initialised in the following line
373 return 0;
374
375 DoubleTab& mon_Ti = Ti_wall_->valeurs ();
376
377 int is_pb_fluide = 0;
378 DoubleTab mon_h (mon_Ti);
379 DoubleTab mautre_h (mon_Ti);
380 int opt = 0;
381 calculer_h_autre_pb (mautre_h, 0., opt);
382 // Here, compute h_diffusion in the fluid side
383 calculer_h_mon_pb (mon_h, 0., opt);
384
385 // Use Twalltmp to avoid resize distributed array mon_Ti
386 // when calling calculer_Teta_paroi
387 DoubleTab Twalltmp (mon_Ti);
388 Twalltmp.detach_vect ();
389
390 calculer_Teta_paroi (Twalltmp, mon_h, mautre_h, is_pb_fluide, temps);
391
392 // Echange_contact_VDF initilise T as temp of liq
393 // some pb in initilization of Twall
394 // T_autre_pb().mettre_a_jour(temps);
395
396 int taille = mon_Ti.dimension (0);
397 for (int ii = 0; ii < taille; ii++)
398 {
399 double tempValue = Twalltmp(ii); // Store the result of Twalltmp(ii) in a temporary variable
400 if (tempValue < 0)
401 {
402 mon_Ti(ii, 0) = 0.; // If the value is negative, set mon_Ti(ii, 0) to 0
403 }
404 else
405 {
406 mon_Ti(ii, 0) = tempValue; // Otherwise, use the original value
407 }
408 }
409
410 Champ_front_calc& chbis=ref_cast(Champ_front_calc, indicatrice_.valeur());
411 return chbis.initialiser(temps,domaine_Cl_dis().equation().inconnue());
412}
413
415{
416 if (Ti_wall_)
417 Ti_wall_->set_temps_defaut(temps);
418 if (indicatrice_)
419 indicatrice_->set_temps_defaut(temps);
421}
423{
424
425 if (Ti_wall_->valeurs().size() == 1)
426 return Ti_wall_->valeurs()(0, 0);
427 else if (Ti_wall_->valeurs().dimension(1) == 1)
428 return Ti_wall_->valeurs()(i, 0);
429 else
430 Cerr << "Echange_contact_VDF_FT_Disc::Ti_wall_ erreur" << finl;
432 return 0.;
433}
virtual void associer_fr_dis_base(const Frontiere_dis_base &)
Associe une frontiere discretisee au champ.
virtual DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ.
virtual void mettre_a_jour(double temps)
NE FAIT RIEN, a surcharger.
virtual void completer()
classe Champ_front_calc Classe derivee de Champ_front_var qui represente les
void creer(const Nom &, const Nom &, const Motcle &)
Cree l'objet Champ_front_calc representant la trace d'un champ inconnue sur une frontiere a partir de...
int initialiser(double, const Champ_Inc_base &) override
Initialisation en debut de calcul.
void set_distant(int d)
const Milieu_base & milieu() const
Renvoie le milieu associe a l'equation qui porte le champ inconnue dont on prend la trace.
void fixer_nb_valeurs_temporelles(int nb_cases) override
Surcharge Champ_front_base::fixer_nb_valeurs_temporelles.
Domaine_Cl_dis_base & domaine_Cl_dis()
Renvoie le domaine des conditions aux limites discretisee dont l'objet fait partie.
std::vector< Motcle > app_domains
virtual Frontiere_dis_base & frontiere_dis()
Renvoie la frontiere discretisee a laquelle les conditions aux limites s'appliquent.
Classe Conduction Cette classe represente l'equation d'evolution.
Definition Conduction.h:41
class Domaine_VF
Definition Domaine_VF.h:44
virtual const DoubleVect & face_surfaces() const
Definition Domaine_VF.h:51
double xv(int num_face, int k) const
Definition Domaine_VF.h:76
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Definition Domaine_VF.h:418
: class Echange_contact_VDF_FT_Disc
virtual double Ti_wall(int num) const
int avancer(double temps) override
Tourne la roue de la CL.
void changer_temps_futur(double temps, int i) override
Change le i-eme temps futur de la CL.
int reculer(double temps) override
Tourne la roue de la CL.
void mettre_a_jour(double) override
Effectue une mise a jour en temps de la condition aux limites.
void set_temps_defaut(double temps) override
Change le i-eme temps futur de la cl.
void completer() override
NE FAIT RIEN A surcharger dans les classes derivees.
int initialiser(double temps) override
Initialisation en debut de calcul.
int reculer(double temps) override
Tourne la roue de la CL.
int initialiser(double temps) override
Initialisation en debut de calcul.
void completer() override
NE FAIT RIEN A surcharger dans les classes derivees.
void changer_temps_futur(double temps, int i) override
Change le i-eme temps futur de la CL.
void calculer_h_autre_pb(DoubleTab &tab, double invhparoi, int opt)
virtual void calculer_Teta_equiv(DoubleTab &Teta_equiv, const DoubleTab &mon_h, const DoubleTab &autre_h, int is_pb_fluide, double temps)
remplit Teta_eq utilise T_autre_pb au temps passe en parametre
int avancer(double temps) override
Tourne la roue de la CL.
virtual void calculer_Teta_paroi(DoubleTab &tab_p, const DoubleTab &mon_h, const DoubleTab &autre_h, int is_pb_fluide, double temps)
remplit Teta_p utilise T_autre_pb au temps passe en parametre
virtual Champ_front_base & T_autre_pb()
void calculer_h_mon_pb(DoubleTab &, double, int)
void set_temps_defaut(double temps) override
Change le i-eme temps futur de la cl.
void mettre_a_jour(double temps) override
Effectue une mise a jour en temps de la condition aux limites.
void fixer_nb_valeurs_temporelles(int nb_cases) override
Appele par Conds_lim::completer Appel cha_front_base::fixer_nb_valeurs_temporelles.
virtual Champ_front_base & T_ext()
Renvoie le champ T_ext de temperature imposee a la frontiere.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Schema_Temps_base & schema_temps()
Renvoie le schema en temps associe a l'equation.
virtual void fixer_nb_comp(int i)
Fixe le nombre de composantes du champ.
virtual int nb_comp() const
Definition Field_base.h:56
int_t num_premiere_face() const
Definition Frontiere.h:67
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Frontiere.h:49
int_t nb_faces() const
Renvoie le nombre de faces de la frontiere.
Definition Frontiere.h:59
const Frontiere & frontiere() const
Renvoie la frontiere geometrique associee.
static Objet_U & objet(const Nom &)
Voir Interprete_bloc::objet_global() BM: la classe Interprete n'est pas le meilleur endroit pour cett...
classe Milieu_base Cette classe est la base de la hierarchie des milieux (physiques)
Definition Milieu_base.h:50
virtual const Champ_Don_base & conductivite() const
Renvoie la conductivite du milieu.
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Definition MorEqn.h:62
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
const Nom & le_nom() const override
Renvoie *this;.
Definition Nom.cpp:563
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
@ REQUIRED
Definition Param.h:115
const Triple_Line_Model_FT_Disc & tcl() const
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
static double mp_max(double)
Definition Process.cpp:376
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
Definition Process.cpp:146
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
virtual int nb_valeurs_temporelles() const =0
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ size_array() const
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
virtual void detach_vect()
Definition TRUSTVect.h:176
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")