TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
IJK_Field_template.tpp
1/****************************************************************************
2* Copyright (c) 2026, 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 IJK_Field_template_TPP_H
17#define IJK_Field_template_TPP_H
18
19#include <IJK_Shear_Periodic_helpler.h>
20#include <IJK_communications.h>
21#include <Domaine_IJK.h>
22#include <LataTools.h>
23#include <LataDB.h>
24#include <EcrFicPartageBin.h>
25#include <errno.h>
26#include <IJK_Striped_Writer.h>
27#include <Parallel_io_parameters.h>
28#include <Perf_counters.h>
29
30template<typename _TYPE_, typename _TYPE_ARRAY_>
31void IJK_Field_template<_TYPE_, _TYPE_ARRAY_>::exchange_data(int pe_send_, /* processor to send to */
32 int is, int js, int ks, /* ijk coordinates of first data to send */
33 int pe_recv_, /* processor to recv from */
34 int ir, int jr, int kr, /* ijk coordinates of first data to recv */
35 int isz, int jsz, int ksz, /* size of block data to send/recv */
36 double offset, double jump_i, int nb_ghost) /* decallage a appliquer pour la condition de shear periodique*/
37{
38
39 if (pe_send_ == Process::me() && pe_recv_ == Process::me())
40 {
41 // Self (periodicity on same processor)
43
44 // for classical variable --> just a copy
45 if (offset == 0.)
46 {
47 for (int i = 0; i < isz; i++)
48 for (int k = 0; k < ksz; k++)
49 for (int j = 0; j < jsz; j++)
51
52 }
53 // for pressure in case of shear periodicity (zmax)--> ghost value reconstructed from Isigkappa and pressure interpolation
54 else if (shear_BC_helpler_.monofluide_variable_==1 && offset <0.)
55 {
56 for (int i = 0; i < isz; i++)
57 {
58 shear_BC_helpler_.prepare_interpolation_for_shear_periodicity((int) round((double) i + (double) is + offset), ((double) i + (double) is + offset), isz);
59 for (int k = 0; k < ksz; k++)
60 for (int j = 0; j < jsz; j++)
61 {
62 _TYPE_ interpIsigkappazmin= 0.;
63 _TYPE_ interpIsigkappazmax= 0.;
64 interpolation_for_shear_periodicity_I_sig_kappa(j + js, k+2, k+2, interpIsigkappazmin, interpIsigkappazmax);
65 dest[IJK_Field_local_template<_TYPE_,_TYPE_ARRAY_>::linear_index(i + ir , j + jr , k + kr)] = interpolation_for_shear_periodicity_IJK_Field(j + js, k + ks) + interpIsigkappazmin-(_TYPE_) shear_BC_helpler_.I_sig_kappa_zmax_(i+is , j+js , k+2);
66 }
67 }
68 }
69 // for pressure in case of shear periodicity (zmin)--> ghost value reconstructed from Isigkappa and pressure interpolation
70 else if (shear_BC_helpler_.monofluide_variable_==1 && offset >0.)
71 {
72 for (int i = 0; i < isz; i++)
73 {
74 shear_BC_helpler_.prepare_interpolation_for_shear_periodicity((int) round((double) i + (double) is + offset), ((double) i + (double) is + offset), isz);
75 for (int k = 0; k < ksz; k++)
76 for (int j = 0; j < jsz; j++)
77 {
78 _TYPE_ interpIsigkappazmin= 0.;
79 _TYPE_ interpIsigkappazmax= 0.;
80 interpolation_for_shear_periodicity_I_sig_kappa(j + js, k+2-nb_ghost, k+2-nb_ghost, interpIsigkappazmin, interpIsigkappazmax);
81 dest[IJK_Field_local_template<_TYPE_,_TYPE_ARRAY_>::linear_index(i + ir , j + jr , k + kr)] = interpolation_for_shear_periodicity_IJK_Field(j + js, k + ks) + interpIsigkappazmax-(_TYPE_) shear_BC_helpler_.I_sig_kappa_zmin_(i+is , j+js , k+2-nb_ghost);
82 }
83 }
84 }
85 // for physical properties in case of shear periodicity (zmax)--> ghost value reconstructed from phase indicator function
86 else if (shear_BC_helpler_.monofluide_variable_==2 && offset <0.)
87 {
88 for (int i = 0; i < isz; i++)
89 for (int k = 0; k < ksz; k++)
90 for (int j = 0; j < jsz; j++)
91 dest[IJK_Field_local_template<_TYPE_,_TYPE_ARRAY_>::linear_index(i + ir , j + jr , k + kr)]=(_TYPE_) shear_BC_helpler_.indicatrice_ghost_zmax_(i + ir , j + jr , k+2)*(_TYPE_)shear_BC_helpler_.Phi_ppty_l_+((_TYPE_)1.-(_TYPE_) shear_BC_helpler_.indicatrice_ghost_zmax_(i + ir , j + jr , k+2))*(_TYPE_)shear_BC_helpler_.Phi_ppty_v_;
92
93
94 }
95 // for physical properties in case of shear periodicity (zmin)--> ghost value reconstructed from phase indicator function
96 else if (shear_BC_helpler_.monofluide_variable_==2 && offset >0.)
97 {
98 for (int i = 0; i < isz; i++)
99 for (int k = 0; k < ksz; k++)
100 for (int j = 0; j < jsz; j++)
101 dest[IJK_Field_local_template<_TYPE_,_TYPE_ARRAY_>::linear_index(i + ir , j + jr , k + kr)]=(_TYPE_) shear_BC_helpler_.indicatrice_ghost_zmin_(i + ir , j + jr , k+2-nb_ghost)*(_TYPE_)shear_BC_helpler_.Phi_ppty_l_+((_TYPE_)1.-(_TYPE_) shear_BC_helpler_.indicatrice_ghost_zmin_(i + ir , j + jr , k+2-nb_ghost))*(_TYPE_)shear_BC_helpler_.Phi_ppty_v_;
102
103 }
104 // for all other variable in case of shear periodicity --> interpolation + jump at the z-boundary for velocity field
105 else
106 {
107 for (int i = 0; i < isz; i++)
108 {
109 shear_BC_helpler_.prepare_interpolation_for_shear_periodicity((int) round((double) i + (double) is + offset), ((double) i + (double) is + offset), isz);
110 for (int k = 0; k < ksz; k++)
111 for (int j = 0; j < jsz; j++)
112 dest[IJK_Field_local_template<_TYPE_,_TYPE_ARRAY_>::linear_index(i + ir , j + jr , k + kr)] = interpolation_for_shear_periodicity_IJK_Field(j + js, k + ks) + (_TYPE_) jump_i ;
113 }
114 }
115
116 return;
117 }
118 const int data_size = isz * jsz * ksz;
119 const int data_size_other_buf = 1;
120 const int type_size = sizeof(_TYPE_);
121 const int double_size = sizeof(double);
122 const int int_size = sizeof(int);
123 _TYPE_ *send_buffer = 0;
124 _TYPE_ *recv_buffer = 0;
125 double *send_buffer_offset = 0;
126 double *recv_buffer_offset = 0;
127 int *send_buffer_nb_ghost = 0;
128 int *recv_buffer_nb_ghost = 0;
129
130 if (pe_send_ >= 0)
131 {
132 send_buffer = new _TYPE_[data_size];
133 _TYPE_ *buf = send_buffer;
134 send_buffer_offset = new double[data_size_other_buf];
135 double *buf_offset = send_buffer_offset;
136 send_buffer_nb_ghost = new int[data_size_other_buf];
137 int *buf_nb_ghost = send_buffer_nb_ghost;
138 *buf_offset=offset;
139 *buf_nb_ghost=nb_ghost;
140 // for classical variable --> just a copy
141 if (offset==0.)
142 {
143 for (int i = 0; i < isz; i++)
144 for (int k = 0; k < ksz; k++)
145 for (int j = 0; j < jsz; j++, buf++)
146 *buf= IJK_Field_local_template<_TYPE_,_TYPE_ARRAY_>::operator()(i + is, j + js, k + ks);
147 }
148 // for pressure in case of shear periodicity (zmax)--> ghost value reconstructed from Isigkappa and pressure interpolation
149 else if (shear_BC_helpler_.monofluide_variable_==1 && offset <0.)
150 {
151 for (int i = 0; i < isz; i++)
152 {
153 shear_BC_helpler_.prepare_interpolation_for_shear_periodicity((int) round((double) i + (double) is + offset), ((double) i + (double) is + offset), isz);
154 for (int k = 0; k < ksz; k++)
155 for (int j = 0; j < jsz; j++, buf++)
156 {
157 _TYPE_ interpIsigkappazmin= 0.;
158 _TYPE_ interpIsigkappazmax= 0.;
159 interpolation_for_shear_periodicity_I_sig_kappa(j + js, k+2, k+2, interpIsigkappazmin, interpIsigkappazmax);
160 *buf = interpolation_for_shear_periodicity_IJK_Field(j + js, k + ks) + interpIsigkappazmin;
161 }
162 }
163 }
164 // for pressure in case of shear periodicity (zmin)--> ghost value reconstructed from Isigkappa and pressure interpolation
165 else if (shear_BC_helpler_.monofluide_variable_==1 && offset >0.)
166 {
167 for (int i = 0; i < isz; i++)
168 {
169 shear_BC_helpler_.prepare_interpolation_for_shear_periodicity((int) round((double) i + (double) is + offset), ((double) i + (double) is + offset), isz);
170 for (int k = 0; k < ksz; k++)
171 for (int j = 0; j < jsz; j++, buf++)
172 {
173 _TYPE_ interpIsigkappazmin= 0.;
174 _TYPE_ interpIsigkappazmax= 0.;
175 interpolation_for_shear_periodicity_I_sig_kappa(j + js, k+2-nb_ghost, k+2-nb_ghost, interpIsigkappazmin, interpIsigkappazmax);
176 *buf = interpolation_for_shear_periodicity_IJK_Field(j + js, k + ks) + interpIsigkappazmax;
177 }
178 }
179 }
180 // for physical properties in case of shear periodicity --> ghost value reconstructed from phase indicator function
181 else if (shear_BC_helpler_.monofluide_variable_==2)
182 {
183 for (int i = 0; i < isz; i++)
184 for (int k = 0; k < ksz; k++)
185 for (int j = 0; j < jsz; j++, buf++)
186 *buf= (_TYPE_) 0.;
187 }
188 // for all other variable in case of shear periodicity --> interpolation + jump at the z-boundary for velocity field
189 else
190 {
191 for (int i = 0; i < isz; i++)
192 {
193 shear_BC_helpler_.prepare_interpolation_for_shear_periodicity((int) round((double) i + (double) is + offset), ((double) i + (double) is + offset), isz);
194 for (int k = 0; k < ksz; k++)
195 for (int j = 0; j < jsz; j++, buf++)
196 *buf= interpolation_for_shear_periodicity_IJK_Field(j + js, k + ks) + (_TYPE_) jump_i;
197 }
198 }
199 }
200
201 if (pe_recv_ >= 0)
202 {
203 recv_buffer = new _TYPE_[data_size];
204 recv_buffer_offset = new double[data_size_other_buf];
205 recv_buffer_nb_ghost = new int[data_size_other_buf];
206 }
207 ::envoyer_recevoir(send_buffer, data_size * type_size, pe_send_, recv_buffer, data_size * type_size, pe_recv_);
208 ::envoyer_recevoir(send_buffer_offset, data_size_other_buf * double_size, pe_send_, recv_buffer_offset, data_size_other_buf * double_size, pe_recv_);
209 ::envoyer_recevoir(send_buffer_nb_ghost, data_size_other_buf * int_size, pe_send_, recv_buffer_nb_ghost, data_size_other_buf * int_size, pe_recv_);
210
211 if (pe_recv_ >= 0)
212 {
213 _TYPE_ *buf = recv_buffer;
214 double *buf_offset = recv_buffer_offset;
215 int *buf_nb_ghost= recv_buffer_nb_ghost;
217 // for classical variable --> just a copy
218 if (*buf_offset == 0.)
219 {
220 for (int i = 0; i < isz; i++)
221 for (int k = 0; k < ksz; k++)
222 for (int j = 0; j < jsz; j++, buf++)
223 dest[IJK_Field_local_template<_TYPE_,_TYPE_ARRAY_>::linear_index(ir + i, jr + j, kr + k)] = *buf;
224 }
225 // for pressure in case of shear periodicity (zmax)--> ghost value reconstructed from Isigkappa and pressure interpolation
226 else if (shear_BC_helpler_.monofluide_variable_==1 && *buf_offset <0.)
227 {
228 for (int i = 0; i < isz; i++)
229 for (int k = 0; k < ksz; k++)
230 for (int j = 0; j < jsz; j++, buf++)
231 {
232 dest[IJK_Field_local_template<_TYPE_,_TYPE_ARRAY_>::linear_index(i + ir , j + jr , k + kr)] = *buf - (_TYPE_) shear_BC_helpler_.I_sig_kappa_zmax_(i+is , j+js , k+2);
233 }
234 }
235 // for pressure in case of shear periodicity (zmin)--> ghost value reconstructed from Isigkappa and pressure interpolation
236 else if (shear_BC_helpler_.monofluide_variable_==1 && *buf_offset >0.)
237 {
238 for (int i = 0; i < isz; i++)
239 for (int k = 0; k < ksz; k++)
240 for (int j = 0; j < jsz; j++, buf++)
241 {
242 dest[IJK_Field_local_template<_TYPE_,_TYPE_ARRAY_>::linear_index(i + ir , j + jr , k + kr)] = *buf - (_TYPE_) shear_BC_helpler_.I_sig_kappa_zmin_(i+is , j+js , k+2-nb_ghost);
243 }
244
245 }
246 // for physical properties in case of shear periodicity (zmax) --> ghost value reconstructed from phase indicator function
247 else if (shear_BC_helpler_.monofluide_variable_==2 && *buf_offset <0.)
248 {
249 for (int i = 0; i < isz; i++)
250 for (int k = 0; k < ksz; k++)
251 for (int j = 0; j < jsz; j++, buf++)
252 dest[IJK_Field_local_template<_TYPE_,_TYPE_ARRAY_>::linear_index(ir + i, jr + j, kr + k)]=(_TYPE_) shear_BC_helpler_.indicatrice_ghost_zmax_(ir + i , jr + j , k+2)*(_TYPE_)shear_BC_helpler_.Phi_ppty_l_+((_TYPE_)1.-(_TYPE_) shear_BC_helpler_.indicatrice_ghost_zmax_(ir + i , jr + j , k+2))*(_TYPE_)shear_BC_helpler_.Phi_ppty_v_;
253
254 }
255 // for physical properties in case of shear periodicity (zmin) --> ghost value reconstructed from phase indicator function
256 else if (shear_BC_helpler_.monofluide_variable_==2 && *buf_offset >0.)
257 {
258 for (int i = 0; i < isz; i++)
259 for (int k = 0; k < ksz; k++)
260 for (int j = 0; j < jsz; j++, buf++)
261 dest[IJK_Field_local_template<_TYPE_,_TYPE_ARRAY_>::linear_index(ir + i, jr + j, kr + k)]=(_TYPE_) shear_BC_helpler_.indicatrice_ghost_zmin_(ir + i , jr + j , k+2-*buf_nb_ghost)*(_TYPE_)shear_BC_helpler_.Phi_ppty_l_+((_TYPE_)1.-(_TYPE_) shear_BC_helpler_.indicatrice_ghost_zmin_(ir + i , jr + j , k+2-*buf_nb_ghost))*(_TYPE_)shear_BC_helpler_.Phi_ppty_v_;
262
263 }
264 // for all other variable in case of shear periodicity --> interpolation + jump at the z-boundary for velocity field
265 else
266 {
267 for (int i = 0; i < isz; i++)
268 for (int k = 0; k < ksz; k++)
269 for (int j = 0; j < jsz; j++, buf++)
270 dest[IJK_Field_local_template<_TYPE_,_TYPE_ARRAY_>::linear_index(ir + i, jr + j, kr + k)] = *buf;
271 }
272
273 }
274
275 delete[] send_buffer;
276 delete[] recv_buffer;
277 delete[] send_buffer_offset;
278 delete[] recv_buffer_offset;
279 delete[] send_buffer_nb_ghost;
280 delete[] recv_buffer_nb_ghost;
281}
282
283/*! @brief Exchange data over "ghost" number of cells.
284 *
285 */
286template<typename _TYPE_, typename _TYPE_ARRAY_>
288{
289 statistics().begin_count(STD_COUNTERS::virtual_swap);
291 const Domaine_IJK& dom = domaine_ref_.valeur();
292 int pe_imin_ = dom.get_neighbour_processor(0, 0);
293 int pe_imax_ = dom.get_neighbour_processor(1, 0);
294 int pe_jmin_ = dom.get_neighbour_processor(0, 1);
295 int pe_jmax_ = dom.get_neighbour_processor(1, 1);
296
297 int pe_kmin_ = dom.get_neighbour_processor(0, 2);
298 int pe_kmax_ = dom.get_neighbour_processor(1, 2);
299 int z_index = dom.get_local_slice_index(2);
300 int z_index_min = 0;
301 int z_index_max = dom.get_nprocessor_per_direction(2) - 1;
302
306 // calculation of the offset due to shear periodicity between zmin and zmax
307 double offset_i = 0.0;
309 {
310 double Lx = dom.get_domain_length(0);
312 double DX = Lx/nii ;
313 double Shear_x_time = IJK_Shear_Periodic_helpler::shear_x_time_;
314 offset_i = Shear_x_time/DX;
315 }
316 exchange_data(pe_imin_, 0, 0, 0, pe_imax_, nii, 0, 0, le_ghost, njj, nkk); /* size of block data to send */
317 exchange_data(pe_imax_, nii - le_ghost, 0, 0, pe_imin_, -le_ghost, 0, 0, le_ghost, njj, nkk);
318 exchange_data(pe_jmin_, 0, 0, 0, pe_jmax_, 0, njj, 0, nii, le_ghost, nkk);
319 exchange_data(pe_jmax_, 0, njj - le_ghost, 0, pe_jmin_, 0, -le_ghost, 0, nii, le_ghost, nkk);
320
321 if (z_index != z_index_min and IJK_Shear_Periodic_helpler::defilement_ == 1)
322 exchange_data(pe_kmin_, 0, 0, 0, pe_kmax_, 0, 0, nkk, nii , njj , le_ghost);
323 else
324 exchange_data(pe_kmin_, 0, 0, 0, pe_kmax_, 0, 0, nkk, nii, njj, le_ghost, -offset_i, shear_BC_helpler_.DU_, le_ghost);
325
326 if (z_index != z_index_max and IJK_Shear_Periodic_helpler::defilement_ == 1)
327 exchange_data(pe_kmax_, 0, 0, nkk - le_ghost, pe_kmin_, 0, 0, -le_ghost, nii, njj, le_ghost);
328 else
329 exchange_data(pe_kmax_, 0, 0, nkk - le_ghost, pe_kmin_, 0, 0, -le_ghost, nii, njj, le_ghost, offset_i, -shear_BC_helpler_.DU_, le_ghost);
330
331 // send 2D ghost corner value (12 parallepipede)
332 exchange_data(pe_imin_, 0, -le_ghost, 0 , pe_imax_, nii, -le_ghost, 0, le_ghost, le_ghost, nkk);
333 exchange_data(pe_imin_, 0, njj , 0 , pe_imax_, nii, njj , 0, le_ghost, le_ghost, nkk);
334 exchange_data(pe_imax_, nii-le_ghost, -le_ghost, 0 , pe_imin_, -le_ghost, -le_ghost, 0, le_ghost, le_ghost, nkk);
335 exchange_data(pe_imax_, nii-le_ghost, njj , 0 , pe_imin_, -le_ghost, njj , 0, le_ghost, le_ghost, nkk);
336
337 exchange_data(pe_jmin_, 0, 0, -le_ghost, pe_jmax_, 0 , njj, -le_ghost, nii, le_ghost, le_ghost);
338 exchange_data(pe_jmin_, 0, 0, nkk , pe_jmax_, 0 , njj, nkk , nii, le_ghost, le_ghost);
339 exchange_data(pe_jmax_, 0, njj-le_ghost, - le_ghost, pe_jmin_, 0, -le_ghost, -le_ghost, nii, le_ghost, le_ghost);
340 exchange_data(pe_jmax_, 0, njj-le_ghost, nkk , pe_jmin_, 0, -le_ghost, nkk , nii, le_ghost, le_ghost);
341
342 exchange_data(pe_kmin_, -le_ghost, 0 , 0, pe_kmax_, -le_ghost, 0, nkk, le_ghost, njj, le_ghost);
343 exchange_data(pe_kmin_, nii , 0 , 0, pe_kmax_, nii , 0, nkk, le_ghost, njj, le_ghost);
344 exchange_data(pe_kmax_, -le_ghost, 0 , nkk-le_ghost, pe_kmin_, -le_ghost, 0, -le_ghost, le_ghost, njj, le_ghost);
345 exchange_data(pe_kmax_, nii , 0 , nkk-le_ghost, pe_kmin_, nii , 0, -le_ghost, le_ghost, njj, le_ghost);
346
347 // send 3D ghost corner value (8 cubes)
348 exchange_data(pe_imin_, 0, -le_ghost, -le_ghost , pe_imax_, nii, -le_ghost, -le_ghost, le_ghost, le_ghost, le_ghost);
349 exchange_data(pe_imin_, 0, njj , -le_ghost , pe_imax_, nii, njj , -le_ghost, le_ghost, le_ghost, le_ghost);
350 exchange_data(pe_imin_, 0, -le_ghost, nkk , pe_imax_, nii, -le_ghost, nkk , le_ghost, le_ghost, le_ghost);
351 exchange_data(pe_imin_, 0, njj , nkk , pe_imax_, nii, njj , nkk , le_ghost, le_ghost, le_ghost);
352 exchange_data(pe_imax_, nii-le_ghost, -le_ghost, -le_ghost, pe_imin_, -le_ghost, -le_ghost, -le_ghost , le_ghost, le_ghost, le_ghost);
353 exchange_data(pe_imax_, nii-le_ghost, njj , -le_ghost, pe_imin_, -le_ghost, njj , -le_ghost , le_ghost, le_ghost, le_ghost);
354 exchange_data(pe_imax_, nii-le_ghost, -le_ghost, nkk , pe_imin_, -le_ghost, -le_ghost, nkk , le_ghost, le_ghost, le_ghost);
355 exchange_data(pe_imax_, nii-le_ghost, njj , nkk , pe_imin_, -le_ghost, njj , nkk , le_ghost, le_ghost, le_ghost);
356
357 statistics().end_count(STD_COUNTERS::virtual_swap);
358}
359
360template<typename _TYPE_, typename _TYPE_ARRAY_>
362{
363 // execute the shear-periodicity interpolation.
364 // prepare_interpolation_for_shear_periodicity has to be called before
365 _TYPE_ resu = (_TYPE_)0. ;
366 int nb_points = shear_BC_helpler_.order_interpolation_+1;
367 for (int pt = 0; pt < nb_points ; pt++)
368 {
369 resu += (_TYPE_)(shear_BC_helpler_.res_[pt]/shear_BC_helpler_.denum_[pt]*IJK_Field_local_template<_TYPE_,_TYPE_ARRAY_>::operator()(shear_BC_helpler_.send_i_real_[pt], send_j, send_k));
370 }
371
372 return resu;
373}
374template<typename _TYPE_, typename _TYPE_ARRAY_>
375void IJK_Field_template<_TYPE_, _TYPE_ARRAY_>::interpolation_for_shear_periodicity_I_sig_kappa(const int send_j, const int send_k_zmin, const int send_k_zmax, _TYPE_& Isigkappazmin, _TYPE_& Isigkappazmax)
376{
377 // execute the shear-periodicity interpolation.
378 // prepare_interpolation_for_shear_periodicity has to be called before
379 Isigkappazmin = (_TYPE_)0. ;
380 Isigkappazmax = (_TYPE_)0. ;
381 int nb_points = shear_BC_helpler_.order_interpolation_+1;
382 for (int pt = 0; pt < nb_points ; pt++)
383 {
384 Isigkappazmin += (_TYPE_)(shear_BC_helpler_.res_[pt]/shear_BC_helpler_.denum_[pt]*shear_BC_helpler_.I_sig_kappa_zmin_(shear_BC_helpler_.send_i_real_[pt], send_j, send_k_zmin));
385 Isigkappazmax += (_TYPE_)(shear_BC_helpler_.res_[pt]/shear_BC_helpler_.denum_[pt]*shear_BC_helpler_.I_sig_kappa_zmax_(shear_BC_helpler_.send_i_real_[pt], send_j, send_k_zmax));
386 }
387
388 return;
389}
390
391
392template<typename _TYPE_, typename _TYPE_ARRAY_>
393void IJK_Field_template<_TYPE_, _TYPE_ARRAY_>::redistribute_with_shear_domain_ft(const IJK_Field_double& input, double DU_perio, const int ft_extension)
394{
395 // To shift the velocity field in FT domain after redistribute operator from NS domain
396 // According to the shear periodicity condition
397
399 Domaine_IJK splitting_ns = input.get_domaine();
400 Domaine_IJK& splitting_ft = domaine_ref_.valeur();
401 double Lx = splitting_ns.get_domain_length(0);
402 int ni = input.ni();
403 double DX = Lx/ni ;
407 int last_global_k = splitting_ns.get_nb_items_global(Domaine_IJK::ELEM, 2)-1;
408
409 ArrOfDouble output_tmp;
410 output_tmp.resize_array(nii);
411 for (int k = 0; k < nkk; k++ )
412 {
413 int k_reel = k + splitting_ft.get_offset_local(2) - ft_extension;
414 if (k_reel>=0 && k_reel<= last_global_k)
415 continue;
416
417 for (int j = 0; j < njj; j++ )
418 {
419 for (int i = 0; i < nii; i++ )
420 {
421 if (k_reel<0)
422 {
424 shear_BC_helpler_.prepare_interpolation_for_shear_periodicity((int) round(istmp), istmp, ni);
425 output_tmp[i]=interpolation_for_shear_periodicity_IJK_Field(j, k)-DU_perio;
426 }
427 else if (k_reel>last_global_k)
428 {
430 shear_BC_helpler_.prepare_interpolation_for_shear_periodicity((int) round(istmp), istmp, ni);
431 output_tmp[i]=interpolation_for_shear_periodicity_IJK_Field(j, k)+DU_perio;
432 }
433 else
434 {
436 }
437 }
438 for (int i = 0; i < nii; i++ )
439 {
441 }
442 }
443 }
444 return;
445}
446
447
448
449// ajout au second membre de pressure_rhs un terme correctif
450// ce terme compense l erreur commise par l interpolation sur le bord perio z de la pression monofluide dans le cas de conditions shear periodique
451template<typename _TYPE_, typename _TYPE_ARRAY_>
453{
454 if (shear_BC_helpler_.monofluide_variable_==1)
455 {
456 const Domaine_IJK& geom = domaine_ref_.valeur();
460 const double dxk = geom.get_constant_delta(2);
461 const double dxj = geom.get_constant_delta(1);
462 const double dxi = geom.get_constant_delta(0);
463 double Shear_x_time = IJK_Shear_Periodic_helpler::shear_x_time_;
464 double offset = Shear_x_time/dxi;
465
466 // Les coeffs de la matrice de pression sont multiplies par V/h^2
467 // ici on parle d'un voisin sur dz donc h = dz
468 // coef = dx*dy*dz/dz*dz = dx*dy/dz
469 // on ajoute le terme a pressure_rhs juste avant l'appel du solveur de pression
470 // pressure_rhs a deja integre d_velocity sur le volume et divise par rho
471 // Le coeff a appliquer est donc dx*dy/dz/rho
472
473 double coeff_matrice = dxi * dxj / dxk;
474 int last_global_k = geom.get_nb_items_global(Domaine_IJK::ELEM, 2);
475
476 // EQUIVALENCE GHOST_MIN_MAX ARRAY AVEC INDICE Z REEL POUR SPLITTING_NS_
477 // I_sigma_kappa_ghost_zmin_[0] --> -ghost (derniere maille ghost)
478 // I_sigma_kappa_ghost_zmin_[ghost-1] --> -1 (premiere maille ghost)
479 // I_sigma_kappa_ghost_zmin_[ghost] --> 0 (premiere maille reelle)
480 // I_sigma_kappa_ghost_zmin_[2*ghost] --> +ghost (derniere maille reelle)
481// I_sigma_kappa_ghost_zmax_[0] --> nk-1-ghost(derniere maille reelle)
482// I_sigma_kappa_ghost_zmax_[ghost] --> nk-1 (premiere maille reelle)
483// I_sigma_kappa_ghost_zmax_[ghost+1] --> nk (premiere maille ghost)
484// I_sigma_kappa_ghost_zmax_[2*ghost] --> nk-1+ghost (derniere maille ghost)
485
486 for (int j = 0 ; j < nj; j++)
487 {
488 for (int i = 0 ; i < ni; i++)
489 {
490 shear_BC_helpler_.prepare_interpolation_for_shear_periodicity((int) round((double) i + offset), ((double) i + offset), ni);
491
492 // for k=0 --> pression voisine problematique en k=-1 (qui renvoie a une interpolation sur k=nk-1)
493 // I_sigma_kappa interpole en k=nk-1
494 // I_sigma_kappa reel en k=-1
495 // for k=0 (z_index_min --> + offset)
496 if(geom.get_offset_local(2)==0)
497 {
498 double rho_minus_1 = shear_BC_helpler_.Phi_ppty_l_*shear_BC_helpler_.indicatrice_ghost_zmin_(i,j,1)+shear_BC_helpler_.Phi_ppty_v_*(1.-shear_BC_helpler_.indicatrice_ghost_zmin_(i,j,1));
499 double rho_0 = shear_BC_helpler_.Phi_ppty_l_*shear_BC_helpler_.indicatrice_ghost_zmin_(i,j,2)+shear_BC_helpler_.Phi_ppty_v_*(1.-shear_BC_helpler_.indicatrice_ghost_zmin_(i,j,2));
500 double rho;
501 if (shear_BC_helpler_.use_inv_rho_in_pressure_solver_==1.)
502 {
503 rho =2./((1./rho_minus_1)+(1./rho_0));
504 }
505 else
506 {
507 rho =(rho_minus_1+rho_0)/2.;
508 }
509 _TYPE_ interpIsigkappazmin = 0.;
510 _TYPE_ interpIsigkappazmax = 0.;
511 interpolation_for_shear_periodicity_I_sig_kappa(j, 1, 1, interpIsigkappazmin, interpIsigkappazmax);
512 _TYPE_ erreur = interpIsigkappazmax-(_TYPE_)shear_BC_helpler_.I_sig_kappa_zmin_(i , j , 1);
513 resu(i,j,0)+=(coeff_matrice/rho)*erreur;
514 }
515
516 // for k=nk-1 --> pression voisine problematique en k=nk (qui renvoie a une interpolation sur k=0)
517 // I_sigma_kappa interpole en k=0
518 // I_sigma_kappa reel en k=nk
519 // for k=nk-1 (z_index_max --> - offset)
520 if(geom.get_offset_local(2)+nk==last_global_k)
521 {
522 double rho_nk_plus_1 = shear_BC_helpler_.Phi_ppty_l_*shear_BC_helpler_.indicatrice_ghost_zmax_(i,j,2)+shear_BC_helpler_.Phi_ppty_v_*(1.-shear_BC_helpler_.indicatrice_ghost_zmax_(i,j,2));
523 double rho_nk = shear_BC_helpler_.Phi_ppty_l_*shear_BC_helpler_.indicatrice_ghost_zmax_(i,j,1)+shear_BC_helpler_.Phi_ppty_v_*(1.-shear_BC_helpler_.indicatrice_ghost_zmax_(i,j,1));
524 double rho;
525 if (shear_BC_helpler_.use_inv_rho_in_pressure_solver_==1.)
526 {
527 rho =2./((1./rho_nk_plus_1)+(1./rho_nk));
528 }
529 else
530 {
531 rho =(rho_nk_plus_1+rho_nk)/2.;
532 }
533 _TYPE_ interpIsigkappazmin= 0.;
534 _TYPE_ interpIsigkappazmax= 0.;
535 interpolation_for_shear_periodicity_I_sig_kappa(j, 2, 2, interpIsigkappazmin, interpIsigkappazmax);
536 _TYPE_ erreur = interpIsigkappazmin-(_TYPE_)shear_BC_helpler_.I_sig_kappa_zmax_(i , j , 2);
537 resu(i,j,nk-1)+=(coeff_matrice/rho)*erreur;
538 }
539 }
540 }
541 }
542}
543
544// Initializes the field and allocates memory
545// geom: reference to the geometry of the IJK mesh and how the mesh is split on processors.
546// The field stores a reference to this Domaine_IJK object so do not delete it.
547// loc: localisation of the field (elements, nodes, faces in direction i, j, or k)
548// The number of "real" items in each direction (returned by the ni(), nj() or nk() method) is obtained from
549// the Domaine_IJK object. Warning: on a processor that is in the middle of the mesh, the nodes on the
550// right of the rightmost real element are not real, they are virtual, values are copied from the neigbour
551// processor.
552// ghost_size: number of ghost layers to allocate. When an exchange of ghost cells data is requested, a smaller
553// number of layers can be requested if all layers are not needed by the following operations
554// additional_k_layers: allocates more layers of cells in the k direction for use with the
555// shift_k_origin() method (optimization trick used by the temporally blocked algorithms in the multigrid
556// solver
557// nb_compo: number of components of the field. Warning: you cannot allocate the velocity field at faces
558// with nb_compo=3: numbers of faces in each direction differ.
559// Also, components are not grouped by node but stored by layers in k. nb_compo>1 is essentially used
560// in the multigrid solver to optimize memory accesses to the components of the matrix.
561template<typename _TYPE_, typename _TYPE_ARRAY_>
562void IJK_Field_template<_TYPE_, _TYPE_ARRAY_>::allocate(const Domaine_IJK& geom, Domaine_IJK::Localisation loc, int ghost_size, int additional_k_layers, int ncompo, const Nom& name, bool external_storage, int type, double phy_ppty_v, double phy_ppty_l, int use_inv_rho_in_pressure_solver)
563{
564 this->nommer(name);
565 const int ni_local = geom.get_nb_items_local(loc, 0);
566 const int nj_local = geom.get_nb_items_local(loc, 1);
567 const int nk_local = geom.get_nb_items_local(loc, 2);
568 IJK_Field_local_template<_TYPE_, _TYPE_ARRAY_>::allocate(ni_local, nj_local, nk_local, ghost_size, additional_k_layers, ncompo);
569 shear_BC_helpler_.allocate(ni_local, nj_local, nk_local, ghost_size, ncompo, type, phy_ppty_v, phy_ppty_l, use_inv_rho_in_pressure_solver);
570 domaine_ref_ = geom;
571 localisation_ = loc;
573}
574
575template<typename _TYPE_, typename _TYPE_ARRAY_>
576void IJK_Field_template<_TYPE_, _TYPE_ARRAY_>::dumplata_scalar(const char *filename, int step) const
577{
579 SFichier master_file;
580 Nom prefix = Nom(filename) + Nom(".") + Nom(step) + Nom(".");
581 Nom fd = prefix + this->le_nom();
582 IJK_Striped_Writer striped_writer;
583 const Size_t n = striped_writer.write_data_template<float,_TYPE_,_TYPE_ARRAY_>(fd, *this);
585 {
586 master_file.ouvrir(filename, ios::app);
587 Nom loc;
589 loc = "ELEM";
590 else
591 loc = "SOM";
592 const Nom& geomname = get_domaine().le_nom();
593
594 Nom path, base_name;
595 split_path_filename(fd, path, base_name);
596 master_file << "Champ " << this->le_nom() << " "<< base_name << " geometrie=" << geomname;
597#ifdef INT_is_64_
598 master_file << " file_offset=6";
599#endif
600 master_file << " size=" << (int)n << " localisation=" << loc << " composantes=1" << finl;
601 }
603}
604#endif /* IJK_Field_template_TPP_H */
This class encapsulates all the information related to the eulerian mesh for TrioIJK.
Definition Domaine_IJK.h:47
int get_offset_local(int direction) const
Returns the local offset in requested direction.
int get_neighbour_processor(int previous_or_next, int direction) const
Returns the index of the requested neighbour processor (-1 if no neighbour).
double get_domain_length(int direction) const
Returns the length of the entire domain in requested direction.
int get_nprocessor_per_direction(int direction) const
Returns the number of slices in the given 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_nb_items_global(Localisation loc, int direction) const
Returns the number of local items (on this processor) for the given localisation in the requested dir...
int get_local_slice_index(int direction) const
Returns the position of the local subdomain in the requested direction.
Localisation
Localisation sub class.
Definition Domaine_IJK.h:53
const Nom & le_nom() const override
Renvoie le nom du champ.
void nommer(const Nom &) override
Donne un nom au champ.
: This class describes a scalar field in an ijk box without any parallel information.
void allocate(int ni, int nj, int nk, int ghosts, int additional_k_layers=0, int nb_compo=1, bool external_storage=false)
int linear_index(int i, int j, int k) const
_TYPE_ & operator()(int i, int j, int k)
IJK_Shear_Periodic_helpler shear_BC_helpler_
static int alloc_counter_
To monitor how many field allocations we perform.
void ajouter_second_membre_shear_perio(IJK_Field_double &resu)
void allocate(const Domaine_IJK &d, Domaine_IJK::Localisation l, int ghost_size, int additional_k_layers=0, int nb_compo=1, const Nom &name=Nom(), bool external_storage=false, int monofluide=0, double rov=0., double rol=0., int use_inv_rho_in_pressure_solver=0)
void echange_espace_virtuel(int ghost)
Exchange data over "ghost" number of cells.
Domaine_IJK::Localisation get_localisation() const
Domaine_IJK::Localisation localisation_
void interpolation_for_shear_periodicity_I_sig_kappa(const int send_j, const int send_k_zmin, const int send_k_zmax, _TYPE_ &Isigkappazmin, _TYPE_ &Isigkappazmax)
void redistribute_with_shear_domain_ft(const IJK_Field_double &input, double DU_perio, const int ft_extension)
void exchange_data(int pe_imin_, int is, int js, int ks, int pe_imax_, int ir, int jr, int kr, int isz, int jsz, int ksz, double offset_i=0., double jump_i=0., int nb_ghost=0)
_TYPE_ interpolation_for_shear_periodicity_IJK_Field(const int send_j, const int send_k)
virtual void dumplata_scalar(const char *filename, int step) const
const Domaine_IJK & get_domaine() const
: class IJK_Striped_Writer
Size_t write_data_template(const char *filename, const IJK_Field_template< _TYPE_, _TYPE_ARRAY_ > &f)
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
static void barrier()
Synchronise tous les processeurs du groupe courant (attend que tous les processeurs soient arrives a ...
Definition Process.cpp:136
static int me()
renvoie mon rang dans le groupe de communication courant.
Definition Process.cpp:125
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
Definition Process.cpp:86
Cette classe est a la classe C++ ofstream ce que la classe Sortie est a la classe C++ ostream Elle re...
Definition SFichier.h:27
virtual int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::out)
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)