/*============================================================================
*
*                    Code_Saturne version 1.3
*                    ------------------------
*
*
*     This file is part of the Code_Saturne Kernel, element of the
*     Code_Saturne CFD tool.
*
*     Copyright (C) 1998-2007 EDF S.A., France
*
*     contact: saturne-support@edf.fr
*
*     The Code_Saturne Kernel is free software; you can redistribute it
*     and/or modify it under the terms of the GNU General Public License
*     as published by the Free Software Foundation; either version 2 of
*     the License, or (at your option) any later version.
*
*     The Code_Saturne Kernel is distributed in the hope that it will be
*     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
*     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*     GNU General Public License for more details.
*
*     You should have received a copy of the GNU General Public License
*     along with the Code_Saturne Kernel; if not, write to the
*     Free Software Foundation, Inc.,
*     51 Franklin St, Fifth Floor,
*     Boston, MA  02110-1301  USA
*
*============================================================================*/

/*============================================================================
 * Fonctions associées a la périodicité
 *============================================================================*/


/* includes système */

#include <assert.h>
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#include <string.h>


/* Includes librairie */

#include "cs_base.h"
#include "cs_maillage.h"
#include "cs_maillage_grd.h"

#include "cs_perio.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */


/*============================================================================
 * Définitions de macros
 *============================================================================*/


/*============================================================================
 * Prototypes de fonctions privées
 *============================================================================*/


/*============================================================================
 * Fonctions publiques pour API Fortran
 *============================================================================*/

/*----------------------------------------------------------------------------
 * Communication entre cellules periodiques
 * VARIJ represente la variable a laquelle on impose la periodicite
 *
 * Les cas de periodicite qui peuvent etre traites sont :
 *
 * - Periodicite d'un scalaire (IDIMTE = 0, ITENSO = 0) que ce soit une
 *   periodicite de translation ou de rotation, le tableau change est VAR11
 * - Periodicite d'un scalaire (IDIMTE = 0, ITENSO = 1) en translation
 *   seulement, la variable changee est VAR11. Elle sert a impliciter les
 *   conditions de periodicite sur les composantes d'un tenseur
 * - Periodicite d'un scalaire (IDIMTE = 0, ITENSO = 11)
 *   reprend (IDIMTE = 0, ITENSO = 1) et, en outre, en rotation seulement,
 *   la variable VAR11 est annulee. On utilise l'option pour annuler le halo
 *   des periodicites de rotation dans les solveurs iteratifs lors des
 *   resolutions par increment des vecteurs et des tenseurs. Il s'agit d'une
 *   condition approchee mais en attendant les tests pas pire qu'une autre
 * - Periodicite d'un vecteur (IDIMTE = 0, ITENSO = 2) en translation
 *   seulement, les tableaux changes sont VAR11, VAR22, VAR33
 * - Periodicite d'un vecteur (IDIMTE = 1, ITENSO = *) en translation et
 *   rotation, les tableaux changes sont VAR11, VAR22, VAR33
 * - Periodicite d'un tenseur d'ordre 2 (IDIMTE = 2, ITENSO = *) en
 *   translation et rotation, les tableaux changes sont VAR11, VAR13, VAR13,
 *   VAR21, VAR22, VAR23, VAR31, VAR32, VAR33
 * - Periodicite d'un tenseur d'ordre 2 (IDIMTE = 21, ITENSO = *) en
 *   translation et rotation, les tableaux changes sont VAR11, VAR22, VAR33
 *   (on suppose le tenseur diagonal)
 *
 * Interface Fortran :
 *
 * SUBROUTINE PERCOM
 * *****************
 *
 * INTEGER          IDIMTE        :  -> : dimension de la variable (maximum 3)
 *                                        0 : scalaire (VAR11), ou assimile
 *                                            scalaire
 *                                        1 : vecteur (VAR11,VAR22,VAR33)
 *                                        2 : tenseur d'ordre 2 (VARIJ)
 *                                       21 : tenseur d'ordre 2 suppose
 *                                            diagonal (VAR11, VAR22, VAR33)
 * INTEGER          ITENSO        :  -> : pour l'explicitation de la rotation
 *                                        0 : scalaire (VAR11)
 *                                        1 : composante de vecteur ou de
 *                                            tenseur (VAR11) implicite pour
 *                                            la translation
 *                                       11 : reprend le traitement ITENSO=1
 *                                            et composante de vecteur ou de
 *                                            tenseur annulee pour la rotation
 *                                        2 : vecteur (VAR11 et VAR22 et VAR33)
 *                                            implicite pour la rotation
 * DOUBLE PRECISION VAR11(NCELET) :  -  : composante 11 du tenseur d'ordre 2
 * DOUBLE PRECISION VAR12(NCELET) :  -  : composante 12 du tenseur d'ordre 2
 * DOUBLE PRECISION VAR13(NCELET) :  -  : composante 13 du tenseur d'ordre 2
 * DOUBLE PRECISION VAR21(NCELET) :  -  : composante 21 du tenseur d'ordre 2
 * DOUBLE PRECISION VAR22(NCELET) :  -  : composante 22 du tenseur d'ordre 2
 * DOUBLE PRECISION VAR23(NCELET) :  -  : composante 23 du tenseur d'ordre 2
 * DOUBLE PRECISION VAR31(NCELET) :  -  : composante 31 du tenseur d'ordre 2
 * DOUBLE PRECISION VAR32(NCELET) :  -  : composante 32 du tenseur d'ordre 2
 * DOUBLE PRECISION VAR33(NCELET) :  -  : composante 33 du tenseur d'ordre 2
 *----------------------------------------------------------------------------*/

