TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
IJK_Ghost_Fluid_Fields.cpp
1/****************************************************************************
2* Copyright (c) 2024, 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_Ghost_Fluid_Fields.h>
17#include <Probleme_FTD_IJK_base.h>
18#include <IJK_Navier_Stokes_tools.h>
19#include <IJK_Ghost_Fluid_tools.h>
20#include <IJK_Bubble_tools.h>
21
22
23Implemente_instanciable_sans_constructeur( IJK_Ghost_Fluid_Fields, "IJK_Ghost_Fluid_Fields", Objet_U ) ;
24
25IJK_Ghost_Fluid_Fields::IJK_Ghost_Fluid_Fields()
26{
27
28}
29
31{
32 Objet_U::printOn( os );
33 return os;
34}
35
37{
38 Objet_U::readOn( is );
39 return is;
40}
41
43{
44 ref_ijk_ft_ = ijk_ft;
45}
46
48{
50 {
51 /*
52 * TODO: Move to IJK_Interfaces
53 */
54 // Laplacian(d) necessitates 2 ghost cells like temperature
56 const int nb_ghost_parallel_calls = 2;
57 const int dist_ghost = avoid_gfm_parallel_calls_ ? n_iter_base + nb_ghost_parallel_calls : 2;
58
59 eulerian_distance_ft_.allocate(ref_ijk_ft_->get_domaine_ft(), Domaine_IJK::ELEM, dist_ghost);
60
63
64 const int dist_tmp_ghost = avoid_gfm_parallel_calls_ ? n_iter_base + nb_ghost_parallel_calls : 0;
65 tmp_interf_cells_.allocate(ref_ijk_ft_->get_domaine_ft(), Domaine_IJK::ELEM, dist_tmp_ghost);
66 tmp_propagated_cells_.allocate(ref_ijk_ft_->get_domaine_ft(), Domaine_IJK::ELEM, dist_tmp_ghost);
67
68 // grad(d) necessitates 1 ghost cell ?
69 const int normal_ghost = avoid_gfm_parallel_calls_ ? n_iter_base + nb_ghost_parallel_calls : 1;
70 allocate_cell_vector(eulerian_normal_vectors_ft_, ref_ijk_ft_->get_domaine_ft(), normal_ghost);
71
74 // allocate_velocity(eulerian_normal_vectors_, ref_ijk_ft_->get_domaine_ft(), 1);
75
76 allocate_cell_vector(eulerian_facets_barycentre_ft_, ref_ijk_ft_->get_domaine_ft(), 0);
77
78 eulerian_distance_ft_.echange_espace_virtuel(eulerian_distance_ft_.ghost());
79 eulerian_normal_vectors_ft_.echange_espace_virtuel();
80 eulerian_facets_barycentre_ft_.echange_espace_virtuel();
81 /*
82 * TODO: This is already calculated in IJK_Interfaces
83 * Keep it for now and clean later
84 */
85 eulerian_distance_ns_.allocate(splitting, Domaine_IJK::ELEM, 2);
86 allocate_cell_vector(eulerian_normal_vectors_ns_, splitting, 1);
87 allocate_cell_vector(eulerian_facets_barycentre_ns_, splitting, 0);
88 eulerian_distance_ns_.echange_espace_virtuel(eulerian_distance_ns_.ghost());
89 eulerian_normal_vectors_ns_.echange_espace_virtuel();
90 eulerian_facets_barycentre_ns_.echange_espace_virtuel();
91 allocate_cell_vector(eulerian_normal_vectors_ns_normed_, splitting, 1);
92 eulerian_normal_vectors_ns_normed_.echange_espace_virtuel();
93
95 {
96 assert(eulerian_distance_ft_.ghost()==tmp_old_dist_val_.ghost());
97 assert(eulerian_distance_ft_.ghost()==tmp_new_dist_val_.ghost());
98 assert(eulerian_normal_vectors_ft_[0].ghost()==tmp_old_vector_val_[0].ghost());
99 assert(eulerian_normal_vectors_ft_[0].ghost()==tmp_new_vector_val_[0].ghost());
100 }
101 }
103 {
104 // Laplacian(d) necessitates 0 ghost cells like div_lambda_grad_T
105 // but if calculated using the neighbours maybe 1
106 // const int curvature_ghost = avoid_gfm_parallel_calls_ ? n_iter_distance_ : 1;
107 const int curvature_ghost = avoid_gfm_parallel_calls_ ? 1 : 1;
108 eulerian_curvature_ft_.allocate(ref_ijk_ft_->get_domaine_ft(), Domaine_IJK::ELEM, curvature_ghost);
109
112
113 eulerian_curvature_ft_.echange_espace_virtuel(eulerian_curvature_ft_.ghost());
114 // Only calculated in the mixed cells ghost_cells = 0
115 eulerian_interfacial_area_ft_.allocate(ref_ijk_ft_->get_domaine_ft(), Domaine_IJK::ELEM, 0);
116 eulerian_interfacial_area_ft_.echange_espace_virtuel(eulerian_interfacial_area_ft_.ghost());
117 /*
118 * TODO: This is already calculated in IJK_Interfaces
119 * Keep it for now and clean later
120 */
121 eulerian_curvature_ns_.allocate(splitting, Domaine_IJK::ELEM, 1);
122 eulerian_curvature_ns_.echange_espace_virtuel(eulerian_curvature_ns_.ghost());
123 eulerian_interfacial_area_ns_.allocate(splitting, Domaine_IJK::ELEM, 0);
124 eulerian_interfacial_area_ns_.echange_espace_virtuel(eulerian_interfacial_area_ns_.ghost());
125 }
126}
127
128void IJK_Ghost_Fluid_Fields::Fill_postprocessable_fields(std::vector<FieldInfo_t>& chps)
129{
130 std::vector<FieldInfo_t> c =
131 {
132 // Name / Localisation (elem, face, ...) / Nature (scalare, vector) / Located on interface?
133 { "TEMPERATURE", Entity::ELEMENT, Nature_du_champ::scalaire, false },
134 { "TEMPERATURE_ADIMENSIONNELLE_THETA", Entity::ELEMENT, Nature_du_champ::scalaire, false },
135 { "DIV_LAMBDA_GRAD_T_VOLUME", Entity::ELEMENT, Nature_du_champ::scalaire, false },
136
137 };
138 chps.insert(chps.end(), c.begin(), c.end());
139}
140
141
142
144{
145 for (const auto& n : champs_compris_.liste_noms_compris())
146 noms.add(n);
147 for (const auto& n : champs_compris_.liste_noms_compris_vectoriel())
148 noms.add(n);
149}
150
152{
153 if (champs_compris_.liste_noms_compris().contient_(nom))
154 return champs_compris_.has_champ(nom);
155 else if (champs_compris_.liste_noms_compris_vectoriel().contient_(nom))
156 return champs_compris_.has_champ_vectoriel(nom);
157 else
158 return false;
159}
160
161const IJK_Field_double& IJK_Ghost_Fluid_Fields::get_IJK_field(const Motcle& nom)
162{
163 if (champs_compris_.liste_noms_compris().contient_(nom))
164 return champs_compris_.get_champ(nom);
165 else
166 {
167 Cerr << "ERROR in IJK_Ghost_Fluid_Fields::get_IJK_field : " << finl;
168 Cerr << "Requested field '" << nom << "' is not recognized by IJK_Ghost_Fluid_Fields::get_IJK_field()." << finl;
169 throw;
170 }
171}
172
173const IJK_Field_vector3_double& IJK_Ghost_Fluid_Fields::get_IJK_field_vector(const Motcle& nom)
174{
175 if (champs_compris_.liste_noms_compris_vectoriel().contient_(nom))
176 return champs_compris_.get_champ_vectoriel(nom);
177 else
178 {
179 Cerr << "ERROR in IJK_Ghost_Fluid_Fields::get_IJK_field_vector : " << finl;
180 Cerr << "Requested field '" << nom << "' is not recognized by IJK_Ghost_Fluid_Fields::get_IJK_field_vector()." << finl;
181 throw;
182 }
183}
184static void enforce_zero_value_eulerian_field(IJK_Field_double& eulerian_field)
185{
186 const int nx = eulerian_field.ni();
187 const int ny = eulerian_field.nj();
188 const int nz = eulerian_field.nk();
189 static const double invalid_distance_value = -1.e30;
190 for (int k=0; k < nz ; k++)
191 for (int j=0; j< ny; j++)
192 for (int i=0; i < nx; i++)
193 if (eulerian_field(i,j,k) < invalid_distance_value)
194 eulerian_field(i,j,k) = 0.;
195}
196
197static void enforce_max_value_eulerian_field(IJK_Field_double& eulerian_field)
198{
199 double eulerian_field_max = -1.e20;
200 const int nx = eulerian_field.ni();
201 const int ny = eulerian_field.nj();
202 const int nz = eulerian_field.nk();
203 static const double invalid_distance_value = -1.e30;
204 for (int k=0; k < nz ; k++)
205 for (int j=0; j< ny; j++)
206 for (int i=0; i < nx; i++)
207 eulerian_field_max = std::max(eulerian_field_max, eulerian_field(i,j,k));
208 for (int k=0; k < nz ; k++)
209 for (int j=0; j< ny; j++)
210 for (int i=0; i < nx; i++)
211 if (eulerian_field(i,j,k) < invalid_distance_value)
212 eulerian_field(i,j,k) = eulerian_field_max;
213}
214
215//static void enforce_min_value_eulerian_field(IJK_Field_double& eulerian_field)
216//{
217// double eulerian_field_min = 1.e20;
218// const int nx = eulerian_field.ni();
219// const int ny = eulerian_field.nj();
220// const int nz = eulerian_field.nk();
221// static const double invalid_distance_value = -1.e30;
222// for (int k=0; k < nz ; k++)
223// for (int j=0; j< ny; j++)
224// for (int i=0; i < nx; i++)
225// eulerian_field_min = std::min(eulerian_field_min, eulerian_field(i,j,k));
226// for (int k=0; k < nz ; k++)
227// for (int j=0; j< ny; j++)
228// for (int i=0; i < nx; i++)
229// if (eulerian_field(i,j,k) < invalid_distance_value)
230// eulerian_field(i,j,k) = eulerian_field_min;
231//}
232
234{
236 {
238 {
239 Navier_Stokes_FTD_IJK& ns = ref_ijk_ft_->eq_ns();
240
241 // TODO: Do we need to perform an echange_virtuel with interfaces ?
242 compute_eulerian_normal_distance_facet_barycentre_field(ref_ijk_ft_->get_interface(),
257 eulerian_distance_ft_.echange_espace_virtuel(eulerian_distance_ft_.ghost());
258 eulerian_distance_ns_.data() = 0.;
259 eulerian_distance_ns_.echange_espace_virtuel(eulerian_distance_ns_.ghost());
261 eulerian_distance_ns_.echange_espace_virtuel(eulerian_distance_ns_.ghost());
262 for(int dir=0; dir<3; dir++)
263 {
266 }
270 const int nx = eulerian_normal_vectors_ns_normed_[0].ni();
271 const int ny = eulerian_normal_vectors_ns_normed_[0].nj();
272 const int nz = eulerian_normal_vectors_ns_normed_[0].nk();
273 for (int k=0; k < nz ; k++)
274 for (int j=0; j< ny; j++)
275 for (int i=0; i < nx; i++)
276 {
277 double norm_x = eulerian_normal_vectors_ns_[0](i,j,k);
278 double norm_y = eulerian_normal_vectors_ns_[1](i,j,k);
279 double norm_z = eulerian_normal_vectors_ns_[2](i,j,k);
280 norm_x *= norm_x;
281 norm_y *= norm_y;
282 norm_z *= norm_z;
283 const double norm = norm_x + norm_y + norm_z;
284 if (norm > 0)
285 {
286 eulerian_normal_vectors_ns_normed_[0](i,j,k) = eulerian_normal_vectors_ns_[0](i,j,k) / sqrt(norm);
287 eulerian_normal_vectors_ns_normed_[1](i,j,k) = eulerian_normal_vectors_ns_[1](i,j,k) / sqrt(norm);
288 eulerian_normal_vectors_ns_normed_[2](i,j,k) = eulerian_normal_vectors_ns_[2](i,j,k) / sqrt(norm);
289 }
290 }
291 eulerian_normal_vectors_ns_normed_.echange_espace_virtuel();
292 // has_computed_distance_ = true;
293 }
294 else
295 Cerr << "Don't compute the eulerian distance field" << finl;
296 }
297}
298
300{
301 /*
302 * For post-processings purposes
303 */
306 enforce_max_value_eulerian_field(eulerian_interfacial_area_ft_);
307}
308
310{
312 {
313 enforce_zero_value_eulerian_field(eulerian_distance_ft_);
314 enforce_zero_value_eulerian_field(eulerian_distance_ns_);
315 }
316 else
317 Cerr << "Eulerian distance has not been computed" << finl;
318}
319
321{
323 {
324 /*
325 * Laplacian operator may not work properly with FT_field ?
326 */
327 eulerian_distance_ft_.echange_espace_virtuel(eulerian_distance_ft_.ghost());
328 compute_eulerian_curvature_field_from_distance_field(eulerian_distance_ft_,
332 eulerian_curvature_ft_.echange_espace_virtuel(eulerian_curvature_ft_.ghost());
333 ref_ijk_ft_->eq_ns().redistribute_from_splitting_ft_elem(eulerian_curvature_ft_, eulerian_curvature_ns_);
334 }
335 else
336 Cerr << "Don't compute the eulerian curvature field" << finl;
337}
338
340{
342 {
344 {
345 eulerian_interfacial_area_ft_.echange_espace_virtuel(eulerian_interfacial_area_ft_.ghost());
346 eulerian_normal_vectors_ft_.echange_espace_virtuel();
347 int nb_groups = ref_ijk_ft_->get_interface().nb_groups();
348 // Boucle debute a -1 pour faire l'indicatrice globale.
349 // S'il n'y a pas de groupes de bulles (monophasique ou monodisperse), on passe exactement une fois dans la boucle
350 if (nb_groups == 1)
351 nb_groups = 0; // Quand il n'y a qu'un groupe, on ne posttraite pas les choses pour ce groupe unique puisque c'est identique au cas global
352 for (int igroup = -1; igroup < nb_groups; igroup++)
353 {
354 compute_eulerian_curvature_field_from_interface(eulerian_normal_vectors_ft_,
355 ref_ijk_ft_->get_interface(),
361 igroup);
362 }
363 eulerian_interfacial_area_ft_.echange_espace_virtuel(eulerian_interfacial_area_ft_.ghost());
364 eulerian_curvature_ft_.echange_espace_virtuel(eulerian_curvature_ft_.ghost());
365 ref_ijk_ft_->eq_ns().redistribute_from_splitting_ft_elem(eulerian_interfacial_area_ft_, eulerian_interfacial_area_ns_);
366 ref_ijk_ft_->eq_ns().redistribute_from_splitting_ft_elem(eulerian_curvature_ft_, eulerian_curvature_ns_);
367 // has_computed_curvature_ = true;
368 }
369 else
370 Cerr << "Don't compute the eulerian curvature field" << finl;
371 }
372}
373
375{
377 enforce_zero_value_eulerian_field(eulerian_curvature_ft_);
378 else
379 Cerr << "Eulerian curvature has not been computed" << finl;
380}
381
383{
385 {
386 enforce_max_value_eulerian_field(eulerian_curvature_ft_);
387 enforce_max_value_eulerian_field(eulerian_curvature_ns_);
388 }
389 else
390 Cerr << "Eulerian curvature has not been computed" << finl;
391}
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
const IJK_Field_double & get_IJK_field(const Motcle &nom) override
IJK_Field_local_double boundary_flux_kmin_
void get_noms_champs_postraitables(Noms &noms, Option opt=NONE) const
IJK_Field_vector3_double tmp_old_vector_val_
IJK_Field_double eulerian_distance_ns_
IJK_Field_double eulerian_distance_ft_
static void Fill_postprocessable_fields(std::vector< FieldInfo_t > &chps)
IJK_Field_vector3_double eulerian_normal_vectors_ns_
IJK_Field_double eulerian_curvature_ft_
IJK_Field_vector3_double tmp_new_vector_val_
IJK_Field_vector3_double eulerian_facets_barycentre_ft_
IJK_Field_local_double boundary_flux_kmax_
IJK_Field_vector3_double eulerian_facets_barycentre_ns_
IJK_Field_double eulerian_interfacial_area_ft_
void associer(const Probleme_FTD_IJK_base &ijk_ft)
void initialize(const Domaine_IJK &splitting)
FixedVector< ArrOfInt, 3 > propagated_cells_indices_
IJK_Field_vector3_double eulerian_normal_vectors_ns_normed_
const IJK_Field_vector3_double & get_IJK_field_vector(const Motcle &nom) override
IJK_Field_double eulerian_curvature_ns_
IJK_Field_vector3_double eulerian_normal_vectors_ft_
bool has_champ(const Motcle &nom) const override
FixedVector< ArrOfInt, 3 > gfm_first_cells_indices_
Champs_compris_IJK champs_compris_
void enforce_distance_curvature_values_for_post_processings()
FixedVector< ArrOfInt, 3 > interf_cells_indices_
IJK_Field_double eulerian_interfacial_area_ns_
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
void redistribute_from_splitting_ft_elem(const IJK_Field_double &input_field, IJK_Field_double &output_field)
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
classe Objet_U Cette classe est la classe de base des Objets de TRUST
Definition Objet_U.h:73
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
Classe de base des flux de sortie.
Definition Sortie.h:52