TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Matrice_Grossiere.cpp
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#include <Matrice_Grossiere.h>
17#include <Matrice_Morse_Sym.h>
18
19void Matrice_Grossiere::add_virt_bloc(int pe, int& count, int imin, int jmin, int kmin,
20 int imax, int jmax, int kmax, ArrOfInt& virt_blocs)
21{
22 const int ni = renum_.dimension(2) - 2;
23 const int nj = renum_.dimension(1) - 2;
24 const int nk = renum_.dimension(0) - 2;
25 if (pe == Process::me())
26 {
27 // Frontiere periodique avec cote oppose sur meme processeur
28 for (int k = kmin; k < kmax; k++)
29 for (int j = jmin; j < jmax; j++)
30 for (int i = imin; i < imax; i++)
31 {
32 int ii = (i + ni ) % ni;
33 int jj = (j + nj) % nj;
34 int kk = (k + nk) % nk;
35 renum(i, j, k) = renum(ii, jj, kk);
36 }
37
38 }
39 else
40 {
41 // cas ou la frontiere nest pas des deux cotes sur le meme proc...
42
43 virt_blocs.append_array(count);
44
45 for (int k = kmin; k < kmax; k++)
46 for (int j = jmin; j < jmax; j++)
47 for (int i = imin; i < imax; i++)
48 {
49 {
50 int index = count++;
51 renum(i,j,k) = index;
52 }
53 }
54
55 virt_blocs.append_array(count); // end of virtual bloc of data
56 }
57}
58
59void Matrice_Grossiere::add_dist_bloc(int pe, int imin, int jmin, int kmin,
60 int imax, int jmax, int kmax, ArrOfInt& items_to_send)
61{
62 if (pe == Process::me())
63 return;
64
65 for (int k = kmin; k < kmax; k++)
66 for (int j = jmin; j < jmax; j++)
67 for (int i = imin; i < imax; i++)
68 {
69 int index=renum(i, j, k);
70 assert(index >= 0);
71 items_to_send.append_array(index);
72 }
73}
74
75void Matrice_Grossiere::interpolation_for_shear_periodicity(const int i, const int send_i /*offset2*/, const double istmp/*istmp*/,
76 const int real_size_i /*ni*/, const double shear_perio)
77{
78 // renvoi la valeur interpolee pour la condition de shear-periodicity
79 const int nb_points = order_interpolation_poisson_solver_+1;
80 ArrOfInt x;
81 ArrOfDouble a;
82 x.resize_array(nb_points);
83 a.resize_array(nb_points);
84
85 if (nb_points==2)
86 {
87 x[0] = (int) floor(istmp);
88 x[1] = (int) floor(istmp)+1;
89 }
90 else if(nb_points==3)
91 {
92 x[0] = send_i-1;
93 x[1] = send_i;
94 x[2] = send_i+1;
95 }
96 else if(nb_points==5)
97 {
98 x[0] = send_i-2;
99 x[1] = send_i-1;
100 x[2] = send_i;
101 x[3] = send_i+1;
102 x[4] = send_i+2;
103 }
104 else if(nb_points==7)
105 {
106 x[0] = send_i-3;
107 x[1] = send_i-2;
108 x[2] = send_i-1;
109 x[3] = send_i;
110 x[4] = send_i+1;
111 x[5] = send_i+2;
112 x[6] = send_i+3;
113 }
114
115
116 for (int pt = 0; pt < nb_points ; pt++)
117 {
118 double denum = 1.;
119 for (int pt_autre = 0; pt_autre < nb_points ; pt_autre++)
120 {
121 if (pt_autre!=pt)
122 denum *= (x[pt] - x[pt_autre]);
123 }
124 a[pt]=1./denum;
125 }
126
127
128 for (int pt = 0; pt < nb_points ; pt++)
129 {
130 if (shear_perio>0.)
131 {
132 ponderation_shear_p_[pt] = a[pt];
133 }
134 else
135 {
136 ponderation_shear_m_[pt] = a[pt];
137 }
138 for (int pt_autre = 0; pt_autre < nb_points ; pt_autre++)
139 {
140 if (pt_autre!=pt)
141 {
142 if (shear_perio>0.)
143 {
144 ponderation_shear_p_[pt] *= (istmp - x[pt_autre]);
145 }
146 else
147 {
148 ponderation_shear_m_[pt] *= (istmp - x[pt_autre]);
149 }
150 }
151 }
152 }
153
154 for (int pt = 0; pt < nb_points ; pt++)
155 {
156 if (shear_perio>0.)
157 {
158 ii_p_[pt] = (i + real_size_i + x[pt] % real_size_i + real_size_i) % real_size_i;
159 }
160 else if (shear_perio<0.)
161 {
162 ii_m_[pt] = (i + real_size_i + x[pt] % real_size_i + real_size_i) % real_size_i;
163 }
164 }
165
166 return;
167
168}
169
170
171/*! @brief ajoute deux coefficients diagonal/extra-diagonal a la matrice
172 *
173 */
174void Matrice_Grossiere::ajoute_coeff(int i, int j, int k,
175 int i_voisin, int j_voisin, int k_voisin,
176 const double coeff, const double shear_perio)
177{
178 const int indice=renum(i, j, k);
179 const int indice_voisin = renum(i_voisin, j_voisin, k_voisin);
180
181 const bool voisin_shear = !(shear_perio == 0.);
182
183 // coefficient extra diagonal (- surface_face / distance_centres_elements)
184 const double x = -coeff;
185 if (indice_voisin > indice)
186 {
187 // Coefficient dans la partie triangulaire superieure, a stocker.
188 const int nreels = coeff_diag_.size_array();
189 if (indice_voisin < nreels)
190 {
191 // Element reel
192
193 if(voisin_shear)
194 {
195 if(shear_perio>0.)
196 {
197 for (int interp = 0; interp < order_interpolation_poisson_solver_+1; interp++)
198 {
199 voisins_[indice].add(indice_voisin - i + ii_p_[interp]);
200 coeffs_[indice].add(x*ponderation_shear_p_[interp]);
201 }
202 }
203 else if (shear_perio<0.)
204 {
205 for (int interp = 0; interp < order_interpolation_poisson_solver_+1; interp++)
206 {
207 voisins_[indice].add(indice_voisin - i + ii_m_[interp]);
208 coeffs_[indice].add(x*ponderation_shear_m_[interp]);
209 }
210 }
211 }
212 else
213 {
214 voisins_[indice].add(indice_voisin);
215 coeffs_[indice].add(x);
216 }
217 }
218 else
219 {
220 // Element virtuel
221
222 if(voisin_shear)
223 {
224 if(shear_perio>0.)
225 {
226 for (int interp = 0; interp < order_interpolation_poisson_solver_+1; interp++)
227 {
228 voisins_virt_[indice].add(indice_voisin - i + ii_p_[interp] - nreels);
229 coeffs_virt_[indice].add(x*ponderation_shear_p_[interp]);
230 }
231 }
232 else if(shear_perio<0.)
233 {
234 for (int interp = 0; interp < order_interpolation_poisson_solver_+1; interp++)
235 {
236 voisins_virt_[indice].add(indice_voisin - i + ii_m_[interp] - nreels);
237 coeffs_virt_[indice].add(x*ponderation_shear_m_[interp]);
238 }
239 }
240 }
241 else
242 {
243 voisins_virt_[indice].add(indice_voisin - nreels);
244 coeffs_virt_[indice].add(x);
245 }
246
247 }
248 }
249
250 // Contribution a la diagonale
251 coeff_diag_[indice] -= x;
252}
253
254/*! @brief ajoute deux coefficients diagonal/extra-diagonal a la matrice
255 *
256 */
257void Matrice_Grossiere::ajoute_coeff2(int i, int j, int k,
258 int i_voisin, int j_voisin, int k_voisin,
259 const double coeff, const double shear_perio)
260{
261 const int indice=renum(i, j, k);
262 const int indice_voisin = renum(i_voisin, j_voisin, k_voisin);
263
264 const bool voisin_shear = !(shear_perio == 0.);
265
266 // coefficient extra diagonal (- surface_face / distance_centres_elements)
267 const double x = -coeff;
268
269 const int nreels = coeff_diag_.size_array();
270 if ( (0 <= indice_voisin) && ( indice_voisin < nreels ) )
271 {
272 // Element reel
273
274 if(voisin_shear)
275 {
276 if(shear_perio>0.)
277 {
278 for (int interp = 0; interp < order_interpolation_poisson_solver_+1; interp++)
279 {
280 voisins_2_[indice].add(indice_voisin - i + ii_p_[interp]);
281 coeffs_2_[indice].add(x*ponderation_shear_p_[interp]);
282 }
283 }
284 else if (shear_perio<0.)
285 {
286 for (int interp = 0; interp < order_interpolation_poisson_solver_+1; interp++)
287 {
288 voisins_2_[indice].add( indice_voisin - i + ii_m_[interp] );
289 coeffs_2_[indice].add(x*ponderation_shear_p_[interp]);
290 }
291 }
292 }
293 else
294 {
295 voisins_2_[indice].add(indice_voisin);
296 coeffs_2_[indice].add(x);
297 }
298 }
299 else
300 {
301 // Element virtuel
302
303 if(voisin_shear)
304 {
305 if(shear_perio>0.)
306 {
307 for (int interp = 0; interp < order_interpolation_poisson_solver_+1; interp++)
308 {
309 voisins_virt_2_[indice].add( ((indice_voisin%nreels)+nreels)%nreels - i + ii_p_[interp] );
310 coeffs_virt_2_[indice].add(x*ponderation_shear_p_[interp]);
311 }
312 }
313 else if(shear_perio<0.)
314 {
315 for (int interp = 0; interp < order_interpolation_poisson_solver_+1; interp++)
316 {
317 voisins_virt_2_[indice].add( ((indice_voisin%nreels)+nreels)%nreels - i + ii_m_[interp]);
318 coeffs_virt_2_[indice].add(x*ponderation_shear_p_[interp]);
319 }
320 }
321 }
322 else
323 {
324 voisins_virt_2_[indice].add(((indice_voisin%nreels)+nreels)%nreels);
325 coeffs_virt_2_[indice].add(x);
326 }
327
328 }
329
330 // Contribution a la diagonale
331 coeff_diag_[indice] -= x;
332}
333
334void Matrice_Grossiere::ajoute_coeff(int i, int j, int k,
335 int i_voisin, int j_voisin, int k_voisin,
336 const double coeff)
337{
338 const int indice=renum(i, j, k);
339 const int indice_voisin = renum(i_voisin, j_voisin, k_voisin);
340
341 // coefficient extra diagonal (- surface_face / distance_centres_elements)
342 const double x = -coeff;
343 if (indice_voisin > indice)
344 {
345 // Coefficient dans la partie triangulaire superieure, a stocker.
346 const int nreels = coeff_diag_.size_array();
347 if (indice_voisin < nreels)
348 {
349 voisins_[indice].add(indice_voisin);
350 coeffs_[indice].add(x);
351 }
352 else
353 {
354 voisins_virt_[indice].add(indice_voisin - nreels);
355 coeffs_virt_[indice].add(x);
356 }
357 }
358
359 // Contribution a la diagonale
360 coeff_diag_[indice] -= x;
361}
362
363void Matrice_Grossiere::ajoute_coeff2(int i, int j, int k,
364 int i_voisin, int j_voisin, int k_voisin,
365 const double coeff)
366{
367 const int indice=renum(i, j, k);
368 const int indice_voisin = renum(i_voisin, j_voisin, k_voisin);
369
370 // coefficient extra diagonal (- surface_face / distance_centres_elements)
371 const double x = -coeff;
372
373 const int nreels = coeff_diag_.size_array();
374 if ( (0 <= indice_voisin) && ( indice_voisin < nreels ) )
375 {
376 voisins_2_[indice].add(indice_voisin);
377 coeffs_2_[indice].add(x);
378 }
379 else
380 {
381 voisins_virt_2_[indice].add(((indice_voisin%nreels)+nreels)%nreels);
382 coeffs_virt_2_[indice].add(x);
383 }
384
385 // Contribution a la diagonale
386 coeff_diag_[indice] -= x;
387
388
389}
390
391
392
ArrOfDouble ponderation_shear_p_
const int & renum(int i, int j, int k) const
void interpolation_for_shear_periodicity(const int i, const int send_i, const double istmp, const int real_size_i, const double shear_perio)
void ajoute_coeff(int i, int j, int k, int i_voisin, int j_voisin, int k_voisin, const double coeff, const double shear_perio)
ajoute deux coefficients diagonal/extra-diagonal a la matrice
ArrOfDouble ponderation_shear_m_
void ajoute_coeff2(int i, int j, int k, int i_voisin, int j_voisin, int k_voisin, const double coeff, const double shear_perio)
ajoute deux coefficients diagonal/extra-diagonal a la matrice
void add_dist_bloc(int pe, int imin, int jmin, int kmin, int imax, int jmax, int kmax, ArrOfInt &items_to_send)
void add_virt_bloc(int pe, int &count, int imin, int jmin, int kmin, int imax, int jmax, int kmax, ArrOfInt &virt_blocs)
static int me()
renvoie mon rang dans le groupe de communication courant.
Definition Process.cpp:125
void append_array(_TYPE_ valeur)
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)