void CS_PROCF (percom, PERCOM)
(
 const cs_int_t    *idimte,
 const cs_int_t    *itenso,
       cs_real_t    var11[],
       cs_real_t    var12[],
       cs_real_t    var13[],
       cs_real_t    var21[],
       cs_real_t    var22[],
       cs_real_t    var23[],
       cs_real_t    var31[],
       cs_real_t    var32[],
       cs_real_t    var33[]
)
{

  cs_int_t   i, j, k ;

  cs_real_t  wvar11, wvar22, wvar33 ;

  cs_int_t   ind_loc ;
  cs_int_t   dbloc ;

  cs_int_t   iper ;

  cs_int_t   ielt ;
  cs_int_t   ind_elt_per ;

  cs_bool_t  bool_err = CS_FALSE ;

  cs_real_t  tensA[CS_DIM_3][CS_DIM_3] ;
  cs_real_t  tensB[CS_DIM_3][CS_DIM_3] ;

  cs_maillage_t    *maillage        = cs_glob_maillage ;
  cs_param_perio_t *liste_param_per = maillage->liste_param_per ;

  const cs_int_t   ncel   = maillage->nbr_cel ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /*---------------------*/
  /* 1. Vérifications    */
  /*---------------------*/

  if (*idimte != 0 && *idimte != 1 && *idimte != 2 && *idimte != 21)
    bool_err = CS_TRUE ;

  if (*itenso != 0 && *itenso != 1 && *itenso != 11 && *itenso != 2)
    bool_err = CS_TRUE ;

  if (bool_err == CS_TRUE)
    /***********************/
    /* afficher une erreur */
    /***********************/
    cs_exit(EXIT_FAILURE) ;


  /*----------------*/
  /* 2. Echanges    */
  /*----------------*/


  /* --> Si on veut traiter la variable comme un scalaire */

  if (*idimte == 0) {


    /* Si la variable est un scalaire, tout va bien : on echange tout,
       rotation ou translation. */

    if (*itenso == 0) {


      for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

        dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

        if (maillage->nbr_dom == 1 ||
            maillage->num_dom_fac_par[ind_loc] == maillage->num_dom)

          for (iper = 0 ; iper < maillage->nbr_per ; iper++)

            for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                 ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                 ielt++) {

              ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;
              var11[ncel + ielt] = var11[ind_elt_per] ;

            }

      } /* Fin boucle domaines */


    } /* Fin itenso == 0 */


    /* -- itenso == 1  :
       Si la variable est issue d'un vecteur, on ne peut echanger
       qu'en translation (on peut supposer que pour les rotations,
       qqch de particulier a ete fait)
       -- itenso == 11 :
       Si la variable est issue d'un vecteur, on peut souhaiter en outre
       annuler le halo en rotation (en particulier dans le cas
       de la resolution de la vitesse ou des tensions de Reynolds
       dans Jacobi). */

    else if (*itenso == 1 || *itenso == 11) {


      for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

        dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

        if (maillage->nbr_dom == 1 ||
            maillage->num_dom_fac_par[ind_loc] == maillage->num_dom)

          for (iper = 0 ; iper < maillage->nbr_per ; iper++) {

            if (liste_param_per[iper].type_perio == CS_PERIO_TYPE_TRANS)

              for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                   ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                   ielt++) {

                ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;
                var11[ncel + ielt] = var11[ind_elt_per] ;

              }

            else if (   liste_param_per[iper].type_perio == CS_PERIO_TYPE_ROTA
                     && *itenso == 11)

              for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                   ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                   ielt++) {

                var11[ncel + ielt] = 0. ;

              }

          } /* Fin boucle periodicites sur domaine courant */


        else

          for (iper = 0 ; iper < maillage->nbr_per ; iper++)

            if (   liste_param_per[iper].type_perio == CS_PERIO_TYPE_ROTA
                && *itenso == 11)

              for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                   ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                   ielt++) {

                var11[ncel + ielt] = 0. ;

              }


      } /* Fin boucle domaines */


    } /* Fin itenso == 1 ou itenso == 11 */


    /* La variable est issue d'un tenseur, on ne peut echanger
       qu'en translation ; on echange trois composantes (on peut
       supposer que pour les rotations,
       qqch de particulier a ete fait ; voir PERINR par exemple). */

    else if (*itenso == 2) {


      for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

        dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

        if (maillage->nbr_dom == 1 ||
            maillage->num_dom_fac_par[ind_loc] == maillage->num_dom)

          for (iper = 0 ; iper < maillage->nbr_per ; iper++)

            if (liste_param_per[iper].type_perio == CS_PERIO_TYPE_TRANS)

              for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                   ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                   ielt++) {

                ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;

                var11[ncel + ielt] = var11[ind_elt_per] ;
                var22[ncel + ielt] = var22[ind_elt_per] ;
                var33[ncel + ielt] = var33[ind_elt_per] ;

              }

      } /* Fin boucle domaines */


    } /* Fin itenso == 2 */


  } /* Fin idimte == 0 */



  /* --> Si on veut traiter la variable comme un vecteur
     on suppose que c'est (au moins) un vecteur.
     on echange translation et rotation. */

  else if (*idimte == 1) {

    for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

      dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

      if (maillage->nbr_dom == 1 ||
          maillage->num_dom_fac_par[ind_loc] == maillage->num_dom)

        for (iper = 0 ; iper < maillage->nbr_per ; iper++) {

          if (liste_param_per[iper].type_perio == CS_PERIO_TYPE_TRANS)

            for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                 ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                 ielt++) {

              ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;

              var11[ncel + ielt] = var11[ind_elt_per] ;
              var22[ncel + ielt] = var22[ind_elt_per] ;
              var33[ncel + ielt] = var33[ind_elt_per] ;

            }

          else {

            /* Transformation sens direct */

            for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                 ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
                 ielt++) {

              ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;

              var11[ncel + ielt] = liste_param_per[iper].matrice[0][0] * var11[ind_elt_per] +
                                   liste_param_per[iper].matrice[0][1] * var22[ind_elt_per] +
                                   liste_param_per[iper].matrice[0][2] * var33[ind_elt_per] ;
              var22[ncel + ielt] = liste_param_per[iper].matrice[1][0] * var11[ind_elt_per] +
                                   liste_param_per[iper].matrice[1][1] * var22[ind_elt_per] +
                                   liste_param_per[iper].matrice[1][2] * var33[ind_elt_per] ;
              var33[ncel + ielt] = liste_param_per[iper].matrice[2][0] * var11[ind_elt_per] +
                                   liste_param_per[iper].matrice[2][1] * var22[ind_elt_per] +
                                   liste_param_per[iper].matrice[2][2] * var33[ind_elt_per] ;

            }

            /* Transformation sens inverse */

            for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
                 ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                 ielt++) {

              ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;

              var11[ncel + ielt] = liste_param_per[iper].matrice[0][0] * var11[ind_elt_per] +
                                   liste_param_per[iper].matrice[1][0] * var22[ind_elt_per] +
                                   liste_param_per[iper].matrice[2][0] * var33[ind_elt_per] ;
              var22[ncel + ielt] = liste_param_per[iper].matrice[0][1] * var11[ind_elt_per] +
                                   liste_param_per[iper].matrice[1][1] * var22[ind_elt_per] +
                                   liste_param_per[iper].matrice[2][1] * var33[ind_elt_per] ;
              var33[ncel + ielt] = liste_param_per[iper].matrice[0][2] * var11[ind_elt_per] +
                                   liste_param_per[iper].matrice[1][2] * var22[ind_elt_per] +
                                   liste_param_per[iper].matrice[2][2] * var33[ind_elt_per] ;

            }

          } /* Fin cas d'une rotation */

        } /* Fin boucle periodicites sur domaine courant */


      else

        for (iper = 0 ; iper < maillage->nbr_per ; iper++)

          if (liste_param_per[iper].type_perio == CS_PERIO_TYPE_ROTA) {

            /* Transformation sens direct */

            for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                 ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
                 ielt++) {

              wvar11 = var11[ncel + ielt] ;
              wvar22 = var22[ncel + ielt] ;
              wvar33 = var33[ncel + ielt] ;

              var11[ncel + ielt] = liste_param_per[iper].matrice[0][0] * wvar11 +
                                   liste_param_per[iper].matrice[0][1] * wvar22 +
                                   liste_param_per[iper].matrice[0][2] * wvar33 ;
              var22[ncel + ielt] = liste_param_per[iper].matrice[1][0] * wvar11 +
                                   liste_param_per[iper].matrice[1][1] * wvar22 +
                                   liste_param_per[iper].matrice[1][2] * wvar33 ;
              var33[ncel + ielt] = liste_param_per[iper].matrice[2][0] * wvar11 +
                                   liste_param_per[iper].matrice[2][1] * wvar22 +
                                   liste_param_per[iper].matrice[2][2] * wvar33 ;

            }

            /* Transformation sens inverse */

            for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
                 ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                 ielt++) {

              wvar11 = var11[ncel + ielt] ;
              wvar22 = var22[ncel + ielt] ;
              wvar33 = var33[ncel + ielt] ;

              var11[ncel + ielt] = liste_param_per[iper].matrice[0][0] * wvar11 +
                                   liste_param_per[iper].matrice[1][0] * wvar22 +
                                   liste_param_per[iper].matrice[2][0] * wvar33 ;
              var22[ncel + ielt] = liste_param_per[iper].matrice[0][1] * wvar11 +
                                   liste_param_per[iper].matrice[1][1] * wvar22 +
                                   liste_param_per[iper].matrice[2][1] * wvar33 ;
              var33[ncel + ielt] = liste_param_per[iper].matrice[0][2] * wvar11 +
                                   liste_param_per[iper].matrice[1][2] * wvar22 +
                                   liste_param_per[iper].matrice[2][2] * wvar33 ;

            }


          } /* Fin cas de la rotation */


    } /* Fin boucle domaines */


  } /* Fin idimte == 1 */



  /* --> Si on veut traiter la variable comme un tenseur
     on suppose que c'est un tenseur
     on echange translation et rotation. */

  else if (*idimte == 2) {


      for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

        dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

        if (maillage->nbr_dom == 1 ||
            maillage->num_dom_fac_par[ind_loc] == maillage->num_dom)

          for (iper = 0 ; iper < maillage->nbr_per ; iper++)

            if (liste_param_per[iper].type_perio == CS_PERIO_TYPE_TRANS)

              for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                   ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                   ielt++) {

                ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;

                var11[ncel + ielt] = var11[ind_elt_per] ;
                var12[ncel + ielt] = var12[ind_elt_per] ;
                var13[ncel + ielt] = var13[ind_elt_per] ;
                var21[ncel + ielt] = var21[ind_elt_per] ;
                var22[ncel + ielt] = var22[ind_elt_per] ;
                var23[ncel + ielt] = var23[ind_elt_per] ;
                var31[ncel + ielt] = var31[ind_elt_per] ;
                var32[ncel + ielt] = var32[ind_elt_per] ;
                var33[ncel + ielt] = var33[ind_elt_per] ;

              }

            else {

              /* Transformation sens direct */

              for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                   ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
                   ielt++) {

                ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;

                tensA[0][0] = var11[ind_elt_per] * liste_param_per[iper].matrice[0][0] +
                              var12[ind_elt_per] * liste_param_per[iper].matrice[0][1] +
                              var13[ind_elt_per] * liste_param_per[iper].matrice[0][2] ;
                tensA[0][1] = var11[ind_elt_per] * liste_param_per[iper].matrice[1][0] +
                              var12[ind_elt_per] * liste_param_per[iper].matrice[1][1] +
                              var13[ind_elt_per] * liste_param_per[iper].matrice[1][2] ;
                tensA[0][2] = var11[ind_elt_per] * liste_param_per[iper].matrice[2][0] +
                              var12[ind_elt_per] * liste_param_per[iper].matrice[2][1] +
                              var13[ind_elt_per] * liste_param_per[iper].matrice[2][2] ;

                tensA[1][0] = var21[ind_elt_per] * liste_param_per[iper].matrice[0][0] +
                              var22[ind_elt_per] * liste_param_per[iper].matrice[0][1] +
                              var23[ind_elt_per] * liste_param_per[iper].matrice[0][2] ;
                tensA[1][1] = var21[ind_elt_per] * liste_param_per[iper].matrice[1][0] +
                              var22[ind_elt_per] * liste_param_per[iper].matrice[1][1] +
                              var23[ind_elt_per] * liste_param_per[iper].matrice[1][2] ;
                tensA[1][2] = var21[ind_elt_per] * liste_param_per[iper].matrice[2][0] +
                              var22[ind_elt_per] * liste_param_per[iper].matrice[2][1] +
                              var23[ind_elt_per] * liste_param_per[iper].matrice[2][2] ;

                tensA[2][0] = var31[ind_elt_per] * liste_param_per[iper].matrice[0][0] +
                              var32[ind_elt_per] * liste_param_per[iper].matrice[0][1] +
                              var33[ind_elt_per] * liste_param_per[iper].matrice[0][2] ;
                tensA[2][1] = var31[ind_elt_per] * liste_param_per[iper].matrice[1][0] +
                              var32[ind_elt_per] * liste_param_per[iper].matrice[1][1] +
                              var33[ind_elt_per] * liste_param_per[iper].matrice[1][2] ;
                tensA[2][2] = var31[ind_elt_per] * liste_param_per[iper].matrice[2][0] +
                              var32[ind_elt_per] * liste_param_per[iper].matrice[2][1] +
                              var33[ind_elt_per] * liste_param_per[iper].matrice[2][2] ;

                for (i = 0 ; i < CS_DIM_3 ; i++)
                  for (j = 0 ; j < CS_DIM_3 ; j++) {
                    tensB[i][j] = 0. ;
                    for (k = 0 ; k < CS_DIM_3 ; k++)
                      tensB[i][j] += liste_param_per[iper].matrice[i][k] * tensA[k][j] ;
                  }

                var11[ncel + ielt] = tensB[0][0] ;
                var12[ncel + ielt] = tensB[0][1] ;
                var13[ncel + ielt] = tensB[0][2] ;
                var21[ncel + ielt] = tensB[1][0] ;
                var22[ncel + ielt] = tensB[1][1] ;
                var23[ncel + ielt] = tensB[1][2] ;
                var31[ncel + ielt] = tensB[2][0] ;
                var32[ncel + ielt] = tensB[2][1] ;
                var33[ncel + ielt] = tensB[2][2] ;

              }

              /* Transformation sens inverse */

              for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
                   ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                   ielt++) {

                ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;

                tensA[0][0] = var11[ind_elt_per] * liste_param_per[iper].matrice[0][0] +
                              var12[ind_elt_per] * liste_param_per[iper].matrice[1][0] +
                              var13[ind_elt_per] * liste_param_per[iper].matrice[2][0] ;
                tensA[0][1] = var11[ind_elt_per] * liste_param_per[iper].matrice[0][1] +
                              var12[ind_elt_per] * liste_param_per[iper].matrice[1][1] +
                              var13[ind_elt_per] * liste_param_per[iper].matrice[2][1] ;
                tensA[0][2] = var11[ind_elt_per] * liste_param_per[iper].matrice[0][2] +
                              var12[ind_elt_per] * liste_param_per[iper].matrice[1][2] +
                              var13[ind_elt_per] * liste_param_per[iper].matrice[2][2] ;

                tensA[1][0] = var21[ind_elt_per] * liste_param_per[iper].matrice[0][0] +
                              var22[ind_elt_per] * liste_param_per[iper].matrice[1][0] +
                              var23[ind_elt_per] * liste_param_per[iper].matrice[2][0] ;
                tensA[1][1] = var21[ind_elt_per] * liste_param_per[iper].matrice[0][1] +
                              var22[ind_elt_per] * liste_param_per[iper].matrice[1][1] +
                              var23[ind_elt_per] * liste_param_per[iper].matrice[2][1] ;
                tensA[1][2] = var21[ind_elt_per] * liste_param_per[iper].matrice[0][2] +
                              var22[ind_elt_per] * liste_param_per[iper].matrice[1][2] +
                              var23[ind_elt_per] * liste_param_per[iper].matrice[2][2] ;

                tensA[2][0] = var31[ind_elt_per] * liste_param_per[iper].matrice[0][0] +
                              var32[ind_elt_per] * liste_param_per[iper].matrice[1][0] +
                              var33[ind_elt_per] * liste_param_per[iper].matrice[2][0] ;
                tensA[2][1] = var31[ind_elt_per] * liste_param_per[iper].matrice[0][1] +
                              var32[ind_elt_per] * liste_param_per[iper].matrice[1][1] +
                              var33[ind_elt_per] * liste_param_per[iper].matrice[2][1] ;
                tensA[2][2] = var31[ind_elt_per] * liste_param_per[iper].matrice[0][2] +
                              var32[ind_elt_per] * liste_param_per[iper].matrice[1][2] +
                              var33[ind_elt_per] * liste_param_per[iper].matrice[2][2] ;

                for (i = 0 ; i < CS_DIM_3 ; i++)
                  for (j = 0 ; j < CS_DIM_3 ; j++) {
                    tensB[i][j] = 0. ;
                    for (k = 0 ; k < CS_DIM_3 ; k++)
                      tensB[i][j] += liste_param_per[iper].matrice[k][i] * tensA[k][j] ;
                  }

                var11[ncel + ielt] = tensB[0][0] ;
                var12[ncel + ielt] = tensB[0][1] ;
                var13[ncel + ielt] = tensB[0][2] ;
                var21[ncel + ielt] = tensB[1][0] ;
                var22[ncel + ielt] = tensB[1][1] ;
                var23[ncel + ielt] = tensB[1][2] ;
                var31[ncel + ielt] = tensB[2][0] ;
                var32[ncel + ielt] = tensB[2][1] ;
                var33[ncel + ielt] = tensB[2][2] ;

              }

            } /* Fin boucle periodicites sur domaine courant */


        else


          for (iper = 0 ; iper < maillage->nbr_per ; iper++)

            if (liste_param_per[iper].type_perio == CS_PERIO_TYPE_ROTA) {

              /* Transformation sens direct */

              for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                   ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
                   ielt++) {

                tensA[0][0] = var11[ncel + ielt] * liste_param_per[iper].matrice[0][0] +
                              var12[ncel + ielt] * liste_param_per[iper].matrice[0][1] +
                              var13[ncel + ielt] * liste_param_per[iper].matrice[0][2] ;
                tensA[0][1] = var11[ncel + ielt] * liste_param_per[iper].matrice[1][0] +
                              var12[ncel + ielt] * liste_param_per[iper].matrice[1][1] +
                              var13[ncel + ielt] * liste_param_per[iper].matrice[1][2] ;
                tensA[0][2] = var11[ncel + ielt] * liste_param_per[iper].matrice[2][0] +
                              var12[ncel + ielt] * liste_param_per[iper].matrice[2][1] +
                              var13[ncel + ielt] * liste_param_per[iper].matrice[2][2] ;

                tensA[1][0] = var21[ncel + ielt] * liste_param_per[iper].matrice[0][0] +
                              var22[ncel + ielt] * liste_param_per[iper].matrice[0][1] +
                              var23[ncel + ielt] * liste_param_per[iper].matrice[0][2] ;
                tensA[1][1] = var21[ncel + ielt] * liste_param_per[iper].matrice[1][0] +
                              var22[ncel + ielt] * liste_param_per[iper].matrice[1][1] +
                              var23[ncel + ielt] * liste_param_per[iper].matrice[1][2] ;
                tensA[1][2] = var21[ncel + ielt] * liste_param_per[iper].matrice[2][0] +
                              var22[ncel + ielt] * liste_param_per[iper].matrice[2][1] +
                              var23[ncel + ielt] * liste_param_per[iper].matrice[2][2] ;

                tensA[2][0] = var31[ncel + ielt] * liste_param_per[iper].matrice[0][0] +
                              var32[ncel + ielt] * liste_param_per[iper].matrice[0][1] +
                              var33[ncel + ielt] * liste_param_per[iper].matrice[0][2] ;
                tensA[2][1] = var31[ncel + ielt] * liste_param_per[iper].matrice[1][0] +
                              var32[ncel + ielt] * liste_param_per[iper].matrice[1][1] +
                              var33[ncel + ielt] * liste_param_per[iper].matrice[1][2] ;
                tensA[2][2] = var31[ncel + ielt] * liste_param_per[iper].matrice[2][0] +
                              var32[ncel + ielt] * liste_param_per[iper].matrice[2][1] +
                              var33[ncel + ielt] * liste_param_per[iper].matrice[2][2] ;

                for (i = 0 ; i < CS_DIM_3 ; i++)
                  for (j = 0 ; j < CS_DIM_3 ; j++) {
                    tensB[i][j] = 0. ;
                    for (k = 0 ; k < CS_DIM_3 ; k++)
                      tensB[i][j] += liste_param_per[iper].matrice[i][k] * tensA[k][j] ;
                  }

                var11[ncel + ielt] = tensB[0][0] ;
                var12[ncel + ielt] = tensB[0][1] ;
                var13[ncel + ielt] = tensB[0][2] ;
                var21[ncel + ielt] = tensB[1][0] ;
                var22[ncel + ielt] = tensB[1][1] ;
                var23[ncel + ielt] = tensB[1][2] ;
                var31[ncel + ielt] = tensB[2][0] ;
                var32[ncel + ielt] = tensB[2][1] ;
                var33[ncel + ielt] = tensB[2][2] ;

              }

              /* Transformation sens inverse */

              for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
                   ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                   ielt++) {

                tensA[0][0] = var11[ncel + ielt] * liste_param_per[iper].matrice[0][0] +
                              var12[ncel + ielt] * liste_param_per[iper].matrice[1][0] +
                              var13[ncel + ielt] * liste_param_per[iper].matrice[2][0] ;
                tensA[0][1] = var11[ncel + ielt] * liste_param_per[iper].matrice[0][1] +
                              var12[ncel + ielt] * liste_param_per[iper].matrice[1][1] +
                              var13[ncel + ielt] * liste_param_per[iper].matrice[2][1] ;
                tensA[0][2] = var11[ncel + ielt] * liste_param_per[iper].matrice[0][2] +
                              var12[ncel + ielt] * liste_param_per[iper].matrice[1][2] +
                              var13[ncel + ielt] * liste_param_per[iper].matrice[2][2] ;

                tensA[1][0] = var21[ncel + ielt] * liste_param_per[iper].matrice[0][0] +
                              var22[ncel + ielt] * liste_param_per[iper].matrice[1][0] +
                              var23[ncel + ielt] * liste_param_per[iper].matrice[2][0] ;
                tensA[1][1] = var21[ncel + ielt] * liste_param_per[iper].matrice[0][1] +
                              var22[ncel + ielt] * liste_param_per[iper].matrice[1][1] +
                              var23[ncel + ielt] * liste_param_per[iper].matrice[2][1] ;
                tensA[1][2] = var21[ncel + ielt] * liste_param_per[iper].matrice[0][2] +
                              var22[ncel + ielt] * liste_param_per[iper].matrice[1][2] +
                              var23[ncel + ielt] * liste_param_per[iper].matrice[2][2] ;

                tensA[2][0] = var31[ncel + ielt] * liste_param_per[iper].matrice[0][0] +
                              var32[ncel + ielt] * liste_param_per[iper].matrice[1][0] +
                              var33[ncel + ielt] * liste_param_per[iper].matrice[2][0] ;
                tensA[2][1] = var31[ncel + ielt] * liste_param_per[iper].matrice[0][1] +
                              var32[ncel + ielt] * liste_param_per[iper].matrice[1][1] +
                              var33[ncel + ielt] * liste_param_per[iper].matrice[2][1] ;
                tensA[2][2] = var31[ncel + ielt] * liste_param_per[iper].matrice[0][2] +
                              var32[ncel + ielt] * liste_param_per[iper].matrice[1][2] +
                              var33[ncel + ielt] * liste_param_per[iper].matrice[2][2] ;

                for (i = 0 ; i < CS_DIM_3 ; i++)
                  for (j = 0 ; j < CS_DIM_3 ; j++) {
                    tensB[i][j] = 0. ;
                    for (k = 0 ; k < CS_DIM_3 ; k++)
                      tensB[i][j] += liste_param_per[iper].matrice[k][i] * tensA[k][j] ;
                  }

                var11[ncel + ielt] = tensB[0][0] ;
                var12[ncel + ielt] = tensB[0][1] ;
                var13[ncel + ielt] = tensB[0][2] ;
                var21[ncel + ielt] = tensB[1][0] ;
                var22[ncel + ielt] = tensB[1][1] ;
                var23[ncel + ielt] = tensB[1][2] ;
                var31[ncel + ielt] = tensB[2][0] ;
                var32[ncel + ielt] = tensB[2][1] ;
                var33[ncel + ielt] = tensB[2][2] ;

              }

            } /* Fin cas de la rotation */


      } /* Fin boucle domaines */


  }  /* Fin idimte == 2 */



  /* --> Si on veut traiter la variable comme un tenseur
     mais que c'est la diagonale d'un tenseur
     on suppose que c'est un tenseur
     on echange translation et rotation. */

  else if (*idimte == 21) {


    for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

      dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

      if (maillage->nbr_dom == 1 ||
          maillage->num_dom_fac_par[ind_loc] == maillage->num_dom)

        for (iper = 0 ; iper < maillage->nbr_per ; iper++)

          if (liste_param_per[iper].type_perio == CS_PERIO_TYPE_TRANS)

            for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                 ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                 ielt++) {

              ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;

              var11[ncel + ielt] = var11[ind_elt_per] ;
              var22[ncel + ielt] = var22[ind_elt_per] ;
              var33[ncel + ielt] = var33[ind_elt_per] ;

            }

          else {

            /* Transformation sens direct */

            for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                 ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
                 ielt++) {

              ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;

              tensA[0][0] = var11[ind_elt_per] * liste_param_per[iper].matrice[0][0] ;
              tensA[0][1] = var11[ind_elt_per] * liste_param_per[iper].matrice[1][0] ;
              tensA[0][2] = var11[ind_elt_per] * liste_param_per[iper].matrice[2][0] ;

              tensA[1][0] = var22[ind_elt_per] * liste_param_per[iper].matrice[0][1] ;
              tensA[1][1] = var22[ind_elt_per] * liste_param_per[iper].matrice[1][1] ;
              tensA[1][2] = var22[ind_elt_per] * liste_param_per[iper].matrice[2][1] ;

              tensA[2][0] = var33[ind_elt_per] * liste_param_per[iper].matrice[0][2] ;
              tensA[2][1] = var33[ind_elt_per] * liste_param_per[iper].matrice[1][2] ;
              tensA[2][2] = var33[ind_elt_per] * liste_param_per[iper].matrice[2][2] ;

              for (i = 0 ; i < CS_DIM_3 ; i++)
                for (j = 0 ; j < CS_DIM_3 ; j++) {
                  tensB[i][j] = 0. ;
                  for (k = 0 ; k < CS_DIM_3 ; k++)
                    tensB[i][j] += liste_param_per[iper].matrice[i][k] * tensA[k][j] ;
                }

              var11[ncel + ielt] = tensB[0][0] ;
              var22[ncel + ielt] = tensB[1][1] ;
              var33[ncel + ielt] = tensB[2][2] ;

            }

            /* Transformation sens inverse */

            for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
                 ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                 ielt++) {

              ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;

              tensA[0][0] = var11[ind_elt_per] * liste_param_per[iper].matrice[0][0] ;
              tensA[0][1] = var11[ind_elt_per] * liste_param_per[iper].matrice[0][1] ;
              tensA[0][2] = var11[ind_elt_per] * liste_param_per[iper].matrice[0][2] ;

              tensA[1][0] = var22[ind_elt_per] * liste_param_per[iper].matrice[1][0] ;
              tensA[1][1] = var22[ind_elt_per] * liste_param_per[iper].matrice[1][1] ;
              tensA[1][2] = var22[ind_elt_per] * liste_param_per[iper].matrice[1][2] ;

              tensA[2][0] = var33[ind_elt_per] * liste_param_per[iper].matrice[2][0] ;
              tensA[2][1] = var33[ind_elt_per] * liste_param_per[iper].matrice[2][1] ;
              tensA[2][2] = var33[ind_elt_per] * liste_param_per[iper].matrice[2][2] ;

              for (i = 0 ; i < CS_DIM_3 ; i++)
                for (j = 0 ; j < CS_DIM_3 ; j++) {
                  tensB[i][j] = 0. ;
                  for (k = 0 ; k < CS_DIM_3 ; k++)
                tensB[i][j] += liste_param_per[iper].matrice[k][i] * tensA[k][j] ;
                }

              var11[ncel + ielt] = tensB[0][0] ;
              var22[ncel + ielt] = tensB[1][1] ;
              var33[ncel + ielt] = tensB[2][2] ;

            }

          } /* Fin boucle periodicites sur domaine courant */

      else


        for (iper = 0 ; iper < maillage->nbr_per ; iper++)

          if (liste_param_per[iper].type_perio == CS_PERIO_TYPE_ROTA) {

            /* Transformation sens direct */

            for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                 ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
                 ielt++) {

              tensA[0][0] = var11[ncel + ielt] * liste_param_per[iper].matrice[0][0] ;
              tensA[0][1] = var11[ncel + ielt] * liste_param_per[iper].matrice[1][0] ;
              tensA[0][2] = var11[ncel + ielt] * liste_param_per[iper].matrice[2][0] ;

              tensA[1][0] = var22[ncel + ielt] * liste_param_per[iper].matrice[0][1] ;
              tensA[1][1] = var22[ncel + ielt] * liste_param_per[iper].matrice[1][1] ;
              tensA[1][2] = var22[ncel + ielt] * liste_param_per[iper].matrice[2][1] ;

              tensA[2][0] = var33[ncel + ielt] * liste_param_per[iper].matrice[0][2] ;
              tensA[2][1] = var33[ncel + ielt] * liste_param_per[iper].matrice[1][2] ;
              tensA[2][2] = var33[ncel + ielt] * liste_param_per[iper].matrice[2][2] ;

              for (i = 0 ; i < CS_DIM_3 ; i++)
                for (j = 0 ; j < CS_DIM_3 ; j++) {
                  tensB[i][j] = 0. ;
                  for (k = 0 ; k < CS_DIM_3 ; k++)
                    tensB[i][j] += liste_param_per[iper].matrice[i][k] * tensA[k][j] ;
                }

              var11[ncel + ielt] = tensB[0][0] ;
              var22[ncel + ielt] = tensB[1][1] ;
              var33[ncel + ielt] = tensB[2][2] ;

            }

            /* Transformation sens inverse */

            for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
                 ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                 ielt++) {

              tensA[0][0] = var11[ncel + ielt] * liste_param_per[iper].matrice[0][0] ;
              tensA[0][1] = var11[ncel + ielt] * liste_param_per[iper].matrice[0][1] ;
              tensA[0][2] = var11[ncel + ielt] * liste_param_per[iper].matrice[0][2] ;

              tensA[1][0] = var22[ncel + ielt] * liste_param_per[iper].matrice[1][0] ;
              tensA[1][1] = var22[ncel + ielt] * liste_param_per[iper].matrice[1][1] ;
              tensA[1][2] = var22[ncel + ielt] * liste_param_per[iper].matrice[1][2] ;

              tensA[2][0] = var33[ncel + ielt] * liste_param_per[iper].matrice[2][0] ;
              tensA[2][1] = var33[ncel + ielt] * liste_param_per[iper].matrice[2][1] ;
              tensA[2][2] = var33[ncel + ielt] * liste_param_per[iper].matrice[2][2] ;

              for (i = 0 ; i < CS_DIM_3 ; i++)
                for (j = 0 ; j < CS_DIM_3 ; j++) {
                  tensB[i][j] = 0. ;
                  for (k = 0 ; k < CS_DIM_3 ; k++)
                    tensB[i][j] += liste_param_per[iper].matrice[k][i] * tensA[k][j] ;
                }

              var11[ncel + ielt] = tensB[0][0] ;
              var22[ncel + ielt] = tensB[1][1] ;
              var33[ncel + ielt] = tensB[2][2] ;

            }

          }


    } /* Fin boucle domaines */


  } /* Fin idimte == 21 */


}


