16#include <IJK_Navier_Stokes_tools_cut_cell.h>
18#include <IJK_Interfaces.h>
19#include <Cut_cell_FT_Disc.h>
23 void dgetrf_(
int* M,
int *N,
double* A,
int* lda,
int* IPIV,
int* INFO);
26 void dgetri_(
int* N,
double* A,
int* lda,
int* IPIV,
double* WORK,
int* lwork,
int* INFO);
29void inverse(
double* A,
int N)
31 int *IPIV =
new int[N];
33 double *WORK =
new double[LWORK];
36 dgetrf_(&N,&N,A,&N,IPIV,&INFO);
37 dgetri_(&N,A,&N,IPIV,WORK,&LWORK,&INFO);
73static const int max_number_of_involved_sommet = 512;
75static const int max_number_of_cell_candidates = 27;
76static const Int3 candidate_offset[max_number_of_cell_candidates] =
78 {-1,-1,-1}, {-1,-1, 0}, {-1,-1,+1},
79 {-1, 0,-1}, {-1, 0, 0}, {-1, 0,+1},
80 {-1,+1,-1}, {-1,+1, 0}, {-1,+1,+1},
81 { 0,-1,-1}, { 0,-1, 0}, { 0,-1,+1},
82 { 0, 0,-1}, { 0, 0, 0}, { 0, 0,+1},
83 { 0,+1,-1}, { 0,+1, 0}, { 0,+1,+1},
84 {+1,-1,-1}, {+1,-1, 0}, {+1,-1,+1},
85 {+1, 0,-1}, {+1, 0, 0}, {+1, 0,+1},
86 {+1,+1,-1}, {+1,+1, 0}, {+1,+1,+1}
89static const int max_number_of_candidates = max_number_of_involved_sommet + max_number_of_cell_candidates;
92Vecteur3 compute_lambda(
int index_vertex0,
int index_vertex1,
int index_vertex2,
int index_vertex3, T candidates[max_number_of_candidates],
double xfact,
double yfact,
double zfact)
94 double x_0 = candidates[index_vertex0].coord[0];
95 double y_0 = candidates[index_vertex0].coord[1];
96 double z_0 = candidates[index_vertex0].coord[2];
98 double x_1 = candidates[index_vertex1].coord[0];
99 double y_1 = candidates[index_vertex1].coord[1];
100 double z_1 = candidates[index_vertex1].coord[2];
101 double dx_1 = x_1 - x_0;
102 double dy_1 = y_1 - y_0;
103 double dz_1 = z_1 - z_0;
105 double x_2 = candidates[index_vertex2].coord[0];
106 double y_2 = candidates[index_vertex2].coord[1];
107 double z_2 = candidates[index_vertex2].coord[2];
109 double dx_2 = x_2 - x_0;
110 double dy_2 = y_2 - y_0;
111 double dz_2 = z_2 - z_0;
113 double x_3 = candidates[index_vertex3].coord[0];
114 double y_3 = candidates[index_vertex3].coord[1];
115 double z_3 = candidates[index_vertex3].coord[2];
117 double dx_3 = x_3 - x_0;
118 double dy_3 = y_3 - y_0;
119 double dz_3 = z_3 - z_0;
139 double lambda_1 = Matrix[0] * (xfact - x_0) + Matrix[1] * (yfact - y_0) + Matrix[2] * (zfact - z_0);
140 double lambda_2 = Matrix[3] * (xfact - x_0) + Matrix[4] * (yfact - y_0) + Matrix[5] * (zfact - z_0);
141 double lambda_3 = Matrix[6] * (xfact - x_0) + Matrix[7] * (yfact - y_0) + Matrix[8] * (zfact - z_0);
143 Vecteur3 lambda_vec = {lambda_1, lambda_2, lambda_3};
147static void ijk_interpolate_cut_cell_for_given_index(
bool next_time,
int phase,
const Cut_cell_FT_Disc& cut_cell_disc,
const Vecteur3& coordinates,
IndexCoefficient tetrahedra_index_coefficient[4],
int tolerate_not_within_tetrahedron,
int skip_unknown_points,
double value_for_bad_points,
int& status)
150 const int reduced_ghost = ghost - 1;
152 const double x = coordinates[0];
153 const double y = coordinates[1];
154 const double z = coordinates[2];
165 double origin_x = geom.
get_origin(DIRECTION_I);
166 double origin_y = geom.
get_origin(DIRECTION_J);
167 double origin_z = geom.
get_origin(DIRECTION_K);
169 const double x2 = (x - origin_x) / dx;
170 const double y2 = (y - origin_y) / dy;
171 const double z2 = (z - origin_z) / dz;
174 const double xfact = x2 - floor(x2);
175 const double yfact = y2 - floor(y2);
176 const double zfact = z2 - floor(z2);
185 bool ok = (index_i >= -reduced_ghost && index_i < ni + reduced_ghost) && (index_j >= -reduced_ghost && index_j < nj + reduced_ghost) && (index_k >= -reduced_ghost && index_k < nk + reduced_ghost);
186 bool close_to_edge = (index_i == -reduced_ghost || index_i == ni + reduced_ghost - 1) || (index_j == -reduced_ghost || index_j == nj + reduced_ghost - 1) || (index_k == -reduced_ghost || index_k == nk + reduced_ghost - 1);
189 if (skip_unknown_points)
191 tetrahedra_index_coefficient[0] = {-1,value_for_bad_points};
192 tetrahedra_index_coefficient[1] = {-1,value_for_bad_points};
193 tetrahedra_index_coefficient[2] = {-1,value_for_bad_points};
194 tetrahedra_index_coefficient[3] = {-1,value_for_bad_points};
200 Cerr <<
"Error in ijk_interpolate_cut_cell_implementation: request cut-cell interpolation of point " << x <<
" " << y <<
" " << z <<
" which is outside of the domain on processor " <<
Process::me() << finl;
205 int number_of_candidates = 0;
206 Candidate candidates[max_number_of_candidates];
207 for (
int i = 0; i < max_number_of_cell_candidates; i++)
209 int i_candidate_aperio = index_i + candidate_offset[i][0];
210 int j_candidate_aperio = index_j + candidate_offset[i][1];
211 int k_candidate_aperio = index_k + candidate_offset[i][2];
218 double old_indicatrice = cut_cell_disc.
get_interfaces().
I(i_candidate, j_candidate, k_candidate);
219 double next_indicatrice = cut_cell_disc.
get_interfaces().
In(i_candidate, j_candidate, k_candidate);
220 double indicatrice = next_time ? next_indicatrice : old_indicatrice;
221 if ((phase == 0 && indicatrice == 1.) || (phase == 1 && indicatrice == 0.))
227 double candidate_x = (double)candidate_offset[i][0] + (cut_cell_disc.
get_interfaces().
get_barycentre(next_time, 0, phase, i_candidate, j_candidate, k_candidate));
228 double candidate_y = (double)candidate_offset[i][1] + (cut_cell_disc.
get_interfaces().
get_barycentre(next_time, 1, phase, i_candidate, j_candidate, k_candidate));
229 double candidate_z = (double)candidate_offset[i][2] + (cut_cell_disc.
get_interfaces().
get_barycentre(next_time, 2, phase, i_candidate, j_candidate, k_candidate));
230 double decalage_x = candidate_x - xfact;
231 double decalage_y = candidate_y - yfact;
232 double decalage_z = candidate_z - zfact;
233 candidates[number_of_candidates].
index = number_of_candidates;
234 candidates[number_of_candidates].
dist = sqrt(decalage_x*decalage_x + decalage_y*decalage_y + decalage_z*decalage_z);
235 candidates[number_of_candidates].
coord[0] = candidate_x;
236 candidates[number_of_candidates].
coord[1] = candidate_y;
237 candidates[number_of_candidates].
coord[2] = candidate_z;
239 int n_candidate = cut_cell_disc.
get_n(i_candidate, j_candidate, k_candidate);
240 if (n_candidate >= 0)
246 assert((!next_time) || (cut_cell_disc.
get_interfaces().
In(i_candidate,j_candidate,k_candidate) == (
double)phase));
247 assert((next_time) || (cut_cell_disc.
get_interfaces().
I(i_candidate,j_candidate,k_candidate) == (
double)phase));
250 number_of_candidates += 1;
256 assert(number_of_candidates <= max_number_of_candidates);
257 assert(number_of_candidates <= max_number_of_cell_candidates);
258 std::sort(candidates, candidates + number_of_candidates, [&](
const Candidate& c1,
const Candidate& c2)
266 const bool limit_count =
false;
267 const int max_count = 100;
269 int closest_tetrahedron[4] = {-1,-1,-1,-1};
270 double closest_lambda_error = DMAXFLOAT;
271 for (
int n_neighbours = 4; (n_neighbours < number_of_candidates && ((!limit_count) || count < max_count)); n_neighbours++)
273 int index_vertex0 = n_neighbours;
275 for (
int index_vertex1 = 0; (index_vertex1 < index_vertex0-2 && ((!limit_count) || count < max_count)); index_vertex1++)
277 for (
int index_vertex2 = index_vertex1+1; (index_vertex2 < index_vertex0-1 && ((!limit_count) || count < max_count)); index_vertex2++)
279 for (
int index_vertex3 = index_vertex2+1; (index_vertex3 < index_vertex0 && ((!limit_count) || count < max_count)); index_vertex3++)
281 Vecteur3 lambda_vec = compute_lambda(index_vertex0, index_vertex1, index_vertex2, index_vertex3, candidates, xfact, yfact, zfact);
282 double lambda_1 = lambda_vec[0];
283 double lambda_2 = lambda_vec[1];
284 double lambda_3 = lambda_vec[2];
286 double lambda_0 = 1 - lambda_1 - lambda_2 - lambda_3;
288 int lambda_0_within_bounds = ((lambda_0 >= 0) && (lambda_0 <= 1));
289 int lambda_1_within_bounds = ((lambda_1 >= 0) && (lambda_1 <= 1));
290 int lambda_2_within_bounds = ((lambda_2 >= 0) && (lambda_2 <= 1));
291 int lambda_3_within_bounds = ((lambda_3 >= 0) && (lambda_3 <= 1));
293 int point_within_tetrahedron = lambda_0_within_bounds && lambda_1_within_bounds && lambda_2_within_bounds && lambda_3_within_bounds;
296 if (point_within_tetrahedron)
303 tetrahedra_index_coefficient[0] = {signed_independent_index_0, lambda_0};
304 tetrahedra_index_coefficient[1] = {signed_independent_index_1, lambda_1};
305 tetrahedra_index_coefficient[2] = {signed_independent_index_2, lambda_2};
306 tetrahedra_index_coefficient[3] = {signed_independent_index_3, lambda_3};
313 double lambda_error_0 = std::max((lambda_0 < 0)*(-lambda_0), (lambda_0 > 1)*(lambda_0 - 1));
314 double lambda_error_1 = std::max((lambda_1 < 0)*(-lambda_1), (lambda_1 > 1)*(lambda_1 - 1));
315 double lambda_error_2 = std::max((lambda_2 < 0)*(-lambda_2), (lambda_2 > 1)*(lambda_2 - 1));
316 double lambda_error_3 = std::max((lambda_3 < 0)*(-lambda_3), (lambda_3 > 1)*(lambda_3 - 1));
318 double lambda_error = std::max(lambda_error_0, std::max(lambda_error_1, std::max(lambda_error_2, lambda_error_3)));
319 assert(lambda_error > 0);
321 if (closest_lambda_error > lambda_error)
323 closest_tetrahedron[0] = index_vertex0;
324 closest_tetrahedron[1] = index_vertex1;
325 closest_tetrahedron[2] = index_vertex2;
326 closest_tetrahedron[3] = index_vertex3;
327 closest_lambda_error = lambda_error;
336 if ((tolerate_not_within_tetrahedron == 2) || (tolerate_not_within_tetrahedron == 1 && closest_lambda_error < 1e-9))
338 Vecteur3 lambda_vec = compute_lambda(closest_tetrahedron[0], closest_tetrahedron[1], closest_tetrahedron[2], closest_tetrahedron[3], candidates, xfact, yfact, zfact);
339 double lambda_1 = lambda_vec[0];
340 double lambda_2 = lambda_vec[1];
341 double lambda_3 = lambda_vec[2];
343 double lambda_0 = 1 - lambda_1 - lambda_2 - lambda_3;
345 assert(!(((lambda_0 >= 0) && (lambda_0 <= 1)) && ((lambda_1 >= 0) && (lambda_1 <= 1)) && ((lambda_2 >= 0) && (lambda_2 <= 1)) && ((lambda_3 >= 0) && (lambda_3 <= 1))));
352 tetrahedra_index_coefficient[0] = {signed_independent_index_0, lambda_0};
353 tetrahedra_index_coefficient[1] = {signed_independent_index_1, lambda_1};
354 tetrahedra_index_coefficient[2] = {signed_independent_index_2, lambda_2};
355 tetrahedra_index_coefficient[3] = {signed_independent_index_3, lambda_3};
362 Cerr <<
"Value of close_to_edge: " << (int)close_to_edge << finl;
363 Cerr <<
"Error in ijk_interpolate_cut_cell_for_given_index: no tetrahedron containing the point " << x <<
" " << y <<
" " << z <<
" on processor " <<
Process::me() << finl;
364 Cerr <<
"For information, closest_lambda_error=" << closest_lambda_error << finl;
369 tetrahedra_index_coefficient[0] = {-1,-1.};
370 tetrahedra_index_coefficient[1] = {-1,-1.};
371 tetrahedra_index_coefficient[2] = {-1,-1.};
372 tetrahedra_index_coefficient[3] = {-1,-1.};
377static double ijk_interpolate_cut_cell_using_interface_for_given_index(
bool next_time,
int phase,
const IJK_Field_double& field_ft,
const Cut_field_double& field,
const ArrOfDouble& interfacial_temperature,
const Vecteur3& coordinates,
int tolerate_not_within_tetrahedron,
int skip_unknown_points,
double value_for_bad_points,
int& status)
381 Cerr <<
"Error in ijk_interpolate_cut_cell_using_interface_for_given_index: Le calcul est parallele mais cette methode n'est pas correcte dans le cas parallele" << finl;
388 const IntTab& facettes = mesh.
facettes();
389 const DoubleTab& sommets = mesh.
sommets();
395 assert(field.
ghost() >= ghost);
397 const double x = coordinates[0];
398 const double y = coordinates[1];
399 const double z = coordinates[2];
401 const int ni_ft = field_ft.
ni();
402 const int nj_ft = field_ft.
nj();
403 const int nk_ft = field_ft.
nk();
410 double origin_x_ft = geom_ft.
get_origin(DIRECTION_I);
411 double origin_y_ft = geom_ft.
get_origin(DIRECTION_J);
412 double origin_z_ft = geom_ft.
get_origin(DIRECTION_K);
414 const double x2_ft = (x - origin_x_ft) / dx_ft;
415 const double y2_ft = (y - origin_y_ft) / dy_ft;
416 const double z2_ft = (z - origin_z_ft) / dz_ft;
418 const int index_i_ft = (int)(std::floor(x2_ft)) - geom_ft.
get_offset_local(DIRECTION_I);
419 const int index_j_ft = (int)(std::floor(y2_ft)) - geom_ft.
get_offset_local(DIRECTION_J);
420 const int index_k_ft = (int)(std::floor(z2_ft)) - geom_ft.
get_offset_local(DIRECTION_K);
422 const int ni = field.
ni();
423 const int nj = field.
nj();
424 const int nk = field.
nk();
432 double origin_x = geom.
get_origin(DIRECTION_I);
433 double origin_y = geom.
get_origin(DIRECTION_J);
434 double origin_z = geom.
get_origin(DIRECTION_K);
436 const double x2 = (x - origin_x) / dx;
437 const double y2 = (y - origin_y) / dy;
438 const double z2 = (z - origin_z) / dz;
441 const double xfact = x2 - floor(x2);
442 const double yfact = y2 - floor(y2);
443 const double zfact = z2 - floor(z2);
452 bool ok = (index_i >= -ghost && index_i < ni + ghost) && (index_j >= -ghost && index_j < nj + ghost) && (index_k >= -ghost && index_k < nk + ghost);
453 bool close_to_edge = (index_i == -ghost || index_i == ni + ghost - 1) || (index_j == -ghost || index_j == nj + ghost - 1) || (index_k == -ghost || index_k == nk + ghost - 1);
456 if (skip_unknown_points)
458 return value_for_bad_points;
463 Cerr <<
"Error in ijk_interpolate_cut_cell_implementation: request cut-cell interpolation of point " << x <<
" " << y <<
" " << z <<
" which is outside of the domain on processor " <<
Process::me() << finl;
468 Sommet involved_sommet[max_number_of_involved_sommet] = {};
469 for (
int i = 0; i < max_number_of_involved_sommet; i++)
471 involved_sommet[i].
sommet = -1;
472 involved_sommet[i].
fa7 = -1;
473 involved_sommet[i].
value = 0.;
474 involved_sommet[i].
count = 0;
476 int number_of_involved_sommet = 0;
478 int number_of_candidates = 0;
480 for (
int i = 0; i < max_number_of_cell_candidates; i++)
482 int i_candidate_aperio = index_i + candidate_offset[i][0];
483 int j_candidate_aperio = index_j + candidate_offset[i][1];
484 int k_candidate_aperio = index_k + candidate_offset[i][2];
491 double old_indicatrice = cut_cell_disc.
get_interfaces().
I(i_candidate, j_candidate, k_candidate);
492 double next_indicatrice = cut_cell_disc.
get_interfaces().
In(i_candidate, j_candidate, k_candidate);
493 double indicatrice = next_time ? next_indicatrice : old_indicatrice;
494 if ((phase == 0 && indicatrice == 1.) || (phase == 1 && indicatrice == 0.))
500 double candidate_x = (double)candidate_offset[i][0] + (cut_cell_disc.
get_interfaces().
get_barycentre(next_time, 0, phase, i_candidate, j_candidate, k_candidate));
501 double candidate_y = (double)candidate_offset[i][1] + (cut_cell_disc.
get_interfaces().
get_barycentre(next_time, 1, phase, i_candidate, j_candidate, k_candidate));
502 double candidate_z = (double)candidate_offset[i][2] + (cut_cell_disc.
get_interfaces().
get_barycentre(next_time, 2, phase, i_candidate, j_candidate, k_candidate));
503 double decalage_x = candidate_x - xfact;
504 double decalage_y = candidate_y - yfact;
505 double decalage_z = candidate_z - zfact;
506 candidates[number_of_candidates].
index = number_of_candidates;
507 candidates[number_of_candidates].
dist = sqrt(decalage_x*decalage_x + decalage_y*decalage_y + decalage_z*decalage_z);
508 candidates[number_of_candidates].
coord[0] = candidate_x;
509 candidates[number_of_candidates].
coord[1] = candidate_y;
510 candidates[number_of_candidates].
coord[2] = candidate_z;
512 int n_candidate = cut_cell_disc.
get_n(i_candidate, j_candidate, k_candidate);
513 if (n_candidate >= 0)
515 candidates[number_of_candidates].
value = (phase == 0) ? field.
diph_v_(n_candidate) : field.
diph_l_(n_candidate);
519 assert((!next_time) || (cut_cell_disc.
get_interfaces().
In(i_candidate,j_candidate,k_candidate) == (
double)phase));
520 assert((next_time) || (cut_cell_disc.
get_interfaces().
I(i_candidate,j_candidate,k_candidate) == (
double)phase));
521 candidates[number_of_candidates].
value = field.
pure_(i_candidate,j_candidate,k_candidate);
523 assert(candidates[number_of_candidates].value != 0);
524 number_of_candidates += 1;
527 int i_candidate_ft = index_i_ft + candidate_offset[i][0];
528 int j_candidate_ft = index_j_ft + candidate_offset[i][1];
529 int k_candidate_ft = index_k_ft + candidate_offset[i][2];
531 if (i_candidate_ft < 0 || j_candidate_ft < 0 || k_candidate_ft < 0 || i_candidate_ft >= ni_ft || j_candidate_ft >= nj_ft || k_candidate_ft >= nk_ft)
536 const ArrOfInt& index_elem = intersec.
index_elem();
538 int index = index_elem[num_elem];
546 for (
int som = 0; som < 3; som++)
555 assert(number_of_involved_sommet < max_number_of_involved_sommet);
556 involved_sommet[number_of_involved_sommet].
sommet = facettes(fa7, som);
557 involved_sommet[number_of_involved_sommet].
fa7 = fa7;
558 involved_sommet[number_of_involved_sommet].
value = interfacial_temperature(fa7)/surface_facettes(fa7);
559 involved_sommet[number_of_involved_sommet].
count = 1;
560 number_of_involved_sommet += 1;
568 std::sort(involved_sommet, involved_sommet + number_of_involved_sommet, [&](
const Sommet& s1,
const Sommet& s2)
576 int initial_number_of_involved_sommet = number_of_involved_sommet;
578 int precedente_fa7 = -1;
579 int precedent_sommet = -1;
580 int premier_i_avec_ce_sommet = -1;
581 for (
int i = 0; i < initial_number_of_involved_sommet; i++)
583 int sommet = involved_sommet[i].
sommet;
584 int fa7 = involved_sommet[i].
fa7;
585 assert(sommet != -1);
586 if (sommet == precedent_sommet)
589 if (fa7 == precedente_fa7)
597 involved_sommet[premier_i_avec_ce_sommet].
value += involved_sommet[i].
value;
598 involved_sommet[premier_i_avec_ce_sommet].
count += 1;
600 precedente_fa7 = fa7;
603 involved_sommet[i].
sommet = -1;
604 involved_sommet[i].
fa7 = -1;
605 involved_sommet[i].
value = 0.;
606 involved_sommet[i].
count = 1;
608 number_of_involved_sommet -= 1;
613 premier_i_avec_ce_sommet = i;
614 precedent_sommet = sommet;
619 for (
int i = 0; i < initial_number_of_involved_sommet; i++)
621 involved_sommet[i].
value /= involved_sommet[i].
count;
622 involved_sommet[i].
count = 1;
625 std::sort(involved_sommet, involved_sommet + initial_number_of_involved_sommet, [&](
const Sommet& s1,
const Sommet& s2)
634 for (
int i = 0; i < number_of_involved_sommet; i++)
636 int sommet = involved_sommet[i].
sommet;
639 assert(sommet != involved_sommet[i-1].sommet);
642 double decalage_x = (sommets(sommet, 0) - x)/dx;
643 double decalage_y = (sommets(sommet, 1) - y)/dy;
644 double decalage_z = (sommets(sommet, 2) - z)/dz;
645 double candidate_x = decalage_x + xfact;
646 double candidate_y = decalage_y + yfact;
647 double candidate_z = decalage_z + zfact;
649 candidates[number_of_candidates].
dist = sqrt(decalage_x*decalage_x + decalage_y*decalage_y + decalage_z*decalage_z);
650 candidates[number_of_candidates].
coord[0] = candidate_x;
651 candidates[number_of_candidates].
coord[1] = candidate_y;
652 candidates[number_of_candidates].
coord[2] = candidate_z;
653 candidates[number_of_candidates].
value = involved_sommet[i].
value;
654 number_of_candidates += 1;
657 assert(number_of_candidates <= max_number_of_candidates);
666 const bool limit_count =
false;
667 const bool force_use_fist_neighbour =
true;
668 const int max_count = 100;
670 int closest_tetrahedron[4] = {-1,-1,-1,-1};
671 double closest_lambda_error = DMAXFLOAT;
672 for (
int n_neighbours = 4; (n_neighbours < number_of_candidates && ((!limit_count) || count < max_count)); n_neighbours++)
674 int index_vertex0 = n_neighbours;
676 for (
int index_vertex1 = 0; (index_vertex1 < (force_use_fist_neighbour ? 1 : index_vertex0-2) && ((!limit_count) || count < max_count)); index_vertex1++)
678 for (
int index_vertex2 = index_vertex1+1; (index_vertex2 < index_vertex0-1 && ((!limit_count) || count < max_count)); index_vertex2++)
680 for (
int index_vertex3 = index_vertex2+1; (index_vertex3 < index_vertex0 && ((!limit_count) || count < max_count)); index_vertex3++)
682 Vecteur3 lambda_vec = compute_lambda(index_vertex0, index_vertex1, index_vertex2, index_vertex3, candidates, xfact, yfact, zfact);
683 double lambda_1 = lambda_vec[0];
684 double lambda_2 = lambda_vec[1];
685 double lambda_3 = lambda_vec[2];
687 double lambda_0 = 1 - lambda_1 - lambda_2 - lambda_3;
689 int lambda_0_within_bounds = ((lambda_0 >= 0) && (lambda_0 <= 1));
690 int lambda_1_within_bounds = ((lambda_1 >= 0) && (lambda_1 <= 1));
691 int lambda_2_within_bounds = ((lambda_2 >= 0) && (lambda_2 <= 1));
692 int lambda_3_within_bounds = ((lambda_3 >= 0) && (lambda_3 <= 1));
694 int point_within_tetrahedron = lambda_0_within_bounds && lambda_1_within_bounds && lambda_2_within_bounds && lambda_3_within_bounds;
697 if (point_within_tetrahedron)
699 double field_0 = candidates[index_vertex0].
value;
700 double field_1 = candidates[index_vertex1].
value;
701 double field_2 = candidates[index_vertex2].
value;
702 double field_3 = candidates[index_vertex3].
value;
703 assert(field_0 != 0);
704 assert(field_1 != 0);
705 assert(field_2 != 0);
706 assert(field_3 != 0);
708 double r = field_0*lambda_0 + field_1*lambda_1 + field_2*lambda_2 + field_3*lambda_3;
715 double lambda_error_0 = std::max((lambda_0 < 0)*(-lambda_0), (lambda_0 > 1)*(lambda_0 - 1));
716 double lambda_error_1 = std::max((lambda_1 < 0)*(-lambda_1), (lambda_1 > 1)*(lambda_1 - 1));
717 double lambda_error_2 = std::max((lambda_2 < 0)*(-lambda_2), (lambda_2 > 1)*(lambda_2 - 1));
718 double lambda_error_3 = std::max((lambda_3 < 0)*(-lambda_3), (lambda_3 > 1)*(lambda_3 - 1));
720 double lambda_error = std::max(lambda_error_0, std::max(lambda_error_1, std::max(lambda_error_2, lambda_error_3)));
721 assert(lambda_error > 0);
723 if (closest_lambda_error > lambda_error)
725 closest_tetrahedron[0] = index_vertex0;
726 closest_tetrahedron[1] = index_vertex1;
727 closest_tetrahedron[2] = index_vertex2;
728 closest_tetrahedron[3] = index_vertex3;
729 closest_lambda_error = lambda_error;
738 if ((tolerate_not_within_tetrahedron == 2) || (tolerate_not_within_tetrahedron == 1 && closest_lambda_error < 5e-2))
740 Vecteur3 lambda_vec = compute_lambda(closest_tetrahedron[0], closest_tetrahedron[1], closest_tetrahedron[2], closest_tetrahedron[3], candidates, xfact, yfact, zfact);
741 double lambda_1 = lambda_vec[0];
742 double lambda_2 = lambda_vec[1];
743 double lambda_3 = lambda_vec[2];
745 double lambda_0 = 1 - lambda_1 - lambda_2 - lambda_3;
747 assert(!(((lambda_0 >= 0) && (lambda_0 <= 1)) && ((lambda_1 >= 0) && (lambda_1 <= 1)) && ((lambda_2 >= 0) && (lambda_2 <= 1)) && ((lambda_3 >= 0) && (lambda_3 <= 1))));
749 double field_0 = candidates[closest_tetrahedron[0]].
value;
750 double field_1 = candidates[closest_tetrahedron[1]].
value;
751 double field_2 = candidates[closest_tetrahedron[2]].
value;
752 double field_3 = candidates[closest_tetrahedron[3]].
value;
754 double r = field_0*lambda_0 + field_1*lambda_1 + field_2*lambda_2 + field_3*lambda_3;
761 Cerr <<
"Value of close_to_edge: " << (int)close_to_edge << finl;
762 Cerr <<
"Error in ijk_interpolate_cut_cell_using_interface_for_given_index: no tetrahedron containing the point " << x <<
" " << y <<
" " << z <<
" on processor " <<
Process::me() << finl;
763 Cerr <<
"For information, closest_lambda_error=" << closest_lambda_error << finl;
773static void ijk_interpolate_cut_cell_implementation(
bool next_time,
int phase,
const Cut_field_double& field,
const DoubleTab& coordinates, ArrOfDouble& result,
int skip_unknown_points,
double value_for_bad_points)
775 const int nb_coords = coordinates.
dimension(0);
777 for (
int idx = 0; idx < nb_coords; idx++)
779 Vecteur3 coordinates_for_given_index(coordinates(idx,0), coordinates(idx,1), coordinates(idx,2));
780 int tolerate_not_within_tetrahedron = 1;
783 ijk_interpolate_cut_cell_for_given_index(next_time, phase, field.
get_cut_cell_disc(), coordinates_for_given_index, tetrahedra_index_coefficient, tolerate_not_within_tetrahedron, skip_unknown_points, value_for_bad_points, status);
790 double interpolated_value = field_0*tetrahedra_index_coefficient[0].
coefficient + field_1*tetrahedra_index_coefficient[1].
coefficient + field_2*tetrahedra_index_coefficient[2].
coefficient + field_3*tetrahedra_index_coefficient[3].
coefficient;
791 result[idx] = interpolated_value;
795static void ijk_interpolate_cut_cell_implementation(
bool next_time,
int phase,
const Cut_cell_FT_Disc& cut_cell_disc,
const DoubleTab& coordinates, IntTabFT& signed_independent_index, DoubleTabFT& coefficient,
int skip_unknown_points,
double value_for_bad_points)
797 const int nb_coords = coordinates.
dimension(0);
798 signed_independent_index.
resize(nb_coords, 4);
799 coefficient.
resize(nb_coords, 4);
800 for (
int idx = 0; idx < nb_coords; idx++)
802 Vecteur3 coordinates_for_given_index(coordinates(idx,0), coordinates(idx,1), coordinates(idx,2));
803 int tolerate_not_within_tetrahedron = 1;
806 ijk_interpolate_cut_cell_for_given_index(next_time, phase, cut_cell_disc, coordinates_for_given_index, tetrahedra_index_coefficient, tolerate_not_within_tetrahedron, skip_unknown_points, value_for_bad_points, status);
808 signed_independent_index(idx,0) = tetrahedra_index_coefficient[0].
index;
809 signed_independent_index(idx,1) = tetrahedra_index_coefficient[1].
index;
810 signed_independent_index(idx,2) = tetrahedra_index_coefficient[2].
index;
811 signed_independent_index(idx,3) = tetrahedra_index_coefficient[3].
index;
812 coefficient(idx,0) = tetrahedra_index_coefficient[0].
coefficient;
813 coefficient(idx,1) = tetrahedra_index_coefficient[1].
coefficient;
814 coefficient(idx,2) = tetrahedra_index_coefficient[2].
coefficient;
815 coefficient(idx,3) = tetrahedra_index_coefficient[3].
coefficient;
819void ijk_interpolate_cut_cell_skip_unknown_points(
bool next_time,
int phase,
const Cut_field_double& field,
const DoubleTab& coordinates, ArrOfDouble& result,
const double value_for_bad_points)
821 ijk_interpolate_cut_cell_implementation(next_time, phase, field, coordinates, result, 1 , value_for_bad_points);
824void ijk_interpolate_cut_cell(
bool next_time,
int phase,
const Cut_field_double& field,
const DoubleTab& coordinates, ArrOfDouble& result)
826 ijk_interpolate_cut_cell_implementation(next_time, phase, field, coordinates, result, 0 , 0.);
829void ijk_interpolate_cut_cell_skip_unknown_points(
bool next_time,
int phase,
const Cut_cell_FT_Disc& cut_cell_disc,
const DoubleTab& coordinates, IntTabFT& signed_independent_index, DoubleTabFT& coefficient,
const double value_for_bad_points)
831 ijk_interpolate_cut_cell_implementation(next_time, phase, cut_cell_disc, coordinates, signed_independent_index, coefficient, 1 , value_for_bad_points);
834void ijk_interpolate_cut_cell(
bool next_time,
int phase,
const Cut_cell_FT_Disc& cut_cell_disc,
const DoubleTab& coordinates, IntTabFT& signed_independent_index, DoubleTabFT& coefficient)
836 ijk_interpolate_cut_cell_implementation(next_time, phase, cut_cell_disc, coordinates, signed_independent_index, coefficient, 0 , 0.);
839double ijk_interpolate_cut_cell_using_interface_skip_unknown_points(
bool next_time,
int phase,
const IJK_Field_double& field_ft,
const Cut_field_double& field,
const ArrOfDouble& interfacial_temperature,
const Vecteur3& coordinates,
int tolerate_not_within_tetrahedron,
const double value_for_bad_points,
int& status)
841 double interpolated_value = ijk_interpolate_cut_cell_using_interface_for_given_index(next_time, phase, field_ft, field, interfacial_temperature, coordinates, tolerate_not_within_tetrahedron, 1, value_for_bad_points, status);
842 return interpolated_value;
845double ijk_interpolate_cut_cell_using_interface(
bool next_time,
int phase,
const IJK_Field_double& field_ft,
const Cut_field_double& field,
const ArrOfDouble& interfacial_temperature,
const Vecteur3& coordinates,
int tolerate_not_within_tetrahedron,
int& status)
847 double interpolated_value = ijk_interpolate_cut_cell_using_interface_for_given_index(next_time, phase, field_ft, field, interfacial_temperature, coordinates, tolerate_not_within_tetrahedron, 0, 0., status);
848 return interpolated_value;
852static void ijk_interpolate_one_value(
bool next_time,
const Cut_cell_FT_Disc& cut_cell_disc,
const Vecteur3& coordinates, IntTabFT& signed_independent_index, DoubleTabFT& coefficient,
int skip_unknown_points,
double value_for_bad_points)
864 double origin_x = geom.
get_origin(DIRECTION_I);
865 double origin_y = geom.
get_origin(DIRECTION_J);
866 double origin_z = geom.
get_origin(DIRECTION_K);
867 const double x = coordinates[0];
868 const double y = coordinates[1];
869 const double z = coordinates[2];
870 const double x2 = (x - origin_x) / dx;
871 const double y2 = (y - origin_y) / dy;
872 const double z2 = (z - origin_z) / dz;
877 const double xfact = x2 - floor(x2);
878 const double yfact = y2 - floor(y2);
879 const double zfact = z2 - floor(z2);
882 bool ok = (index_i >= -ghost && index_i < ni + ghost - 1) && (index_j >= -ghost && index_j < nj + ghost - 1) && (index_k >= -ghost && index_k < nk + ghost - 1);
885 if (skip_unknown_points)
891 Cerr <<
"Error in ijk_interpolate_implementation: request interpolation of point " << x <<
" " << y <<
" " << z <<
" which is outside of the domain on processor " <<
Process::me()
897 double indic_0 = next_time ? (1 - cut_cell_disc.
get_interfaces().In_ft(index_i, index_j, index_k)) : (1 - cut_cell_disc.get_interfaces().I_ft(index_i, index_j, index_k));
898 double indic_1 = next_time ? (1 - cut_cell_disc.
get_interfaces().In_ft(index_i+1, index_j, index_k)) : (1 - cut_cell_disc.
get_interfaces().
I_ft(index_i+1, index_j, index_k));
904 double indic_7 = next_time ? (1 - cut_cell_disc.
get_interfaces().
In_ft(index_i+1, index_j+1, index_k+1)) : (1 - cut_cell_disc.
get_interfaces().
I_ft(index_i+1, index_j+1, index_k+1));
914 int output_index = -1;
920 coefficient(output_index) = indic_0 * (1.-xfact) * (1.-yfact) * (1.-zfact);
927 coefficient(output_index) = indic_1 * (xfact) * (1.-yfact) * (1.-zfact);
934 coefficient(output_index) = indic_2 * (1.-xfact) * (yfact) * (1.-zfact);
941 coefficient(output_index) = indic_3 * (xfact) * (yfact) * (1.-zfact);
948 coefficient(output_index) = indic_4 * (1.-xfact) * (1.-yfact) * (zfact);
955 coefficient(output_index) = indic_5 * (xfact) * (1.-yfact) * (zfact);
962 coefficient(output_index) = indic_6 * (1.-xfact) * (yfact) * (zfact);
969 coefficient(output_index) = indic_7 * (xfact) * (yfact) * (zfact);
976 coefficient(output_index) = indic_8 * (1.-xfact) * (1.-yfact) * (1.-zfact);
983 coefficient(output_index) = indic_9 * (xfact) * (1.-yfact) * (1.-zfact);
990 coefficient(output_index) = indic_10 * (1.-xfact) * (yfact) * (1.-zfact);
997 coefficient(output_index) = indic_11 * (xfact) * (yfact) * (1.-zfact);
1004 coefficient(output_index) = indic_12 * (1.-xfact) * (1.-yfact) * (zfact);
1011 coefficient(output_index) = indic_13 * (xfact) * (1.-yfact) * (zfact);
1018 coefficient(output_index) = indic_14 * (1.-xfact) * (yfact) * (zfact);
1025 coefficient(output_index) = indic_15 * (xfact) * (yfact) * (zfact);
1028 signed_independent_index.
resize(output_index+1);
1029 coefficient.
resize(output_index+1);
1032void ijk_interpolate_skip_unknown_points(
bool next_time,
int phase,
const Cut_cell_FT_Disc& cut_cell_disc,
const Vecteur3& coordinates, IntTabFT& signed_independent_index, DoubleTabFT& coefficient,
const double value_for_bad_points)
1034 signed_independent_index.
resize(16);
1036 ijk_interpolate_one_value(next_time, cut_cell_disc, coordinates, signed_independent_index, coefficient, 1 , value_for_bad_points);
1039void ijk_interpolate(
bool next_time,
int phase,
const Cut_cell_FT_Disc& cut_cell_disc,
const Vecteur3& coordinates, IntTabFT& signed_independent_index, DoubleTabFT& coefficient)
1041 signed_independent_index.
resize(16);
1043 ijk_interpolate_one_value(next_time, cut_cell_disc, coordinates, signed_independent_index, coefficient, 0 , 0.);
1046void euler_explicit_update_cut_cell_notransport(
double timestep,
bool next_time,
const Cut_field_double& dv, Cut_field_double& v)
1049 const double delta_t = timestep;
1050 const int imax = v.
ni();
1051 const int jmax = v.
nj();
1052 const int kmax = v.
nk();
1053 for (
int k = 0; k < kmax; k++)
1055 for (
int j = 0; j < jmax; j++)
1057 for (
int i = 0; i < imax; i++)
1062 int n = cut_cell_disc.
get_n(i,j,k);
1065 double x = dv.
pure_(i,j,k);
1066 double next_v_vol = v.
pure_(i,j,k) + x * delta_t;
1067 v.
pure_(i,j,k) = next_v_vol;
1074 double next_v_vol_l = v.
diph_l_(n)*nonzero_indicatrice_l + x_l * delta_t;
1075 double next_v_vol_v = v.
diph_v_(n)*nonzero_indicatrice_v + x_v * delta_t;
1076 v.
diph_l_(n) = next_v_vol_l/nonzero_indicatrice_l;
1077 v.
diph_v_(n) = next_v_vol_v/nonzero_indicatrice_v;
1084void runge_kutta3_update_cut_cell_notransport(
bool next_time,
const Cut_field_double& dv, Cut_field_double& F, Cut_field_double& v,
const int step,
double dt_tot,
const Cut_field_int& cellule_rk_restreint)
1086 const double coeff_a[3] = { 0., -5. / 9., -153. / 128. };
1088 const double coeff_Fk[3] = { 1., 4. / 9., 15. / 32. };
1090 const double facteurF = coeff_a[step];
1091 const double intermediate_dt = compute_fractionnal_timestep_rk3(dt_tot, step);
1092 const double delta_t_divided_by_Fk = intermediate_dt / coeff_Fk[step];
1093 const int imax = v.
ni();
1094 const int jmax = v.
nj();
1095 const int kmax = v.
nk();
1102 for (
int k = 0; k < kmax; k++)
1104 for (
int j = 0; j < jmax; j++)
1106 for (
int i = 0; i < imax; i++)
1111 int n = cut_cell_disc.
get_n(i,j,k);
1114 double x = dv.
pure_(i,j,k);
1115 double next_v_vol = v.
pure_(i,j,k) + x * delta_t_divided_by_Fk;
1117 v.
pure_(i,j,k) = next_v_vol;
1124 double next_v_vol_l = v.
diph_l_(n)*nonzero_indicatrice_l + x_l * delta_t_divided_by_Fk;
1125 double next_v_vol_v = v.
diph_v_(n)*nonzero_indicatrice_v + x_v * delta_t_divided_by_Fk;
1128 v.
diph_l_(n) = next_v_vol_l/nonzero_indicatrice_l;
1129 v.
diph_v_(n) = next_v_vol_v/nonzero_indicatrice_v;
1137 for (
int k = 0; k < kmax; k++)
1139 for (
int j = 0; j < jmax; j++)
1141 for (
int i = 0; i < imax; i++)
1146 int n = cut_cell_disc.
get_n(i,j,k);
1149 if (cellule_rk_restreint.
pure_(i,j,k) == 0)
1151 double x = F.
pure_(i, j, k) * facteurF + dv.
pure_(i,j,k);
1152 double next_v_vol = v.
pure_(i,j,k) + x * delta_t_divided_by_Fk;
1154 v.
pure_(i,j,k) = next_v_vol;
1158 double x = dv.
pure_(i,j,k);
1159 double next_v_vol = v.
pure_(i,j,k) + x * intermediate_dt;
1161 v.
pure_(i,j,k) = next_v_vol;
1166 if (cellule_rk_restreint.
diph_v_(n) == 0)
1170 double next_v_vol_v = v.
diph_v_(n)*nonzero_indicatrice_v + x_v * delta_t_divided_by_Fk;
1172 v.
diph_v_(n) = next_v_vol_v/nonzero_indicatrice_v;
1178 double next_v_vol_v = v.
diph_v_(n)*nonzero_indicatrice_v + x_v * intermediate_dt;
1180 v.
diph_v_(n) = next_v_vol_v/nonzero_indicatrice_v;
1183 if (cellule_rk_restreint.
diph_l_(n) == 0)
1187 double next_v_vol_l = v.
diph_l_(n)*nonzero_indicatrice_l + x_l * delta_t_divided_by_Fk;
1189 v.
diph_l_(n) = next_v_vol_l/nonzero_indicatrice_l;
1195 double next_v_vol_l = v.
diph_l_(n)*nonzero_indicatrice_l + x_l * intermediate_dt;
1197 v.
diph_l_(n) = next_v_vol_l/nonzero_indicatrice_l;
1206 for (
int k = 0; k < kmax; k++)
1208 for (
int j = 0; j < jmax; j++)
1210 for (
int i = 0; i < imax; i++)
1215 int n = cut_cell_disc.
get_n(i,j,k);
1218 if (cellule_rk_restreint.
pure_(i,j,k) == 0)
1220 double x = F.
pure_(i, j, k) * facteurF + dv.
pure_(i,j,k);
1221 double next_v_vol = v.
pure_(i,j,k) + x * delta_t_divided_by_Fk;
1222 v.
pure_(i,j,k) = next_v_vol;
1226 double x = dv.
pure_(i,j,k);
1227 double next_v_vol = v.
pure_(i,j,k) + x * intermediate_dt;
1228 v.
pure_(i,j,k) = next_v_vol;
1233 if (cellule_rk_restreint.
diph_v_(n) == 0)
1237 double next_v_vol_v = v.
diph_v_(n)*nonzero_indicatrice_v + x_v * delta_t_divided_by_Fk;
1238 v.
diph_v_(n) = next_v_vol_v/nonzero_indicatrice_v;
1244 double next_v_vol_v = v.
diph_v_(n)*nonzero_indicatrice_v + x_v * intermediate_dt;
1245 v.
diph_v_(n) = next_v_vol_v/nonzero_indicatrice_v;
1248 if (cellule_rk_restreint.
diph_l_(n) == 0)
1252 double next_v_vol_l = v.
diph_l_(n)*nonzero_indicatrice_l + x_l * delta_t_divided_by_Fk;
1253 v.
diph_l_(n) = next_v_vol_l/nonzero_indicatrice_l;
1259 double next_v_vol_l = v.
diph_l_(n)*nonzero_indicatrice_l + x_l * intermediate_dt;
1260 v.
diph_l_(n) = next_v_vol_l/nonzero_indicatrice_l;
1268 Cerr <<
"Error in runge_kutta_update: wrong step" << finl;
1273void euler_explicit_update_cut_cell_transport(
double timestep,
const Cut_field_double& dv, Cut_field_double& v)
1276 const double delta_t = timestep;
1277 const int imax = v.
ni();
1278 const int jmax = v.
nj();
1279 const int kmax = v.
nk();
1280 for (
int k = 0; k < kmax; k++)
1282 for (
int j = 0; j < jmax; j++)
1284 for (
int i = 0; i < imax; i++)
1291 int n = cut_cell_disc.
get_n(i,j,k);
1294 double x = dv.
pure_(i,j,k);
1295 assert(old_nonzero_indicatrice_l == next_nonzero_indicatrice_l);
1296 double next_v_vol = v.
pure_(i,j,k) + x * delta_t;
1297 v.
pure_(i,j,k) = next_v_vol;
1304 double next_v_vol_l = v.
diph_l_(n)*old_nonzero_indicatrice_l + x_l * delta_t;
1305 double next_v_vol_v = v.
diph_v_(n)*old_nonzero_indicatrice_v + x_v * delta_t;
1306 v.
diph_l_(n) = next_v_vol_l/next_nonzero_indicatrice_l;
1307 v.
diph_v_(n) = next_v_vol_v/next_nonzero_indicatrice_v;
1314void runge_kutta3_update_cut_cell_transport(
const Cut_field_double& dv, Cut_field_double& F, Cut_field_double& v,
const int step,
double dt_tot,
const Cut_field_int& cellule_rk_restreint)
1316 const double coeff_a[3] = { 0., -5. / 9., -153. / 128. };
1318 const double coeff_Fk[3] = { 1., 4. / 9., 15. / 32. };
1320 const double facteurF = coeff_a[step];
1321 const double intermediate_dt = compute_fractionnal_timestep_rk3(dt_tot, step);
1322 const double delta_t_divided_by_Fk = intermediate_dt / coeff_Fk[step];
1323 const int imax = v.
ni();
1324 const int jmax = v.
nj();
1325 const int kmax = v.
nk();
1332 for (
int k = 0; k < kmax; k++)
1334 for (
int j = 0; j < jmax; j++)
1336 for (
int i = 0; i < imax; i++)
1343 int n = cut_cell_disc.
get_n(i,j,k);
1346 double x = dv.
pure_(i,j,k);
1347 assert(old_nonzero_indicatrice_l == next_nonzero_indicatrice_l);
1348 double next_v_vol = v.
pure_(i,j,k) + x * delta_t_divided_by_Fk;
1350 v.
pure_(i,j,k) = next_v_vol;
1357 double next_v_vol_l = v.
diph_l_(n)*old_nonzero_indicatrice_l + x_l * delta_t_divided_by_Fk;
1358 double next_v_vol_v = v.
diph_v_(n)*old_nonzero_indicatrice_v + x_v * delta_t_divided_by_Fk;
1362 v.
diph_l_(n) = next_v_vol_l/next_nonzero_indicatrice_l;
1363 v.
diph_v_(n) = next_v_vol_v/next_nonzero_indicatrice_v;
1371 for (
int k = 0; k < kmax; k++)
1373 for (
int j = 0; j < jmax; j++)
1375 for (
int i = 0; i < imax; i++)
1382 int n = cut_cell_disc.
get_n(i,j,k);
1385 if (cellule_rk_restreint.
pure_(i,j,k) == 0)
1387 double x = F.
pure_(i, j, k) * facteurF + dv.
pure_(i,j,k);
1388 assert(old_nonzero_indicatrice_l == next_nonzero_indicatrice_l);
1389 double next_v_vol = v.
pure_(i,j,k) + x * delta_t_divided_by_Fk;
1391 v.
pure_(i,j,k) = next_v_vol;
1395 double x = dv.
pure_(i,j,k);
1396 assert(old_nonzero_indicatrice_l == next_nonzero_indicatrice_l);
1397 double next_v_vol = v.
pure_(i,j,k) + x * intermediate_dt;
1399 v.
pure_(i,j,k) = next_v_vol;
1404 if (cellule_rk_restreint.
diph_v_(n) == 0)
1408 double next_v_vol_v = v.
diph_v_(n)*old_nonzero_indicatrice_v + x_v * delta_t_divided_by_Fk;
1411 v.
diph_v_(n) = next_v_vol_v/next_nonzero_indicatrice_v;
1417 double next_v_vol_v = v.
diph_v_(n)*old_nonzero_indicatrice_v + x_v * intermediate_dt;
1420 v.
diph_v_(n) = next_v_vol_v/next_nonzero_indicatrice_v;
1423 if (cellule_rk_restreint.
diph_l_(n) == 0)
1427 double next_v_vol_l = v.
diph_l_(n)*old_nonzero_indicatrice_l + x_l * delta_t_divided_by_Fk;
1430 v.
diph_l_(n) = next_v_vol_l/next_nonzero_indicatrice_l;
1436 double next_v_vol_l = v.
diph_l_(n)*old_nonzero_indicatrice_l + x_l * intermediate_dt;
1439 v.
diph_l_(n) = next_v_vol_l/next_nonzero_indicatrice_l;
1448 for (
int k = 0; k < kmax; k++)
1450 for (
int j = 0; j < jmax; j++)
1452 for (
int i = 0; i < imax; i++)
1459 int n = cut_cell_disc.
get_n(i,j,k);
1462 if (cellule_rk_restreint.
pure_(i,j,k) == 0)
1464 double x = F.
pure_(i, j, k) * facteurF + dv.
pure_(i,j,k);
1465 assert(old_nonzero_indicatrice_l == next_nonzero_indicatrice_l);
1466 double next_v_vol = v.
pure_(i,j,k) + x * delta_t_divided_by_Fk;
1467 v.
pure_(i,j,k) = next_v_vol;
1471 double x = dv.
pure_(i,j,k);
1472 assert(old_nonzero_indicatrice_l == next_nonzero_indicatrice_l);
1473 double next_v_vol = v.
pure_(i,j,k) + x * intermediate_dt;
1474 v.
pure_(i,j,k) = next_v_vol;
1479 if (cellule_rk_restreint.
diph_v_(n) == 0)
1483 double next_v_vol_v = v.
diph_v_(n)*old_nonzero_indicatrice_v + x_v * delta_t_divided_by_Fk;
1485 v.
diph_v_(n) = next_v_vol_v/next_nonzero_indicatrice_v;
1491 double next_v_vol_v = v.
diph_v_(n)*old_nonzero_indicatrice_v + x_v * intermediate_dt;
1493 v.
diph_v_(n) = next_v_vol_v/next_nonzero_indicatrice_v;
1496 if (cellule_rk_restreint.
diph_l_(n) == 0)
1500 double next_v_vol_l = v.
diph_l_(n)*old_nonzero_indicatrice_l + x_l * delta_t_divided_by_Fk;
1502 v.
diph_l_(n) = next_v_vol_l/next_nonzero_indicatrice_l;
1508 double next_v_vol_l = v.
diph_l_(n)*old_nonzero_indicatrice_l + x_l * intermediate_dt;
1510 v.
diph_l_(n) = next_v_vol_l/next_nonzero_indicatrice_l;
1518 Cerr <<
"Error in runge_kutta_update: wrong step" << finl;
1523void cut_cell_switch_field_time(Cut_field_double& v)
1526 const int imax = v.
ni();
1527 const int jmax = v.
nj();
1528 const int kmax = v.
nk();
1529 for (
int k = 0; k < kmax; k++)
1531 for (
int j = 0; j < jmax; j++)
1533 for (
int i = 0; i < imax; i++)
1540 int n = cut_cell_disc.
get_n(i,j,k);
1543 assert(old_nonzero_indicatrice_l == next_nonzero_indicatrice_l);
1544 double next_v_vol = v.
pure_(i,j,k);
1545 v.
pure_(i,j,k) = next_v_vol;
1549 double next_v_vol_l = v.
diph_l_(n)*old_nonzero_indicatrice_l;
1550 double next_v_vol_v = v.
diph_v_(n)*old_nonzero_indicatrice_v;
1552 v.
diph_l_(n) = next_v_vol_l/next_nonzero_indicatrice_l;
1553 v.
diph_v_(n) = next_v_vol_v/next_nonzero_indicatrice_v;
1560void runge_kutta3_update_surfacic_fluxes(Cut_field_double& dv, Cut_field_double& F,
const int step,
const int k_layer,
const int dir,
double dt_tot,
const Cut_field_int& cellule_rk_restreint)
1562 const double coeff_a[3] = { 0., -5. / 9., -153. / 128. };
1564 const double coeff_Fk[3] = { 1., 4. / 9., 15. / 32. };
1566 int di = (dir == 0) ? -1 : 0;
1567 int dj = (dir == 1) ? -1 : 0;
1568 int dk = (dir == 2) ? -1 : 0;
1570 const double facteurF = coeff_a[step];
1571 const double one_divided_by_Fk = 1. / coeff_Fk[step];
1572 const int imax = dv.
ni();
1573 const int jmax = dv.
nj();
1574 const int ghost = dv.
ghost();
1581 for (
int j = -ghost; j < jmax+ghost; j++)
1583 for (
int i = -ghost; i < imax+ghost; i++)
1585 int n = cut_cell_disc.
get_n(i,j,k_layer);
1588 double x = dv.
pure_(i,j,k_layer);
1589 dv.
pure_(i,j,k_layer) = x * one_divided_by_Fk;
1590 F.
pure_(i,j,k_layer) = x;
1597 dv.
diph_l_(n) = x_l * one_divided_by_Fk;
1598 dv.
diph_v_(n) = x_v * one_divided_by_Fk;
1602 int n_decale = cut_cell_disc.
get_n(i+di,j+dj,k_layer+dk);
1615 for (
int j = -ghost; j < jmax+ghost; j++)
1617 for (
int i = -ghost; i < imax+ghost; i++)
1619 int n = cut_cell_disc.
get_n(i,j,k_layer);
1623 if ((cellule_rk_restreint.
pure_(i,j,k_layer) == 0) && (cellule_rk_restreint.
from_ijk_and_phase(i+di,j+dj,k_layer+dk,phase) == 0))
1625 double x = F.
pure_(i, j, k_layer) * facteurF + dv.
pure_(i,j,k_layer);
1626 dv.
pure_(i,j,k_layer) = x * one_divided_by_Fk;
1627 F.
pure_(i,j,k_layer) = x;
1631 double x = dv.
pure_(i,j,k_layer);
1632 dv.
pure_(i,j,k_layer) = x;
1633 F.
pure_(i,j,k_layer) = x;
1642 dv.
diph_v_(n) = x_v * one_divided_by_Fk;
1657 dv.
diph_l_(n) = x_l * one_divided_by_Fk;
1668 int n_decale = cut_cell_disc.
get_n(i+di,j+dj,k_layer+dk);
1681 for (
int j = -ghost; j < jmax+ghost; j++)
1683 for (
int i = -ghost; i < imax+ghost; i++)
1685 int n = cut_cell_disc.
get_n(i,j,k_layer);
1689 if ((cellule_rk_restreint.
pure_(i,j,k_layer) == 0) && (cellule_rk_restreint.
from_ijk_and_phase(i+di,j+dj,k_layer+dk,phase) == 0))
1691 double x = F.
pure_(i, j, k_layer) * facteurF + dv.
pure_(i,j,k_layer);
1692 dv.
pure_(i,j,k_layer) = x * one_divided_by_Fk;
1696 double x = dv.
pure_(i,j,k_layer);
1697 dv.
pure_(i,j,k_layer) = x;
1706 dv.
diph_v_(n) = x_v * one_divided_by_Fk;
1719 dv.
diph_l_(n) = x_l * one_divided_by_Fk;
1728 int n_decale = cut_cell_disc.
get_n(i+di,j+dj,k_layer+dk);
1740 Cerr <<
"Error in runge_kutta_update: wrong step" << finl;
1748void add_flux_times_vol_over_dt_surface(
double fractional_timestep,
const Cut_field_vector3_double& cut_field_current_fluxes, Cut_field_vector3_double& cut_field_RK3_F_fluxes)
1751 assert(cut_field_current_fluxes[0].get_cut_cell_disc().get_domaine().is_uniform(0));
1752 assert(cut_field_current_fluxes[0].get_cut_cell_disc().get_domaine().is_uniform(1));
1753 assert(cut_field_current_fluxes[0].get_cut_cell_disc().get_domaine().is_uniform(2));
1757 double vol = dx*dy*dz;
1759 for (
int dir = 0; dir < 3; dir++)
1761 const int ni = cut_field_current_fluxes[dir].ni();
1762 const int nj = cut_field_current_fluxes[dir].nj();
1763 const int nk = cut_field_current_fluxes[dir].nk();
1764 for (
int k = 0; k < nk; k++)
1766 for (
int j = 0; j < nj; j++)
1768 for (
int i = 0; i < ni; i++)
1770 double vol_over_dt = vol/fractional_timestep;
1772 cut_field_RK3_F_fluxes[dir].pure_(i,j,k) += cut_field_current_fluxes[dir].pure_(i,j,k)*vol_over_dt;
1777 const Cut_cell_FT_Disc& cut_cell_disc = cut_field_current_fluxes[dir].get_cut_cell_disc();
1778 for (
int n = 0; n < cut_cell_disc.
get_n_tot(); n++)
1780 double vol_over_dt = vol/fractional_timestep;
1783 double indicatrice_surface = indicatrice_surfacique(n,dir);
1785 cut_field_RK3_F_fluxes[dir].diph_l_(n) += (indicatrice_surface == 0.) ? 0. : cut_field_current_fluxes[dir].diph_l_(n)*vol_over_dt/indicatrice_surface;
1786 cut_field_RK3_F_fluxes[dir].diph_v_(n) += ((1 - indicatrice_surface) == 0.) ? 0. : cut_field_current_fluxes[dir].diph_v_(n)*vol_over_dt/(1 - indicatrice_surface);
1791void set_rk_restreint(
int rk_step,
int rk_restriction_leniency,
const Cut_cell_FT_Disc& cut_cell_disc, Cut_field_int& cellule_rk_restreint)
1798 if (rk_restriction_leniency == 10)
1803 if (rk_restriction_leniency == 11)
1805 for (
int n = 0; n < cut_cell_disc.
get_n_tot(); n++)
1807 Int3 ijk = cut_cell_disc.
get_ijk(n);
1812 cellule_rk_restreint.
pure_(i,j,k) = 1;
1813 cellule_rk_restreint.
diph_v_(n) = 1;
1814 cellule_rk_restreint.
diph_l_(n) = 1;
1823 for (
int index = index_min; index < index_max; index++)
1827 Int3 ijk = cut_cell_disc.
get_ijk(n);
1832 if ((rk_restriction_leniency == 4) || (rk_restriction_leniency == 5))
1835 if ((rk_restriction_leniency == 1) || (rk_restriction_leniency == 3))
1842 cellule_rk_restreint.
diph_v_(n) = 1;
1846 cellule_rk_restreint.
diph_l_(n) = 1;
1849 else if ((rk_restriction_leniency == 0) || (rk_restriction_leniency == 2))
1851 cellule_rk_restreint.
diph_v_(n) = 1;
1852 cellule_rk_restreint.
diph_l_(n) = 1;
1861 assert(statut_diphasique_petit == statut_diphasique_naissant + 1);
1864 for (
int index = index_min; index < index_max; index++)
1868 Int3 ijk = cut_cell_disc.
get_ijk(n);
1873 if (rk_step == 0 && ((rk_restriction_leniency == 5) || (rk_restriction_leniency == 4) || (rk_restriction_leniency == 3) || (rk_restriction_leniency == 2)))
1876 if ((rk_restriction_leniency == 1) || (rk_restriction_leniency == 3) || (rk_restriction_leniency == 5))
1885 cellule_rk_restreint.
diph_v_(n) = 1;
1889 cellule_rk_restreint.
diph_l_(n) = 1;
1892 else if ((rk_restriction_leniency == 0) || (rk_restriction_leniency == 2) || (rk_restriction_leniency == 4))
1894 cellule_rk_restreint.
diph_v_(n) = 1;
1895 cellule_rk_restreint.
diph_l_(n) = 1;
const Domaine_IJK & get_domaine() const
const IJK_Interfaces & get_interfaces() const
int get_ghost_size() const
Int3 get_ijk(int n) const
double indic_pure(const int i, const int j, const int k) const
int get_n_from_statut_diphasique_index(int index) const
int get_statut_diphasique_value_index(int statut_diphasique) const
int get_n(int i, int j, int k) const
_TYPE_ & from_ijk_and_phase(int i, int j, int k, bool phase)
_TYPE_ & pure_(int i, int j, int k)
const Cut_cell_FT_Disc & get_cut_cell_disc() const
void set_to_uniform_value(_TYPE_ valeur)
TRUSTTabFT_cut_cell< _TYPE_ > diph_l_
_TYPE_ & from_signed_independent_index(int signed_independent_index)
TRUSTTabFT_cut_cell< _TYPE_ > diph_v_
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.
int get_nb_items_local(Localisation loc, int direction) const
Returns the number of local items (on this processor) for the given localisation in the requested dir...
double get_constant_delta(int direction) const
Returns the size of cells in a direction.
int get_i_along_dir_perio(int direction, double coord_dir, Localisation loc) const
double get_origin(int direction) const
Returns the coordinate of the first node (global) of the mesh in the requested direction.
int get_signed_independent_index(int phase, int i, int j, int k) const
int correct_perio_i_local(int direction, int i) const
int convert_ijk_cell_to_packed(const FixedVector< int, 3 > ijk) const
Converts the ijk index of an element to a cell index.
const Domaine_IJK & get_domaine() const
const Domaine_IJK & get_domaine() const
const DoubleTabFT_cut_cell_vector3 & get_indicatrice_surfacique_efficace_face() const
const IJK_Field_double & I_ft() const
const IJK_Field_double & I() const
double In_nonzero(const int phase, const int i, const int j, const int k) const
double I_nonzero(const int phase, const int i, const int j, const int k) const
const IJK_Field_double & In() const
const Maillage_FT_IJK & old_maillage_ft_ijk() const
const Maillage_FT_IJK & maillage_ft_ijk() const
static int est_pure(double indicatrice)
double get_barycentre(bool next_time, int bary_compo, int phase, int i, int j, int k) const
const IJK_Field_double & In_ft() const
static int convert_indicatrice_to_phase(double indicatrice)
int index_facette_suivante_
: class Intersections_Elem_Facettes
const ArrOfInt & index_elem() const
Renvoie un tableau de taille domaine.
const Intersections_Elem_Facettes_Data & data_intersection(int index) const
Renvoie les donnees de l'intersection stockee a l'indice "index" dans le tableau "data" ( 0 <= index ...
const DoubleTab & sommets() const
renvoie le tableau des sommets (reels et virtuels) dimension(0) = nombre de sommets,
int sommet_virtuel(int i) const
const Intersections_Elem_Facettes & intersections_elem_facettes() const
virtual const ArrOfDouble & get_update_surface_facettes() const
Calcule la grandeur demandee, stocke le resultat dans un tableau interne a la classe et renvoie le re...
const IntTab & facettes() const
renvoie le tableau des facettes (reelles et virtuelles) dimension(0) = nombre de facettes,
static int me()
renvoie mon rang dans le groupe de communication courant.
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_SIZE_ dimension(int d) const
int signed_independent_index