16#include <IJK_Bubble_tools.h>
19static int decoder_numero_bulle(
const int code)
21 const int num_bulle = code >> 6;
25std::vector<int> arg_sort_array(
const ArrOfDouble& array_to_sort)
29 std::vector<int> indices(n);
30 for (
int j=0; j<n; j++)
32 std::sort(indices.begin(), indices.end(), [&array_to_sort](
int i,
int j) {return array_to_sort[i] < array_to_sort[j];});
36std::vector<int> arg_sort_array_phi(
const ArrOfDouble& angle_incr,
const ArrOfDouble& first_angle,
const ArrOfDouble& array_to_sort)
39 const double constant_angle_incr = abs(angle_incr[1] - angle_incr[0]);
40 std::vector<int> indices;
41 std::vector<int> indices_subarray;
42 ArrOfDouble sub_array;
45 const double angle_min = angle_incr(i) - constant_angle_incr / 2;
46 const double angle_max = angle_incr(i) + constant_angle_incr / 2;
48 if (first_angle(j) >= angle_min && first_angle(j) < angle_max)
50 indices_subarray.push_back(j);
53 std::vector<int> indices_subarray_sorted = arg_sort_array(sub_array);
54 const int size_subarray_sorted = (int) indices_subarray_sorted.size();
55 for (
int k=0; k<size_subarray_sorted; k++)
57 const int index = indices_subarray_sorted[k];
58 indices.push_back((
int) indices_subarray[index]);
60 indices_subarray.clear();
64 assert((
int) indices.size() == n);
65 if (!((
int) indices.size() == n))
78void compute_bounding_box_fill_compo(
const IJK_Interfaces& interfaces,
79 DoubleTab& bounding_box,
80 DoubleTab& min_max_larger_box,
81 IJK_Field_double& eulerian_compo_connex,
82 IJK_Field_double& eulerian_compo_connex_ghost,
83 DoubleTab& bubbles_barycentre)
94 eulerian_compo_connex.
data() = -1;
96 eulerian_compo_connex_ghost.
data() = -1;
98 IntTab ghost_to_real_bubble(nb_ghost_bubbles);
99 for (
int l = 0; l < nb_ghost_bubbles; l++)
102 const int ibulle_reelle = decoder_numero_bulle(-ighost);
103 ghost_to_real_bubble(l) = ibulle_reelle;
106 ArrOfDouble bubbles_volume;
116 double delta_xyz[3] = {dx, dy, dz};
121 double geom_origin_x = geometry.
get_origin(DIRECTION_I);
122 double geom_origin_y = geometry.
get_origin(DIRECTION_J);
123 double geom_origin_z = geometry.
get_origin(DIRECTION_K);
124 double origin_x = geom_origin_x + geometry.
get_offset_local(DIRECTION_I) * dx;
125 double origin_y = geom_origin_y + geometry.
get_offset_local(DIRECTION_J) * dy;
126 double origin_z = geom_origin_z + geometry.
get_offset_local(DIRECTION_K) * dz;
127 double geom_origin[3] = {geom_origin_x, geom_origin_y, geom_origin_z};
128 double origin[3] = {origin_x, origin_y, origin_z};
131 min_max_larger_box.
resize(nb_bubbles, 3, 2);
132 DoubleTab min_max_larger_box_absolute(nb_bubbles, 3, 2);
133 for (
int ibubble = 0; ibubble < nb_bubbles; ibubble++)
135 for (
int dir = 0; dir < 3; dir++)
137 min_max_larger_box(ibubble, dir, 0) = origin[dir] + trunc((bounding_box(ibubble, dir, 0) - geom_origin[dir]) / delta_xyz[dir])
139 min_max_larger_box_absolute(ibubble, dir, 0) = min_max_larger_box(ibubble, dir, 0) - bubbles_barycentre(ibubble, dir);
141 for (
int dir = 0; dir < 3; dir++)
143 min_max_larger_box(ibubble, dir, 1) = origin[dir] + trunc((bounding_box(ibubble, dir, 1) - geom_origin[dir] + delta_xyz[dir]) / delta_xyz[dir]) * delta_xyz[dir];
144 min_max_larger_box_absolute(ibubble, dir, 1) = min_max_larger_box(ibubble, dir, 1) - bubbles_barycentre(ibubble, dir);
150 const int nk = eulerian_compo_connex.
nk();
151 const int nj = eulerian_compo_connex.
nj();
152 const int ni = eulerian_compo_connex.
ni();
154 const IJK_Field_double& indic = interfaces.
In_ft();
155 for (
int k = 0; k < nk; k++)
156 for (
int j = 0; j < nj; j++)
157 for (
int i = 0; i < ni; i++)
158 for (
int ibubble = 0; ibubble < (nb_bubbles + nb_ghost_bubbles); ibubble++)
160 const double cell_pos_x = origin_x + (i + 0.5) * delta_xyz[0];
161 const double cell_pos_y = origin_y + (j + 0.5) * delta_xyz[1];
162 const double cell_pos_z = origin_z + (k + 0.5) * delta_xyz[2];
163 double cell_pos[3] = {cell_pos_x, cell_pos_y, cell_pos_z};
164 const double chi_l = indic(i,j,k);
165 int cell_pos_bool =
true;
167 for (
int dir = 0; dir < 3; dir++)
171 if (ibubble < nb_bubbles)
173 bubble_index = ibubble;
174 min_box = min_max_larger_box(bubble_index, dir, 0);
175 max_box = min_max_larger_box(bubble_index, dir, 1);
179 bubble_index = ghost_to_real_bubble(ibubble - nb_bubbles);
180 min_box = min_max_larger_box_absolute(bubble_index, dir, 0) + bubbles_barycentre(ibubble, dir);
181 max_box = min_max_larger_box_absolute(bubble_index, dir, 1) + bubbles_barycentre(ibubble, dir);
183 cell_pos_bool = (cell_pos_bool && cell_pos[dir] > min_box && cell_pos[dir] < max_box);
185 if (fabs(chi_l) < LIQUID_INDICATOR_TEST)
189 eulerian_compo_connex(i,j,k) = bubble_index;
190 eulerian_compo_connex_ghost(i,j,k) = ibubble;
196void compute_interfacial_compo_fill_compo(
const IJK_Interfaces& interfaces, IJK_Field_double& eulerian_compo_connex)
201void compute_rising_velocity_overall(
const IJK_Interfaces& interfaces,
202 const DoubleTab& rising_vectors,
203 const ArrOfDouble& rising_velocities,
204 const ArrOfDouble& bubbles_volume,
205 Vecteur3& rising_velocities_overall,
206 const DoubleTab& bubbles_velocities_from_interface,
207 const int& use_bubbles_velocities_from_interface,
208 const DoubleTab& bubbles_velocities_from_barycentres,
209 const int& use_bubbles_velocities_from_barycentres)
211 rising_velocities_overall = {0.,0.,0.};
212 double total_volume = 0;
214 for (
int ibubble = 0; ibubble < nb_bubbles; ibubble++)
216 for (
int l=0; l<3; l++)
218 if (use_bubbles_velocities_from_interface)
219 rising_velocities_overall[l] = bubbles_velocities_from_interface(ibubble, l) * bubbles_volume[ibubble];
220 else if (use_bubbles_velocities_from_barycentres)
221 rising_velocities_overall[l] = bubbles_velocities_from_barycentres(ibubble, l) * bubbles_volume[ibubble];
223 rising_velocities_overall[l] = (rising_velocities[ibubble] * rising_vectors(ibubble, l))
224 * bubbles_volume[ibubble];
226 total_volume += bubbles_volume[ibubble];
228 for (
int l=0; l<3; l++)
230 const double rising_velocity_compo = rising_velocities_overall[l];
231 rising_velocities_overall[l] = rising_velocity_compo / total_volume;
235void compute_rising_velocity(
const IJK_Field_vector3_double& velocity,
237 const IJK_Field_int& eulerian_compo_connex_ns,
238 const int& gravity_dir,
239 ArrOfDouble& rising_velocities,
240 DoubleTab& rising_vectors,
242 const DoubleTab& bubbles_velocities_from_interface,
243 const int& use_bubbles_velocities_from_interface,
244 const DoubleTab& bubbles_velocities_from_barycentres,
245 const int& use_bubbles_velocities_from_barycentres)
247 const DoubleTab * bubbles_velocities_interf_bary =
nullptr;
248 if (use_bubbles_velocities_from_barycentres)
249 bubbles_velocities_interf_bary = &bubbles_velocities_from_barycentres;
251 bubbles_velocities_interf_bary = &bubbles_velocities_from_interface;
255 const int nk = eulerian_compo_connex_ns.
nk();
256 const int nj = eulerian_compo_connex_ns.
nj();
257 const int ni = eulerian_compo_connex_ns.
ni();
259 const IJK_Field_double& indic = interfaces.
I();
263 DoubleVect sum_indicator(nb_bubbles);
264 DoubleVect sum_velocity_x_indicator(nb_bubbles);
265 DoubleVect sum_velocity_y_indicator(nb_bubbles);
266 DoubleVect sum_velocity_z_indicator(nb_bubbles);
268 liquid_velocity = 0.;
269 double sum_indicator_liquid = 0.;
271 for (
int k = 0; k < nk; k++)
272 for (
int j = 0; j < nj; j++)
273 for (
int i = 0; i < ni; i++)
275 const double chi_l = indic(i,j,k);
276 const double vel_x = 0.5 * (velocity[0](i,j,k) + velocity[0](i+1,j,k));
277 const double vel_y = 0.5 * (velocity[1](i,j,k) + velocity[1](i,j+1,k));
278 const double vel_z = 0.5 * (velocity[2](i,j,k) + velocity[2](i,j,k+1));
279 if (!(use_bubbles_velocities_from_interface || use_bubbles_velocities_from_barycentres))
281 const double chi_v = (1. - indic(i,j,k));
282 int compo_connex = eulerian_compo_connex_ns(i,j,k);
285 if (compo_connex >= 0)
288 sum_indicator(compo_connex) += chi_v;
289 sum_velocity_x_indicator(compo_connex) += chi_v * vel_x;
290 sum_velocity_y_indicator(compo_connex) += chi_v * vel_y;
291 sum_velocity_z_indicator(compo_connex) += chi_v * vel_z;
295 if (chi_l > VAPOUR_INDICATOR_TEST)
298 Vecteur3 liquid_velocity_local = {vel_x, vel_y, vel_z};
299 liquid_velocity_local *= chi_l;
300 sum_indicator_liquid += chi_l;
301 liquid_velocity += liquid_velocity_local;
305 if (!(use_bubbles_velocities_from_interface || use_bubbles_velocities_from_barycentres))
312 for (
int ibubble = 0; ibubble < nb_bubbles; ibubble++)
314 sum_velocity_x_indicator(ibubble) /= sum_indicator(ibubble);
315 sum_velocity_y_indicator(ibubble) /= sum_indicator(ibubble);
316 sum_velocity_z_indicator(ibubble) /= sum_indicator(ibubble);
317 rising_velocities(ibubble) = sqrt( sum_velocity_x_indicator(ibubble) * sum_velocity_x_indicator(ibubble)
318 + sum_velocity_y_indicator(ibubble) * sum_velocity_y_indicator(ibubble)
319 + sum_velocity_z_indicator(ibubble) * sum_velocity_z_indicator(ibubble));
320 if (rising_velocities(ibubble) > DMINFLOAT)
322 rising_vectors(ibubble, 0) = sum_velocity_x_indicator(ibubble) / rising_velocities(ibubble);
323 rising_vectors(ibubble, 1) = sum_velocity_y_indicator(ibubble) / rising_velocities(ibubble);
324 rising_vectors(ibubble, 2) = sum_velocity_z_indicator(ibubble) / rising_velocities(ibubble);
328 assert(gravity_dir >=0);
329 for (
int l=0; l<3; l++)
330 if (l != gravity_dir)
331 rising_vectors(ibubble, gravity_dir) = 0.;
332 rising_vectors(ibubble, gravity_dir) = 1.;
338 for (
int ibubble = 0; ibubble < nb_bubbles; ibubble++)
340 const double vel_x = (*bubbles_velocities_interf_bary)(ibubble, 0);
341 const double vel_y = (*bubbles_velocities_interf_bary)(ibubble, 1);
342 const double vel_z = (*bubbles_velocities_interf_bary)(ibubble, 2);
343 rising_velocities(ibubble) = sqrt( vel_x * vel_x + vel_y * vel_y + vel_z * vel_z);
344 if (rising_velocities(ibubble) > DMINFLOAT)
346 rising_vectors(ibubble, 0) = vel_x / rising_velocities(ibubble);
347 rising_vectors(ibubble, 1) = vel_y / rising_velocities(ibubble);
348 rising_vectors(ibubble, 2) = vel_z / rising_velocities(ibubble);
352 assert(gravity_dir >=0);
353 for (
int l=0; l<3; l++)
354 if (l != gravity_dir)
355 rising_vectors(ibubble, gravity_dir) = 0.;
356 rising_vectors(ibubble, gravity_dir) = 1.;
362 double liquid_velocity_x = liquid_velocity[0];
363 double liquid_velocity_y = liquid_velocity[1];
364 double liquid_velocity_z = liquid_velocity[2];
366 liquid_velocity = {liquid_velocity_x, liquid_velocity_y, liquid_velocity_z};
367 liquid_velocity *= (1 / (1e-30 + sum_indicator_liquid));
370void fill_rising_velocity_double(
const IJK_Field_double * eulerian_compo_connex_ns,
371 const ArrOfDouble& rising_velocities,
372 IJK_Field_double& eulerian_rising_velocity)
374 const int nk = (*eulerian_compo_connex_ns).nk();
375 const int nj = (*eulerian_compo_connex_ns).nj();
376 const int ni = (*eulerian_compo_connex_ns).ni();
377 for (
int k = 0; k < nk; k++)
378 for (
int j = 0; j < nj; j++)
379 for (
int i = 0; i < ni; i++)
381 double compo_connex = (*eulerian_compo_connex_ns)(i,j,k);
382 int int_compo_connex = (int) compo_connex;
383 if (int_compo_connex >= 0)
385 eulerian_rising_velocity(i,j,k) = rising_velocities(int_compo_connex);
390void fill_rising_velocity_int(
const IJK_Field_int& eulerian_compo_connex_ns,
391 const ArrOfDouble& rising_velocities,
392 IJK_Field_double& eulerian_rising_velocity)
394 const int nk = eulerian_compo_connex_ns.
nk();
395 const int nj = eulerian_compo_connex_ns.
nj();
396 const int ni = eulerian_compo_connex_ns.
ni();
397 for (
int k = 0; k < nk; k++)
398 for (
int j = 0; j < nj; j++)
399 for (
int i = 0; i < ni; i++)
401 int int_compo_connex = eulerian_compo_connex_ns(i,j,k);
402 if (int_compo_connex >= 0)
404 eulerian_rising_velocity(i,j,k) = rising_velocities(int_compo_connex);
This class encapsulates all the information related to the eulerian mesh for TrioIJK.
int get_offset_local(int direction) const
Returns the local offset in requested direction.
double get_constant_delta(int direction) const
Returns the size of cells in a direction.
double get_origin(int direction) const
Returns the coordinate of the first node (global) of the mesh in the requested direction.
void echange_espace_virtuel(int ghost)
Exchange data over "ghost" number of cells.
const Domaine_IJK & get_domaine() const
int get_nb_bulles_ghost(const int print=0) const
const IJK_Field_double & I() const
int get_nb_bulles_reelles() const
int ghost_compo_converter(const int i) const
void calculer_bounding_box_bulles(DoubleTab &bounding_box, int option_shear=0) const
void calculer_volume_bulles(ArrOfDouble &volumes, DoubleTab ¢re_gravite) const
const IJK_Field_double & In_ft() const
static void mp_sum_for_each(T &arg1, T &arg2)
C++14 compatible mp_sum_for_each: combine multiple mp_sum calls into one collective operation Usage: ...
static void mp_sum_for_each_item(TRUSTArray< _TYPE_ > &x, int n=-1)
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
void append_array(_TYPE_ valeur)
_SIZE_ size_array() const
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)