/*============================================================================
 * Fonctions publiques
 *============================================================================*/

/*----------------------------------------------------------------------------
 * Initialisation pour la périodicité (actualisation des cdg et des familles
 * des cellules halos).
 *----------------------------------------------------------------------------*/

void cs_perio_sync_geo
(
 void
)
{

  cs_int_t   i, j ;

  cs_int_t   ind_loc ;
  cs_int_t   dbloc ;

  cs_int_t   iper ;
  cs_int_t   ielt ;
  cs_int_t   ind_elt_per ;

  cs_real_t  vect[CS_DIM_3] ;

  cs_maillage_t    *maillage = cs_glob_maillage ;
  cs_param_perio_t  param_per ;

  cs_int_t   *ifmcel = maillage->fam_cel ;
  cs_real_t  *xyzcen = cs_glob_maillage_grd->cen_cel ;

  const cs_int_t   ncelet = maillage->nbr_cel_etendu ;
  const cs_int_t   ncel   = maillage->nbr_cel ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /*-----------------------------------*/
  /* Calcul des cdg des cellules halos */
  /*-----------------------------------*/


  for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {


    dbloc = (2*maillage->nbr_per + 1)*ind_loc ;


    /* On traite d'abord les cellules halos periodiques 'simples' du domaine */

    if (maillage->nbr_dom == 1 ||
        maillage->num_dom_fac_par[ind_loc] == maillage->num_dom)


      for (iper = 0 ; iper < maillage->nbr_per ; iper++) {

        param_per = maillage->liste_param_per[iper] ;


        /* Sens direct */

          for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
               ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
               ielt++) {

            ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;

            for (i = 0 ; i < CS_DIM_3 ; i++)
            vect[i] = 0. ;

            for (i = 0 ; i < CS_DIM_3 ; i++)
              for (j = 0 ; j < CS_DIM_3 ; j++)
              vect[i] = vect[i] + param_per.matrice[i][j] *
                (xyzcen[ind_elt_per*CS_DIM_3 + j] - param_per.point_inv[j]
                 + param_per.translation[j]) ;

          for (i = 0 ; i < CS_DIM_3 ; i++)
            xyzcen[(ncel + ielt)*CS_DIM_3 + i] =  vect[i] +
              param_per.point_inv[i] ;

            }


        /* Sens inverse */

          for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
               ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
               ielt++) {

            ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;

            for (i = 0 ; i < CS_DIM_3 ; i++)
            vect[i] = 0. ;

          for (i = 0 ; i < CS_DIM_3 ; i++)
              for (j = 0 ; j < CS_DIM_3 ; j++)
              vect[i] = vect[i] + param_per.matrice[j][i] *
                (xyzcen[ind_elt_per*CS_DIM_3 + j] - param_per.point_inv[j]) ;

          for (i = 0 ; i < CS_DIM_3 ; i++)
            xyzcen[(ncel + ielt)*CS_DIM_3 + i] =  vect[i] +
              param_per.point_inv[i] - param_per.translation[i] ;

            }


      } /* Fin boucle periodicites */


    /* Fin domaine courant */


    /* On traite maintenant les cellules halos periodiques dont le
       correspondant appartient a un autre domaine. La valeur de celui-ci a
       ete recupere avant par PARCOM et stocke 'dans' la cellule halo. */

    else


      for (iper = 0 ; iper < maillage->nbr_per ; iper++) {

        param_per = maillage->liste_param_per[iper] ;


        /* Sens direct */

          for (ielt = maillage->pos_per_fac_par[dbloc +        2*iper + 1] - 1 ;
               ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
               ielt++) {

          ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;

            for (i = 0 ; i < CS_DIM_3 ; i++)
            vect[i] = 0. ;

            for (i = 0 ; i < CS_DIM_3 ; i++)
              for (j = 0 ; j < CS_DIM_3 ; j++)
              vect[i] = vect[i] + param_per.matrice[i][j] *
                (xyzcen[(ncel + ielt)*CS_DIM_3 + j] - param_per.point_inv[j] +
                 param_per.translation[j]) ;

          for (i = 0 ; i < CS_DIM_3 ; i++)
            xyzcen[(ncel + ielt)*CS_DIM_3 + i] =  vect[i] +
              param_per.point_inv[i] ;

            }


        /* Sens inverse */

          for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
               ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
               ielt++) {

          ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;

            for (i = 0 ; i < CS_DIM_3 ; i++)
            vect[i] = 0. ;

          for (i = 0 ; i < CS_DIM_3 ; i++)
              for (j = 0 ; j < CS_DIM_3 ; j++)
              vect[i] = vect[i] + param_per.matrice[j][i] *
                (xyzcen[(ncel + ielt)*CS_DIM_3 + j] - param_per.point_inv[j]) ;

          for (i = 0 ; i < CS_DIM_3 ; i++)
            xyzcen[(ncel + ielt)*CS_DIM_3 + i] =  vect[i] +
              param_per.point_inv[i] - param_per.translation[i] ;

            }


      } /* Fin boucle periodicites */


    /* Fin boucle domaines */


  }

  /*--------------------------------------------------------------*/
  /* Calcul des cdg des cellules voisinage étendu s'il est séparé */
  /*--------------------------------------------------------------*/



  /* Uniquement dans le cas d'un voisinage étendu traité séparément
   et non vide sur le processeur courant */

  if(maillage->ind_type_voiset == CS_MAILLAGE_TYPE_VOISET_SEPARE &&
     maillage->nbr_cel_fac_par_voiset > 0) {


    for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par_voiset ; ind_loc++) {


      dbloc = (2*maillage->nbr_per + 1)*ind_loc ;


      /* On traite d'abord les cellules halos periodiques 'simples' du domaine*/

      if (maillage->nbr_dom == 1 ||
          maillage->num_dom_fac_par_voiset[ind_loc] == maillage->num_dom)


        for (iper = 0 ; iper < maillage->nbr_per ; iper++) {

          param_per = maillage->liste_param_per[iper] ;


          /* Sens direct */

          for (ielt = maillage->pos_per_fac_par_voiset[dbloc + 2*iper + 1] - 1 ;
               ielt < maillage->pos_per_fac_par_voiset[dbloc + 2*iper + 2] - 1 ;
               ielt++) {

            ind_elt_per = maillage->num_cel_fac_par_voiset[ielt] - 1 ;

            for (i = 0 ; i < CS_DIM_3 ; i++)
              vect[i] = 0. ;

            for (i = 0 ; i < CS_DIM_3 ; i++)
              for (j = 0 ; j < CS_DIM_3 ; j++)
                vect[i] = vect[i] + param_per.matrice[i][j] *
                  (xyzcen[ind_elt_per*CS_DIM_3 + j] - param_per.point_inv[j]
                   + param_per.translation[j]) ;

            for (i = 0 ; i < CS_DIM_3 ; i++)
              maillage->coord_cel_avec_voiset[((ncelet) + ielt)*CS_DIM_3 + i]
                = vect[i] + param_per.point_inv[i] ;

          }


          /* Sens inverse */

          for (ielt = maillage->pos_per_fac_par_voiset[dbloc + 2*iper + 2] - 1 ;
               ielt < maillage->pos_per_fac_par_voiset[dbloc + 2*iper + 3] - 1 ;
               ielt++) {

            ind_elt_per = maillage->num_cel_fac_par_voiset[ielt] - 1 ;

            for (i = 0 ; i < CS_DIM_3 ; i++)
              vect[i] = 0. ;

            for (i = 0 ; i < CS_DIM_3 ; i++)
              for (j = 0 ; j < CS_DIM_3 ; j++)
                vect[i] = vect[i] + param_per.matrice[j][i] *
                  (xyzcen[ind_elt_per*CS_DIM_3 + j] - param_per.point_inv[j]) ;

            for (i = 0 ; i < CS_DIM_3 ; i++)
              maillage->coord_cel_avec_voiset[((ncelet) + ielt)*CS_DIM_3 + i]
                =  vect[i] + param_per.point_inv[i] - param_per.translation[i] ;

          }


        } /* Fin boucle periodicites */


      /* Fin domaine courant */


      /* On traite maintenant les cellules halos periodiques dont le
         correspondant appartient a un autre domaine. La valeur de celui-ci a
         ete recupere avant par PARCOM et stocke 'dans' la cellule halo. */

      else


        for (iper = 0 ; iper < maillage->nbr_per ; iper++) {

          param_per = maillage->liste_param_per[iper] ;


          /* Sens direct */

          for (ielt = maillage->pos_per_fac_par_voiset[dbloc + 2*iper + 1] - 1 ;
               ielt < maillage->pos_per_fac_par_voiset[dbloc + 2*iper + 2] - 1 ;
               ielt++) {

            ind_elt_per = maillage->num_cel_fac_par_voiset[ielt] - 1 ;

            for (i = 0 ; i < CS_DIM_3 ; i++)
              vect[i] = 0. ;

            for (i = 0 ; i < CS_DIM_3 ; i++)
              for (j = 0 ; j < CS_DIM_3 ; j++)
                vect[i] = vect[i] + param_per.matrice[i][j] *
                  (maillage->coord_cel_avec_voiset
                   [((ncelet) + ielt)*CS_DIM_3 + j]
                   - param_per.point_inv[j] + param_per.translation[j]) ;

            for (i = 0 ; i < CS_DIM_3 ; i++)
              maillage->coord_cel_avec_voiset[((ncelet) + ielt)*CS_DIM_3 + i]
                =  vect[i] + param_per.point_inv[i] ;

          }


          /* Sens inverse */

          for (ielt = maillage->pos_per_fac_par_voiset[dbloc + 2*iper + 2] - 1 ;
               ielt < maillage->pos_per_fac_par_voiset[dbloc + 2*iper + 3] - 1 ;
               ielt++) {

            ind_elt_per = maillage->num_cel_fac_par_voiset[ielt] - 1 ;

            for (i = 0 ; i < CS_DIM_3 ; i++)
              vect[i] = 0. ;

            for (i = 0 ; i < CS_DIM_3 ; i++)
              for (j = 0 ; j < CS_DIM_3 ; j++)
                vect[i] = vect[i] + param_per.matrice[j][i] *
                  (maillage->coord_cel_avec_voiset
                   [((ncelet) + ielt)*CS_DIM_3 + j]
                   - param_per.point_inv[j]) ;

            for (i = 0 ; i < CS_DIM_3 ; i++)
              maillage->coord_cel_avec_voiset[((ncelet) + ielt)*CS_DIM_3 + i]
                =  vect[i] + param_per.point_inv[i] - param_per.translation[i] ;

          }


        } /* Fin boucle periodicites */

      /* Fin domaine non = domaine courant */

    } /* Fin boucle domaines */


    /* Recopie du début du tableau, en parallèle ou pas, car on a
       potentiellement mis a jour la partie periodique du halo
       (encore que, a priori, on n'a pas de voisinage étendu séparé en
       séquentiel...) */

    for (ind_loc = 0 ; ind_loc < (ncelet)*CS_DIM_3 ; ind_loc++)
      maillage->coord_cel_avec_voiset[ind_loc] = xyzcen[ind_loc] ;

  } /* Fin si le voisinage étendu est séparé et de taille locale non nulle */


  /*-----------------------------------------------*/
  /* Actualisation des familles des cellules halos */
  /*-----------------------------------------------*/


  for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

    dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

    /* On traite d'abord les cellules halos periodiques 'simples' du domaine */

    if (maillage->nbr_dom == 1 ||
        maillage->num_dom_fac_par[ind_loc] == maillage->num_dom)

      for (iper = 0 ; iper < maillage->nbr_per ; iper++)

        for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
             ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
             ielt++) {

          ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;

          ifmcel[ncel + ielt] = ifmcel[ind_elt_per] ;

        }

    /* Rien a faire en parallelisme, car les valeurs ont deja ete
       recuperees par PARCOM */

  }


}


