TRUST 1.9.8
HPC thermohydraulic platform
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 pour phase_nom. int : 0 pour liquide et 1 pour gaz
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")) // on ajout les 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")) // on ajout la 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 // on ajout l'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 // Traitement pour les interfaces
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) // pour loi en 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 // Suppression des suffixes "_group1" et "_group2" pour iate 2 groups
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 : utile pour cas reprise !
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 // on discretise les champs sigma / Tsat si besoin ...
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 si interf/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 si saturation seulement
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 // Finalement, on discretise la porosite + diametre_hydro
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 si interf/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 // masse volumique
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 // enthalpie
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 // on fait suivre aux milieux sous-jacents (les fluide_reel en ont besoin!)
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(); //chaque fluide controle
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; //pas d'equation associee -> ???
580 const Schema_Temps_base& sch = equation_.begin()->second->schema_temps(); //on recupere le schema en temps par la 1ere equation
581
582 /* champs dont on doit creer des cases */
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}
classe Champ_Don_base classe de base des Champs donnes (non calcules)
Classe Champ_Inc_base.
void init_champ_calcule(const Objet_U &obj, fonc_calc_t fonc)
virtual int nb_valeurs_temporelles() const
Renvoie le nombre de valeurs temporelles actuellement conservees.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
virtual void associer_eqn(const Equation_base &)
Associe le champ a l'equation dont il represente une inconnue.
virtual DoubleTab & valeurs()=0
classe Champ_Uniforme Represente un champ constant dans l'espace et dans le temps.
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
classe Discretisation_base Cette classe represente un schema de discretisation en espace,...
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
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
virtual const Champ_Inc_base & inconnue() const =0
Domaine_dis_base & domaine_dis()
Renvoie le domaine discretise associe a l'equation.
classe Fluide_base Cette classe represente un d'un fluide incompressible ainsi que
Definition Fluide_base.h:38
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_
Classe Milieu_composite Cette classe represente un fluide reel ainsi que.
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
Effectue une mise a jour en temps du milieu, et donc de ses parametres caracteristiques.
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
Initialise les parametres du fluide.
const Fluide_base & get_fluid(const int i) const
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
const Nom getSuffix(const char *const) const
Definition Nom.cpp:281
virtual int debute_par(const char *const n) const
Definition Nom.cpp:319
const std::string & getString() const
Definition Nom.h:92
static int dimension
Definition Objet_U.h:99
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
Objet_U()
Constructeur par defaut : attribue un numero d'identifiant unique a l'objet (object_id_),...
Definition Objet_U.cpp:55
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
classe Pb_Multiphase Cette classe represente un probleme de thermohydraulique multiphase de type "3*N...
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
const Schema_Temps_base & schema_temps() const
Renvoie le schema en temps associe au probleme.
virtual const Equation_base & equation(int) const =0
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
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
Renvoie le temps courant.
virtual double temps_futur(int i) const =0
virtual int nb_valeurs_futures() const =0
Classe de base des flux de sortie.
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