TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Operateur_IJK_elem_diff_base.tpp
1/****************************************************************************
2* Copyright (c) 2015 - 2016, 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#ifndef Operateur_IJK_elem_diff_base_TPP_included
17#define Operateur_IJK_elem_diff_base_TPP_included
18
19#include <Operateur_IJK_elem_diff_base.h>
20
21#ifndef Operateur_IJK_elem_diff_base_included
22#error __FILE__ should only be included from corresponding header
23#endif
24
25static void copy_boundary_condition(const IJK_Field_local_double& boundary_flux, IJK_Field_local_double& resu)
26{
27 assert(resu.ni() >= boundary_flux.ni());
28 assert(resu.nj() >= boundary_flux.nj());
29 // resu is the temporary array where all fluxes are stored before computing divergence,
30 // they might have more place than ni and nj because there 1 more flux value dans velocity values
31 // to compute divergence
32 const int ni = boundary_flux.ni();
33 const int nj = boundary_flux.nj();
34 for (int j = 0; j < nj; j++)
35 for (int i = 0; i < ni; i++)
36 resu(i,j,0) = boundary_flux(i,j,0);
37}
38
39template <DIRECTION _DIR_>
40void Operateur_IJK_elem_diff_base_double::compute_flux_(IJK_Field_local_double& resu, const int k_layer)
41{
42 const int nx = _DIR_ == DIRECTION::X ? input_field_->ni() + 1 : input_field_->ni() ;
43 const int ny = _DIR_ == DIRECTION::Y ? input_field_->nj() + 1 : input_field_->nj();
44
45 ConstIJK_double_ptr input_field(*input_field_, 0, 0, k_layer);
46 Simd_double uniform_lambda(1.);
47 Simd_double avg_lambda(1.);
49 uniform_lambda = Simd_double(*uniform_lambda_);
50 /*
51 * M.G: lambda point toward the input field just to initialise *structural_model without error
52 * May not work in further configurations (may be handled in IJK_Thermal classes) when operators
53 * are cast.
54 */
55 if (is_uniform_)
57
58
59 /*
60 * Gives lambda field as a dummy field (Avoid the creation of a IJK_Field_local_double
61 * field in the current scope)
62 */
63 /*
64 * Y.Z.: If the model is functional (i.e. not structural) then lambda takes the right value, and the "structural_model" variable points to dummy_field.
65 * Otherwise the model is structural then lambda points towards the dummy_field.
66 */
67 const IJK_Field_local_double& dummy_field = *input_field_;
68 ConstIJK_double_ptr lambda(!is_structural_ ? (is_vectorial_? get_model(_DIR_) : *lambda_) : dummy_field, 0, 0, k_layer);
69 ConstIJK_double_ptr structural_model(is_structural_ ? get_model(_DIR_) : dummy_field, 0, 0, k_layer);
70
71 IJK_double_ptr resu_ptr(resu, 0, 0, 0);
72
73 if (_DIR_ == DIRECTION::Z)
74 {
75 // Are we on the wall ?
76 const int global_k_layer = k_layer + channel_data_.offset_to_global_k_layer();
77 // global index of the layer of flux of the wall
78 // (assume one walls at zmin and zmax)
79 const int first_global_k_layer = 0; // index of k_layer when we are on the wall
80 // Fluxes in direction k are on the faces, hence, index of last flux is equal to number of elements
81 const int last_global_k_layer = channel_data_.nb_elem_k_tot();
82
83 if (!perio_k_)
84 {
85 if (global_k_layer == first_global_k_layer)
86 {
87 // We are on wall at kmin, copy boundary condition fluxes to "resu"
88 if (boundary_flux_kmin_) // boundary condition is not zero flux
89 copy_boundary_condition(*boundary_flux_kmin_, resu);
90 else
91 putzero(resu);
92 return;
93 }
94 else if (global_k_layer == last_global_k_layer)
95 {
96 if (boundary_flux_kmax_) // boundary condition is not zero flux
97 copy_boundary_condition(*boundary_flux_kmax_, resu);
98 else
99 putzero(resu);
100 return;
101 }
102 }
103 }
104
105 double d0 = 0., d1 = 0.;
106 double surface = 1.;
107 switch(_DIR_)
108 {
109 case DIRECTION::X:
110 if (!is_hess_ || is_flux_)
111 {
112 d0 = channel_data_.get_delta_x() * 0.5;
113 d1 = d0;
114 surface = channel_data_.get_delta_y() * channel_data_.get_delta_z()[k_layer];
115 }
116 else
117 surface = 1 / (channel_data_.get_delta_x() * channel_data_.get_delta_x());
118 break;
119 case DIRECTION::Y:
120 if (!is_hess_ || is_flux_)
121 {
122 d0 = channel_data_.get_delta_y() * 0.5;
123 d1 = d0;
124 surface = channel_data_.get_delta_x() * channel_data_.get_delta_z()[k_layer];
125 }
126 else
127 surface = 1 / (channel_data_.get_delta_y() * channel_data_.get_delta_y());
128 break;
129 case DIRECTION::Z:
130 if (!is_hess_ || is_flux_)
131 {
132 d0 = channel_data_.get_delta_z()[k_layer-1] * 0.5;
133 d1 = channel_data_.get_delta_z()[k_layer] * 0.5;
134 surface = channel_data_.get_delta_x() * channel_data_.get_delta_y();
135 }
136 break;
137 }
138
139 Simd_double lambda_m1(uniform_lambda);
140 Simd_double lambda_m2(uniform_lambda);
141 const int imax = nx;
142 const int jmax = ny;
143 const int vsize = Simd_double::size();
144 for (int j = 0; ; j++)
145 {
146 for (int i = 0; i < imax; i += vsize)
147 {
148 Simd_double flux = 0.;
149 if (is_structural_)
150 {
151 Simd_double s_mo, s_mo_dummy;
152 structural_model.get_left_center(_DIR_, i, s_mo_dummy, s_mo);
153 flux = (-1.) * s_mo * surface;
154 }
155 else
156 {
157 Simd_double left_val, right_val;
158 input_field.get_left_center(_DIR_, i, left_val, right_val);
159 Simd_double zeroVec = 0.;
160 Simd_double oneVec = 1.;
161 Simd_double minVec = DMINFLOAT;
162 Simd_double d = 1.;
163 if (!is_hess_ || is_flux_)
164 {
165 // Fetch conductivity on neighbour cells:
166 if (!is_uniform_)
167 {
168 lambda.get_left_center(_DIR_, i, lambda_m1, lambda_m2);
169 }
170 // geometric avg: (d0+d1) / ( d0 / lambda_m1 + d1 / lambda_m2 ), optimized with only 1 division:
171 Simd_double dsabs = SimdSelect(zeroVec, d0 * lambda_m2 + d1 * lambda_m1, d0 * lambda_m2 + d1 * lambda_m1, (-1) * (d0 * lambda_m2 + d1 * lambda_m1));
172 Simd_double ds = SimdSelect(dsabs, minVec, oneVec, d0 * lambda_m2 + d1 * lambda_m1);
174 d = d0 + d1;
175 avg_lambda = SimdSelect(dsabs, minVec, zeroVec, SimdDivideMed(d * lambda_m1 * lambda_m2, ds));
176 }
177 // thermal flux is positive if going from left to right => -grad(T)
178 flux = (left_val - right_val) * avg_lambda * surface;
179 }
180 resu_ptr.put_val(i, flux);
181 }
182 // do not execute end_iloop at last iteration (because of assert on valid j+1)
183 if (j+1==jmax)
184 break;
185 input_field.next_j();
187 lambda.next_j();
189 structural_model.next_j();
190 resu_ptr.next_j();
191 }
192}
193
194template <DIRECTION _DIR_>
196{
197 const int dir_i = (_DIR_ == DIRECTION::X);
198 const int dir_j = (_DIR_ == DIRECTION::Y);
199 const int dir_k = (_DIR_ == DIRECTION::Z);
200
201 const IJK_Field_local_double& input_field = *input_field_;
202 /*
203 * M.G: lambda point toward the input field just to initialise *structural_model without error
204 * May not work in further configurations (may be handled in IJK_Thermal classes) when operators
205 * are cast.
206 */
207 if (is_uniform_)
209
210
211 /*
212 * Gives lambda field as a dummy field (Avoid the creation of a IJK_Field_local_double
213 * field in the current scope)
214 */
215 const IJK_Field_local_double& lambda = is_vectorial_? get_model(_DIR_) : *lambda_;
216 const IJK_Field_local_double& structural_model = is_structural_ ? get_model(_DIR_) : *lambda_;
217
218 BOUNDARY_FLUX type_boundary_flux = flux_determined_by_boundary_condition_<_DIR_>(k);
219 if (type_boundary_flux != BOUNDARY_FLUX::NOT_DETERMINED_BY_BOUNDARY)
220 {
221 double flux = compute_flux_local_boundary_condition_<_DIR_>(type_boundary_flux, i, j);
222 return flux;
223 }
224 else
225 {
226 Vecteur3 surface_d0_d1 = compute_surface_d0_d1_<_DIR_>(k);
227 double surface = surface_d0_d1[0];
228 double d0 = surface_d0_d1[1];
229 double d1 = surface_d0_d1[2];
230
231 double input_left = input_field(i-dir_i,j-dir_j,k-dir_k);
232 double input_centre = input_field(i,j,k);
233 double lambda_left = lambda(i-dir_i,j-dir_j,k-dir_k);
234 double lambda_centre = lambda(i,j,k);
235 double struct_model = is_structural_ ? structural_model(i,j,k) : -1;
236 double flux = Operateur_IJK_elem_diff_base_double::compute_flux_local_<_DIR_>(d0, d1, surface, input_left, input_centre, lambda_left, lambda_centre, struct_model);
237 return flux;
238 }
239}
240
241template <DIRECTION _DIR_>
242double Operateur_IJK_elem_diff_base_double::compute_flux_local_(double d0, double d1, double surface, double input_left, double input_centre, double lambda_left, double lambda_centre, double structural_model)
243{
244 assert(!is_uniform_);
245 assert(!is_anisotropic_);
246 assert(!is_hess_);
247 double flux = 0.;
248 if (is_structural_)
249 {
250 double s_mo = structural_model;
251 flux = (-1.) * s_mo * surface;
252 }
253 else
254 {
255 double lambda_m1 = lambda_left;
256 double lambda_m2 = lambda_centre;
257
258 // geometric avg: (d0+d1) / ( d0 / lambda_m1 + d1 / lambda_m2 ), optimized with only 1 division:
259 double dsabs = (0. < d0 * lambda_m2 + d1 * lambda_m1) ? d0 * lambda_m2 + d1 * lambda_m1 : (-1) * (d0 * lambda_m2 + d1 * lambda_m1);
260 double ds = (dsabs < DMINFLOAT) ? 1. : d0 * lambda_m2 + d1 * lambda_m1;
261
262 double avg_lambda = (dsabs < DMINFLOAT) ? 0. : (lambda_m1 * lambda_m2)/ds;
263
264 // thermal flux is positive if going from left to right => -grad(T)
265 flux = (input_left - input_centre) * avg_lambda * surface;
266 }
267 return flux;
268}
269
270template <DIRECTION _DIR_>
272{
273 if (_DIR_ == DIRECTION::Z)
274 {
275 // Are we on the wall ?
276 const int global_k_layer = k + channel_data_.offset_to_global_k_layer();
277 // global index of the layer of flux of the wall
278 // (assume one walls at zmin and zmax)
279 const int first_global_k_layer = 0; // index of k when we are on the wall
280 // Fluxes in direction k are on the faces, hence, index of last flux is equal to number of elements
281 const int last_global_k_layer = channel_data_.nb_elem_k_tot();
282
283 if (!perio_k_)
284 {
285 if (global_k_layer == first_global_k_layer)
286 {
287 return BOUNDARY_FLUX::KMIN_WALL;
288 }
289 else if (global_k_layer == last_global_k_layer)
290 {
291 return BOUNDARY_FLUX::KMAX_WALL;
292 }
293 }
294 }
295 return BOUNDARY_FLUX::NOT_DETERMINED_BY_BOUNDARY;
296}
297
298template <DIRECTION _DIR_>
299double Operateur_IJK_elem_diff_base_double::compute_flux_local_boundary_condition_(BOUNDARY_FLUX type_boundary_flux, int i, int j)
300{
301 if (type_boundary_flux == BOUNDARY_FLUX::KMIN_WALL)
302 {
303 // We are on wall at kmin, copy boundary condition fluxes to "resu"
304 if (boundary_flux_kmin_) // boundary condition is not zero flux
305 return (*boundary_flux_kmin_)(i,j,0);
306 else
307 return 0.;
308 }
309 else if (type_boundary_flux == BOUNDARY_FLUX::KMAX_WALL)
310 {
311 if (boundary_flux_kmax_) // boundary condition is not zero flux
312 return (*boundary_flux_kmax_)(i,j,0);
313 else
314 return 0.;
315 }
316 else
317 {
318 Cerr << "Unexpected situation in compute_flux_local_boundary_condition_" << finl;
320 return -1;
321 }
322}
323
324template <DIRECTION _DIR_>
326{
327 double d0 = 0., d1 = 0.;
328 double surface = 1.;
329 switch(_DIR_)
330 {
331 case DIRECTION::X:
332 if (!is_hess_)
333 {
334 d0 = channel_data_.get_delta_x() * 0.5;
335 d1 = d0;
336 surface = channel_data_.get_delta_y() * channel_data_.get_delta_z()[k];
337 }
338 else
339 surface = 1 / (channel_data_.get_delta_x() * channel_data_.get_delta_x());
340 break;
341 case DIRECTION::Y:
342 if (!is_hess_)
343 {
344 d0 = channel_data_.get_delta_y() * 0.5;
345 d1 = d0;
346 surface = channel_data_.get_delta_x() * channel_data_.get_delta_z()[k];
347 }
348 else
349 surface = 1 / (channel_data_.get_delta_y() * channel_data_.get_delta_y());
350 break;
351 case DIRECTION::Z:
352 if (!is_hess_)
353 {
354 d0 = channel_data_.get_delta_z()[k-1] * 0.5;
355 d1 = channel_data_.get_delta_z()[k] * 0.5;
356 surface = channel_data_.get_delta_x() * channel_data_.get_delta_y();
357 }
358 break;
359 }
360 return {surface, d0, d1};
361}
362
363template <DIRECTION _DIR_>
364void OpDiffIJKScalar_cut_cell_double::correct_flux_(IJK_Field_local_double *const flux, int k_layer)
365{
366 const int dir = static_cast<int>(_DIR_);
367
368 const Cut_field_double& input_cut_field = static_cast<const Cut_field_double&>(*input_field_);
369 const IJK_Field_local_double& structural_model = is_structural_ ? get_model(_DIR_) : *lambda_;
370 assert(&(*cut_cell_flux_)[0].get_cut_cell_disc() == &(*cut_cell_flux_)[1].get_cut_cell_disc());
371 assert(&(*cut_cell_flux_)[0].get_cut_cell_disc() == &(*cut_cell_flux_)[2].get_cut_cell_disc());
372 const Cut_cell_FT_Disc& cut_cell_disc = (*cut_cell_flux_)[0].get_cut_cell_disc();
373
374 IJK_Field_int& treatment_count = *treatment_count_;
375 int& new_treatment = *new_treatment_;
376 new_treatment += 1;
377
378 int backward_receptive_stencil = 0;
379 int forward_receptive_stencil = 1;
380 assert(backward_receptive_stencil <= cut_cell_disc.get_ghost_size());
381 assert(forward_receptive_stencil <= cut_cell_disc.get_ghost_size());
382
383 if (_DIR_ == DIRECTION::Z)
384 {
385 if (cut_cell_disc.get_domaine().get_periodic_flag(dir))
386 {
387 const int kmax = cut_cell_disc.get_interfaces().I().nk();
388 int n_dir = cut_cell_disc.get_domaine().get_nb_elem_local(dir);
389 int n_dir_tot = cut_cell_disc.get_domaine().get_nb_elem_tot(dir);
390
391 // Le processeur contient deux fois les valeurs sur les bords
392 if (n_dir == n_dir_tot)
393 {
394 if (k_layer == kmax)
395 {
396 k_layer = 0;
397 }
398 }
399 }
400 }
401
402 int min_k = (_DIR_ == DIRECTION::Z) ? k_layer-forward_receptive_stencil : k_layer;
403 int max_k = (_DIR_ == DIRECTION::Z) ? k_layer+backward_receptive_stencil : k_layer;
404 for (int k_c = min_k; k_c <= max_k; k_c++)
405 {
406 for (int index = cut_cell_disc.get_k_value_index(k_c); index < cut_cell_disc.get_k_value_index(k_c+1); index++)
407 {
408 int n = cut_cell_disc.get_n_from_k_index(index);
409
410 Int3 ijk_no_per = cut_cell_disc.get_ijk(n);
411 assert(k_c == ijk_no_per[2]);
412
413 int min_decalage = (_DIR_ == DIRECTION::Z) ? (k_layer - k_c) : -backward_receptive_stencil;
414 int max_decalage = (_DIR_ == DIRECTION::Z) ? (k_layer - k_c) : forward_receptive_stencil;
415 for (int decalage = min_decalage; decalage <= max_decalage; decalage++)
416 {
417 int i = ijk_no_per[0] + (_DIR_ == DIRECTION::X)*decalage;
418 int j = ijk_no_per[1] + (_DIR_ == DIRECTION::Y)*decalage;
419 int k = ijk_no_per[2] + (_DIR_ == DIRECTION::Z)*decalage;
420 assert(k_layer == k);
421
422 if (!cut_cell_disc.get_domaine().within_ghost_<dir>(i, j, k, 0, 1))
423 continue;
424
425 if (treatment_count(i,j,k) == new_treatment)
426 continue;
427
428 {
429 int index_ijk_per = 0;
430 while (index_ijk_per >= 0)
431 {
432 Int3 ijk = cut_cell_disc.ijk_per_of_index(i, j, k, index_ijk_per);
433 index_ijk_per = cut_cell_disc.next_index_ijk_per(i, j, k, index_ijk_per, 0, 1);
434
435 treatment_count(ijk[0],ijk[1],ijk[2]) = new_treatment;
436 }
437 }
438
439 double indicatrice_centre = cut_cell_disc.get_interfaces().In(i,j,k);
440 double old_indicatrice_centre = cut_cell_disc.get_interfaces().I(i,j,k);
441 int n_centre = cut_cell_disc.get_n(i, j, k);
442
443 BOUNDARY_FLUX type_boundary_flux = flux_determined_by_boundary_condition_<_DIR_>(k);
444 if (type_boundary_flux != BOUNDARY_FLUX::NOT_DETERMINED_BY_BOUNDARY)
445 {
446 // Le flux est dans ce cas determine par la condition aux limites
447 // Aucune correction n'est donc necessaire
448 assert(n_centre < 0); // Le cas d'une cellule diphasique avec flux condition aux limites n'est pas traite
449 }
450 else
451 {
452 assert((n_centre >= 0) || ((indicatrice_centre == 0.) || (indicatrice_centre == 1.)));
453 bool centre_monophasique = IJK_Interfaces::est_pure(.5*(old_indicatrice_centre + indicatrice_centre));
454
455 int phase_min = (int)std::floor(.5*(old_indicatrice_centre + indicatrice_centre));
456 int phase_max = (int)std::ceil(.5*(old_indicatrice_centre + indicatrice_centre));
457 for (int phase = phase_min ; phase <= phase_max ; phase++)
458 {
459 const DoubleTabFT_cut_cell& diph_input = (phase == 0) ? input_cut_field.diph_v_ : input_cut_field.diph_l_;
460 DoubleTabFT_cut_cell& diph_flux = (phase == 0) ? (*cut_cell_flux_)[dir].diph_v_ : (*cut_cell_flux_)[dir].diph_l_;
461
462 const int dir_i = (_DIR_ == DIRECTION::X);
463 const int dir_j = (_DIR_ == DIRECTION::Y);
464 const int dir_k = (_DIR_ == DIRECTION::Z);
465
466 int n_left = cut_cell_disc.get_n(i-dir_i,j-dir_j,k-dir_k);
467
468 double indicatrice_left = cut_cell_disc.get_interfaces().In(i-dir_i,j-dir_j,k-dir_k);
469
470 double old_indicatrice_left = cut_cell_disc.get_interfaces().I(i-dir_i,j-dir_j,k-dir_k);
471
472 bool left_monophasique = IJK_Interfaces::est_pure(.5*(old_indicatrice_left + indicatrice_left));
473 bool phase_invalide_centre = (centre_monophasique && (phase != IJK_Interfaces::convert_indicatrice_to_phase(indicatrice_centre)));
474 bool phase_invalide_left = (left_monophasique && (phase != IJK_Interfaces::convert_indicatrice_to_phase(indicatrice_left)));
475
476 double bar_dir_left = cut_cell_disc.get_interfaces().get_barycentre(true, dir, phase, i-dir_i,j-dir_j,k-dir_k);
477 assert((n_left >= 0) || (bar_dir_left == .5));
478
479 double bar_dir_centre = cut_cell_disc.get_interfaces().get_barycentre(true, dir, phase, i,j,k);
480 assert((n_centre >= 0) || (bar_dir_centre == .5));
481
482 Vecteur3 surface_d0_d1 = compute_surface_d0_d1_<_DIR_>(k);
483
484 const DoubleTabFT_cut_cell_vector3& indicatrice_surfacique = cut_cell_disc.get_interfaces().get_indicatrice_surfacique_efficace_face();
485 double indicatrice_surface = (n_centre < 0) ? ((phase == 0) ? 1 - indicatrice_centre : indicatrice_centre) : ((phase == 0) ? 1 - indicatrice_surfacique(n_centre,dir) : indicatrice_surfacique(n_centre,dir));
486
487 const double surface = surface_d0_d1[0] * indicatrice_surface;
488 double d0 = surface_d0_d1[1] * 2*(1 - bar_dir_left);
489 double d1 = surface_d0_d1[2] * 2*(bar_dir_centre);
490
491 int phase_left = (n_left < 0) ? IJK_Interfaces::convert_indicatrice_to_phase(indicatrice_left) : phase;
492 assert((phase_left == phase) || (indicatrice_surface == 0.));
493
494 double input_left = (n_left < 0) ? input_cut_field.pure_(i-dir_i,j-dir_j,k-dir_k) : diph_input(n_left);
495 double input_centre = (n_centre < 0) ? input_cut_field.pure_(i,j,k) : diph_input(n_centre);
496
497 double lambda_value = (phase == 0) ? *uniform_lambda_vapour_ : *uniform_lambda_liquid_;
498
499 double struct_model = is_structural_ ? structural_model(i,j,k) : -1;
500
501 int phase_mourrante_left = cut_cell_disc.get_interfaces().phase_mourrante(phase, old_indicatrice_left, indicatrice_left);
502 int phase_mourrante_centre = cut_cell_disc.get_interfaces().phase_mourrante(phase, old_indicatrice_centre, indicatrice_centre);
503 int phase_naissante_left = cut_cell_disc.get_interfaces().phase_naissante(phase, old_indicatrice_left, indicatrice_left);
504 int phase_naissante_centre = cut_cell_disc.get_interfaces().phase_naissante(phase, old_indicatrice_centre, indicatrice_centre);
505 int petit_left = cut_cell_disc.get_interfaces().next_below_small_threshold_for_phase(phase, old_indicatrice_left, indicatrice_left);
506 int petit_centre = cut_cell_disc.get_interfaces().next_below_small_threshold_for_phase(phase, old_indicatrice_centre, indicatrice_centre);
507
508 double flux_value;
509 if (phase_mourrante_centre || phase_mourrante_left)
510 {
511 flux_value = 0.;
512 }
513 else if (ignore_small_cells_ && (petit_centre || petit_left || phase_naissante_centre || phase_naissante_left))
514 {
515 flux_value = 0.;
516 }
517 else
518 {
519 assert(phase_invalide_left || (input_left != 0.));
520 assert(phase_invalide_centre || (input_centre != 0.));
521 flux_value = Operateur_IJK_elem_diff_base_double::compute_flux_local_<_DIR_>(d0, d1, surface, input_left, input_centre, lambda_value, lambda_value, struct_model);
522 }
523
524 if (n_centre < 0) // Si la cellule est pure
525 {
526 int index_ijk_per = 0;
527 while (index_ijk_per >= 0)
528 {
529 Int3 ijk = cut_cell_disc.ijk_per_of_index(i, j, k, index_ijk_per);
530 index_ijk_per = cut_cell_disc.next_index_ijk_per(i, j, k, index_ijk_per, 0, 1);
531
532 (*flux)(ijk[0],ijk[1],0) = flux_value;
533 }
534 }
535 else
536 {
537 diph_flux(n_centre) = flux_value;
538 if ((n_left < 0) && (phase == phase_left && (!phase_invalide_centre) && (!phase_invalide_left)))
539 {
540 int index_ijk_per = 0;
541 while (index_ijk_per >= 0)
542 {
543 Int3 ijk = cut_cell_disc.ijk_per_of_index(i, j, k, index_ijk_per);
544 index_ijk_per = cut_cell_disc.next_index_ijk_per(i, j, k, index_ijk_per, 0, 1);
545
546 (*flux)(ijk[0],ijk[1],0) = flux_value;
547 }
548 }
549 }
550
551 // Si on est monophasique de la phase non-existante, le flux devrait etre nul
552 if (phase_invalide_centre || phase_invalide_left)
553 {
554 assert(flux_value == 0.);
555 }
556 }
557 }
558 }
559 }
560 }
561}
562
563#endif
564
void next_j()
increments the pointer by j_stride (eg, j = j+1)
void get_left_center(DIRECTION _DIR_, int i_offset, _TYPE_ &left, _TYPE_ &center) const
returns left=field(i+i_offset-1, j, k) and center=field(i+i_offset, j, k)
const Domaine_IJK & get_domaine() const
const IJK_Interfaces & get_interfaces() const
int get_n_from_k_index(int index) const
int get_ghost_size() const
Int3 ijk_per_of_index(int i, int j, int k, int index) const
int next_index_ijk_per(int i, int j, int k, int index, int negative_ghost_size, int positive_ghost_size) const
Int3 get_ijk(int n) const
int get_k_value_index(int k) const
int get_n(int i, int j, int k) const
_TYPE_ & pure_(int i, int j, int k)
Definition Cut_field.h:116
TRUSTTabFT_cut_cell< _TYPE_ > diph_v_
Definition Cut_field.h:50
int get_nb_elem_local(int direction) const
Returns the number of elements owned by this processor in the given direction.
bool get_periodic_flag(int direction) const
Method returns true if periodic in this direction.
int get_nb_elem_tot(int direction) const
Returns the total (global) number of mesh cells in requested direction.
bool within_ghost_(int i, int j, int k, int negative_ghost_size, int positive_ghost_size) const
const DoubleTabFT_cut_cell_vector3 & get_indicatrice_surfacique_efficace_face() const
const IJK_Field_double & I() const
static int phase_naissante(int phase, double old_indicatrice, double next_indicatrice)
const IJK_Field_double & In() const
int next_below_small_threshold_for_phase(int phase, double old_indicatrice, double next_indicatrice) 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
static int phase_mourrante(int phase, double old_indicatrice, double next_indicatrice)
static int convert_indicatrice_to_phase(double indicatrice)
void put_val(int i_offset, const _TYPE_ &val)
Performs the assignment: field(i+i_offset,j,k) = val.
Definition IJK_ptr.h:32
const IJK_Field_local_double * boundary_flux_kmin_
double compute_flux_local_boundary_condition_(BOUNDARY_FLUX type_boundary_flux, int i, int j)
const IJK_Field_local_double & get_model(DIRECTION _DIR_)
const IJK_Field_local_double * boundary_flux_kmax_
void compute_flux_(IJK_Field_local_double &resu, const int k_layer)
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455