/*----------------------------------------------------------------------------
 * Mise à jour du voisinage étendu d'une variable au centre des cellules
 *   dans le voisinage étendu s'il est traité séparément du reste du halo
 *
 * Fonction calquée sur PERCOM, pour la périodicité de translation uniquement
 *
 * Le rôle de cette fonction consiste à recopier les valeurs sur les
 * cellules principales en frontière périodique non parallèle
 * (indices entre 1 et ncel) vers les cellules halo du domaine en
 * cours.
 *
 *----------------------------------------------------------------------------*/

void cs_perio_percve
(
 const cs_real_t * const var       ,/* --> variable au centre des cellules */
       cs_real_t *       var_voiset /* <-> variable au centre des cellules
                                           dans le voisinage étendu        */
)
{
  cs_int_t     ind_loc ;
  cs_int_t     dbloc ;
  cs_int_t     iper ;
  cs_int_t     ielt ;
  cs_int_t     ind_elt_per ;

  cs_int_t     ncelet ;
  cs_int_t     ncel ;

  cs_maillage_t    *maillage        = cs_glob_maillage ;

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/

  ncel   = maillage->nbr_cel ;
  ncelet = maillage->nbr_cel_etendu ;

  /* Uniquement dans le cas d'un voisinage étendu traité séparément
   et non vide sur le processeur courant */

  if(maillage->ind_type_voiset == CS_MAILLAGE_TYPE_VOISET_SEPARE &&
     maillage->nbr_cel_fac_par_voiset > 0) {

    for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par_voiset ; ind_loc++) {

      dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

      if (maillage->nbr_dom == 1 ||
          maillage->num_dom_fac_par_voiset[ind_loc] == maillage->num_dom)

        for (iper = 0 ; iper < maillage->nbr_per ; iper++)

          for (ielt = maillage->pos_per_fac_par_voiset[dbloc + 2*iper + 1] - 1 ;
               ielt < maillage->pos_per_fac_par_voiset[dbloc + 2*iper + 3] - 1 ;
               ielt++) {

            ind_elt_per = maillage->num_cel_fac_par_voiset[ielt] - 1 ;
            var_voiset[ielt] = var[ind_elt_per] ;

          }

    }

  }

}


/*----------------------------------------------------------------------------
 * Interface FORTRAN pour les echanges sur le voisinage étendu lorsqu'il est
 *   traité séparément du halo classique. Le tableau traité est supposé
 *   correctement dimensionné (ncelet + nombre de cellules halo étendu).
 *
 * Appelée en périodique uniquement.
 *
 * Interface Fortran :
 *
 * SUBROUTINE PERCVE
 * *****************
 *
 *    & ( PVAR )
 *
 *----------------------------------------------------------------------------*/

void CS_PROCF (percve, PERCVE)
(
       cs_real_t         pvar[]       /* <-> tab. echangé                     */
 CS_ARGF_SUPP_CHAINE                  /*     (arguments 'longueur' éventuels,
                                             Fortran, inutilisés lors de
                                             l'appel mais placés par de
                                             nombreux compilateurs)           */
)
{
        cs_real_t       *pvar_voiset ;

  cs_maillage_t         *maillage = cs_glob_maillage;


  /* Utile uniquement pour le voisinage étendu séparé */

  if(maillage->ind_type_voiset == CS_MAILLAGE_TYPE_VOISET_SEPARE) {

    /* Identification des pointeurs sur le voisinage étendu séparé */

    if(maillage->nbr_cel_fac_par_voiset > 0) {
      pvar_voiset = pvar + (maillage->nbr_cel + maillage->nbr_cel_fac_par) ;
    }
    else {
      pvar_voiset = NULL ;
    }

    /* Echanges périodiques */

    cs_perio_percve   (pvar, pvar_voiset) ;

  }
}


/*----------------------------------------------------------------------------
 * Gestion de la périodicité pour INIMAS
 *
 * Dans le cas ou INIMAS est appele dans NAVSTO :
 *    On suppose que le gradient aux cellules halo obtenu par une rotation
 *    est connu et est celui de la vitesse au pas de temps précédent
 * Dans le cas ou INIMAS est appele dans DIVRIJ :
 *    On suppose (et ceci est plus justifiable que ce qui précède) que le
 *    gradient aux cellules halo obtenu par une rotation est celui des
 *    varaibles Rij au pas de temps précédent
 *
 * Il reste encore à tester cette approche
 *
 * Interface Fortran :
 *
 * SUBROUTINE PERMAS
 * *****************
 *
 * INTEGER          IMASPE      :  -> : suivant l'appel de INIMAS
 *                                          = 1 si appel de RESOLP ou NAVSTO
 *                                          = 2 si appel de DIVRIJ
 * INTEGER          IPHAS       :  -> : numero de phase courante
 * INTEGER          IMASPE      :  -> : indicateur d'appel dans INIMAS
 *                                          = 1 si appel au debut
 *                                          = 2 si appel a la fin
 * DOUBLE PRECISION ROM(NCELET) :  -> : masse volumique aux cellules
 * DOUBLE PRECISION DUDXYZ      :  -> : gradient de U aux cellules halo pour
 *                                      l'approche explicite en periodicite
 * DOUBLE PRECISION DRDXYZ      :  -> : gradient de R aux cellules halo pour
 *                                      l'approche explicite en periodicite
 * DOUBLE PRECISION WDUDXY      :  -  : tableau de travail pour DUDXYZ
 * DOUBLE PRECISION WDRDXY      :  -  : tableau de travail pour DRDXYZ
 *
 * Les tableaux DUDXYZ et WDUDXY sont de taille (NCELET-NCEL)*3*3*NPHAS
 * Les tableaux DRDXYZ et WDRDXY sont de taille (NCELET-NCEL)*6*3*NPHAS
 *----------------------------------------------------------------------------*/

void CS_PROCF (permas, PERMAS)
(
 const cs_int_t    *imaspe,
 const cs_int_t    *iphas,
 const cs_int_t    *iappel,
 const cs_real_t    rom[],
       cs_real_t   *dudxyz,
       cs_real_t   *drdxyz,
       cs_real_t   *wdudxy,
       cs_real_t   *wdrdxy
)
{

  cs_int_t   i, j ;

  cs_int_t   ind_loc ;
  cs_int_t   dbloc ;

  cs_int_t   iper ;
  cs_int_t   ipos ;

  cs_int_t   ielt ;
  cs_int_t   ind_elt_per ;


  cs_maillage_t    *maillage = cs_glob_maillage ;

  const cs_int_t   ncelet = maillage->nbr_cel_etendu ;
  const cs_int_t   ncel   = maillage->nbr_cel ;

  const cs_int_t ncelhalo = ncelet - ncel ;

  /* Attention! Difference C/Fortran pour l'indicage des tableaux */

  const cs_int_t iphas_c = *iphas - 1;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/



  /* Premier passage */

  if (*iappel == 1) {

    if (*imaspe == 1)


      for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

        dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

        if (maillage->nbr_dom == 1 ||
            maillage->num_dom_fac_par[ind_loc] == maillage->num_dom)

          for (iper = 0 ; iper < maillage->nbr_per ; iper++)

            for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                 ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                 ielt++) {

              ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;

              for (i = 0 ; i < CS_DIM_3 ; i++)
                for (j = 0 ; j < CS_DIM_3 ; j++) {

                  ipos = ielt + ncelhalo*i + CS_DIM_3*ncelhalo*j +
                    CS_DIM_3*CS_DIM_3*ncelhalo*iphas_c ;

                  wdudxy[ipos] = dudxyz[ipos] ;
                  dudxyz[ipos] = rom[ind_elt_per] * dudxyz[ipos] ;

                }

            } /* Fin boucle periodicites sur domaine courant */

        else

          for (iper = 0 ; iper < maillage->nbr_per ; iper++)

            for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                 ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                 ielt++) {

              for (i = 0 ; i < CS_DIM_3 ; i++)
                for (j = 0 ; j < CS_DIM_3 ; j++) {

                  ipos = ielt + ncelhalo*i + CS_DIM_3*ncelhalo*j +
                    CS_DIM_3*CS_DIM_3*ncelhalo*iphas_c ;

                  wdudxy[ipos] = dudxyz[ipos] ;
                  dudxyz[ipos] = rom[ielt] * dudxyz[ipos] ;

                }

            }

      } /* Fin boucle domaines */


    else if (*imaspe == 2)


      for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

        dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

        if (maillage->nbr_dom == 1 ||
            maillage->num_dom_fac_par[ind_loc] == maillage->num_dom)

          for (iper = 0 ; iper < maillage->nbr_per ; iper++)

            for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                 ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                 ielt++) {

              ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;

              for (i = 0 ; i < 2 * CS_DIM_3 ; i++)
                for (j = 0 ; j < CS_DIM_3 ; j++) {

                  ipos = ielt + ncelhalo*i + 2*CS_DIM_3*ncelhalo*j +
                    CS_DIM_3*2*CS_DIM_3*ncelhalo*iphas_c ;

                  wdrdxy[ipos] = drdxyz[ipos] ;
                  drdxyz[ipos] = rom[ind_elt_per] * drdxyz[ipos] ;

                }

            } /* Fin boucle periodicites sur domaine courant */

        else

          for (iper = 0 ; iper < maillage->nbr_per ; iper++)

            for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                 ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                 ielt++) {

              for (i = 0 ; i < 2 * CS_DIM_3 ; i++)
                for (j = 0 ; j < CS_DIM_3 ; j++) {

                  ipos = ielt + ncelhalo*i + 2*CS_DIM_3*ncelhalo*j +
                    CS_DIM_3*2*CS_DIM_3*ncelhalo*iphas_c ;

                  wdrdxy[ipos] = drdxyz[ipos] ;
                  drdxyz[ipos] = rom[ielt] * drdxyz[ipos] ;

                }

            }

      } /* Fin boucle domaines */

  } /* Fin iappel == 1 */


  /* Second passage */

  else if (*iappel == 2) {

    if (*imaspe == 1)


      for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

        dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

        for (iper = 0 ; iper < maillage->nbr_per ; iper++)

          for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
               ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
               ielt++) {

            for (i = 0 ; i < CS_DIM_3 ; i++)
              for (j = 0 ; j < CS_DIM_3 ; j++) {

                ipos = ielt + ncelhalo*i + CS_DIM_3*ncelhalo*j +
                  CS_DIM_3*CS_DIM_3*ncelhalo*iphas_c ;

                dudxyz[ipos] = wdudxy[ipos] ;

              }

          }

      }


    else if (*imaspe == 2)


      for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

        dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

        for (iper = 0 ; iper < maillage->nbr_per ; iper++)

          for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
               ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
               ielt++) {

            for (i = 0 ; i < 2 * CS_DIM_3 ; i++)
              for (j = 0 ; j < CS_DIM_3 ; j++) {

                ipos = ielt + ncelhalo*i + 2*CS_DIM_3*ncelhalo*j +
                  CS_DIM_3*2*CS_DIM_3*ncelhalo*iphas_c ;

                drdxyz[ipos] = wdrdxy[ipos] ;

              }

          }

      }


  } /* Fin iappel == 2 */


}


