1 /*============================================================================
2 * Functions handling periodicity.
3 *============================================================================*/
4
5 /*
6 This file is part of Code_Saturne, a general-purpose CFD tool.
7
8 Copyright (C) 1998-2021 EDF S.A.
9
10 This program is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free Software
12 Foundation; either version 2 of the License, or (at your option) any later
13 version.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
18 details.
19
20 You should have received a copy of the GNU General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
22 Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 */
24
25 /*----------------------------------------------------------------------------*/
26
27 #include "cs_defs.h"
28
29 /*----------------------------------------------------------------------------
30 * Standard C library headers
31 *----------------------------------------------------------------------------*/
32
33 #include <assert.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <math.h>
37 #include <stdarg.h>
38 #include <string.h>
39
40 /*----------------------------------------------------------------------------
41 * Local headers
42 *----------------------------------------------------------------------------*/
43
44 #include "bft_mem.h"
45 #include "bft_printf.h"
46
47 #include "fvm_periodicity.h"
48
49 #include "cs_base.h"
50 #include "cs_halo.h"
51 #include "cs_interface.h"
52 #include "cs_mesh.h"
53 #include "cs_prototypes.h"
54 #include "cs_timer.h"
55
56 /*----------------------------------------------------------------------------
57 * Header for the current file
58 *----------------------------------------------------------------------------*/
59
60 #include "cs_halo_perio.h"
61
62 /*----------------------------------------------------------------------------*/
63
64 BEGIN_C_DECLS
65
66 /*! \cond DOXYGEN_SHOULD_SKIP_THIS */
67
68 /*=============================================================================
69 * Local Macro definitions
70 *============================================================================*/
71
72 /*=============================================================================
73 * Local Structure definitions
74 *============================================================================*/
75
76 /* Structure used for building mesh structure */
77 /* ------------------------------------------ */
78
79 typedef struct {
80
81 /* Periodic features */
82
83 cs_lnum_t *per_face_idx; /* Index on periodicity for per_face_lst */
84
85 cs_lnum_t *per_face_lst; /* Periodic faces list. For each couple,
86 we have the local face number on local rank
87 and the local face number on distant rank */
88
89 cs_lnum_t *per_rank_lst; /* Remote ranks list. For each couple,
90 we have the distant rank number. Exists
91 only in case of parallelism. */
92
93 } _perio_mesh_builder_t ;
94
95 /*============================================================================
96 * Static global variables
97 *============================================================================*/
98
99 /* Table giving the Reynolds stress component for [i][j] */
100
101 /* Warning: old fashion to store Rij */
102 static const int _rij[3][3] = {{0, 3, 4},
103 {3, 1, 5},
104 {4, 5, 2}};
105
106 static const int _symt[3][3] = {{0, 3, 5},
107 {3, 1, 4},
108 {5, 4, 2}};
109
110 /*============================================================================
111 * Private function definitions
112 *============================================================================*/
113
114 /*----------------------------------------------------------------------------
115 * Compute a matrix/vector product to apply a transformation to a given
116 * vector.
117 *
118 * parameters:
119 * matrix[3][4] --> matrix of the transformation in homogeneous coord.
120 * last line = [0; 0; 0; 1] (Not used here)
121 * in_cell_id --> cell_id of the parent cell.
122 * out_cell_id --> cell_id of the generated cell.
123 * xyz <-> array of coordinates
124 *----------------------------------------------------------------------------*/
125
126 static void
_apply_vector_transfo(cs_real_t matrix[3][4],cs_lnum_t in_cell_id,cs_lnum_t out_cell_id,cs_real_t * xyz)127 _apply_vector_transfo(cs_real_t matrix[3][4],
128 cs_lnum_t in_cell_id,
129 cs_lnum_t out_cell_id,
130 cs_real_t *xyz)
131 {
132 cs_lnum_t i, j;
133
134 cs_real_t xyz_a[3 + 1];
135 cs_real_t xyz_b[3];
136
137 /* Define the cell center in homogeneous coordinates before
138 transformation */
139
140 for (j = 0; j < 3; j++)
141 xyz_a[j] = xyz[in_cell_id*3 + j];
142 xyz_a[3] = 1;
143
144 /* Initialize output */
145
146 for (i = 0; i < 3; i++)
147 xyz_b[i] = 0.;
148
149 for (i = 0; i < 3; i++)
150 for (j = 0; j < 4; j++)
151 xyz_b[i] += matrix[i][j]*xyz_a[j];
152
153 /* Store updated cell center */
154
155 for (j = 0; j < 3; j++)
156 xyz[out_cell_id*3 + j] = xyz_b[j];
157
158 }
159
160 /*----------------------------------------------------------------------------
161 * Compute a matrix/vector product to apply a transformation to a given
162 * interleaved vector.
163 *
164 * parameters:
165 * matrix[3][4] --> matrix of the transformation in homogeneous coord.
166 * last line = [0; 0; 0; 1] (Not used here)
167 * xyz <-> array of coordinates
168 *----------------------------------------------------------------------------*/
169
170 static void
_apply_vector_rotation(cs_real_t matrix[3][4],cs_real_t * xyz)171 _apply_vector_rotation(cs_real_t matrix[3][4],
172 cs_real_t *xyz)
173 {
174 cs_lnum_t i;
175
176 cs_real_t t[3];
177 for (i = 0; i < 3; i++)
178 t[i] = xyz[i];
179
180 /* Initialize output */
181
182 for (i = 0; i < 3; i++)
183 xyz[i] = matrix[i][0]*t[0] + matrix[i][1]*t[1] + matrix[i][2]*t[2];
184
185 }
186
187 /*----------------------------------------------------------------------------
188 * Compute a matrix * tensor * Tmatrix product to apply a rotation to a
189 * given tensor
190 *
191 * parameters:
192 * matrix[3][4] --> transformation matrix in homogeneous coords.
193 * last line = [0; 0; 0; 1] (Not used here)
194 * in11, in12, in13 --> incoming first line of the tensor
195 * in21, in22, in23 --> incoming second line of the tensor
196 * in31, in32, in33 --> incoming third line of the tensor
197 * out11, out12, out13 <-- pointer to the first line of the output
198 * out21, out22, out23 <-- pointer to the second line of the output
199 * out31, out32, out33 <-- pointer to the third line of the output
200 *----------------------------------------------------------------------------*/
201
202 static void
_apply_tensor_rotation_ni(cs_real_t matrix[3][4],cs_real_t in11,cs_real_t in12,cs_real_t in13,cs_real_t in21,cs_real_t in22,cs_real_t in23,cs_real_t in31,cs_real_t in32,cs_real_t in33,cs_real_t * out11,cs_real_t * out12,cs_real_t * out13,cs_real_t * out21,cs_real_t * out22,cs_real_t * out23,cs_real_t * out31,cs_real_t * out32,cs_real_t * out33)203 _apply_tensor_rotation_ni(cs_real_t matrix[3][4],
204 cs_real_t in11,
205 cs_real_t in12,
206 cs_real_t in13,
207 cs_real_t in21,
208 cs_real_t in22,
209 cs_real_t in23,
210 cs_real_t in31,
211 cs_real_t in32,
212 cs_real_t in33,
213 cs_real_t *out11,
214 cs_real_t *out12,
215 cs_real_t *out13,
216 cs_real_t *out21,
217 cs_real_t *out22,
218 cs_real_t *out23,
219 cs_real_t *out31,
220 cs_real_t *out32,
221 cs_real_t *out33)
222 {
223 cs_lnum_t i, j, k;
224 cs_real_t tensorA[3][3], tensorB[3][3];
225
226 tensorA[0][0] = matrix[0][0]*in11 + matrix[0][1]*in12 + matrix[0][2]*in13;
227 tensorA[0][1] = matrix[1][0]*in11 + matrix[1][1]*in12 + matrix[1][2]*in13;
228 tensorA[0][2] = matrix[2][0]*in11 + matrix[2][1]*in12 + matrix[2][2]*in13;
229
230 tensorA[1][0] = matrix[0][0]*in21 + matrix[0][1]*in22 + matrix[0][2]*in23;
231 tensorA[1][1] = matrix[1][0]*in21 + matrix[1][1]*in22 + matrix[1][2]*in23;
232 tensorA[1][2] = matrix[2][0]*in21 + matrix[2][1]*in22 + matrix[2][2]*in23;
233
234 tensorA[2][0] = matrix[0][0]*in31 + matrix[0][1]*in32 + matrix[0][2]*in33;
235 tensorA[2][1] = matrix[1][0]*in31 + matrix[1][1]*in32 + matrix[1][2]*in33;
236 tensorA[2][2] = matrix[2][0]*in31 + matrix[2][1]*in32 + matrix[2][2]*in33;
237
238 for (i = 0; i < 3; i++) {
239 for (j = 0; j < 3; j++) {
240 tensorB[i][j] = 0.;
241 for (k = 0; k < 3; k++)
242 tensorB[i][j] += matrix[i][k] * tensorA[k][j];
243 }
244 }
245
246 *out11 = tensorB[0][0];
247 *out22 = tensorB[1][1];
248 *out33 = tensorB[2][2];
249
250 if (out12 != NULL) {
251 *out12 = tensorB[0][1];
252 *out13 = tensorB[0][2];
253 *out21 = tensorB[1][0];
254 *out23 = tensorB[1][2];
255 *out31 = tensorB[2][0];
256 *out32 = tensorB[2][1];
257 }
258
259 }
260
261 /*----------------------------------------------------------------------------
262 * Compute a matrix * tensor * Tmatrix product to apply a rotation to a
263 * given interleaved tensor
264 *
265 * parameters:
266 * matrix[3][4] --> transformation matrix in homogeneous coords.
267 * last line = [0; 0; 0; 1] (Not used here)
268 * tensor <-> incoming 3x3 tensor
269 *----------------------------------------------------------------------------*/
270
271 static void
_apply_tensor_rotation(cs_real_t matrix[3][4],cs_real_t * tensor)272 _apply_tensor_rotation(cs_real_t matrix[3][4],
273 cs_real_t *tensor)
274 {
275 cs_lnum_t i, j, k, l;
276
277 cs_real_t t[3][3];
278
279 for (k = 0; k < 3; k++) {
280 for (j = 0; j < 3; j++) {
281 t[k][j] = 0.;
282 for (l = 0; l < 3; l++)
283 t[k][j] += matrix[j][l] * tensor[k*3+l];
284 }
285 }
286
287 for (i = 0; i < 3; i++) {
288 for (j = 0; j < 3; j++) {
289 tensor[i*3+j] = 0.;
290 for (k = 0; k < 3; k++)
291 tensor[i*3+j] += matrix[i][k] * t[k][j];
292 }
293 }
294
295 }
296
297 /*----------------------------------------------------------------------------
298 * Compute a matrix * tensor * Tmatrix product to apply a rotation to a
299 * given symmetric interleaved tensor
300 *
301 * parameters:
302 * matrix[3][4] --> transformation matrix in homogeneous coords.
303 * last line = [0; 0; 0; 1] (Not used here)
304 * tensor <-> incoming (6) symmetric tensor
305 *----------------------------------------------------------------------------*/
306
307 static void
_apply_sym_tensor_rotation(cs_real_t matrix[3][4],cs_real_t * tensor)308 _apply_sym_tensor_rotation(cs_real_t matrix[3][4],
309 cs_real_t *tensor)
310 {
311 cs_lnum_t i, j, k, l;
312
313 cs_real_t t[3][3];
314 cs_real_t t0[3][3];
315
316 t0[0][0] = tensor[0];
317 t0[1][1] = tensor[1];
318 t0[2][2] = tensor[2];
319 t0[0][1] = tensor[3];
320 t0[1][0] = tensor[3];
321 t0[1][2] = tensor[4];
322 t0[2][1] = tensor[4];
323 t0[0][2] = tensor[5];
324 t0[2][0] = tensor[5];
325
326 for (k = 0; k < 3; k++) {
327 for (j = 0; j < 3; j++) {
328 t[k][j] = 0.;
329 for (l = 0; l < 3; l++)
330 t[k][j] += matrix[j][l] * t0[k][l];
331 }
332 }
333
334 for (i = 0; i < 3; i++) {
335 for (j = 0; j < 3; j++) {
336 t0[i][j] = 0.;
337 for (k = 0; k < 3; k++)
338 t0[i][j] += matrix[i][k] * t[k][j];
339 }
340 }
341
342 tensor[0] = t0[0][0];
343 tensor[1] = t0[1][1];
344 tensor[2] = t0[2][2];
345 tensor[3] = t0[0][1];
346 tensor[3] = t0[1][0];
347 tensor[4] = t0[2][1];
348 tensor[5] = t0[2][0];
349
350 }
351
352 /*----------------------------------------------------------------------------
353 * Compute the rotation of a third-order symmetric interleaved tensor
354 * (18 components)
355 * TENSOR_ijk = M_ip M_jq M_kr TENSOR_pqr
356 *
357 * WARNING: old fashion to store Rij (11, 22, 33, 12, 13, 23)
358 *
359 * parameters:
360 * matrix[3][4] --> transformation matrix in homogeneous coords.
361 * last line = [0; 0; 0; 1] (Not used here)
362 * tensor <-> incoming 3x3x3 tensor
363 * (in fact 3x6 due to symmetry)
364 *----------------------------------------------------------------------------*/
365
366 static void
_apply_tensor3sym_rotation_old(cs_real_t matrix[3][4],cs_real_t * tensor)367 _apply_tensor3sym_rotation_old(cs_real_t matrix[3][4],
368 cs_real_t *tensor)
369 {
370 cs_lnum_t i, j, k, p, q, r;
371
372 cs_real_t t1[3][3][3], t2[3][3][3];
373
374 for (p = 0; p < 3; p++) {
375 for (q = 0; q < 3; q++) {
376 for (k = 0; k < 3; k++) {
377 t1[p][q][k] = 0.;
378 for (r = 0; r < 3; r++)
379 t1[p][q][k] += matrix[k][r] * tensor[3*_rij[p][q] + r];
380 }
381 }
382 }
383
384 for (i = 0; i < 3; i++) {
385 for (j = 0; j < 3; j++) {
386 for (k = 0; k < 3; k++) {
387 t2[i][j][k] = 0.;
388 for (p = 0; p < 3; p++) {
389 for (q = 0; q < 3; q++)
390 t2[i][j][k] += matrix[i][p] * matrix[j][q] * t1[p][q][k];
391 }
392 }
393 }
394 }
395
396 /* Output */
397
398 for (i = 0; i < 3; i++) {
399 for (j = 0; j < 3; j++) {
400 for (k = 0; k < 3; k++)
401 tensor[3*_rij[i][j] + k] = t2[i][j][k];
402 }
403 }
404
405 }
406
407 /*----------------------------------------------------------------------------
408 * Compute the rotation of a third-order symmetric interleaved tensor
409 * (18 components)
410 * TENSOR_ijk = M_ip M_jq M_kr TENSOR_pqr
411 *
412 * Warning: Rij stored as (11, 22, 33, 12, 23, 13)
413 *
414 * parameters:
415 * matrix[3][4] --> transformation matrix in homogeneous coords.
416 * last line = [0; 0; 0; 1] (Not used here)
417 * tensor <-> incoming 3x3x3 tensor
418 * (in fact 3x6 due to symmetry)
419 *----------------------------------------------------------------------------*/
420
421 static void
_apply_tensor3sym_rotation(cs_real_t matrix[3][4],cs_real_t * tensor)422 _apply_tensor3sym_rotation(cs_real_t matrix[3][4],
423 cs_real_t *tensor)
424 {
425 cs_lnum_t i, j, k, p, q, r;
426
427 cs_real_t t1[3][3][3], t2[3][3][3];
428
429 for (p = 0; p < 3; p++) {
430 for (q = 0; q < 3; q++) {
431 for (k = 0; k < 3; k++) {
432 t1[p][q][k] = 0.;
433 for (r = 0; r < 3; r++)
434 t1[p][q][k] += matrix[k][r] * tensor[3*_symt[p][q] + r];
435 }
436 }
437 }
438
439 for (i = 0; i < 3; i++) {
440 for (j = 0; j < 3; j++) {
441 for (k = 0; k < 3; k++) {
442 t2[i][j][k] = 0.;
443 for (p = 0; p < 3; p++) {
444 for (q = 0; q < 3; q++)
445 t2[i][j][k] += matrix[i][p] * matrix[j][q] * t1[p][q][k];
446 }
447 }
448 }
449 }
450
451 /* Output */
452
453 for (i = 0; i < 3; i++) {
454 for (j = 0; j < 3; j++) {
455 for (k = 0; k < 3; k++)
456 tensor[3*_symt[i][j] + k] = t2[i][j][k];
457 }
458 }
459
460 }
461
462 /*----------------------------------------------------------------------------
463 * Test if a halo seems compatible with the main mesh's periodic
464 * transformations.
465 *
466 * If a halo is not compatible, abort with an error message.
467 *
468 * parameters:
469 * halo --> pointer to halo structure
470 *----------------------------------------------------------------------------*/
471
472 static void
_test_halo_compatibility(const cs_halo_t * halo)473 _test_halo_compatibility(const cs_halo_t *halo)
474 {
475 assert(halo != NULL);
476
477 if (cs_glob_mesh->n_transforms != halo->n_transforms)
478 bft_error(__FILE__, __LINE__, 0,
479 _("The %d periodic transformations of the halo do not comply\n"
480 "with the main mesh transformations (numbering %d).\n"),
481 halo->n_transforms, (int)(cs_glob_mesh->n_transforms));
482 }
483
484 /*! (DOXYGEN_SHOULD_SKIP_THIS) \endcond */
485
486 /*============================================================================
487 * Public function definitions
488 *============================================================================*/
489
490 /*----------------------------------------------------------------------------
491 * Apply transformation on coordinates.
492 *
493 * parameters:
494 * halo <-> halo associated with coordinates to synchronize
495 * sync_mode <-- kind of halo treatment (standard or extended)
496 * coords <-- coordinates on which transformation have to be done.
497 *----------------------------------------------------------------------------*/
498
499 void
cs_halo_perio_sync_coords(const cs_halo_t * halo,cs_halo_type_t sync_mode,cs_real_t * coords)500 cs_halo_perio_sync_coords(const cs_halo_t *halo,
501 cs_halo_type_t sync_mode,
502 cs_real_t *coords)
503 {
504 int rank_id, t_id;
505 cs_lnum_t i, shift, start_std, end_std, start_ext, end_ext;
506
507 cs_real_t matrix[3][4];
508
509 const fvm_periodicity_t *periodicity = cs_glob_mesh->periodicity;
510 const int n_transforms = halo->n_transforms;
511 const cs_lnum_t n_elts = halo->n_local_elts;
512
513 if (sync_mode == CS_HALO_N_TYPES)
514 return;
515
516 assert(halo != NULL);
517
518 _test_halo_compatibility(halo);
519
520 /* Compute the new cell centers through periodicity */
521
522 for (t_id = 0; t_id < n_transforms; t_id++) {
523
524 shift = 4 * halo->n_c_domains * t_id;
525
526 fvm_periodicity_get_matrix(periodicity, t_id, matrix);
527
528 for (rank_id = 0; rank_id < halo->n_c_domains; rank_id++) {
529
530 /* apply transformation for standard halo */
531
532 start_std = halo->perio_lst[shift + 4*rank_id];
533 end_std = start_std + halo->perio_lst[shift + 4*rank_id + 1];
534
535 for (i = start_std; i < end_std; i++)
536 _apply_vector_transfo(matrix, n_elts+i, n_elts+i, coords);
537
538 /* apply transformation for extended halo */
539
540 if (sync_mode == CS_HALO_EXTENDED) {
541
542 start_ext = halo->perio_lst[shift + 4*rank_id + 2];
543 end_ext = start_ext + halo->perio_lst[shift + 4*rank_id + 3];
544
545 for (i = start_ext; i < end_ext; i++)
546 _apply_vector_transfo(matrix, n_elts+i, n_elts+i, coords);
547
548 } /* End if extended halo */
549
550 } /* End of loop on ranks */
551
552 } /* End of loop on transformation */
553 }
554
555 /*----------------------------------------------------------------------------
556 * Synchronize values for a real vector (interleaved) between periodic cells.
557 *
558 * parameters:
559 * halo <-> halo associated with variable to synchronize
560 * sync_mode <-- kind of halo treatment (standard or extended)
561 * var <-> vector to update
562 * incvar <-- specifies the increment for the elements of var
563 *----------------------------------------------------------------------------*/
564
565 void
cs_halo_perio_sync_var_vect(const cs_halo_t * halo,cs_halo_type_t sync_mode,cs_real_t var[],int incvar)566 cs_halo_perio_sync_var_vect(const cs_halo_t *halo,
567 cs_halo_type_t sync_mode,
568 cs_real_t var[],
569 int incvar)
570 {
571 int rank_id, t_id;
572 cs_lnum_t i, shift, start_std, end_std, start_ext, end_ext;
573
574 cs_real_t matrix[3][4];
575
576 fvm_periodicity_type_t perio_type = FVM_PERIODICITY_NULL;
577
578 const int n_transforms = halo->n_transforms;
579 const cs_lnum_t n_elts = halo->n_local_elts;
580 const fvm_periodicity_t *periodicity = cs_glob_mesh->periodicity;
581 const int have_rotation = cs_glob_mesh->have_rotation_perio;
582
583 if (sync_mode == CS_HALO_N_TYPES || have_rotation == 0)
584 return;
585
586 assert(halo != NULL);
587 assert(incvar == 3);
588
589 _test_halo_compatibility(halo);
590
591 for (t_id = 0; t_id < n_transforms; t_id++) {
592
593 shift = 4 * halo->n_c_domains * t_id;
594
595 perio_type = fvm_periodicity_get_type(periodicity, t_id);
596
597 if (perio_type >= FVM_PERIODICITY_ROTATION) {
598
599 fvm_periodicity_get_matrix(periodicity, t_id, matrix);
600
601 for (rank_id = 0; rank_id < halo->n_c_domains; rank_id++) {
602
603 start_std = n_elts + halo->perio_lst[shift + 4*rank_id];
604 end_std = start_std + halo->perio_lst[shift + 4*rank_id + 1];
605
606 for (i = start_std; i < end_std; i++)
607 _apply_vector_rotation(matrix, var + i*incvar);
608
609 if (sync_mode == CS_HALO_EXTENDED) {
610
611 start_ext = n_elts + halo->perio_lst[shift + 4*rank_id + 2];
612 end_ext = start_ext + halo->perio_lst[shift + 4*rank_id + 3];
613
614 for (i = start_ext; i < end_ext; i++)
615 _apply_vector_rotation(matrix, var + i*incvar);
616
617 }
618
619 } /* End of loop on ranks */
620
621 } /* End of the treatment of rotation */
622
623 } /* End of loop on transformations */
624 }
625
626 /*----------------------------------------------------------------------------
627 * Synchronize values for a real tensor (interleaved) between periodic cells.
628 *
629 * parameters:
630 * halo <-> halo associated with variable to synchronize
631 * sync_mode <-- kind of halo treatment (standard or extended)
632 * var <-> tensor to update
633 *----------------------------------------------------------------------------*/
634
635 void
cs_halo_perio_sync_var_tens(const cs_halo_t * halo,cs_halo_type_t sync_mode,cs_real_t var[])636 cs_halo_perio_sync_var_tens(const cs_halo_t *halo,
637 cs_halo_type_t sync_mode,
638 cs_real_t var[])
639 {
640 int rank_id, t_id;
641 cs_lnum_t i, shift, start_std, end_std, start_ext, end_ext;
642
643 cs_real_t matrix[3][4];
644
645 fvm_periodicity_type_t perio_type = FVM_PERIODICITY_NULL;
646
647 const int n_transforms = halo->n_transforms;
648 const cs_lnum_t n_elts = halo->n_local_elts;
649 const fvm_periodicity_t *periodicity = cs_glob_mesh->periodicity;
650 const int have_rotation = cs_glob_mesh->have_rotation_perio;
651
652 if (sync_mode == CS_HALO_N_TYPES || have_rotation == 0)
653 return;
654
655 assert(halo != NULL);
656
657 _test_halo_compatibility(halo);
658
659 for (t_id = 0; t_id < n_transforms; t_id++) {
660
661 shift = 4 * halo->n_c_domains * t_id;
662
663 perio_type = fvm_periodicity_get_type(periodicity, t_id);
664
665 if (perio_type >= FVM_PERIODICITY_ROTATION) {
666
667 fvm_periodicity_get_matrix(periodicity, t_id, matrix);
668
669 for (rank_id = 0; rank_id < halo->n_c_domains; rank_id++) {
670
671 start_std = halo->perio_lst[shift + 4*rank_id];
672 end_std = start_std + halo->perio_lst[shift + 4*rank_id + 1];
673
674 for (i = start_std; i < end_std; i++)
675 _apply_tensor_rotation(matrix, var + 9*(n_elts+i));
676
677 if (sync_mode == CS_HALO_EXTENDED) {
678
679 start_ext = halo->perio_lst[shift + 4*rank_id + 2];
680 end_ext = start_ext + halo->perio_lst[shift + 4*rank_id + 3];
681
682 for (i = start_ext; i < end_ext; i++)
683 _apply_tensor_rotation(matrix, var + 9*(n_elts+i));
684
685 } /* End of the treatment of rotation */
686
687 } /* End if halo is extended */
688
689 } /* End of loop on ranks */
690
691 } /* End of loop on transformations for the local rank */
692 }
693
694 /*----------------------------------------------------------------------------
695 * Synchronize values for a real tensor (symmetric interleaved) between
696 * periodic cells.
697 *
698 * parameters:
699 * halo <-> halo associated with variable to synchronize
700 * sync_mode <-- kind of halo treatment (standard or extended)
701 * var <-> symmetric tensor to update (6 values)
702 *----------------------------------------------------------------------------*/
703
704 void
cs_halo_perio_sync_var_sym_tens(const cs_halo_t * halo,cs_halo_type_t sync_mode,cs_real_t var[])705 cs_halo_perio_sync_var_sym_tens(const cs_halo_t *halo,
706 cs_halo_type_t sync_mode,
707 cs_real_t var[])
708 {
709 int rank_id, t_id;
710 cs_lnum_t i, shift, start_std, end_std, start_ext, end_ext;
711
712 cs_real_t matrix[3][4];
713
714 fvm_periodicity_type_t perio_type = FVM_PERIODICITY_NULL;
715
716 const int n_transforms = halo->n_transforms;
717 const cs_lnum_t n_elts = halo->n_local_elts;
718 const fvm_periodicity_t *periodicity = cs_glob_mesh->periodicity;
719 const int have_rotation = cs_glob_mesh->have_rotation_perio;
720
721 if (sync_mode == CS_HALO_N_TYPES || have_rotation == 0)
722 return;
723
724 assert(halo != NULL);
725
726 _test_halo_compatibility(halo);
727
728 for (t_id = 0; t_id < n_transforms; t_id++) {
729
730 shift = 4 * halo->n_c_domains * t_id;
731
732 perio_type = fvm_periodicity_get_type(periodicity, t_id);
733
734 if (perio_type >= FVM_PERIODICITY_ROTATION) {
735
736 fvm_periodicity_get_matrix(periodicity, t_id, matrix);
737
738 for (rank_id = 0; rank_id < halo->n_c_domains; rank_id++) {
739
740 start_std = halo->perio_lst[shift + 4*rank_id];
741 end_std = start_std + halo->perio_lst[shift + 4*rank_id + 1];
742
743 for (i = start_std; i < end_std; i++)
744 _apply_sym_tensor_rotation(matrix, var + 6*(n_elts+i));
745
746 if (sync_mode == CS_HALO_EXTENDED) {
747
748 start_ext = halo->perio_lst[shift + 4*rank_id + 2];
749 end_ext = start_ext + halo->perio_lst[shift + 4*rank_id + 3];
750
751 for (i = start_ext; i < end_ext; i++)
752 _apply_sym_tensor_rotation(matrix, var + 6*(n_elts+i));
753
754 } /* End of the treatment of rotation */
755
756 } /* End if halo is extended */
757
758 } /* End of loop on ranks */
759
760 } /* End of loop on transformations for the local rank */
761 }
762
763 /*----------------------------------------------------------------------------
764 * Synchronize values for a real gradient of a tensor (symmetric interleaved)
765 * between periodic cells.
766 *
767 * parameters:
768 * halo <-> halo associated with variable to synchronize
769 * sync_mode <-- kind of halo treatment (standard or extended)
770 * var <-> symmetric tensor to update (6 values)
771 *----------------------------------------------------------------------------*/
772
773 void
cs_halo_perio_sync_var_sym_tens_grad(const cs_halo_t * halo,cs_halo_type_t sync_mode,cs_real_t var[])774 cs_halo_perio_sync_var_sym_tens_grad(const cs_halo_t *halo,
775 cs_halo_type_t sync_mode,
776 cs_real_t var[])
777 {
778 int rank_id, t_id;
779 cs_lnum_t i, shift, start_std, end_std, start_ext, end_ext;
780
781 cs_real_t matrix[3][4];
782
783 fvm_periodicity_type_t perio_type = FVM_PERIODICITY_NULL;
784
785 const int n_transforms = halo->n_transforms;
786 const cs_lnum_t n_elts = halo->n_local_elts;
787 const fvm_periodicity_t *periodicity = cs_glob_mesh->periodicity;
788 const int have_rotation = cs_glob_mesh->have_rotation_perio;
789
790 if (sync_mode == CS_HALO_N_TYPES || have_rotation == 0)
791 return;
792
793 assert(halo != NULL);
794
795 _test_halo_compatibility(halo);
796
797 for (t_id = 0; t_id < n_transforms; t_id++) {
798
799 shift = 4 * halo->n_c_domains * t_id;
800
801 perio_type = fvm_periodicity_get_type(periodicity, t_id);
802
803 if (perio_type >= FVM_PERIODICITY_ROTATION) {
804
805 fvm_periodicity_get_matrix(periodicity, t_id, matrix);
806
807 for (rank_id = 0; rank_id < halo->n_c_domains; rank_id++) {
808
809 start_std =n_elts + halo->perio_lst[shift + 4*rank_id];
810 end_std = start_std + halo->perio_lst[shift + 4*rank_id + 1];
811
812 for (i = start_std; i < end_std; i++)
813 _apply_tensor3sym_rotation(matrix, var + 18*i);
814
815 if (sync_mode == CS_HALO_EXTENDED) {
816
817 start_ext = n_elts + halo->perio_lst[shift + 4*rank_id + 2];
818 end_ext = start_ext + halo->perio_lst[shift + 4*rank_id + 3];
819
820 for (i = start_ext; i < end_ext; i++)
821 _apply_tensor3sym_rotation(matrix, var + 18*i);
822
823 } /* End of the treatment of rotation */
824
825 } /* End if halo is extended */
826
827 } /* End of loop on ranks */
828
829 } /* End of loop on transformations for the local rank */
830 }
831
832 /*----------------------------------------------------------------------------*/
833
834 END_C_DECLS
835