TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Milieu_composite.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 <Fluide_Incompressible.h>
17#include <Discretisation_base.h>
18#include <Schema_Temps_base.h>
19#include <Milieu_composite.h>
20#include <Champ_Uniforme.h>
21#include <Equation_base.h>
22#include <Probleme_base.h>
23#include <Pb_Multiphase.h>
24#include <Interprete.h>
25#include <Domaine_VF.h>
26
27Implemente_instanciable(Milieu_composite, "Milieu_composite", Fluide_base);
28// XD Milieu_composite listobj Milieu_composite INHERITS_BRACE milieu_base NO_COMMA Composite medium made of several sub
29// XD_CONT mediums.
30
31Sortie& Milieu_composite::printOn(Sortie& os) const { return os; }
32
34{
35 int i = 0;
36 std::vector<std::pair<std::string, int>> especes; // string for phase_name. int: 0 for liquid and 1 for gas
37 Cerr << "Reading Milieu_composite..." << finl;
38 Nom mot;
39 is >> mot;
40 if (mot != "{")
41 {
42 Cerr << "Milieu_composite : { expected instead of " << mot << finl;
44 }
45
46 for (is >> mot; mot != "}"; is >> mot)
47 {
48 if (Motcle(mot) == "POROSITES_CHAMP") is >> ch_porosites_;
49 else if (Motcle(mot) == "DIAMETRE_HYD_CHAMP") is >> ch_diametre_hyd_;
50 else if (Motcle(mot) == "POROSITES")
51 {
52 Cerr << "You should use porosites_champ and not porosites ! Call the 911 !" << finl;
54 }
55 else if (Motcle(mot) == "GRAVITE")
56 {
57 Cerr << que_suis_je() << " : gravity should not be defined in Pb_Multiphase ! Use source_qdm if you want gravity in QDM equation !" << finl;
59 }
60 else if (!mot.debute_par("saturation") && !mot.debute_par("interface")) // add phases
61 {
62 noms_phases_.add(mot);
63 Cerr << "Milieu_composite: add phase " << mot << " ... " << finl;
64 OWN_PTR(Fluide_base) fluide;
65 fluide.typer_lire_simple(is, "Typing the fluid medium ...");
66
67 if (fluide->has_porosites())
68 {
69 Cerr << que_suis_je() + " : porosity should be defined only once in the milieu_composite block, not in " + fluide->que_suis_je() << finl;
71 }
72 if (fluide->a_gravite())
73 {
74 Cerr << que_suis_je() + " : gravity should be defined only once in the milieu_composite block, not in " + fluide->que_suis_je() << finl;
76 }
77 if (fluide->has_hydr_diam())
78 {
79 Cerr << que_suis_je() + " : diametre_hyd_champ should be defined only once in the milieu_composite block, not in " + fluide->que_suis_je() << finl;
81 }
82 if (!sub_type(Fluide_base,fluide.valeur()))
83 {
84 Cerr << que_suis_je() + " : only real fluids should be read and not a fluid of type " + fluide->que_suis_je() << finl;
86 }
87
88 fluide->set_id_composite(i++);
89 fluide->nommer(mot); // XXX
90 fluides_.push_back(fluide);
91 especes.push_back(check_fluid_name(fluide->le_nom()));
92 }
93 else if (mot.debute_par("saturation")) // add saturation
94 {
95 has_saturation_ = true;
96 Cerr << "Milieu_composite: add saturation " << mot << " ... " << finl;
97 sat_lu_.typer_lire_simple(is, "Typing the saturation ...");
98 }
99 else // add interface
100 {
101 has_interface_ = true;
102 Cerr << "Milieu_composite: add interface " << mot << " ... " << finl;
103 inter_lu_.typer_lire_simple(is, "Typing the interface ...");
104 }
105 }
106
107 if (has_saturation() && has_interface())
108 {
109 Cerr << "You define both interface and saturation in Milieu_composite ???" << finl;
111 }
112
113 // Interface processing
114 const int N = (int)fluides_.size();
115 for (int n = 0; n < N; n++)
116 {
117 std::vector<Interface_base *> inter;
118 for (int m = 0; m < N; m++)
119 {
120 const std::string espn = especes[n].first, espm = especes[m].first;
121 const int pn = especes[n].second, pm = especes[m].second;
122
123 if (pn != pm && (has_interface() || (espn == espm && has_saturation())))
124 {
125 Cerr << "Interface between fluid " << n << " : " << fluides_[n]->le_nom() << " and " << m << " : " << fluides_[m]->le_nom() << finl;
126 inter.push_back(&ref_cast(Interface_base, has_saturation_ ? sat_lu_.valeur() : inter_lu_.valeur()));
127 const Saturation_base *sat = sub_type(Saturation_base, *inter.back()) ? &ref_cast(Saturation_base, *inter.back()) : nullptr;
128 if (sat && sat->get_Pref() > 0) // for the law e = e0 + cp * (T - T0)
129 {
130 const double hn = pn ? sat->Hvs(sat->get_Pref()) : sat->Hls(sat->get_Pref()),
131 hm = pm ? sat->Hvs(sat->get_Pref()) : sat->Hls(sat->get_Pref()),
132 T0 = sat->Tsat(sat->get_Pref());
133 fluides_[n]->set_h0_T0(hn, T0), fluides_[m]->set_h0_T0(hm, T0);
134 }
135 }
136 else inter.push_back(nullptr);
137 }
138 tab_interface_.push_back(inter);
139 }
140 return is;
141}
142
143std::pair<std::string, int> Milieu_composite::check_fluid_name(const Nom& name)
144{
145 int phase = name.debute_par("gaz");
146 Nom espece = phase ? name.getSuffix("gaz_") : name.getSuffix("liquide_");
147
148 // Remove suffixes "_group1" and "_group2" for IATE 2-group model
149 std::string nomjdd = espece.getString();
150 std::string suffix1 = "_group1";
151 std::string suffix2 = "_group2";
152 if (nomjdd.size() >= suffix1.size() && nomjdd.compare(nomjdd.size() - suffix1.size(), suffix1.size(), suffix1) == 0)
153 {
154 nomjdd.erase(nomjdd.size() - suffix1.size(), suffix1.size());
155 }
156 else if (nomjdd.size() >= suffix2.size() && nomjdd.compare(nomjdd.size() - suffix2.size(), suffix2.size(), suffix2) == 0)
157 {
158 nomjdd.erase(nomjdd.size() - suffix2.size(), suffix2.size());
159 }
160
161 return std::make_pair(nomjdd, phase);
162}
163
164bool Milieu_composite::has_interface(int k, int l) const
165{
166 if (tab_interface_[k][l]) return true;
167 return false;
168}
169
171{
172 return *(tab_interface_[k][l]);
173}
174
175bool Milieu_composite::has_saturation(int k, int l) const
176{
177 if (tab_interface_[k][l] && sub_type(Saturation_base, *tab_interface_[k][l])) return true;
178 return false;
179}
180
182{
183 return ref_cast(Saturation_base, *(tab_interface_[k][l]));
184}
185
187{
188 assert(i >= 0 && i < (int )fluides_.size());
189 return fluides_[i].valeur();
190}
191
193{
194 assert(i >= 0 && i < (int )fluides_.size());
195 return fluides_[i].valeur();
196}
197
198int Milieu_composite::initialiser(const double temps)
199{
200 for (auto &itr : fluides_) itr->initialiser(temps);
201
202 const bool res_en_T = equation_.count("temperature") ? true : false;
203
204 const Equation_base& eqn = res_en_T ? equation("temperature") : equation("enthalpie");
205 Champ_Inc_base& ch_rho = ref_cast(Champ_Inc_base, ch_rho_.valeur()),
206 &ch_e = ref_cast(Champ_Inc_base, ch_e_int_.valeur()),
207 &ch_h_ou_T = ref_cast(Champ_Inc_base, ch_h_ou_T_.valeur());
208
209 ch_rho.associer_eqn(eqn);
211
212 ch_e.associer_eqn(eqn);
213 ch_e.init_champ_calcule(*this, calculer_energie_interne);
214
215 ch_h_ou_T.associer_eqn(eqn);
216 res_en_T ? ch_h_ou_T.init_champ_calcule(*this, calculer_enthalpie) : ch_h_ou_T.init_champ_calcule(*this, calculer_temperature_multiphase);
217
218 t_init_ = temps;
219
220 // XXX Elie Saikali: useful for restart cases!
221 ch_rho_->changer_temps(temps);
222 ch_e_int_->changer_temps(temps);
223 ch_h_ou_T_->changer_temps(temps);
224
226}
227
233
235{
236 Cerr << "Composite medium discretization." << finl;
237
238 const int N = (int)fluides_.size(), nc = pb.equation(0).inconnue().nb_valeurs_temporelles();
239 const Domaine_dis_base& domaine_dis = pb.equation(0).domaine_dis();
240 const double temps = pb.schema_temps().temps_courant();
241
242 res_en_T_ = sub_type(Pb_Multiphase,pb) ? ref_cast(Pb_Multiphase,pb).resolution_en_T() : true;
243
244 for (auto& itr : fluides_) itr->discretiser(pb, dis);
245
246 /* masse volumique, energie interne, enthalpie : champ_inc */
247 OWN_PTR(Champ_Inc_base) rho_inc, ei_inc, h_ou_T_inc;
248 dis.discretiser_champ("champ_elem", domaine_dis, "masse_volumique", "kg/m^3", N, nc, temps, rho_inc);
249 dis.discretiser_champ("champ_elem", domaine_dis, "energie_interne", "J/m^3", N, nc, temps, ei_inc);
250 if (res_en_T_)
251 dis.discretiser_champ("champ_elem", domaine_dis, "enthalpie", "J/m^3", N, nc, temps, h_ou_T_inc);
252 else
253 dis.discretiser_champ("champ_elem", domaine_dis, "temperature", "C", N, nc, temps, h_ou_T_inc);
254
255 ch_rho_ = rho_inc, ch_e_int_ = ei_inc, ch_h_ou_T_ = h_ou_T_inc;
256
257 /* autres champs : champ_fonc */
258 dis.discretiser_champ("champ_elem", domaine_dis, "viscosite_dynamique", "kg/m/s", N, temps, ch_mu_);
259 dis.discretiser_champ("champ_elem", domaine_dis, "viscosite_cinematique", "m2/s", N, temps, ch_nu_);
260 dis.discretiser_champ("champ_elem", domaine_dis, "diffusivite", "m2/s", N, temps, ch_alpha_);
261 dis.discretiser_champ("champ_elem", domaine_dis, "alpha_fois_rho", "kg/m/s", N, temps, ch_alpha_fois_rho_);
262 dis.discretiser_champ("champ_elem", domaine_dis, "conductivite", "W/m/K", N, temps, ch_lambda_);
263 dis.discretiser_champ("champ_elem", domaine_dis, "capacite_calorifique", "J/kg/K", N, temps, ch_Cp_);
264 dis.discretiser_champ("champ_elem", domaine_dis, "masse_volumique_melange", "kg/m^3", 1, temps, rho_m_);
265 dis.discretiser_champ("champ_elem", domaine_dis, "enthalpie_melange", "J/m^3", 1, temps, h_m_);
266
267 champs_compris_.ajoute_champ(ch_rho_);
268 champs_compris_.ajoute_champ(ch_e_int_);
269 champs_compris_.ajoute_champ(ch_h_ou_T_);
270
271 std::vector<OWN_PTR(Champ_Don_base)* > fields = {&ch_mu_, &ch_nu_, &ch_lambda_, &ch_alpha_, &ch_alpha_fois_rho_, &ch_Cp_, &rho_m_, &h_m_};
272 for (auto && f: fields) champs_compris_.ajoute_champ((*f).valeur());
273
274 // discretize sigma / Tsat fields if needed ...
275 if ((int) tab_interface_.size() > 0)
276 {
277 Cerr << "Milieu_composite::" << __func__ << " ==> Surface tension discretization ..." << finl;
278 if (has_saturation_) Cerr << "Milieu_composite::" << __func__ << " ==> Saturation temperature discretization ..." << finl;
279
280 for (int k = 0; k < N; k++)
281 for (int l = k + 1; l < N; l++)
282 {
283 int phase = fluides_[k]->le_nom().debute_par("gaz");
284 Nom espece = phase ? fluides_[k]->le_nom().getSuffix("gaz_") : fluides_[k]->le_nom().getSuffix("liquide_");
285 if (has_interface(k, l)) // OK if interface/saturation
286 {
287 Interface_base& inter = get_interface(k, l);
288 inter.assoscier_pb(pb);
289 Nom sig_nom = Nom("surface_tension_") + espece;
290 inter.discretiser_sigma(sig_nom, temps);
291 champs_compris_.ajoute_champ(inter.get_sigma_champ());
292 }
293
294 if (has_saturation(k, l)) // OK if saturation only
295 {
296 Saturation_base& sat = get_saturation(k, l);
297 Nom Tsat_nom = Nom("Tsat_") + espece;
298 sat.discretiser_Tsat(Tsat_nom, temps);
299 champs_compris_.ajoute_champ(sat.get_Tsat_champ());
300 }
301 }
302 }
303
304 // Finally, discretize porosity + hydraulic diameter
307}
308
310{
311 for (auto& itr : fluides_) itr->mettre_a_jour(temps);
312
313 ch_rho_->mettre_a_jour(temps);
314 ch_e_int_->mettre_a_jour(temps);
315 ch_h_ou_T_->mettre_a_jour(temps);
316
317 std::vector<OWN_PTR(Champ_Don_base)* > fields = {&ch_mu_, &ch_nu_, &ch_lambda_, &ch_alpha_, &ch_alpha_fois_rho_, &ch_Cp_, &rho_m_, &h_m_};
318 for (auto && f: fields) (*f)->mettre_a_jour(temps);
319
321
322 // MAJ sigma & Tsat
323 if ((int) tab_interface_.size() > 0)
324 {
325 const int N = (int) fluides_.size();
326 for (int k = 0; k < N; k++)
327 for (int l = k + 1; l < N; l++)
328 if (has_interface(k, l)) // OK if interface/saturation
329 get_interface(k, l).mettre_a_jour(temps);
330 }
331
333}
334
336{
337 const int N = (int)fluides_.size();
338
339 /* viscosite dynamique */
340 {
341 DoubleTab& tab = ch_mu_->valeurs();
342 const int Nl = ch_mu_->valeurs().dimension_tot(0);
343 for (int n = 0; n < N; n++)
344 {
345 const Champ_base& ch_n = fluides_[n]->viscosite_dynamique();
346 const int cch = sub_type(Champ_Uniforme, ch_n);
347 for (int i = 0; i < Nl; i++) tab(i, n) = ch_n.valeurs()(!cch * i, 0);
348 }
349 }
350
351 /* viscosite cinematique */
352 {
353 DoubleTab& tab = ch_nu_->valeurs();
354 const int Nl = ch_nu_->valeurs().dimension_tot(0);
355 for (int n = 0; n < N; n++)
356 {
357 const Champ_base& ch_n = fluides_[n]->viscosite_cinematique();
358 const int cch = sub_type(Champ_Uniforme, ch_n);
359 for (int i = 0; i < Nl; i++) tab(i, n) = ch_n.valeurs()(!cch * i, 0);
360 }
361 }
362
363 /* diffusivite */
364 {
365 DoubleTab& tab = ch_alpha_->valeurs();
366 const int Nl = ch_alpha_->valeurs().dimension_tot(0);
367 for (int n = 0; n < N; n++)
368 {
369 const Champ_base& ch_n = fluides_[n]->diffusivite();
370 const int cch = sub_type(Champ_Uniforme, ch_n);
371 for (int i = 0; i < Nl; i++) tab(i, n) = ch_n.valeurs()(!cch * i, 0);
372 }
373 }
374
375 /* alpha fois rho */
376 {
377 DoubleTab& tab = ch_alpha_fois_rho_->valeurs();
378 const int Nl = ch_alpha_fois_rho_->valeurs().dimension_tot(0);
379 for (int n = 0; n < N; n++)
380 {
381 const Champ_base& ch_n = fluides_[n]->diffusivite_fois_rho();
382 const int cch = sub_type(Champ_Uniforme, ch_n);
383 for (int i = 0; i < Nl; i++) tab(i, n) = ch_n.valeurs()(!cch * i, 0);
384 }
385 }
386
387 /* conductivite */
388 {
389 DoubleTab& tab = ch_lambda_->valeurs();
390 const int Nl = ch_lambda_->valeurs().dimension_tot(0);
391 for (int n = 0; n < N; n++)
392 {
393 const Champ_base& ch_n = fluides_[n]->conductivite();
394 const int cch = sub_type(Champ_Uniforme, ch_n);
395 for (int i = 0; i < Nl; i++) tab(i, n) = ch_n.valeurs()(!cch * i, 0);
396 }
397 }
398
399 /* capacite calorifique */
400 {
401 DoubleTab& tab = ch_Cp_->valeurs();
402 const int Nl = ch_Cp_->valeurs().dimension_tot(0);
403 for (int n = 0; n < N; n++)
404 {
405 const Champ_base& ch_n = fluides_[n]->capacite_calorifique();
406 const int cch = sub_type(Champ_Uniforme, ch_n);
407 for (int i = 0; i < Nl; i++) tab(i, n) = ch_n.valeurs()(!cch * i, 0);
408 }
409 }
410
411 /* calcul des quantites melange */
412 DoubleTab& trm = rho_m_->valeurs(), &thm = h_m_->valeurs();
413 trm = 0, thm = 0;
414
415 const DoubleTab& a = equation("alpha").inconnue().valeurs(), &r = ch_rho_->valeurs(),
416 &ent = res_en_T_ ? ch_h_ou_T_->valeurs() : equation("enthalpie").inconnue().valeurs();
417
418 const int Nl = rho_m_->valeurs().dimension_tot(0);
419
420 // density
421 for (int n = 0; n < N; n++)
422 for (int i = 0; i < Nl; i++) trm(i) += a(i, n) * r(i, n);
423
424 // enthalpy
425 for (int n = 0; n < N; n++)
426 for (int i = 0; i < Nl; i++) thm(i) += a(i, n) * r(i, n) * ent(i, n);
427 for (int i = 0; i < Nl; i++) thm(i) /= trm(i);
428}
429
431{
433 // propagate to underlying media (real fluids need this)
434 for (const auto& itr : fluides_) itr->associer_equation(eqn);
435}
436
438{
439 int ok = 1;
440 for (int i = 0; ok && i < (int)fluides_.size(); i++) ok &= fluides_[i]->check_unknown_range(); // each fluid is checked
441 return ok;
442}
443
444void Milieu_composite::calculer_masse_volumique(const Objet_U& obj, DoubleTab& val, DoubleTab& bval, tabs_t& deriv)
445{
446 const Milieu_composite& mil = ref_cast(Milieu_composite, obj);
447 const Domaine_VF& zvf = ref_cast(Domaine_VF, mil.equation_.begin()->second->domaine_dis());
448 int i, Ni = val.dimension_tot(0), Nb = bval.dimension_tot(0), n, N = (int)mil.fluides_.size();
449 std::vector<const DoubleTab *> split(N);
450 for (n = 0; n < N; n++) split[n] = &mil.fluides_[n]->masse_volumique().valeurs();
451 for (i = 0; i < Ni; i++)
452 for (n = 0; n < N; n++) val(i, n) = (*split[n])(i * (split[n]->dimension(0) > 1), 0);
453
454 std::vector<DoubleTab> bsplit(N);
455 for (n = 0; n < N; n++)
456 if (mil.fluides_[n]->masse_volumique().a_un_domaine_dis_base())
457 bsplit[n] = mil.fluides_[n]->masse_volumique().valeur_aux_bords();
458 else bsplit[n].resize(bval.dimension_tot(0), 1), mil.fluides_[n]->masse_volumique().valeur_aux(zvf.xv_bord(), bsplit[n]);
459 for (i = 0; i < Nb; i++)
460 for (n = 0; n < N; n++) bval(i, n) = bsplit[n](i * (split[n]->dimension(0) > 1), 0);
461
462 /* derivees */
463 std::vector<const tabs_t *> split_der(N);
464 for (n = 0; n < N; n++) split_der[n] = sub_type(Champ_Inc_base, mil.fluides_[n]->masse_volumique()) ? &ref_cast(Champ_Inc_base, mil.fluides_[n]->masse_volumique()).derivees() : nullptr;
465 std::set<std::string> noms_der;
466 for (n = 0; n < N; n++)
467 if (split_der[n])
468 for (auto &&n_d : *split_der[n]) noms_der.insert(n_d.first);
469 for (auto &&nom : noms_der)
470 {
471 for (n = 0; n < N; n++) split[n] = split_der[n] && split_der[n]->count(nom) ? &split_der[n]->at(nom) : nullptr;
472 DoubleTab& der = deriv[nom];
473 for (der.resize(Ni, N), i = 0; i < Ni; i++)
474 for (n = 0; n < N; n++) der(i, n) = split[n] ? (*split[n])(i * (split[n]->dimension(0) > 1)) : 0;
475 }
476}
477
478void Milieu_composite::calculer_energie_interne(const Objet_U& obj, DoubleTab& val, DoubleTab& bval, tabs_t& deriv)
479{
480 const Milieu_composite& mil = ref_cast(Milieu_composite, obj);
481 int i, Ni = val.dimension_tot(0), Nb = bval.dimension_tot(0), n, N = (int)mil.fluides_.size();
482 std::vector<const DoubleTab *> split(N);
483 for (n = 0; n < N; n++) split[n] = &mil.fluides_[n]->energie_interne().valeurs();
484 for (i = 0; i < Ni; i++)
485 for (n = 0; n < N; n++) val(i, n) = (*split[n])(i * (split[n]->dimension(0) > 1), 0);
486
487 std::vector<DoubleTab> bsplit(N);
488 for (n = 0; n < N; n++) bsplit[n] = mil.fluides_[n]->energie_interne().valeur_aux_bords();
489 for (i = 0; i < Nb; i++)
490 for (n = 0; n < N; n++) bval(i, n) = bsplit[n](i * (split[n]->dimension(0) > 1), 0);
491
492 /* derivees */
493 std::vector<const tabs_t *> split_der(N);
494 for (n = 0; n < N; n++) split_der[n] = sub_type(Champ_Inc_base, mil.fluides_[n]->energie_interne()) ? &ref_cast(Champ_Inc_base, mil.fluides_[n]->energie_interne()).derivees() : nullptr;
495 std::set<std::string> noms_der;
496 for (n = 0; n < N; n++)
497 if (split_der[n])
498 for (auto &&n_d : *split_der[n]) noms_der.insert(n_d.first);
499 for (auto &&nom : noms_der)
500 {
501 for (n = 0; n < N; n++) split[n] = split_der[n] && split_der[n]->count(nom) ? &split_der[n]->at(nom) : nullptr;
502 DoubleTab& der = deriv[nom];
503 for (der.resize(Ni, N), i = 0; i < Ni; i++)
504 for (n = 0; n < N; n++) der(i, n) = split[n] ? (*split[n])(i * (split[n]->dimension(0) > 1)) : 0;
505 }
506}
507
508void Milieu_composite::calculer_enthalpie(const Objet_U& obj, DoubleTab& val, DoubleTab& bval, tabs_t& deriv)
509{
510 const Milieu_composite& mil = ref_cast(Milieu_composite, obj);
511 int i, Ni = val.dimension_tot(0), Nb = bval.dimension_tot(0), n, N = (int)mil.fluides_.size();
512 std::vector<const DoubleTab *> split(N);
513 for (n = 0; n < N; n++) split[n] = &mil.fluides_[n]->enthalpie().valeurs();
514 for (i = 0; i < Ni; i++)
515 for (n = 0; n < N; n++) val(i, n) = (*split[n])(i * (split[n]->dimension(0) > 1), 0);
516
517 std::vector<DoubleTab> bsplit(N);
518 for (n = 0; n < N; n++) bsplit[n] = mil.fluides_[n]->enthalpie().valeur_aux_bords();
519 for (i = 0; i < Nb; i++)
520 for (n = 0; n < N; n++) bval(i, n) = bsplit[n](i * (split[n]->dimension(0) > 1), 0);
521
522 /* derivees */
523 std::vector<const tabs_t *> split_der(N);
524 for (n = 0; n < N; n++) split_der[n] = sub_type(Champ_Inc_base, mil.fluides_[n]->enthalpie()) ? &ref_cast(Champ_Inc_base, mil.fluides_[n]->enthalpie()).derivees() : nullptr;
525 std::set<std::string> noms_der;
526 for (n = 0; n < N; n++)
527 if (split_der[n])
528 for (auto &&n_d : *split_der[n]) noms_der.insert(n_d.first);
529 for (auto &&nom : noms_der)
530 {
531 for (n = 0; n < N; n++) split[n] = split_der[n] && split_der[n]->count(nom) ? &split_der[n]->at(nom) : nullptr;
532 DoubleTab& der = deriv[nom];
533 for (der.resize(Ni, N), i = 0; i < Ni; i++)
534 for (n = 0; n < N; n++) der(i, n) = split[n] ? (*split[n])(i * (split[n]->dimension(0) > 1)) : 0;
535 }
536}
537
538void Milieu_composite::calculer_temperature_multiphase(const Objet_U& obj, DoubleTab& val, DoubleTab& bval, tabs_t& deriv)
539{
540 const Milieu_composite& mil = ref_cast(Milieu_composite, obj);
541 int i, Ni = val.dimension_tot(0), Nb = bval.dimension_tot(0), n, N = (int)mil.fluides_.size();
542 std::vector<const DoubleTab *> split(N);
543 for (n = 0; n < N; n++) split[n] = &mil.fluides_[n]->temperature_multiphase().valeurs();
544 for (i = 0; i < Ni; i++)
545 for (n = 0; n < N; n++) val(i, n) = (*split[n])(i * (split[n]->dimension(0) > 1), 0);
546
547 std::vector<DoubleTab> bsplit(N);
548 for (n = 0; n < N; n++) bsplit[n] = mil.fluides_[n]->temperature_multiphase().valeur_aux_bords();
549 for (i = 0; i < Nb; i++)
550 for (n = 0; n < N; n++) bval(i, n) = bsplit[n](i * (split[n]->dimension(0) > 1), 0);
551
552 /* derivees */
553 std::vector<const tabs_t *> split_der(N);
554 for (n = 0; n < N; n++) split_der[n] = sub_type(Champ_Inc_base, mil.fluides_[n]->temperature_multiphase()) ? &ref_cast(Champ_Inc_base, mil.fluides_[n]->temperature_multiphase()).derivees() : nullptr;
555 std::set<std::string> noms_der;
556 for (n = 0; n < N; n++)
557 if (split_der[n])
558 for (auto &&n_d : *split_der[n]) noms_der.insert(n_d.first);
559 for (auto &&nom : noms_der)
560 {
561 for (n = 0; n < N; n++) split[n] = split_der[n] && split_der[n]->count(nom) ? &split_der[n]->at(nom) : nullptr;
562 DoubleTab& der = deriv[nom];
563 for (der.resize(Ni, N), i = 0; i < Ni; i++)
564 for (n = 0; n < N; n++) der(i, n) = split[n] ? (*split[n])(i * (split[n]->dimension(0) > 1)) : 0;
565 }
566}
567
569{
571 if (ch_e_int_) ch_e_int_->abortTimeStep();
572 if (ch_h_ou_T_) ch_h_ou_T_->abortTimeStep();
573}
574
576{
577 for (auto& itr : fluides_) itr->initTimeStep(dt);
578
579 if (!equation_.size()) return true; // no associated equation -> ???
580 const Schema_Temps_base& sch = equation_.begin()->second->schema_temps(); // retrieve the time scheme from the first equation
581
582 /* fields for which time levels must be created */
583 std::vector<Champ_Inc_base *> vch;
584 if (ch_rho_ && sub_type(Champ_Inc_base, ch_rho_.valeur()))
585 vch.push_back(&ref_cast(Champ_Inc_base, ch_rho_.valeur()));
586 if (ch_e_int_ && sub_type(Champ_Inc_base, ch_e_int_.valeur()))
587 vch.push_back(&ref_cast(Champ_Inc_base, ch_e_int_.valeur()));
588 if (ch_h_ou_T_ && sub_type(Champ_Inc_base, ch_h_ou_T_.valeur()))
589 vch.push_back(&ref_cast(Champ_Inc_base, ch_h_ou_T_.valeur()));
590
591 for (auto &pch : vch)
592 for (int i = 1; i <= sch.nb_valeurs_futures(); i++)
593 {
594 pch->changer_temps_futur(sch.temps_futur(i), i);
595 pch->futur(i) = pch->valeurs();
596 }
597 return true;
598}
class Champ_Don_base base class of Given Fields (not calculated)
Class Champ_Inc_base.
void init_champ_calcule(const Objet_U &obj, fonc_calc_t fonc)
virtual int nb_valeurs_temporelles() const
Returns the number of temporal values currently kept.
DoubleTab & valeurs() override
Returns the array of field values at the current time.
virtual void associer_eqn(const Equation_base &)
Associates the field with the equation of which it represents an unknown.
virtual DoubleTab & valeurs()=0
Champ_Uniforme Represents a field that is constant in space and time.
class Champ_base This class is the base of the fields hierarchy.
Definition Champ_base.h:43
class Discretisation_base This class represents a spatial discretization scheme, which
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
class Domaine_VF
Definition Domaine_VF.h:44
virtual const DoubleTab & xv_bord() const
class Domaine_dis_base This class is the base of the hierarchy of discretized domains.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
class Equation_base The role of an equation is the calculation of one or more fields....
virtual const Champ_Inc_base & inconnue() const =0
Domaine_dis_base & domaine_dis()
Returns the discretized domain associated with the equation.
Base class for an incompressible fluid and its properties:
Definition Fluide_base.h:36
void calculer_temperature_multiphase() const
void discretiser_sigma(const Nom &sig_nom, double temps)
Champ_Don_base & get_sigma_champ()
void assoscier_pb(const Probleme_base &pb)
virtual void mettre_a_jour(double)
virtual void associer_equation(const Equation_base *eqn) const
void discretiser_porosite(const Probleme_base &pb, const Discretisation_base &dis)
virtual const Equation_base & equation(const std::string &nom_inc) const
virtual void abortTimeStep()
int initialiser_porosite(const double temps)
void discretiser_diametre_hydro(const Probleme_base &pb, const Discretisation_base &dis)
Champs_compris champs_compris_
void mettre_a_jour_porosite(double temps)
std::map< std::string, const Equation_base * > equation_
Composite medium representing a multiphase fluid and its properties:
void associer_equation(const Equation_base *eqn) const override
OWN_PTR(Champ_Don_base) rho_m_
std::vector< OWN_PTR(Fluide_base)> fluides_
static void calculer_enthalpie(const Objet_U &obj, DoubleTab &val, DoubleTab &bval, tabs_t &deriv)
static void calculer_temperature_multiphase(const Objet_U &obj, DoubleTab &val, DoubleTab &bval, tabs_t &deriv)
void preparer_calcul() override
static void calculer_masse_volumique(const Objet_U &obj, DoubleTab &val, DoubleTab &bval, tabs_t &deriv)
void abortTimeStep() override
std::vector< std::vector< Interface_base * > > tab_interface_
bool has_interface() const
virtual void mettre_a_jour_tabs()
bool has_saturation() const
Interface_base & get_interface(int k, int l) const
bool initTimeStep(double dt) override
void discretiser(const Probleme_base &pb, const Discretisation_base &dis) override
Saturation_base & get_saturation(int k, int l) const
void mettre_a_jour(double temps) override
Performs a time update of the medium and therefore of its characteristic parameters.
static void calculer_energie_interne(const Objet_U &obj, DoubleTab &val, DoubleTab &bval, tabs_t &deriv)
int check_unknown_range() const override
std::pair< std::string, int > check_fluid_name(const Nom &name)
int initialiser(const double temps) override
Initializes the fluid parameters.
const Fluide_base & get_fluid(const int i) const
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
const Nom getSuffix(const char *const) const
Definition Nom.cpp:276
virtual int debute_par(const char *const n) const
Definition Nom.cpp:314
const std::string & getString() const
Definition Nom.h:92
static int dimension
Definition Objet_U.h:94
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
Objet_U()
Default constructor: assigns a unique identifier to the object (object_id_) and registers the object ...
Definition Objet_U.cpp:54
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
Multiphase thermohydraulics problem of type "3*N equations":
class Probleme_base It is a Probleme_U that is not a coupling.
const Schema_Temps_base & schema_temps() const
Returns the time scheme associated with the problem.
virtual const Equation_base & equation(int) const =0
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
void discretiser_Tsat(const Nom &Tsat_nom, double temps)
double get_Pref() const
void Tsat(const SpanD P, SpanD res, int ncomp=1, int ind=0) const
void Hls(const SpanD P, SpanD res, int ncomp=1, int ind=0) const
Champ_Don_base & get_Tsat_champ()
void Hvs(const SpanD P, SpanD res, int ncomp=1, int ind=0) const
class Schema_Temps_base
double temps_courant() const
Returns the current time.
virtual double temps_futur(int i) const =0
virtual int nb_valeurs_futures() const =0
Base class for output streams.
Definition Sortie.h:52
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160