/*----------------------------------------------------------------------------
 * Préparation des tableaux DPDX, DPDY et DPDZ pour GRADRC en cas de
 * périodicité de rotation pour la vitesse et les tensions de Reynolds
 *
 * Pour la vitesse et les tensions de Reynolds, on récupère le gradient estimé
 * par PERINU et PERINR (PHYVAR) dans le tableau représentant le halo et on
 * l'affecte au gradient DPDX, DPDY, DPDZ (tableaux NCELET).
 *
 *  La nécessité de disposer des trois composantes interdit la prise en compte
 * implicite des périodicités de rotation du gradient de grandeurs non
 * scalaires dans GRADRC.
 *  Les valeurs correspondant à des périodicités de translation peuvent par
 * contre etre traitées en implicite : elles seront écrasées plus loin dans
 * GRADRC.
 *  Pour les variables U er R, on indique donc qu'il ne reste qu'à transférer
 * les valeurs de périodicité de translation, et pour cela on positionne
 * IDIMTE=0, ITENSO=2.
 *  Pour les autres variables, on suppose qu'il est correct de traiter toutes
 * les périodicités en implicite dans GRADRC, et on positionne alors IDIMTE=1,
 * ITENSO=0.
 *
 * Interface Fortran :
 *
 * SUBROUTINE PERING
 * *****************
 *
 * INTEGER          NPHAS        :  -> : numero de phase courante
 * INTEGER          IVAR         :  -> : numero de la variable
 * INTEGER          IDIMTE       :  -> : dimension de la variable (maximum 3)
 *                                        0 : scalaire (VAR11), ou assimile
 *                                            scalaire
 *                                        1 : vecteur (VAR11,VAR22,VAR33)
 *                                        2 : tenseur d'ordre 2 (VARIJ)
 *                                       21 : tenseur d'ordre 2 suppose
 *                                            diagonal (VAR11, VAR22, VAR33)
 * INTEGER          ITENSO       :  -> : pour l'explicitation de la rotation
 *                                        0 : scalaire (VAR11)
 *                                        1 : composante de vecteur ou de
 *                                            tenseur (VAR11) implicite pour
 *                                            la translation
 *                                       11 : reprend le traitement ITENSO=1
 *                                            et composante de vecteur ou de
 *                                            tenseur annulee pour la rotation
 *                                        2 : vecteur (VAR11 et VAR22 et VAR33)
 *                                            implicite pour la rotation
 * INTEGER          IPEROT       :  -> : indicateur du nombre de periodicte de
 *                                       rotation
 * INTEGER          IGUPER       :  -> : 0/1 indique qu'on a /n'a pas calcule
 *                                       les gradients dans DUDXYZ
 * INTEGER          IGRPER       :  -> : 0/1 indique qu'on a /n'a pas calcule
 *                                       les gradients dans DRDXYZ
 * INTEGER          IU           :  -> : position de la Vitesse(x,y,z)
 * INTEGER          IV           :  -> : dans RTP, RTPA
 * INTEGER          IW           :  -> :     "                   "
 * INTEGER          ITYTUR       :  -> : turbulence (Rij-epsilon ITYTUR = 3)
 * INTEGER          IR11         :  -> : position des Tensions de Reynolds
 * INTEGER          IR22         :  -> : en Rij dans RTP, RTPA
 * INTEGER          IR33         :  -> :     "                   "
 * INTEGER          IR12         :  -> :     "                   "
 * INTEGER          IR13         :  -> :     "                   "
 * INTEGER          IR23         :  -> :     "                   "
 * DOUBLE PRECISION DPDX(NCELET) :  -> : gradient de IVAR
 * DOUBLE PRECISION DPDY(NCELET) :  -> :    "        "
 * DOUBLE PRECISION DPDZ(NCELET) :  -> :    "        "
 * DOUBLE PRECISION DUDXYZ       :  -> : gradient de U aux cellules halo pour
 *                                       l'approche explicite en periodicite
 * DOUBLE PRECISION DRDXYZ       :  -> : gradient de R aux cellules halo pour
 *                                       l'approche explicite en periodicite
 *
 * Le tableau DUDXYZ est de taille (NCELET-NCEL)*3*3*NPHAS
 * Le tableau DRDXYZ est de taille (NCELET-NCEL)*6*3*NPHAS
 *----------------------------------------------------------------------------*/

void CS_PROCF (pering, PERING)
(
 const cs_int_t    *nphas,
 const cs_int_t    *ivar,
       cs_int_t    *idimte,
       cs_int_t    *itenso,
 const cs_int_t    *iperot,
 const cs_int_t    *iguper,
 const cs_int_t    *igrper,
 const cs_int_t     iu[CS_NPHSMX],
 const cs_int_t     iv[CS_NPHSMX],
 const cs_int_t     iw[CS_NPHSMX],
 const cs_int_t     itytur[CS_NPHSMX],
 const cs_int_t     ir11[CS_NPHSMX],
 const cs_int_t     ir22[CS_NPHSMX],
 const cs_int_t     ir33[CS_NPHSMX],
 const cs_int_t     ir12[CS_NPHSMX],
 const cs_int_t     ir13[CS_NPHSMX],
 const cs_int_t     ir23[CS_NPHSMX],
       cs_real_t    dpdx[],
       cs_real_t    dpdy[],
       cs_real_t    dpdz[],
       cs_real_t   *dudxyz,
       cs_real_t   *drdxyz
)
{

  cs_int_t   ind_loc ;
  cs_int_t   dbloc ;

  cs_int_t   iper ;
  cs_int_t   ielt ;
  cs_int_t   iphas ;
  cs_int_t   indic ;
  cs_int_t   ind_var ;

  cs_maillage_t    *maillage = cs_glob_maillage ;

  const cs_int_t   ncelet = maillage->nbr_cel_etendu ;
  const cs_int_t   ncel   = maillage->nbr_cel ;

  const cs_int_t ncelhalo = ncelet - ncel ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /* Par defaut, on traitera le gradient comme un vecteur ...
     (i.e. on suppose que c'est le gradient d'une grandeurs scalaire) */

  *idimte = 1 ;
  *itenso = 0 ;


  /*
     Lorsqu'il y a de la rotation (potentielle) :
       - On determine si la variable est un vecteur (vitesse) ou un tenseur
         (de Reynolds)
       - On recupere alors dans le halo son gradient evalue au pas de temps
         precedent sans reconstruction
       - On positionne (a la fin) IDIMTE et ITENSO pour que dans percom
         les cellules halo non rotation soient ecrasees par la "bonne" valeur
         du gradient, et que les cellules halo rotation restent inchangees
  */

  if (*iperot > 0) {

    indic = 0 ;

    for (iphas = 0 ; iphas < *nphas ; iphas++) {

      if (*ivar == iu[iphas]) {

        indic = 1 ;

        if (*iguper == 1)

          for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

            dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

            for (iper = 0 ; iper < maillage->nbr_per ; iper++)
              for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                   ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                   ielt++) {

                dpdx[ncel + ielt] =
                  dudxyz[ielt + ncelhalo*0 + CS_DIM_3*ncelhalo*0 +
                         CS_DIM_3*CS_DIM_3*ncelhalo*iphas] ;

                dpdy[ncel + ielt] =
                  dudxyz[ielt + ncelhalo*0 + CS_DIM_3*ncelhalo*1 +
                         CS_DIM_3*CS_DIM_3*ncelhalo*iphas] ;

                dpdz[ncel + ielt] =
                  dudxyz[ielt + ncelhalo*0 + CS_DIM_3*ncelhalo*2 +
                         CS_DIM_3*CS_DIM_3*ncelhalo*iphas] ;

              }

          }

      } /* Fin ivar == iu[iphas] */

      else if (*ivar == iv[iphas]) {

        indic = 1 ;

        if (*iguper == 1)

          for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

            dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

            for (iper = 0 ; iper < maillage->nbr_per ; iper++)
              for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                   ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                   ielt++) {

                dpdx[ncel + ielt] =
                  dudxyz[ielt + ncelhalo*1 + CS_DIM_3*ncelhalo*0 +
                         CS_DIM_3*CS_DIM_3*ncelhalo*iphas] ;

                dpdy[ncel + ielt] =
                  dudxyz[ielt + ncelhalo*1 + CS_DIM_3*ncelhalo*1 +
                         CS_DIM_3*CS_DIM_3*ncelhalo*iphas] ;

                dpdz[ncel + ielt] =
                  dudxyz[ielt + ncelhalo*1 + CS_DIM_3*ncelhalo*2 +
                         CS_DIM_3*CS_DIM_3*ncelhalo*iphas] ;

              }

          }

      } /* Fin ivar == iv[iphas] */

      else if (*ivar == iw[iphas]) {

        indic = 1 ;

        if (*iguper == 1)

          for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

            dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

            for (iper = 0 ; iper < maillage->nbr_per ; iper++)

              for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                   ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                   ielt++) {

                dpdx[ncel + ielt] =
                  dudxyz[ielt + ncelhalo*2 + CS_DIM_3*ncelhalo*0 +
                         CS_DIM_3*CS_DIM_3*ncelhalo*iphas] ;

                dpdy[ncel + ielt] =
                  dudxyz[ielt + ncelhalo*2 + CS_DIM_3*ncelhalo*1 +
                         CS_DIM_3*CS_DIM_3*ncelhalo*iphas] ;

                dpdz[ncel + ielt] =
                  dudxyz[ielt + ncelhalo*2 + CS_DIM_3*ncelhalo*2 +
                         CS_DIM_3*CS_DIM_3*ncelhalo*iphas] ;

              }

          }

      } /* Fin ivar == iw[iphas] */

      else if ((itytur[iphas] == 3) &&
               (*ivar == ir11[iphas] || *ivar == ir22[iphas] ||
                *ivar == ir33[iphas] || *ivar == ir12[iphas] ||
                *ivar == ir13[iphas] || *ivar == ir23[iphas])) {

        if (*ivar == ir11[iphas]) ind_var = 0 ;
        if (*ivar == ir22[iphas]) ind_var = 1 ;
        if (*ivar == ir33[iphas]) ind_var = 2 ;
        if (*ivar == ir12[iphas]) ind_var = 3 ;
        if (*ivar == ir13[iphas]) ind_var = 4 ;
        if (*ivar == ir23[iphas]) ind_var = 5 ;

        indic = 1 ;

        if (*igrper == 1)

          for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

            dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

            for (iper = 0 ; iper < maillage->nbr_per ; iper++)
              for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
                   ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
                   ielt++) {

                dpdx[ncel + ielt] =
                  drdxyz[ielt + ncelhalo*ind_var + 2*CS_DIM_3*ncelhalo*0 +
                         CS_DIM_3*2*CS_DIM_3*ncelhalo*iphas] ;

                dpdy[ncel + ielt] =
                  drdxyz[ielt + ncelhalo*ind_var + 2*CS_DIM_3*ncelhalo*1 +
                         CS_DIM_3*2*CS_DIM_3*ncelhalo*iphas] ;

                dpdz[ncel + ielt] =
                  drdxyz[ielt + ncelhalo*ind_var + 2*CS_DIM_3*ncelhalo*2 +
                         CS_DIM_3*2*CS_DIM_3*ncelhalo*iphas] ;

              }

          }

      } /* Fin itytur[iphas] == 3 && ivar == ir..[iphas] */


    } /* Fin de la boucle sur les phases */


    if (indic == 1) {
      *idimte = 0 ;
      *itenso = 2 ;
    }


  }

}


/*----------------------------------------------------------------------------
 * Routine d'echange de tableaux pour PERINU
 *
 * Interface Fortran :
 *
 * SUBROUTINE PEINU1
 * *****************
 *
 * INTEGER          ISOU          :  -> : composante de la vitesse
 * INTEGER          IPHAS         :  -> : numero de phase courante
 * DOUBLE PRECISION DUDXYZ        :  -> : gradient de U aux cellules halo pour
 *                                        l'approche explicite en periodicite
 * DOUBLE PRECISION W1..3(NCELET) :  -  : tableaux de travail
 *
 * Le tableau DUDXYZ est de taille (NCELET-NCEL)*3*3*NPHAS
 *----------------------------------------------------------------------------*/

void CS_PROCF (peinu1, PEINU1)
(
 const cs_int_t    *isou,
 const cs_int_t    *iphas,
       cs_real_t   *dudxyz,
       cs_real_t    w1[],
       cs_real_t    w2[],
       cs_real_t    w3[]
)
{

  cs_int_t   ind_loc ;
  cs_int_t   dbloc ;

  cs_int_t   iper ;
  cs_int_t   ielt ;
  cs_int_t   ind_elt_per ;

  cs_maillage_t *maillage = cs_glob_maillage ;

  const cs_int_t ncelet = maillage->nbr_cel_etendu ;
  const cs_int_t ncel   = maillage->nbr_cel ;

  const cs_int_t ncelhalo = ncelet - ncel ;

  /* Attention! Difference C/Fortran pour l'indicage des tableaux */

  const cs_int_t isou_c  = *isou - 1 ;
  const cs_int_t iphas_c = *iphas - 1 ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

    dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

    if (maillage->nbr_dom == 1 ||
        maillage->num_dom_fac_par[ind_loc] == maillage->num_dom)

      for (iper = 0 ; iper < maillage->nbr_per ; iper++)

        for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
             ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
             ielt++) {

          ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;


          dudxyz[ielt + ncelhalo*isou_c +  CS_DIM_3*ncelhalo*0 +
                 CS_DIM_3*CS_DIM_3*ncelhalo*iphas_c] =
            w1[ind_elt_per] ;

          dudxyz[ielt + ncelhalo*isou_c +  CS_DIM_3*ncelhalo*1 +
                 CS_DIM_3*CS_DIM_3*ncelhalo*iphas_c] =
            w2[ind_elt_per] ;

          dudxyz[ielt + ncelhalo*isou_c +  CS_DIM_3*ncelhalo*2 +
                 CS_DIM_3*CS_DIM_3*ncelhalo*iphas_c] =
            w3[ind_elt_per] ;

      } /* Fin boucle periodicites sur domaine courant */

    else

      for (iper = 0 ; iper < maillage->nbr_per ; iper++)

        for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
             ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
             ielt++) {

          dudxyz[ielt + ncelhalo*isou_c +  CS_DIM_3*ncelhalo*0 +
                 CS_DIM_3*CS_DIM_3*ncelhalo*iphas_c] =
            w1[ncel + ielt] ;

          dudxyz[ielt + ncelhalo*isou_c +  CS_DIM_3*ncelhalo*1 +
                 CS_DIM_3*CS_DIM_3*ncelhalo*iphas_c] =
            w2[ncel + ielt] ;

          dudxyz[ielt + ncelhalo*isou_c +  CS_DIM_3*ncelhalo*2 +
                 CS_DIM_3*CS_DIM_3*ncelhalo*iphas_c] =
            w3[ncel + ielt] ;

        }


   } /* Fin boucle domaines */


}


