TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
IJK_Thermals.cpp
1/****************************************************************************
2* Copyright (c) 2023, 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 <IJK_Thermal_Onefluid.h>
17#include <Probleme_FTD_IJK.h>
18#include <IJK_switch_FT.h>
19#include <IJK_Thermals.h>
20#include <IJK_switch.h>
21#include <Option_IJK.h>
22
23// XD ijk_thermals objet_lecture ijk_thermals NO_BRACE IJK thermal-equation list, dispatched at runtime by
24// XD_CONT IJK_Thermal_base::typer_lire_thermal_equation. The braced block carries a comma-separated list of `cut_cell {
25// XD_CONT }` / `onefluid { }` / `onefluidenergy { }` / `subresolution { }` / `multiplesubresolutions { }` entries
26// XD_CONT opaque to trustify, validated by the C++ readOn. Declared as objet_lecture (not eqn_base) so trustify does
27// XD_CONT not try to apply eqn_base's optional `convection`/`diffusion` attributes onto the next braced block in the
28// XD_CONT parent problem.
29// XD attr bloc bloc_lecture bloc REQ Opaque block carrying the comma-separated list of thermal entries.
30Implemente_instanciable( IJK_Thermals, "IJK_Thermals", Equation_base) ;
31
33{
34 return os;
35}
36
38{
39 if (liste_thermique_.size())
40 liste_thermique_.vide();
41
42 Motcle nom;
43 is >> nom;
44
45 if (nom != "{")
46 Process::exit("Error while reading the IJK_Thermals list. One expected an opened bracket '{' to start !!! \n");
47
48 while (1)
49 {
50 liste_thermique_.add(OWN_PTR(IJK_Thermal_base)());
51 IJK_Thermal_base::typer_lire_thermal_equation(liste_thermique_.dernier(), is);
52 is >> nom;
53 if (nom == "}") return is;
54 if (nom != ",")
55 {
56 Cerr << "Error while reading the IJK_Thermals list. One expected a comma ',' or a closing bracket '}' and not " << nom << finl;
57 Process::exit("Check your data file ! \n");
58 }
59 }
60
61}
62
63void IJK_Thermals::set_fichier_reprise(const char *lataname)
64{
65 if (!liste_thermique_.est_vide())
66 for (auto& itr : liste_thermique_)
67 itr->set_fichier_reprise(lataname);
68}
69
71{
72 assert(!liste_thermique_.est_vide());
73 return liste_thermique_[0]->get_fichier_reprise();
74}
75
77{
78 if (!le_fluide_)
79 {
80 Cerr << "You forgot to associate a fluid to the problem named " << probleme().le_nom() << finl;
82 }
83 return le_fluide_.valeur();
84}
85
87{
88 if (!le_fluide_)
89 {
90 Cerr << "You forgot to associate a fluid to the problem named " << probleme().le_nom() << finl;
92 }
93 return le_fluide_.valeur();
94}
95
97{
98 const Fluide_Diphasique_IJK& mil = milieu_ijk();
101 {
102 Cerr << "Error in IJK_Thermals::verifie_milieu() !! " << finl;
103 Cerr << "You forgot to define the cp and/or fields in your Fluide_Diphasique_IJK medium ! Update your data file." << finl;
105 }
106
107 const int nb_cp0 = mil.fluide_phase(0).capacite_calorifique().valeurs().size(),
108 nb_lamb0 = mil.fluide_phase(0).conductivite().valeurs().size(),
109 nb_cp1 = mil.fluide_phase(1).capacite_calorifique().valeurs().size(),
110 nb_lamb1 = mil.fluide_phase(1).conductivite().valeurs().size();
111
112 if (nb_cp0 != liste_thermique_.size() || nb_lamb0 != nb_cp0 || nb_cp1 != nb_cp0 || nb_lamb1 != nb_cp0)
113 {
114 Cerr << "Error in IJK_Thermals::verifie_milieu() !! " << finl;
115 Cerr << "You define " << liste_thermique_.size() << " thermal equations in your list which is not coherent with the medium :"<< finl;
116 Cerr << " - Size cp vapour field = " << nb_cp0 << finl;
117 Cerr << " - Size cp liquid field = " << nb_cp1 << finl;
118 Cerr << " - Size lambda vapour field = " << nb_lamb0 << finl;
119 Cerr << " - Size lambda liquid field = " << nb_lamb1 << finl;
121 }
122}
123
125{
126 if (sub_type(Fluide_Diphasique_IJK, un_milieu))
127 {
128 const Milieu_base& un_fluide = ref_cast(Milieu_base, un_milieu);
129 le_fluide_ = un_fluide;
130 }
131 else
132 {
133 Cerr << "Error of fluid type for the method IJK_Thermals::associer_milieu_base" << finl;
135 }
136
138
139 int idth =0;
140 for (auto& itr : liste_thermique_)
141 {
142 itr->associer_milieu_base(un_milieu, idth);
143 idth++;
144 }
145}
146
148{
149 if (!sub_type(Probleme_FTD_IJK_base, pb))
150 {
151 Cerr << "Error for the method IJK_Interfaces::associer_pb_base\n";
152 Cerr << " IJK_Thermals equation must be associated to\n";
153 Cerr << " a Probleme_FTD_IJK_base problem type\n";
155 }
156 mon_probleme = pb;
157 if (nom_ == "??")
158 {
159 nom_ = pb.le_nom();
160 nom_ += que_suis_je();
161 }
162
163 ref_ijk_ft_ = ref_cast(Probleme_FTD_IJK_base, pb);
164}
165
167{
168 associer_post(ref_ijk_ft_->get_post());
169 associer_interface_intersections(ref_ijk_ft_->get_interface().get_intersection_ijk_cell(), ref_ijk_ft_->get_interface().get_intersection_ijk_face());
170 for (auto& itr : liste_thermique_)
171 {
172 itr->associer(ref_ijk_ft_.valeur());
173 itr->associer_ghost_fluid_fields(ghost_fluid_fields_);
174 }
175 ghost_fluid_fields_.associer(ref_ijk_ft_.valeur());
176 if (!liste_thermique_.est_vide())
178}
179
181{
182 int compute_distance = 1;
183 int compute_curvature = 1;
184 int n_iter_distance = 3;
185 int avoid_gfm_parallel_calls = 0;
186 IJK_Field_local_double boundary_flux_kmin;
187 IJK_Field_local_double boundary_flux_kmax;
188 assert(!liste_thermique_.est_vide());
189 liste_thermique_[0]->get_boundary_fluxes(boundary_flux_kmin, boundary_flux_kmax);
190 for (auto& itr : liste_thermique_)
191 itr->retrieve_ghost_fluid_params(compute_distance,
192 compute_curvature,
193 n_iter_distance,
194 avoid_gfm_parallel_calls);
195 ghost_fluid_fields_.retrieve_ghost_fluid_params(compute_distance,
196 compute_curvature,
197 n_iter_distance,
198 avoid_gfm_parallel_calls,
199 boundary_flux_kmin,
200 boundary_flux_kmax);
201}
202
204{
205 ref_ijk_ft_post_ = ijk_ft_post;
206 for (auto& itr : liste_thermique_)
207 itr->associer_post(ijk_ft_post);
208}
209
211{
212 ref_ijk_ft_switch_ = ijk_ft_switch;
213 for (auto& itr : liste_thermique_)
214 itr->associer_switch(ref_ijk_ft_switch_);
215}
216/*
217* Here, Name is actually a prefix
218* In the individual thermal equations, it must be appended with "_" + Nom(rank_)
219* when named with method nommer (or at allocation with the 4th argument of allocate)
220* It must be named before being added to the list of understood fields (champs_compris, method ajoute_champ)
221*
222* See in Postprocessing_IJK::register_one_field what is done with these prefixes
223*/
224void IJK_Thermals::Fill_postprocessable_fields(std::vector<FieldInfo_t>& chps)
225{
226
227 std::vector<FieldInfo_t> c =
228 {
229 // Name / Localisation (elem, face, ...) / Nature (scalare, vector) / Located on interface?
230 { "TEMPERATURE", Entity::ELEMENT, Nature_du_champ::scalaire, false },
231 { "TEMPERATURE_ANA", Entity::ELEMENT, Nature_du_champ::scalaire, false },
232 { "ECART_T_ANA", Entity::ELEMENT, Nature_du_champ::scalaire, false },
233 { "TEMPERATURE_ADIMENSIONNELLE_THETA", Entity::ELEMENT, Nature_du_champ::scalaire, false },
234 { "TEMPERATURE_PHYSIQUE_T", Entity::ELEMENT, Nature_du_champ::scalaire, false },
235 { "SOURCE_TEMPERATURE", Entity::ELEMENT, Nature_du_champ::scalaire, false },
236 { "T_RUST", Entity::ELEMENT, Nature_du_champ::scalaire, false },
237 { "DIV_LAMBDA_GRAD_T_VOLUME", Entity::ELEMENT, Nature_du_champ::scalaire, false },
238 { "DIV_RHO_CP_T_VOLUME", Entity::ELEMENT, Nature_du_champ::scalaire, false },
239 { "U_T_CONVECTIVE_VOLUME", Entity::ELEMENT, Nature_du_champ::scalaire, false },
240 { "U_T_CONVECTIVE", Entity::ELEMENT, Nature_du_champ::scalaire, false }
241
242 };
243 chps.insert(chps.end(), c.begin(), c.end());
244}
245
247{
248 for (auto& itr : liste_thermique_)
249 {
250 itr->get_noms_champs_postraitables(noms,opt);
251 }
252
253 ghost_fluid_fields_.get_noms_champs_postraitables(noms,opt);
254}
255
256bool IJK_Thermals::has_champ(const Motcle& nom) const
257{
258
259 for (auto& itr : liste_thermique_)
260 {
261 if (itr->has_champ(nom))
262 {
263 return true;
264 }
265 }
266
267 if (ghost_fluid_fields_.has_champ(nom))
268 {
269 return true;
270 }
271 return false;
272
273}
274
275const IJK_Field_double& IJK_Thermals::get_IJK_field(const Motcle& nom)
276{
277 for (auto& itr : liste_thermique_)
278 {
279 if (itr->has_champ(nom))
280 {
281 return itr->get_IJK_field(nom);
282 }
283 }
284
285 if (ghost_fluid_fields_.has_champ(nom))
286 {
287 return ghost_fluid_fields_.get_IJK_field(nom);
288 }
289 Cerr << "IJK_Thermals::get_IJK_field requested field " << nom << " is not known by any equation"<< finl;
290 throw;
291}
292
293const IJK_Field_vector3_double& IJK_Thermals::get_IJK_field_vector(const Motcle& nom)
294{
295 for (auto& itr : liste_thermique_)
296 {
297 if (itr->has_champ(nom))
298 {
299 return itr->get_IJK_field_vector(nom);
300 }
301 }
302
303 if (ghost_fluid_fields_.has_champ(nom))
304 {
305 return ghost_fluid_fields_.get_IJK_field_vector(nom);
306 }
307 Cerr << "IJK_Thermals::get_IJK_field requested field vector " << nom << " is not known by any equation"<< finl;
308 throw;
309}
310
312 const Intersection_Interface_ijk_face& intersection_ijk_face)
313{
314 ref_intersection_ijk_cell_ = intersection_ijk_cell;
315 ref_intersection_ijk_face_ = intersection_ijk_face;
316 for (auto& itr : liste_thermique_)
317 itr->associer_interface_intersections(intersection_ijk_cell, intersection_ijk_face);
318}
319
321{
322 double modified_time;
323 if (liste_thermique_.est_vide())
324 modified_time = ref_ijk_ft_->schema_temps_ijk().get_current_time();
325 else
326 modified_time = 0.;
327 for (auto& itr : liste_thermique_)
328 modified_time = std::max(modified_time, itr->get_modified_time());
329 return modified_time;
330}
331
332void IJK_Thermals::get_rising_velocities_parameters(int& compute_rising_velocities,
333 int& fill_rising_velocities,
334 int& use_bubbles_velocities_from_interface,
335 int& use_bubbles_velocities_from_barycentres)
336{
337 if (!liste_thermique_.est_vide())
338 for (auto& itr : liste_thermique_)
339 itr->get_rising_velocities_parameters(compute_rising_velocities,
340 fill_rising_velocities,
341 use_bubbles_velocities_from_interface,
342 use_bubbles_velocities_from_barycentres);
343}
344
346 const int& stop)
347{
348 int idth = 0;
349 for (auto& itr : liste_thermique_)
350 {
351 itr->sauvegarder_temperature(lata_name, idth, stop);
352 idth++;
353 }
354}
355
357{
358 int flag_list_not_empty_th = 0;
359 if (liste_thermique_.size() > 0)
360 {
361 fichier << " thermals {\n" ;
362 flag_list_not_empty_th = 1;
363 }
364 for(auto itr = liste_thermique_.begin(); itr != liste_thermique_.end(); )
365 {
366 fichier << *itr ;
367 ++itr;
368 if (itr != liste_thermique_.end())
369 fichier << ", \n" ;
370 else
371 fichier << "\n" ;
372 }
373 if (flag_list_not_empty_th)
374 fichier << " } \n" ;
375}
376
377void IJK_Thermals::compute_timestep(double& dt_thermals, const double dxmin)
378{
379 for (auto& itr : liste_thermique_)
380 {
381 const double dt_th = itr->compute_timestep(dt_thermals, dxmin);
382 // We take the most restrictive of all thermal problems and use it for all:
383 dt_thermals = std::min(dt_thermals, dt_th);
384 }
385}
386
388{
389 if (!liste_thermique_.est_vide())
390 {
391 ghost_fluid_fields_.initialize(splitting);
392 int idth =0;
393 Nom thermal_outputs_rank_base = Nom("thermal_outputs_rank_");
394 const int max_digit = 3;
395 for (auto& itr : liste_thermique_)
396 {
397 itr->initialize(splitting);
399 itr->update_thermal_properties();
400 const int max_rank_digit = idth < 1 ? 1 : (int) (log10(idth) + 1);
401 thermal_rank_folder_.add(thermal_outputs_rank_base
402 + Nom(std::string(max_digit - max_rank_digit, '0')) + Nom(idth));
403 idth++;
404 }
406 {
407 overall_bubbles_quantities_folder_ = Nom("overall_bubbles_quantities");
408 interfacial_quantities_thermal_probes_folder_ = Nom("interfacial_quantities_thermal_probes");
409 shell_quantities_thermal_probes_folder_ = Nom("shell_quantities_thermal_probes");
410 local_quantities_thermal_probes_folder_ = Nom("local_quantities_thermal_probes");
411 local_quantities_thermal_probes_time_index_folder_ = Nom("local_quantities_thermal_probes_time_index_");
412 local_quantities_thermal_slices_folder_ = Nom("local_quantities_thermal_slices");
413 local_quantities_thermal_slices_time_index_folder_ = Nom("local_quantities_thermal_slices_time_index_");
414 local_quantities_thermal_lines_folder_ = Nom("local_quantities_thermal_lines");
415 local_quantities_thermal_lines_time_index_folder_ = Nom("local_quantities_thermal_lines_time_index_");
416 }
417 for (auto& itr : liste_thermique_)
418 {
419 lata_step_reprise_.push_back(itr->get_latastep_reprise());
420 lata_step_reprise_ini_.push_back(itr->get_latastep_reprise_ini());
421 }
422 }
423}
424
426{
427 for (auto& itr : liste_thermique_)
428 itr->recompute_temperature_init();
429}
430
432{
433 int size=0;
434 for (auto& itr : liste_thermique_)
435 {
436 if (thermal_problem == itr->get_thermal_problem_type())
437 size++;
438 }
439 return size;
440}
441
443{
444 for (auto& itr : liste_thermique_)
445 itr->update_thermal_properties();
446}
447
448void IJK_Thermals::euler_time_step(const double timestep)
449{
450 for (auto& itr : liste_thermique_)
451 itr->euler_time_step(timestep);
452 ghost_fluid_fields_.enforce_distance_curvature_values_for_post_processings();
453}
454
455void IJK_Thermals::euler_rustine_step(const double timestep)
456{
457 for (auto& itr : liste_thermique_)
458 // Make sense only if (sub_type(IJK_Thermal_Onefluid, itr.valeur())) but empty methods are coded otherwise...
459 itr->euler_rustine_step(timestep);
460}
461
462void IJK_Thermals::rk3_sub_step(const int rk_step, const double total_timestep, const double time)
463{
464 for (auto& itr : liste_thermique_)
465 {
466 int thermal_rank = itr->get_thermal_rank();
467 switch (thermal_rank)
468 {
469 case 0:
470 Cerr << "RK3 Time scheme is not implemented yet with" << itr->get_thermal_words()[thermal_rank] << finl;
471 break;
472 case 1:
473 Cerr << "RK3 Time scheme is not implemented yet with" << itr->get_thermal_words()[thermal_rank] << finl;
474 break;
475 case 2:
476 itr->rk3_sub_step(rk_step, total_timestep, time);
477 Cerr << "RK3 Time scheme is implemented with" << itr->get_thermal_words()[thermal_rank] << finl;
478 break;
479 case 3:
480 Cerr << "RK3 Time scheme is not implemented with" << itr->get_thermal_words()[thermal_rank] << finl;
481 break;
482 case 4:
483 itr->rk3_sub_step(rk_step, total_timestep, time);
484 Cerr << "RK3 Time scheme is implemented with" << itr->get_thermal_words()[thermal_rank] << finl;
485 break;
486 default:
488 }
489 }
490}
491
492void IJK_Thermals::rk3_rustine_sub_step(const int rk_step, const double total_timestep,
493 const double fractionnal_timestep, const double time)
494{
495 for (auto& itr : liste_thermique_)
496 itr->rk3_rustine_sub_step(rk_step, total_timestep, fractionnal_timestep, time);
497}
498
499void IJK_Thermals::ecrire_statistiques_bulles(int reset, const Nom& nom_cas, const double current_time, const ArrOfDouble& surface)
500{
501 int idx_th = 0;
502 for (auto &itr : liste_thermique_)
503 {
504 itr->ecrire_statistiques_bulles(reset, nom_cas, current_time, surface, idx_th);
505 ++idx_th;
506 }
507}
508
510{
511 int idx_th = 0;
512 for (auto &itr : liste_thermique_)
513 {
514 itr->posttraiter_tous_champs_thermal(liste_post_instantanes_, idx_th);
515 ++idx_th;
516 }
517}
518
520 const char *lata_name,
521 const int latastep,
522 const double current_time,
523 int& n)
524{
525 throw; // THIS METHOD SHOULD NOT BE CALLED ANYMORE
526
527 /* Cerr << "Post-process Eulerian fields related to the temperature resolution" << finl;
528 int idx_th = 0;
529 for (auto &itr : liste_thermique_)
530 {
531 int nb = itr->posttraiter_champs_instantanes_thermal(liste_post_instantanes,
532 lata_name,
533 latastep,
534 current_time,
535 idx_th);
536 // Interfacial thermal fields :
537 if (!Option_IJK::DISABLE_DIPHASIQUE)
538 nb += itr->posttraiter_champs_instantanes_thermal_interface(liste_post_instantanes,
539 lata_name,
540 latastep,
541 current_time,
542 idx_th);
543 if (idx_th == 0)
544 n -= nb; // On compte comme "un" tous les CHAMPS_N (ou N est la longueur de la liste)
545 ++idx_th;
546 } */
547}
548
550{
551 int idx =0;
552 for (auto& itr : liste_thermique_)
553 {
554 Cout << "Reading the old temperature field from " << Nom(itr->get_fichier_sauvegarde())
555 << " to fill the liste_thermique_ field."<< finl;
556 itr->initialize_switch(splitting, idx);
557 idx++;
558 }
559}
560
561void IJK_Thermals::prepare_thermals(const char *lata_name)
562{
563 for (auto& itr : liste_thermique_)
564 itr->set_fichier_sauvegarde(lata_name);
565}
566
567void IJK_Thermals::ecrire_fichier_reprise(SFichier& fichier, const char *lata_name)
568{
569 Cerr << " potentially saving temperature fields... " << finl;
570 int flag_list_not_empty = 0;
571 if ((int) liste_thermique_.size() > 0)
572 {
573 fichier << " thermals {\n" ;
574 flag_list_not_empty = 1;
575 }
576 int idx =0;
577 for (auto itr = liste_thermique_.begin(); itr != liste_thermique_.end(); )
578 {
579 (*itr)->set_fichier_sauvegarde(lata_name);
580 fichier << *itr ;
581 ++itr;
582 if (itr != liste_thermique_.end() )
583 fichier << ", \n" ;
584 else
585 fichier << "\n" ;
586 Cerr << " end of temperature field #" << idx << "... " << finl;
587 ++idx;
588 }
589 if (flag_list_not_empty)
590 fichier << " } \n" ;
591}
592
594{
595 int ghost_fluid = 0;
596 for (auto& itr : liste_thermique_)
597 {
598 ghost_fluid = itr->get_ghost_fluid_flag();
599 if (ghost_fluid)
600 return ghost_fluid;
601 }
602 return ghost_fluid;
603}
604
606{
607 for (auto& itr : liste_thermique_)
608 itr->compute_ghost_cell_numbers_for_subproblems(splitting, ghost_init);
609}
610
612{
613 int ghost_cells = ghost_init;
614 for (auto& itr : liste_thermique_)
615 {
616 const int itr_ghost_cells = itr->get_ghost_cells();
617 if (itr_ghost_cells > ghost_cells)
618 ghost_cells = itr_ghost_cells;
619 }
620 return ghost_cells;
621}
622
624{
625 for (auto& itr : liste_thermique_)
626 itr->update_intersections();
627}
628
630{
631 for (auto& itr : liste_thermique_)
632 itr->clean_ijk_intersections();
633}
634
636{
637 assert(!liste_thermique_.est_vide());
638 ghost_fluid_fields_.compute_eulerian_distance();
639}
640
642{
643 assert(!liste_thermique_.est_vide());
644 ghost_fluid_fields_.compute_eulerian_curvature();
645}
646
648{
649 assert(!liste_thermique_.est_vide());
650 ghost_fluid_fields_.compute_eulerian_curvature_from_interface();
651}
652
654{
655 if (!liste_thermique_.est_vide())
656 if (ghost_fluid_flag())
657 {
660 }
661}
662
664{
665 int disable_post_processing_probes_out_files = 1;
666 for (auto& itr : liste_thermique_)
667 disable_post_processing_probes_out_files = (disable_post_processing_probes_out_files && itr->get_disable_post_processing_probes_out_files());
668 return disable_post_processing_probes_out_files;
669}
670
672{
673 if (stop)
674 for (auto& itr : liste_thermique_)
675 itr->set_latastep_reprise(ref_ijk_ft_->schema_temps_ijk().get_tstep() + 1);
676}
677
678void IJK_Thermals::thermal_subresolution_outputs(const int& dt_post_thermals_probes)
679{
680 const int disable_post_processing_probes_out_files = get_disable_post_processing_probes_out_files();
681 if (!disable_post_processing_probes_out_files && post_pro_first_call_)
682 {
684 {
687 }
688 int rank = 0;
689 for (auto& itr : liste_thermique_)
690 {
691 const int last_time = ref_ijk_ft_->schema_temps_ijk().get_tstep() + lata_step_reprise_ini_[rank];
692 const int max_digit_time = 8;
693 const int nb_digit_tstep = last_time < 1 ? 1 : (int) (log10(last_time) + 1);
694 Nom prefix_local_quantities = thermal_rank_folder_[rank] + "/";
695 Nom suffix_local_quantities = Nom(std::string(max_digit_time - nb_digit_tstep, '0')) + Nom(last_time);
696 Nom local_quantities_thermal_probes_time_index_folder = prefix_local_quantities
699 + suffix_local_quantities;
700 Nom overall_bubbles_quantities = thermal_rank_folder_[rank] + "/" + overall_bubbles_quantities_folder_;
701 Nom interfacial_quantities_thermal_probes = thermal_rank_folder_[rank] + "/" + interfacial_quantities_thermal_probes_folder_;
702 Nom shell_quantities_thermal_probes = thermal_rank_folder_[rank] + "/" + shell_quantities_thermal_probes_folder_;
703 Nom local_quantities_thermal_slices_time_index_folder = prefix_local_quantities
706 + suffix_local_quantities;
707 Nom local_quantities_thermal_lines_time_index_folder = prefix_local_quantities
710 + suffix_local_quantities;
711
712 create_folders(local_quantities_thermal_probes_time_index_folder);
713 create_folders(local_quantities_thermal_slices_time_index_folder);
714 create_folders(local_quantities_thermal_lines_time_index_folder);
715
716 itr->thermal_subresolution_outputs(interfacial_quantities_thermal_probes,
717 shell_quantities_thermal_probes,
718 overall_bubbles_quantities,
719 local_quantities_thermal_probes_time_index_folder,
720 local_quantities_thermal_slices_time_index_folder,
721 local_quantities_thermal_lines_time_index_folder);
722 // .sauv written before the post-processing on probes
723 int latastep_reprise = lata_step_reprise_ini_[rank] + ref_ijk_ft_->schema_temps_ijk().get_tstep() + 2;
724 const int nb_dt_max = ref_ijk_ft_->schema_temps_ijk().get_nb_timesteps();
725 if ((ref_ijk_ft_->schema_temps_ijk().get_tstep() + dt_post_thermals_probes) >= nb_dt_max)
726 latastep_reprise = nb_dt_max + 1;
727 itr->set_latastep_reprise(latastep_reprise);
728 rank++;
729 }
730 }
732}
733
735{
736 for (int idth = 0; idth < liste_thermique_.size(); idth++)
737 {
738 create_folders(thermal_rank_folder_[idth]);
739 create_folders(thermal_rank_folder_[idth] + "/" + overall_bubbles_quantities_folder_);
740 create_folders(thermal_rank_folder_[idth] + "/" + interfacial_quantities_thermal_probes_folder_);
741 create_folders(thermal_rank_folder_[idth] + "/" + shell_quantities_thermal_probes_folder_);
742 create_folders(thermal_rank_folder_[idth] + "/" + local_quantities_thermal_probes_folder_);
743 create_folders(thermal_rank_folder_[idth] + "/" + local_quantities_thermal_slices_folder_);
744 create_folders(thermal_rank_folder_[idth] + "/" + local_quantities_thermal_lines_folder_);
745 }
746}
747
748void IJK_Thermals::create_folders(Nom folder_name_base)
749{
751 {
752 Nom spacing = " ";
753 Nom folder_name = "mkdir -p";
754 folder_name = folder_name + spacing + folder_name_base.getString(); // donothing";
755 Cerr << "Shell command executed: " << folder_name << finl;
756 int error = system(folder_name);
757 assert(!error);
758 if (error)
760 }
761}
762
763void IJK_Thermals::set_first_step_thermals_post(int& first_step_thermals_post)
764{
765 first_step_thermals_post = 0;
766 for (int idth = 0; idth < liste_thermique_.size(); idth++)
767 first_step_thermals_post = (first_step_thermals_post || liste_thermique_[idth]->get_first_step_thermals_post());
768}
769
771{
772 for (auto& itr : liste_thermique_)
773 itr->compute_temperature_init();
774}
775
777 const Domaine_IJK& new_mesh,
778 const Nom& lata_name,
779 DoubleTab& coeff_i,
780 IntTab Indice_i,
781 DoubleTab& coeff_j,
782 IntTab Indice_j,
783 DoubleTab& coeff_k,
784 IntTab Indice_k)
785{
786 IJK_Field_double new_thermal_field;
787 if (liste_thermique_.size() > 0)
788 {
789 switch_double_ft.calculer_coords_elem();
790 switch_double_ft.calculer_coeff(coeff_i,Indice_i,coeff_j,Indice_j,coeff_k,Indice_k);
791 new_thermal_field.allocate(new_mesh /* it is in fact a splitting */, Domaine_IJK::ELEM, 0);
792 }
793 int idth = 0;
794 for (auto& itr : liste_thermique_)
795 {
796 switch_double_ft.switch_scalar_field(*itr->get_temperature(),
797 new_thermal_field,
798 coeff_i, Indice_i,
799 coeff_j ,Indice_j,
800 coeff_k ,Indice_k);
801
802 Cout << "Writing " << Nom("TEMPERATURE_") + Nom(idth) << " into " << lata_name << finl;
803 dumplata_scalar(lata_name, Nom("TEMPERATURE_") + Nom(idth), new_thermal_field, 0 /*we store a 0 */);
804 ++idth;
805 }
806}
807
809{
810 for (auto& itr : liste_thermique_)
811 itr->copy_previous_interface_state();
812}
813
815{
816 for (auto& itr : liste_thermique_)
817 itr->copie_pure_vers_diph_sans_interpolation();
818}
819
821{
822 for (auto& itr : liste_thermique_)
823 itr->echange_pure_vers_diph_cellules_initialement_pures();
824}
825
827{
828 for (auto& itr : liste_thermique_)
829 itr->echange_diph_vers_pure_cellules_finalement_pures();
830}
831
833{
834 for (auto& itr : liste_thermique_)
835 itr->vide_phase_invalide_cellules_diphasiques();
836}
837
839{
840 for (auto& itr : liste_thermique_)
841 itr->remplir_tableau_pure_cellules_diphasiques(next_time);
842}
DoubleTab & valeurs() override
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
This class encapsulates all the information related to the eulerian mesh for TrioIJK.
Definition Domaine_IJK.h:47
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....
OWN_PTR(Parametre_equation_base) &parametre_equation()
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
const Fluide_Incompressible & fluide_phase(int la_phase) const
void allocate(const Domaine_IJK &d, Domaine_IJK::Localisation l, int ghost_size, int additional_k_layers=0, int nb_compo=1, const Nom &name=Nom(), bool external_storage=false, int monofluide=0, double rov=0., double rol=0., int use_inv_rho_in_pressure_solver=0)
static void typer_lire_thermal_equation(OWN_PTR(IJK_Thermal_base)&, Entree &)
void thermal_subresolution_outputs(const int &dt_post_thermals_probes=0)
std::vector< int > lata_step_reprise_
void set_first_step_thermals_post(int &first_step_thermals_post)
void associer_switch(const Switch_FT_double &ijk_ft_switch)
void prepare_thermals(const char *lataname)
void associer_post(const Postprocessing_IJK &ijk_ft_post)
void create_folders_for_probes()
void compute_ghost_cell_numbers_for_subproblems(const Domaine_IJK &splitting, int ghost_init)
void retrieve_ghost_fluid_params()
int get_disable_post_processing_probes_out_files() const
void ecrire_statistiques_bulles(int reset, const Nom &nom_cas, const double current_time, const ArrOfDouble &surface)
void rk3_rustine_sub_step(const int rk_step, const double total_timestep, const double fractionnal_timestep, const double time)
void verifie_milieu()
void update_intersections()
Nom local_quantities_thermal_lines_time_index_folder_
void get_noms_champs_postraitables(Noms &noms, Option opt=NONE) const override
void set_fichier_reprise(const char *lataname)
void vide_phase_invalide_cellules_diphasiques()
void set_temperature_ini()
void echange_diph_vers_pure_cellules_finalement_pures()
void get_rising_velocities_parameters(int &compute_rising_velocities, int &fill_rising_velocities, int &use_bubbles_velocities_from_interface, int &use_bubbles_velocities_from_barycentres)
Nom local_quantities_thermal_probes_folder_
Nom shell_quantities_thermal_probes_folder_
void echange_pure_vers_diph_cellules_initialement_pures()
int get_probes_ghost_cells(int ghost_init)
Nom overall_bubbles_quantities_folder_
void remplir_tableau_pure_cellules_diphasiques(bool next_time)
void associer_interface_intersections(const Intersection_Interface_ijk_cell &intersection_ijk_cell_, const Intersection_Interface_ijk_face &intersection_ijk_face_)
void associer_milieu_base(const Milieu_base &) override
int ini_folder_out_files_
const IJK_Field_vector3_double & get_IJK_field_vector(const Motcle &nom) override
bool has_champ(const Motcle &nom) const override
void clean_ijk_intersections()
void sauvegarder_temperature(Nom &lata_name, const int &stop)
void initialize(const Domaine_IJK &splitting)
void euler_rustine_step(const double timestep)
void set_latastep_reprise(const bool stop)
void ecrire_fichier_reprise(SFichier &fichier, const char *lata_name)
void posttraiter_tous_champs_thermal(Motcles &liste_post_instantanes_)
int post_pro_first_call_
void init_switch_thermals(const Domaine_IJK &splitting)
void copy_previous_interface_state()
const Nom & get_fichier_reprise()
Nom local_quantities_thermal_probes_time_index_folder_
int size() const
const IJK_Field_double & get_IJK_field(const Motcle &nom) override
Nom local_quantities_thermal_slices_folder_
static void Fill_postprocessable_fields(std::vector< FieldInfo_t > &chps)
std::vector< int > lata_step_reprise_ini_
void sauvegarder_thermals(SFichier &fichier)
Nom local_quantities_thermal_slices_time_index_folder_
int size_thermal_problem(Nom thermal_problem)
double get_modified_time()
IJK_Ghost_Fluid_Fields ghost_fluid_fields_
void posttraiter_champs_instantanes_thermal(const Motcles &liste_post_instantanes, const char *lata_name, const int latastep, const double current_time, int &n)
void update_thermal_properties()
void compute_new_thermal_field(Switch_FT_double &switch_double_ft, const Domaine_IJK &new_mesh, const Nom &lata_name, DoubleTab &coeff_i, IntTab Indice_i, DoubleTab &coeff_j, IntTab Indice_j, DoubleTab &coeff_k, IntTab Indice_k)
void compute_eulerian_distance_curvature()
Fluide_Diphasique_IJK & milieu_ijk()
void completer() override
Complete la construction (initialisation) des objets associes a l'equation.
void rk3_sub_step(const int rk_step, const double total_timestep, const double time)
void associer_pb_base(const Probleme_base &) override
S'associe au Probleme passe en parametre.
void create_folders(Nom folder_name_base)
void compute_eulerian_curvature()
void compute_timestep(double &dt_thermals, const double dxmin)
Nom local_quantities_thermal_lines_folder_
Nom interfacial_quantities_thermal_probes_folder_
void compute_eulerian_distance()
void recompute_temperature_init()
void compute_eulerian_curvature_from_interface()
const Milieu_base & milieu() const override
void euler_time_step(const double timestep)
void copie_pure_vers_diph_sans_interpolation()
classe Milieu_base Cette classe est la base de la hierarchie des milieux (physiques)
Definition Milieu_base.h:50
bool has_conductivite() const
virtual const Champ_Don_base & capacite_calorifique() const
Renvoie la capacite calorifique du milieu.
bool has_capacite_calorifique() const
virtual const Champ_Don_base & conductivite() const
Renvoie la conductivite du milieu.
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
Un tableau d'objets de la classe Motcle.
Definition Motcle.h:63
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
const std::string & getString() const
Definition Nom.h:92
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
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
static bool DISABLE_DIPHASIQUE
Definition Option_IJK.h:26
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Probleme_U.h:109
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
Definition Process.cpp:86
Cette classe est a la classe C++ ofstream ce que la classe Sortie est a la classe C++ ostream Elle re...
Definition SFichier.h:27
Classe de base des flux de sortie.
Definition Sortie.h:52
void calculer_coeff(DoubleTab &coeff_i, IntTab &Indice_i, DoubleTab &coeff_j, IntTab &Indice_j, DoubleTab &coeff_k, IntTab &Indice_k)
void calculer_coords_elem()
void switch_scalar_field(const IJK_Field_double &oldf, IJK_Field_double &newf, DoubleTab coeff_i, IntTab Indice_i, DoubleTab coeff_j, IntTab Indice_j, DoubleTab coeff_k, IntTab Indice_k) const
_SIZE_ size() const
Definition TRUSTVect.tpp:45