/*----------------------------------------------------------------------------
 * On fait tourner le tenseur DUDXYZ
 *
 * Interface Fortran :
 *
 * SUBROUTINE PEINU2 (VAR)
 * *****************
 *
 * INTEGER          IPHAS         :  -> : numero de phase courante
 * DOUBLE PRECISION DUDXYZ        :  -> : gradient de U aux cellules halo pour
 *                                        l'approche explicite en periodicite
 *
 * Le tableau DUDXYZ est de taille (NCELET-NCEL)*3*3*NPHAS
 *----------------------------------------------------------------------------*/

void CS_PROCF (peinu2, PEINU2)
(
 const cs_int_t    *iphas,
       cs_real_t   *dudxyz
)
{

  cs_int_t   i, j, k ;

  cs_int_t   ind_loc ;
  cs_int_t   dbloc ;

  cs_int_t   iper ;
  cs_int_t   ielt ;

  cs_real_t  tensA[CS_DIM_3][CS_DIM_3] ;
  cs_real_t  tensB[CS_DIM_3][CS_DIM_3] ;

  cs_maillage_t    *maillage        = cs_glob_maillage ;
  cs_param_perio_t *liste_param_per = maillage->liste_param_per ;

  const cs_int_t ncelet = maillage->nbr_cel_etendu ;
  const cs_int_t ncel   = maillage->nbr_cel ;

  const cs_int_t ncelhalo = ncelet - ncel ;

  /* Attention! Difference C/Fortran pour l'indicage des tableaux */

  const cs_int_t iphas_c = *iphas - 1;

  /* Macro pour la position au sein d'un tableau */

#define POINT_TENS_1(ielt, i, j)   (  \
 ielt + ncelhalo*i + CS_DIM_3*ncelhalo*j + CS_DIM_3*CS_DIM_3*ncelhalo*iphas_c )


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

    dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

    for (iper = 0 ; iper < maillage->nbr_per ; iper++)

      if (liste_param_per[iper].type_perio == CS_PERIO_TYPE_ROTA) {

        /* Transformation sens direct */

        for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
             ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
             ielt++) {

          tensA[0][0] = dudxyz[POINT_TENS_1(ielt,0,0)] * liste_param_per[iper].matrice[0][0] +
                        dudxyz[POINT_TENS_1(ielt,0,1)] * liste_param_per[iper].matrice[0][1] +
                        dudxyz[POINT_TENS_1(ielt,0,2)] * liste_param_per[iper].matrice[0][2] ;
          tensA[0][1] = dudxyz[POINT_TENS_1(ielt,0,0)] * liste_param_per[iper].matrice[1][0] +
                        dudxyz[POINT_TENS_1(ielt,0,1)] * liste_param_per[iper].matrice[1][1] +
                        dudxyz[POINT_TENS_1(ielt,0,2)] * liste_param_per[iper].matrice[1][2] ;
          tensA[0][2] = dudxyz[POINT_TENS_1(ielt,0,0)] * liste_param_per[iper].matrice[2][0] +
                        dudxyz[POINT_TENS_1(ielt,0,1)] * liste_param_per[iper].matrice[2][1] +
                        dudxyz[POINT_TENS_1(ielt,0,2)] * liste_param_per[iper].matrice[2][2] ;

          tensA[1][0] = dudxyz[POINT_TENS_1(ielt,1,0)] * liste_param_per[iper].matrice[0][0] +
                        dudxyz[POINT_TENS_1(ielt,1,1)] * liste_param_per[iper].matrice[0][1] +
                        dudxyz[POINT_TENS_1(ielt,1,2)] * liste_param_per[iper].matrice[0][2] ;
          tensA[1][1] = dudxyz[POINT_TENS_1(ielt,1,0)] * liste_param_per[iper].matrice[1][0] +
                        dudxyz[POINT_TENS_1(ielt,1,1)] * liste_param_per[iper].matrice[1][1] +
                        dudxyz[POINT_TENS_1(ielt,1,2)] * liste_param_per[iper].matrice[1][2] ;
          tensA[1][2] = dudxyz[POINT_TENS_1(ielt,1,0)] * liste_param_per[iper].matrice[2][0] +
                        dudxyz[POINT_TENS_1(ielt,1,1)] * liste_param_per[iper].matrice[2][1] +
                        dudxyz[POINT_TENS_1(ielt,1,2)] * liste_param_per[iper].matrice[2][2] ;

          tensA[2][0] = dudxyz[POINT_TENS_1(ielt,2,0)] * liste_param_per[iper].matrice[0][0] +
                        dudxyz[POINT_TENS_1(ielt,2,1)] * liste_param_per[iper].matrice[0][1] +
                        dudxyz[POINT_TENS_1(ielt,2,2)] * liste_param_per[iper].matrice[0][2] ;
          tensA[2][1] = dudxyz[POINT_TENS_1(ielt,2,0)] * liste_param_per[iper].matrice[1][0] +
                        dudxyz[POINT_TENS_1(ielt,2,1)] * liste_param_per[iper].matrice[1][1] +
                        dudxyz[POINT_TENS_1(ielt,2,2)] * liste_param_per[iper].matrice[1][2] ;
          tensA[2][2] = dudxyz[POINT_TENS_1(ielt,2,0)] * liste_param_per[iper].matrice[2][0] +
                        dudxyz[POINT_TENS_1(ielt,2,1)] * liste_param_per[iper].matrice[2][1] +
                        dudxyz[POINT_TENS_1(ielt,2,2)] * liste_param_per[iper].matrice[2][2] ;

          for (j = 0 ; j < CS_DIM_3 ; j++)
            for (i = 0 ; i < CS_DIM_3 ; i++) {
              tensB[i][j] = 0. ;
              for (k = 0 ; k < CS_DIM_3 ; k++)
                tensB[i][j] += liste_param_per[iper].matrice[i][k] * tensA[k][j] ;
            }

          dudxyz[POINT_TENS_1(ielt,0,0)] = tensB[0][0] ;
          dudxyz[POINT_TENS_1(ielt,0,1)] = tensB[0][1] ;
          dudxyz[POINT_TENS_1(ielt,0,2)] = tensB[0][2] ;
          dudxyz[POINT_TENS_1(ielt,1,0)] = tensB[1][0] ;
          dudxyz[POINT_TENS_1(ielt,1,1)] = tensB[1][1] ;
          dudxyz[POINT_TENS_1(ielt,1,2)] = tensB[1][2] ;
          dudxyz[POINT_TENS_1(ielt,2,0)] = tensB[2][0] ;
          dudxyz[POINT_TENS_1(ielt,2,1)] = tensB[2][1] ;
          dudxyz[POINT_TENS_1(ielt,2,2)] = tensB[2][2] ;

        }

        /* Transformation sens inverse */

        for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
             ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
             ielt++) {

          tensA[0][0] = dudxyz[POINT_TENS_1(ielt,0,0)] * liste_param_per[iper].matrice[0][0] +
                        dudxyz[POINT_TENS_1(ielt,0,1)] * liste_param_per[iper].matrice[1][0] +
                        dudxyz[POINT_TENS_1(ielt,0,2)] * liste_param_per[iper].matrice[2][0] ;
          tensA[0][1] = dudxyz[POINT_TENS_1(ielt,0,0)] * liste_param_per[iper].matrice[0][1] +
                        dudxyz[POINT_TENS_1(ielt,0,1)] * liste_param_per[iper].matrice[1][1] +
                        dudxyz[POINT_TENS_1(ielt,0,2)] * liste_param_per[iper].matrice[2][1] ;
          tensA[0][2] = dudxyz[POINT_TENS_1(ielt,0,0)] * liste_param_per[iper].matrice[0][2] +
                        dudxyz[POINT_TENS_1(ielt,0,1)] * liste_param_per[iper].matrice[1][2] +
                        dudxyz[POINT_TENS_1(ielt,0,2)] * liste_param_per[iper].matrice[2][2] ;

          tensA[1][0] = dudxyz[POINT_TENS_1(ielt,1,0)] * liste_param_per[iper].matrice[0][0] +
                        dudxyz[POINT_TENS_1(ielt,1,1)] * liste_param_per[iper].matrice[1][0] +
                        dudxyz[POINT_TENS_1(ielt,1,2)] * liste_param_per[iper].matrice[2][0] ;
          tensA[1][1] = dudxyz[POINT_TENS_1(ielt,1,0)] * liste_param_per[iper].matrice[0][1] +
                        dudxyz[POINT_TENS_1(ielt,1,1)] * liste_param_per[iper].matrice[1][1] +
                        dudxyz[POINT_TENS_1(ielt,1,2)] * liste_param_per[iper].matrice[2][1] ;
          tensA[1][2] = dudxyz[POINT_TENS_1(ielt,1,0)] * liste_param_per[iper].matrice[0][2] +
                        dudxyz[POINT_TENS_1(ielt,1,1)] * liste_param_per[iper].matrice[1][2] +
                        dudxyz[POINT_TENS_1(ielt,1,2)] * liste_param_per[iper].matrice[2][2] ;

          tensA[2][0] = dudxyz[POINT_TENS_1(ielt,2,0)] * liste_param_per[iper].matrice[0][0] +
                        dudxyz[POINT_TENS_1(ielt,2,1)] * liste_param_per[iper].matrice[1][0] +
                        dudxyz[POINT_TENS_1(ielt,2,2)] * liste_param_per[iper].matrice[2][0] ;
          tensA[2][1] = dudxyz[POINT_TENS_1(ielt,2,0)] * liste_param_per[iper].matrice[0][1] +
                        dudxyz[POINT_TENS_1(ielt,2,1)] * liste_param_per[iper].matrice[1][1] +
                        dudxyz[POINT_TENS_1(ielt,2,2)] * liste_param_per[iper].matrice[2][1] ;
          tensA[2][2] = dudxyz[POINT_TENS_1(ielt,2,0)] * liste_param_per[iper].matrice[0][2] +
                        dudxyz[POINT_TENS_1(ielt,2,1)] * liste_param_per[iper].matrice[1][2] +
                        dudxyz[POINT_TENS_1(ielt,2,2)] * liste_param_per[iper].matrice[2][2] ;

          for (j = 0 ; j < CS_DIM_3 ; j++)
            for (i = 0 ; i < CS_DIM_3 ; i++) {
              tensB[i][j] = 0. ;
              for (k = 0 ; k < CS_DIM_3 ; k++)
                tensB[i][j] += liste_param_per[iper].matrice[k][i] * tensA[k][j] ;
            }

          dudxyz[POINT_TENS_1(ielt,0,0)] = tensB[0][0] ;
          dudxyz[POINT_TENS_1(ielt,0,1)] = tensB[0][1] ;
          dudxyz[POINT_TENS_1(ielt,0,2)] = tensB[0][2] ;
          dudxyz[POINT_TENS_1(ielt,1,0)] = tensB[1][0] ;
          dudxyz[POINT_TENS_1(ielt,1,1)] = tensB[1][1] ;
          dudxyz[POINT_TENS_1(ielt,1,2)] = tensB[1][2] ;
          dudxyz[POINT_TENS_1(ielt,2,0)] = tensB[2][0] ;
          dudxyz[POINT_TENS_1(ielt,2,1)] = tensB[2][1] ;
          dudxyz[POINT_TENS_1(ielt,2,2)] = tensB[2][2] ;

        }

      } /* Fin boucle periodicites */

  } /* Fin boucle domaines */


}


/*----------------------------------------------------------------------------
 * Routine d'echange de tableaux pour PERINR
 *
 * Interface Fortran :
 *
 * SUBROUTINE PEINR1 (VAR)
 * *****************
 *
 * INTEGER          ISOU          :  -> : composante du tenseur de Reynolds
 * INTEGER          IPHAS         :  -> : numero de phase courante
 * DOUBLE PRECISION DRDXYZ        :  -> : gradient de U aux cellules halo pour
 *                                        l'approche explicite en periodicite
 * DOUBLE PRECISION W1..3(NCELET) :  -  : tableaux de travail
 *
 * Le tableau DRDXYZ est de taille (NCELET-NCEL)*6*3*NPHAS
 *----------------------------------------------------------------------------*/

void CS_PROCF (peinr1, PEINR1)
(
 const cs_int_t    *isou,
 const cs_int_t    *iphas,
       cs_real_t   *drdxyz,
       cs_real_t    w1[],
       cs_real_t    w2[],
       cs_real_t    w3[]
)
{

  cs_int_t   ind_loc ;
  cs_int_t   dbloc ;

  cs_int_t   iper ;
  cs_int_t   ielt ;
  cs_int_t   ind_elt_per ;

  cs_maillage_t *maillage = cs_glob_maillage ;

  const cs_int_t ncelet = maillage->nbr_cel_etendu ;
  const cs_int_t ncel   = maillage->nbr_cel ;

  const cs_int_t ncelhalo = ncelet - ncel ;

  /* Attention! Difference C/Fortran pour l'indicage des tableaux */

  const cs_int_t isou_c  = *isou - 1 ;
  const cs_int_t iphas_c = *iphas - 1 ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

    dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

    if (maillage->nbr_dom == 1 ||
        maillage->num_dom_fac_par[ind_loc] == maillage->num_dom)

      for (iper = 0 ; iper < maillage->nbr_per ; iper++)

        for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
             ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
             ielt++) {

          ind_elt_per = maillage->num_cel_fac_par[ielt] - 1 ;


          drdxyz[ielt + ncelhalo*isou_c + 2*CS_DIM_3*ncelhalo*0 +
                 CS_DIM_3*2*CS_DIM_3*ncelhalo*iphas_c] =
            w1[ind_elt_per] ;

          drdxyz[ielt + ncelhalo*isou_c + 2*CS_DIM_3*ncelhalo*1 +
                 CS_DIM_3*2*CS_DIM_3*ncelhalo*iphas_c] =
            w2[ind_elt_per] ;

          drdxyz[ielt + ncelhalo*isou_c + 2*CS_DIM_3*ncelhalo*2 +
                 CS_DIM_3*2*CS_DIM_3*ncelhalo*iphas_c] =
            w3[ind_elt_per] ;

        } /* Fin boucle periodicites sur domaine courant */

    else

      for (iper = 0 ; iper < maillage->nbr_per ; iper++)

        for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
             ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
             ielt++) {

          drdxyz[ielt + ncelhalo*isou_c + 2*CS_DIM_3*ncelhalo*0 +
                 CS_DIM_3*2*CS_DIM_3*ncelhalo*iphas_c] =
            w1[ncel + ielt] ;

          drdxyz[ielt + ncelhalo*isou_c + 2*CS_DIM_3*ncelhalo*1 +
                 CS_DIM_3*2*CS_DIM_3*ncelhalo*iphas_c] =
            w2[ncel + ielt] ;

          drdxyz[ielt + ncelhalo*isou_c + 2*CS_DIM_3*ncelhalo*2 +
                 CS_DIM_3*2*CS_DIM_3*ncelhalo*iphas_c] =
            w3[ncel + ielt] ;

      }


  } /* Fin boucle domaines */


}


/*----------------------------------------------------------------------------
 * On fait tourner le tenseur DRDXYZ
 *
 * Interface Fortran :
 *
 * SUBROUTINE PEINR2 (VAR)
 * *****************
 *
 * INTEGER          IPHAS         :  -> : numero de phase courante
 * DOUBLE PRECISION DRDXYZ        :  -> : gradient de U aux cellules halo pour
 *                                        l'approche explicite en periodicite
 *
 * Le tableau DRDXYZ est de taille (NCELET-NCEL)*6*3*NPHAS
 *----------------------------------------------------------------------------*/

void CS_PROCF (peinr2, PEINR2)
(
 const cs_int_t    *iphas,
       cs_real_t   *drdxyz
)
{

  cs_int_t   i1, i2, j, k, l, m ;

  cs_int_t   ind_loc ;
  cs_int_t   dbloc ;

  cs_int_t   iper ;
  cs_int_t   ielt ;

  cs_real_t  tensA[CS_DIM_3][CS_DIM_3][CS_DIM_3] ;
  cs_real_t  tensB[CS_DIM_3][CS_DIM_3][CS_DIM_3] ;
  cs_real_t  tensC[CS_DIM_3][CS_DIM_3][CS_DIM_3] ;

  cs_maillage_t    *maillage        = cs_glob_maillage ;
  cs_param_perio_t *liste_param_per = maillage->liste_param_per ;
  const cs_int_t   ncelet = maillage->nbr_cel_etendu ;
  const cs_int_t   ncel   = maillage->nbr_cel ;

  const cs_int_t ncelhalo = ncelet - ncel ;

  /* Attention! Difference C/Fortran pour l'indicage des tableaux */

  const cs_int_t iphas_c = *iphas - 1;

  /* Macro pour la position au sein d'un tableau */

#define POINT_TENS_2(ielt, i, j)   ( \
 ielt + ncelhalo*i + 2*CS_DIM_3*ncelhalo*j + \
 CS_DIM_3*2*CS_DIM_3*ncelhalo*iphas_c )


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  for (ind_loc = 0 ; ind_loc < maillage->nbr_dom_fac_par ; ind_loc++) {

    dbloc = (2*maillage->nbr_per + 1)*ind_loc ;

    for (iper = 0 ; iper < maillage->nbr_per ; iper++)

      if (liste_param_per[iper].type_perio == CS_PERIO_TYPE_ROTA) {

        /* Transformation sens direct */

        for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 1] - 1 ;
             ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
             ielt++) {


          tensA[0][0][0] = drdxyz[POINT_TENS_2(ielt,0,0)] * liste_param_per[iper].matrice[0][0] +
                           drdxyz[POINT_TENS_2(ielt,0,1)] * liste_param_per[iper].matrice[0][1] +
                           drdxyz[POINT_TENS_2(ielt,0,2)] * liste_param_per[iper].matrice[0][2] ;
          tensA[0][1][0] = drdxyz[POINT_TENS_2(ielt,3,0)] * liste_param_per[iper].matrice[0][0] +
                           drdxyz[POINT_TENS_2(ielt,3,1)] * liste_param_per[iper].matrice[0][1] +
                           drdxyz[POINT_TENS_2(ielt,3,2)] * liste_param_per[iper].matrice[0][2] ;
          tensA[0][2][0] = drdxyz[POINT_TENS_2(ielt,4,0)] * liste_param_per[iper].matrice[0][0] +
                           drdxyz[POINT_TENS_2(ielt,4,1)] * liste_param_per[iper].matrice[0][1] +
                           drdxyz[POINT_TENS_2(ielt,4,2)] * liste_param_per[iper].matrice[0][2] ;

          tensA[0][0][1] = drdxyz[POINT_TENS_2(ielt,0,0)] * liste_param_per[iper].matrice[1][0] +
                           drdxyz[POINT_TENS_2(ielt,0,1)] * liste_param_per[iper].matrice[1][1] +
                           drdxyz[POINT_TENS_2(ielt,0,2)] * liste_param_per[iper].matrice[1][2] ;
          tensA[0][1][1] = drdxyz[POINT_TENS_2(ielt,3,0)] * liste_param_per[iper].matrice[1][0] +
                           drdxyz[POINT_TENS_2(ielt,3,1)] * liste_param_per[iper].matrice[1][1] +
                           drdxyz[POINT_TENS_2(ielt,3,2)] * liste_param_per[iper].matrice[1][2] ;
          tensA[0][2][1] = drdxyz[POINT_TENS_2(ielt,4,0)] * liste_param_per[iper].matrice[1][0] +
                           drdxyz[POINT_TENS_2(ielt,4,1)] * liste_param_per[iper].matrice[1][1] +
                           drdxyz[POINT_TENS_2(ielt,4,2)] * liste_param_per[iper].matrice[1][2] ;

          tensA[0][0][2] = drdxyz[POINT_TENS_2(ielt,0,0)] * liste_param_per[iper].matrice[2][0] +
                           drdxyz[POINT_TENS_2(ielt,0,1)] * liste_param_per[iper].matrice[2][1] +
                           drdxyz[POINT_TENS_2(ielt,0,2)] * liste_param_per[iper].matrice[2][2] ;
          tensA[0][1][2] = drdxyz[POINT_TENS_2(ielt,3,0)] * liste_param_per[iper].matrice[2][0] +
                           drdxyz[POINT_TENS_2(ielt,3,1)] * liste_param_per[iper].matrice[2][1] +
                           drdxyz[POINT_TENS_2(ielt,3,2)] * liste_param_per[iper].matrice[2][2] ;
          tensA[0][2][2] = drdxyz[POINT_TENS_2(ielt,4,0)] * liste_param_per[iper].matrice[2][0] +
                           drdxyz[POINT_TENS_2(ielt,4,1)] * liste_param_per[iper].matrice[2][1] +
                           drdxyz[POINT_TENS_2(ielt,4,2)] * liste_param_per[iper].matrice[2][2] ;

          tensA[1][0][0] = drdxyz[POINT_TENS_2(ielt,3,0)] * liste_param_per[iper].matrice[0][0] +
                           drdxyz[POINT_TENS_2(ielt,3,1)] * liste_param_per[iper].matrice[0][1] +
                           drdxyz[POINT_TENS_2(ielt,3,2)] * liste_param_per[iper].matrice[0][2] ;
          tensA[1][1][0] = drdxyz[POINT_TENS_2(ielt,1,0)] * liste_param_per[iper].matrice[0][0] +
                           drdxyz[POINT_TENS_2(ielt,1,1)] * liste_param_per[iper].matrice[0][1] +
                           drdxyz[POINT_TENS_2(ielt,1,2)] * liste_param_per[iper].matrice[0][2] ;
          tensA[1][2][0] = drdxyz[POINT_TENS_2(ielt,5,0)] * liste_param_per[iper].matrice[0][0] +
                           drdxyz[POINT_TENS_2(ielt,5,1)] * liste_param_per[iper].matrice[0][1] +
                           drdxyz[POINT_TENS_2(ielt,5,2)] * liste_param_per[iper].matrice[0][2] ;

          tensA[1][0][1] = drdxyz[POINT_TENS_2(ielt,3,0)] * liste_param_per[iper].matrice[1][0] +
                           drdxyz[POINT_TENS_2(ielt,3,1)] * liste_param_per[iper].matrice[1][1] +
                           drdxyz[POINT_TENS_2(ielt,3,2)] * liste_param_per[iper].matrice[1][2] ;
          tensA[1][1][1] = drdxyz[POINT_TENS_2(ielt,1,0)] * liste_param_per[iper].matrice[1][0] +
                           drdxyz[POINT_TENS_2(ielt,1,1)] * liste_param_per[iper].matrice[1][1] +
                           drdxyz[POINT_TENS_2(ielt,1,2)] * liste_param_per[iper].matrice[1][2] ;
          tensA[1][2][1] = drdxyz[POINT_TENS_2(ielt,5,0)] * liste_param_per[iper].matrice[1][0] +
                           drdxyz[POINT_TENS_2(ielt,5,1)] * liste_param_per[iper].matrice[1][1] +
                           drdxyz[POINT_TENS_2(ielt,5,2)] * liste_param_per[iper].matrice[1][2] ;

          tensA[1][0][2] = drdxyz[POINT_TENS_2(ielt,3,0)] * liste_param_per[iper].matrice[2][0] +
                           drdxyz[POINT_TENS_2(ielt,3,1)] * liste_param_per[iper].matrice[2][1] +
                           drdxyz[POINT_TENS_2(ielt,3,2)] * liste_param_per[iper].matrice[2][2] ;
          tensA[1][1][2] = drdxyz[POINT_TENS_2(ielt,1,0)] * liste_param_per[iper].matrice[2][0] +
                           drdxyz[POINT_TENS_2(ielt,1,1)] * liste_param_per[iper].matrice[2][1] +
                           drdxyz[POINT_TENS_2(ielt,1,2)] * liste_param_per[iper].matrice[2][2] ;
          tensA[1][2][2] = drdxyz[POINT_TENS_2(ielt,5,0)] * liste_param_per[iper].matrice[2][0] +
                           drdxyz[POINT_TENS_2(ielt,5,1)] * liste_param_per[iper].matrice[2][1] +
                           drdxyz[POINT_TENS_2(ielt,5,2)] * liste_param_per[iper].matrice[2][2] ;

          tensA[2][0][0] = drdxyz[POINT_TENS_2(ielt,4,0)] * liste_param_per[iper].matrice[0][0] +
                           drdxyz[POINT_TENS_2(ielt,4,1)] * liste_param_per[iper].matrice[0][1] +
                           drdxyz[POINT_TENS_2(ielt,4,2)] * liste_param_per[iper].matrice[0][2] ;
          tensA[2][1][0] = drdxyz[POINT_TENS_2(ielt,5,0)] * liste_param_per[iper].matrice[0][0] +
                           drdxyz[POINT_TENS_2(ielt,5,1)] * liste_param_per[iper].matrice[0][1] +
                           drdxyz[POINT_TENS_2(ielt,5,2)] * liste_param_per[iper].matrice[0][2] ;
          tensA[2][2][0] = drdxyz[POINT_TENS_2(ielt,2,0)] * liste_param_per[iper].matrice[0][0] +
                           drdxyz[POINT_TENS_2(ielt,2,1)] * liste_param_per[iper].matrice[0][1] +
                           drdxyz[POINT_TENS_2(ielt,2,2)] * liste_param_per[iper].matrice[0][2] ;

          tensA[2][0][1] = drdxyz[POINT_TENS_2(ielt,4,0)] * liste_param_per[iper].matrice[1][0] +
                           drdxyz[POINT_TENS_2(ielt,4,1)] * liste_param_per[iper].matrice[1][1] +
                           drdxyz[POINT_TENS_2(ielt,4,2)] * liste_param_per[iper].matrice[1][2] ;
          tensA[2][1][1] = drdxyz[POINT_TENS_2(ielt,5,0)] * liste_param_per[iper].matrice[1][0] +
                           drdxyz[POINT_TENS_2(ielt,5,1)] * liste_param_per[iper].matrice[1][1] +
                           drdxyz[POINT_TENS_2(ielt,5,2)] * liste_param_per[iper].matrice[1][2] ;
          tensA[2][2][1] = drdxyz[POINT_TENS_2(ielt,2,0)] * liste_param_per[iper].matrice[1][0] +
                           drdxyz[POINT_TENS_2(ielt,2,1)] * liste_param_per[iper].matrice[1][1] +
                           drdxyz[POINT_TENS_2(ielt,2,2)] * liste_param_per[iper].matrice[1][2] ;

          tensA[2][0][2] = drdxyz[POINT_TENS_2(ielt,4,0)] * liste_param_per[iper].matrice[2][0] +
                           drdxyz[POINT_TENS_2(ielt,4,1)] * liste_param_per[iper].matrice[2][1] +
                           drdxyz[POINT_TENS_2(ielt,4,2)] * liste_param_per[iper].matrice[2][2] ;
          tensA[2][1][2] = drdxyz[POINT_TENS_2(ielt,5,0)] * liste_param_per[iper].matrice[2][0] +
                           drdxyz[POINT_TENS_2(ielt,5,1)] * liste_param_per[iper].matrice[2][1] +
                           drdxyz[POINT_TENS_2(ielt,5,2)] * liste_param_per[iper].matrice[2][2] ;
          tensA[2][2][2] = drdxyz[POINT_TENS_2(ielt,2,0)] * liste_param_per[iper].matrice[2][0] +
                           drdxyz[POINT_TENS_2(ielt,2,1)] * liste_param_per[iper].matrice[2][1] +
                           drdxyz[POINT_TENS_2(ielt,2,2)] * liste_param_per[iper].matrice[2][2] ;


          for (j = 0 ; j < CS_DIM_3 ; j++)
            for (l = 0 ; l < CS_DIM_3 ; l++)
              for (k = 0 ; k < CS_DIM_3 ; k++) {
                tensB[j][l][k] = 0. ;
                for (m = 0 ; m < CS_DIM_3 ; m++)
                  tensB[j][l][k] += liste_param_per[iper].matrice[j][m] * tensA[l][m][k] ;
              }

          for (k = 0 ; k < CS_DIM_3 ; k++)
            for (i1 = 0 ; i1 < CS_DIM_3 ; i1++)
              for (i2 = 0 ; i2 < CS_DIM_3 ; i2++) {
                tensC[k][i1][i2] = 0. ;
                for (l = 0 ; l < CS_DIM_3 ; l++)
                  tensC[k][i1][i2] += liste_param_per[iper].matrice[k][l] * tensB[i1][l][i2] ;
              }


          drdxyz[POINT_TENS_2(ielt,0,0)] = tensC[0][0][0] ;
          drdxyz[POINT_TENS_2(ielt,0,1)] = tensC[0][0][1] ;
          drdxyz[POINT_TENS_2(ielt,0,2)] = tensC[0][0][2] ;

          drdxyz[POINT_TENS_2(ielt,3,0)] = tensC[0][1][0] ;
          drdxyz[POINT_TENS_2(ielt,3,1)] = tensC[0][1][1] ;
          drdxyz[POINT_TENS_2(ielt,3,2)] = tensC[0][1][2] ;

          drdxyz[POINT_TENS_2(ielt,4,0)] = tensC[0][2][0] ;
          drdxyz[POINT_TENS_2(ielt,4,1)] = tensC[0][2][1] ;
          drdxyz[POINT_TENS_2(ielt,4,2)] = tensC[0][2][2] ;

          drdxyz[POINT_TENS_2(ielt,1,0)] = tensC[1][1][0] ;
          drdxyz[POINT_TENS_2(ielt,1,1)] = tensC[1][1][1] ;
          drdxyz[POINT_TENS_2(ielt,1,2)] = tensC[1][1][2] ;

          drdxyz[POINT_TENS_2(ielt,5,0)] = tensC[1][2][0] ;
          drdxyz[POINT_TENS_2(ielt,5,1)] = tensC[1][2][1] ;
          drdxyz[POINT_TENS_2(ielt,5,2)] = tensC[1][2][2] ;

          drdxyz[POINT_TENS_2(ielt,2,0)] = tensC[2][2][0] ;
          drdxyz[POINT_TENS_2(ielt,2,1)] = tensC[2][2][1] ;
          drdxyz[POINT_TENS_2(ielt,2,2)] = tensC[2][2][2] ;


        }


        /* Transformation sens inverse */

        for (ielt = maillage->pos_per_fac_par[dbloc + 2*iper + 2] - 1 ;
             ielt < maillage->pos_per_fac_par[dbloc + 2*iper + 3] - 1 ;
             ielt++) {


          tensA[0][0][0] = drdxyz[POINT_TENS_2(ielt,0,0)] * liste_param_per[iper].matrice[0][0] +
                           drdxyz[POINT_TENS_2(ielt,0,1)] * liste_param_per[iper].matrice[1][0] +
                           drdxyz[POINT_TENS_2(ielt,0,2)] * liste_param_per[iper].matrice[2][0] ;
          tensA[0][1][0] = drdxyz[POINT_TENS_2(ielt,3,0)] * liste_param_per[iper].matrice[0][0] +
                           drdxyz[POINT_TENS_2(ielt,3,1)] * liste_param_per[iper].matrice[1][0] +
                           drdxyz[POINT_TENS_2(ielt,3,2)] * liste_param_per[iper].matrice[2][0] ;
          tensA[0][2][0] = drdxyz[POINT_TENS_2(ielt,4,0)] * liste_param_per[iper].matrice[0][0] +
                           drdxyz[POINT_TENS_2(ielt,4,1)] * liste_param_per[iper].matrice[1][0] +
                           drdxyz[POINT_TENS_2(ielt,4,2)] * liste_param_per[iper].matrice[2][0] ;

          tensA[0][0][1] = drdxyz[POINT_TENS_2(ielt,0,0)] * liste_param_per[iper].matrice[0][1] +
                           drdxyz[POINT_TENS_2(ielt,0,1)] * liste_param_per[iper].matrice[1][1] +
                           drdxyz[POINT_TENS_2(ielt,0,2)] * liste_param_per[iper].matrice[2][1] ;
          tensA[0][1][1] = drdxyz[POINT_TENS_2(ielt,3,0)] * liste_param_per[iper].matrice[0][1] +
                           drdxyz[POINT_TENS_2(ielt,3,1)] * liste_param_per[iper].matrice[1][1] +
                           drdxyz[POINT_TENS_2(ielt,3,2)] * liste_param_per[iper].matrice[2][1] ;
          tensA[0][2][1] = drdxyz[POINT_TENS_2(ielt,4,0)] * liste_param_per[iper].matrice[0][1] +
                           drdxyz[POINT_TENS_2(ielt,4,1)] * liste_param_per[iper].matrice[1][1] +
                           drdxyz[POINT_TENS_2(ielt,4,2)] * liste_param_per[iper].matrice[2][1] ;

          tensA[0][0][2] = drdxyz[POINT_TENS_2(ielt,0,0)] * liste_param_per[iper].matrice[0][2] +
                           drdxyz[POINT_TENS_2(ielt,0,1)] * liste_param_per[iper].matrice[1][2] +
                           drdxyz[POINT_TENS_2(ielt,0,2)] * liste_param_per[iper].matrice[2][2] ;
          tensA[0][1][2] = drdxyz[POINT_TENS_2(ielt,3,0)] * liste_param_per[iper].matrice[0][2] +
                           drdxyz[POINT_TENS_2(ielt,3,1)] * liste_param_per[iper].matrice[1][2] +
                           drdxyz[POINT_TENS_2(ielt,3,2)] * liste_param_per[iper].matrice[2][2] ;
          tensA[0][2][2] = drdxyz[POINT_TENS_2(ielt,4,0)] * liste_param_per[iper].matrice[0][2] +
                           drdxyz[POINT_TENS_2(ielt,4,1)] * liste_param_per[iper].matrice[1][2] +
                           drdxyz[POINT_TENS_2(ielt,4,2)] * liste_param_per[iper].matrice[2][2] ;

          tensA[1][0][0] = drdxyz[POINT_TENS_2(ielt,3,0)] * liste_param_per[iper].matrice[0][0] +
                           drdxyz[POINT_TENS_2(ielt,3,1)] * liste_param_per[iper].matrice[1][0] +
                           drdxyz[POINT_TENS_2(ielt,3,2)] * liste_param_per[iper].matrice[2][0] ;
          tensA[1][1][0] = drdxyz[POINT_TENS_2(ielt,1,0)] * liste_param_per[iper].matrice[0][0] +
                           drdxyz[POINT_TENS_2(ielt,1,1)] * liste_param_per[iper].matrice[1][0] +
                           drdxyz[POINT_TENS_2(ielt,1,2)] * liste_param_per[iper].matrice[2][0] ;
          tensA[1][2][0] = drdxyz[POINT_TENS_2(ielt,5,0)] * liste_param_per[iper].matrice[0][0] +
                           drdxyz[POINT_TENS_2(ielt,5,1)] * liste_param_per[iper].matrice[1][0] +
                           drdxyz[POINT_TENS_2(ielt,5,2)] * liste_param_per[iper].matrice[2][0] ;

          tensA[1][0][1] = drdxyz[POINT_TENS_2(ielt,3,0)] * liste_param_per[iper].matrice[0][1] +
                           drdxyz[POINT_TENS_2(ielt,3,1)] * liste_param_per[iper].matrice[1][1] +
                           drdxyz[POINT_TENS_2(ielt,3,2)] * liste_param_per[iper].matrice[2][1] ;
          tensA[1][1][1] = drdxyz[POINT_TENS_2(ielt,1,0)] * liste_param_per[iper].matrice[0][1] +
                           drdxyz[POINT_TENS_2(ielt,1,1)] * liste_param_per[iper].matrice[1][1] +
                           drdxyz[POINT_TENS_2(ielt,1,2)] * liste_param_per[iper].matrice[2][1] ;
          tensA[1][2][1] = drdxyz[POINT_TENS_2(ielt,5,0)] * liste_param_per[iper].matrice[0][1] +
                           drdxyz[POINT_TENS_2(ielt,5,1)] * liste_param_per[iper].matrice[1][1] +
                           drdxyz[POINT_TENS_2(ielt,5,2)] * liste_param_per[iper].matrice[2][1] ;

          tensA[1][0][2] = drdxyz[POINT_TENS_2(ielt,3,0)] * liste_param_per[iper].matrice[0][2] +
                           drdxyz[POINT_TENS_2(ielt,3,1)] * liste_param_per[iper].matrice[1][2] +
                           drdxyz[POINT_TENS_2(ielt,3,2)] * liste_param_per[iper].matrice[2][2] ;
          tensA[1][1][2] = drdxyz[POINT_TENS_2(ielt,1,0)] * liste_param_per[iper].matrice[0][2] +
                           drdxyz[POINT_TENS_2(ielt,1,1)] * liste_param_per[iper].matrice[1][2] +
                           drdxyz[POINT_TENS_2(ielt,1,2)] * liste_param_per[iper].matrice[2][2] ;
          tensA[1][2][2] = drdxyz[POINT_TENS_2(ielt,5,0)] * liste_param_per[iper].matrice[0][2] +
                           drdxyz[POINT_TENS_2(ielt,5,1)] * liste_param_per[iper].matrice[1][2] +
                           drdxyz[POINT_TENS_2(ielt,5,2)] * liste_param_per[iper].matrice[2][2] ;

          tensA[2][0][0] = drdxyz[POINT_TENS_2(ielt,4,0)] * liste_param_per[iper].matrice[0][0] +
                           drdxyz[POINT_TENS_2(ielt,4,1)] * liste_param_per[iper].matrice[1][0] +
                           drdxyz[POINT_TENS_2(ielt,4,2)] * liste_param_per[iper].matrice[2][0] ;
          tensA[2][1][0] = drdxyz[POINT_TENS_2(ielt,5,0)] * liste_param_per[iper].matrice[0][0] +
                           drdxyz[POINT_TENS_2(ielt,5,1)] * liste_param_per[iper].matrice[1][0] +
                           drdxyz[POINT_TENS_2(ielt,5,2)] * liste_param_per[iper].matrice[2][0] ;
          tensA[2][2][0] = drdxyz[POINT_TENS_2(ielt,2,0)] * liste_param_per[iper].matrice[0][0] +
                           drdxyz[POINT_TENS_2(ielt,2,1)] * liste_param_per[iper].matrice[1][0] +
                           drdxyz[POINT_TENS_2(ielt,2,2)] * liste_param_per[iper].matrice[2][0] ;

          tensA[2][0][1] = drdxyz[POINT_TENS_2(ielt,4,0)] * liste_param_per[iper].matrice[0][1] +
                           drdxyz[POINT_TENS_2(ielt,4,1)] * liste_param_per[iper].matrice[1][1] +
                           drdxyz[POINT_TENS_2(ielt,4,2)] * liste_param_per[iper].matrice[2][1] ;
          tensA[2][1][1] = drdxyz[POINT_TENS_2(ielt,5,0)] * liste_param_per[iper].matrice[0][1] +
                           drdxyz[POINT_TENS_2(ielt,5,1)] * liste_param_per[iper].matrice[1][1] +
                           drdxyz[POINT_TENS_2(ielt,5,2)] * liste_param_per[iper].matrice[2][1] ;
          tensA[2][2][1] = drdxyz[POINT_TENS_2(ielt,2,0)] * liste_param_per[iper].matrice[0][1] +
                           drdxyz[POINT_TENS_2(ielt,2,1)] * liste_param_per[iper].matrice[1][1] +
                           drdxyz[POINT_TENS_2(ielt,2,2)] * liste_param_per[iper].matrice[2][1] ;

          tensA[2][0][2] = drdxyz[POINT_TENS_2(ielt,4,0)] * liste_param_per[iper].matrice[0][2] +
                           drdxyz[POINT_TENS_2(ielt,4,1)] * liste_param_per[iper].matrice[1][2] +
                           drdxyz[POINT_TENS_2(ielt,4,2)] * liste_param_per[iper].matrice[2][2] ;
          tensA[2][1][2] = drdxyz[POINT_TENS_2(ielt,5,0)] * liste_param_per[iper].matrice[0][2] +
                           drdxyz[POINT_TENS_2(ielt,5,1)] * liste_param_per[iper].matrice[1][2] +
                           drdxyz[POINT_TENS_2(ielt,5,2)] * liste_param_per[iper].matrice[2][2] ;
          tensA[2][2][2] = drdxyz[POINT_TENS_2(ielt,2,0)] * liste_param_per[iper].matrice[0][2] +
                           drdxyz[POINT_TENS_2(ielt,2,1)] * liste_param_per[iper].matrice[1][2] +
                           drdxyz[POINT_TENS_2(ielt,2,2)] * liste_param_per[iper].matrice[2][2] ;


          for (j = 0 ; j < CS_DIM_3 ; j++)
            for (l = 0 ; l < CS_DIM_3 ; l++)
              for (k = 0 ; k < CS_DIM_3 ; k++) {
                tensB[j][l][k] = 0. ;
                for (m = 0 ; m < CS_DIM_3 ; m++)
                  tensB[j][l][k] += liste_param_per[iper].matrice[m][j] * tensA[l][m][k] ;
              }

          for (k = 0 ; k < CS_DIM_3 ; k++)
            for (i1 = 0 ; i1 < CS_DIM_3 ; i1++)
              for (i2 = 0 ; i2 < CS_DIM_3 ; i2++) {
                tensC[k][i1][i2] = 0. ;
                for (l = 0 ; l < CS_DIM_3 ; l++)
                  tensC[k][i1][i2] += liste_param_per[iper].matrice[l][k] * tensB[i1][l][i2] ;
              }


          drdxyz[POINT_TENS_2(ielt,0,0)] = tensC[0][0][0] ;
          drdxyz[POINT_TENS_2(ielt,0,1)] = tensC[0][0][1] ;
          drdxyz[POINT_TENS_2(ielt,0,2)] = tensC[0][0][2] ;

          drdxyz[POINT_TENS_2(ielt,3,0)] = tensC[0][1][0] ;
          drdxyz[POINT_TENS_2(ielt,3,1)] = tensC[0][1][1] ;
          drdxyz[POINT_TENS_2(ielt,3,2)] = tensC[0][1][2] ;

          drdxyz[POINT_TENS_2(ielt,4,0)] = tensC[0][2][0] ;
          drdxyz[POINT_TENS_2(ielt,4,1)] = tensC[0][2][1] ;
          drdxyz[POINT_TENS_2(ielt,4,2)] = tensC[0][2][2] ;

          drdxyz[POINT_TENS_2(ielt,1,0)] = tensC[1][1][0] ;
          drdxyz[POINT_TENS_2(ielt,1,1)] = tensC[1][1][1] ;
          drdxyz[POINT_TENS_2(ielt,1,2)] = tensC[1][1][2] ;

          drdxyz[POINT_TENS_2(ielt,5,0)] = tensC[1][2][0] ;
          drdxyz[POINT_TENS_2(ielt,5,1)] = tensC[1][2][1] ;
          drdxyz[POINT_TENS_2(ielt,5,2)] = tensC[1][2][2] ;

          drdxyz[POINT_TENS_2(ielt,2,0)] = tensC[2][2][0] ;
          drdxyz[POINT_TENS_2(ielt,2,1)] = tensC[2][2][1] ;
          drdxyz[POINT_TENS_2(ielt,2,2)] = tensC[2][2][2] ;


        }


      }

  } /* Fin boucle domaines */

}


/*============================================================================
 * Fonctions privées
 *============================================================================*/


syntax highlighted by Code2HTML, v. 0.9.1