
// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL  : gerardrio56@free.fr
//
// This program 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 3 of the License,
// or (at your option) any later version.
//
// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.

/************************************************************************
 *  UNIVERSITE DE BRETAGNE SUD (UBS) --- ENSIBS DE LORIENT              *
 ************************************************************************
 *           IRDL - Equipe DE GENIE MECANIQUE ET MATERIAUX (EG2M)       *
 * Centre de Recherche Rue de Saint Maudé - 56325 Lorient cedex         *
 * tel. 02.97.87.45.70 fax. 02.97.87.45.72 http://www-lg2m.univ-ubs.fr  *
 ************************************************************************
 *     DATE:        08/03/2005                                          *
 *                                                                $     *
 *     AUTEUR:      G RIO/H LAURENT  (mailto:gerard.rio@univ-ubs.fr)    *
 *                  Tel 0297874571   fax : 02.97.87.45.72               *
 *                                                                $     *
 ************************************************************************
 *     BUT:  échange de structures de données: fortran Umat -> C++      *
 *           fonction C a implanter du coté d'abaqus (ou autre prog)    *
 *           accés directe aux informations.                            *
 *                                                                      *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     * 
 *                                                                     *
 *     VERIFICATION:                                                    *
 *                                                                      *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *     !        !            !                                    !     *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *
 *     MODIFICATIONS:                                                   *
 *     !  date  !   auteur   !       but                          !     *
 *       5 avril 2016 : G Rio : prise en compte des éléments axi        *
 *       17 janvier 2018 : G Rio : prise en compte des contraintes      *
 *                                   planes et déformation planes.      *
 *     ------------------------------------------------------------     *
 *                                                                $     *
 ************************************************************************/

 #include <sys/types.h>
 #include <sys/stat.h>
 #include <stdio.h>
 #include <fcntl.h> /* Pour O_WRONLY, etc */
 #include <unistd.h>    /* pour les ordres read write close*/

/* définition d'une union qui lie les réels, les entiers et les caractères */
union Tab_car_double_int
  {  char    tampon[928];
     double  x[116];
	    int     n[232];
   } ;
Tab_car_double_int t_car_x_n; 
 
/* --- def des variables globales (a commenter certaines si elles sont declarees autre part)  */
    /* nom du tube nommé pour l'envoi des donnees */
    char* envoi="../Umat_envoi_Hz";
    /* nom du tube nomme pour la reception des donnees */
    char* reception="../Umat_reception_Hz"; 
    /* -- declarations des variables de passages avec un nom assez long pour qu'il n'y ait pas */
    /* -- de confusion avec les noms du programme appelant */
              /* --- en sortie uniquement */
double* u_herezh_DDSDDT  =  &t_car_x_n.x[0]; /* 6 */
double* u_herezh_DRPLDE  =  &t_car_x_n.x[6]; /* 6 */
double* u_herezh_DDSDDE =   &t_car_x_n.x[12]; /* 36 */
          /* --- en entrée - sortie */
double* u_herezh_RPL  =     &t_car_x_n.x[48]; /* 1 */
double* u_herezh_STRESS =   &t_car_x_n.x[49]; /* 6 */
double* u_herezh_SSE =      &t_car_x_n.x[55]; /* 1 */
double* u_herezh_SPD =      &t_car_x_n.x[56]; /* 1 */
double* u_herezh_SCD =      &t_car_x_n.x[57]; /* 1 */
double* u_herezh_DRPLDT  =  &t_car_x_n.x[58]; /* 1 */
double* u_herezh_PNEWDT  =  &t_car_x_n.x[59]; /* 1 */
          /* --- en entrée seulement */
double* u_herezh_STRAN  =   &t_car_x_n.x[60]; /* 6 */
double* u_herezh_DSTRAN  =  &t_car_x_n.x[66]; /* 6 */
double* u_herezh_TIME  =    &t_car_x_n.x[72]; /* 2 */
double* u_herezh_DTIME =    &t_car_x_n.x[74]; /* 1 */
double* u_herezh_TemP  =    &t_car_x_n.x[75]; /* 1 */
double* u_herezh_DTEMP  =   &t_car_x_n.x[76]; /* 1 */
double* u_herezh_COORDS  =  &t_car_x_n.x[77]; /* 3 */
double* u_herezh_DROT  =    &t_car_x_n.x[80]; /* 9 */
double* u_herezh_CELENT  =  &t_car_x_n.x[89]; /* 1 */
double* u_herezh_DFGRD0  =  &t_car_x_n.x[90]; /* 9 */
double* u_herezh_DFGRD1  =  &t_car_x_n.x[99]; /* 9 */

int*    u_herezh_NDI  =     &t_car_x_n.n[216]; /* 1 */
int*    u_herezh_NSHR  =    &t_car_x_n.n[217]; /* 1 */
int*    u_herezh_NTENS =    &t_car_x_n.n[218]; /* 1 */
int*    u_herezh_NSTATV  =  &t_car_x_n.n[219]; /* 1 */
int*    u_herezh_NOEL  =    &t_car_x_n.n[220]; /* 1 */
int*    u_herezh_NPT =      &t_car_x_n.n[221]; /* 1 */
int*    u_herezh_LAYER =    &t_car_x_n.n[222]; /* 1 */
int*    u_herezh_KSPT =     &t_car_x_n.n[223]; /* 1 */
int*    u_herezh_KSTEP =    &t_car_x_n.n[224]; /* 1 */
int*    u_herezh_KINC =     &t_car_x_n.n[225]; /* 1 */

char*   u_herezh_CMNAME  =  &t_car_x_n.tampon[904]; /* 24 */

 
/* --------------------- rappel des parametres de passage de la routine fortran ------------- */
    
/*          SUBROUTINE UMAT(STRESS,STATEV,DDSDDE,SSE,SPD,SCD,
     1 RPL,DDSDDT,DRPLDE,DRPLDT,STRAN,DSTRAN,
     2 TIME,DTIME,TEMP,DTEMP,PREDEF,DPRED,MATERL,NDI,NSHR,NTENS,
     3 NSTATV,PROPS,NPROPS,COORDS,DROT,PNEWDT,CELENT,
     4 DFGRD0,DFGRD1,NOEL,NPT,KSLAY,KSPT,KSTEP,KINC)
C
      INCLUDE 'ABA_PARAM.INC'
C
      CHARACTER*80 MATERL
      DIMENSION STRESS(NTENS),STATEV(NSTATV),
     1 DDSDDE(NTENS,NTENS),DDSDDT(NTENS),DRPLDE(NTENS),
     2 STRAN(NTENS),DSTRAN(NTENS),TIME(2),PREDEF(1),DPRED(1),
     3 PROPS(NPROPS),COORDS(3),DROT(3,3),
     4 DFGRD0(3,3),DFGRD1(3,3)
C
      DIMENSION EELAS(6),EPLAS(6),FLOW(6)
      PARAMETER (ONE=1.0D0,TWO=2.0D0,THREE=3.0D0,SIX=6.0D0)
      DATA NEWTON,TOLER/10,1.D-6/
*/

/* --------------------- fin rappel des parametres de passage de la routine fortran ------------- */

    /* procedure de lecture de recuperation sur le pipe des infos calculees */
    void LectureDonneesUmat(double* STRESS,double*  DDSDDE
                           ,double* SSE,double* SPD,double* SCD
                           ,const int* NDI,const int* NSHR,const int* NTENS
                           ,double* PNEWDT
                           ,double* RPL,double* DDSDDT,double* DRPLDE,double* DRPLDT)                           
                          
   { 
   
     /*   Creation d'un processus de reception des donnees */
     int tub;
     /* ouverture du tube nomme en lecture  */
     tub = open(envoi,O_RDONLY);  
     /* lecture dans le tampon  */  
     read (tub,t_car_x_n.tampon,480);    
     close (tub); /* fermeture du tampon */
     /* transformation de l'information
      a priori *NDI + *NSHR = *NTENS, mais abaqus garde les 3 valeurs donc on se refere uniquement sur les 2
      premieres donnees -> d'ou un test */
     if ((*NDI == 3) && (*NSHR == 3))
	     {/* cas classique 3D */
	      int ij;
	      for (ij=0;ij<6;ij++)
		      {STRESS[ij] = u_herezh_STRESS[ij];
		       DDSDDT[ij] = u_herezh_DDSDDT[ij];
		       DRPLDE[ij] = u_herezh_DRPLDE[ij];
		       int kl;
		       for (kl=0;kl<6;kl++)
		        {int r=ij*6+kl;
		         DDSDDE[r] = u_herezh_DDSDDE[r];
		        };
		      };
	     }
     else if ((*NDI == 2) && (*NSHR == 1))
      { /* cas des contraintes planes */
        int ij;
        for (ij=0;ij<3;ij++)
         { STRESS[ij] = u_herezh_STRESS[ij];
           DDSDDT[ij] = u_herezh_DDSDDT[ij];
           DRPLDE[ij] = u_herezh_DRPLDE[ij];
           int kl;
           for (kl=0;kl<3;kl++)
             {int r=ij*3+kl;
              DDSDDE[r] = u_herezh_DDSDDE[r];
             };
         };
      }
     else if ((*NDI == 3) && (*NSHR == 1))
	     {/* cas d'elements axisymetrique 3D */
	      int ij;
	      for (ij=0;ij<4;ij++)
		      {STRESS[ij] = u_herezh_STRESS[ij];
		       DDSDDT[ij] = u_herezh_DDSDDT[ij];
		       DRPLDE[ij] = u_herezh_DRPLDE[ij];
		       int kl;
		       for (kl=0;kl<4;kl++)
		        {int r=ij*4+kl;
		         DDSDDE[r] = u_herezh_DDSDDE[r];
		        };
		      };
	     };
     *SSE = *u_herezh_SSE; *SPD = *u_herezh_SPD; *SCD = *u_herezh_SCD;
     *PNEWDT = *u_herezh_PNEWDT;
     *RPL =  *u_herezh_RPL; 
     *DRPLDT = *u_herezh_DRPLDT; 
   };
                           
  union Tab_car_et_double
  {  char tampon[21];
     double truc[2];
   } ;
                           
    /* procedure d'ecriture sur le pipe des infos passees par le programme principal */
    void EcritureDonneesUmat(double* STRESS
                             ,double* SSE,double* SPD,double* SCD                             
                             ,const double* STRAN,const double* DSTRAN
                             ,const double* TIME,const double* DTIME,const double* TemP,const double* DTEMP
                             ,const char* CMNAME
                             ,const int* NDI,const int* NSHR,const int* NTENS
                             ,const int* NSTATV
                             ,const double* COORDS,const double* DROT
                             ,double* PNEWDT,const double* CELENT
                             ,const double* DFGRD0,const double* DFGRD1
                             ,const int* NOEL,const int* NPT,const int* LAYER
                             ,const int* KSPT,const int* KSTEP,const int* KINC)
{  

      /* a priori *NDI + *NSHR = *NTENS, mais abaqus garde les 3 valeurs donc on se refere uniquement sur les 2
      premieres donnees -> d'ou un test (que l'on pourrait sans doute eviter ) */
   if ((*NDI == 3) && (*NSHR == 3))
    { /* cas classique 3D */
      int ij;
      for (ij=0;ij<6;ij++)
      {u_herezh_STRESS[ij] = STRESS[ij];
       u_herezh_STRAN[ij] = STRAN[ij];
       u_herezh_DSTRAN[ij] = DSTRAN[ij];
      };
    }
   else if ((*NDI == 2) && (*NSHR == 1))
    { /* cas des contraintes planes */
      int ij;
      for (ij=0;ij<3;ij++)
       {u_herezh_STRESS[ij] = STRESS[ij];
        u_herezh_STRAN[ij] = STRAN[ij];
        u_herezh_DSTRAN[ij] = DSTRAN[ij];
       };
    }
   else if ((*NDI == 3) && (*NSHR == 1))
    { /* cas d'éléments axisymétrique 3D */
      int ij;
      for (ij=0;ij<4;ij++)
       {u_herezh_STRESS[ij] = STRESS[ij];
        u_herezh_STRAN[ij] = STRAN[ij];
        u_herezh_DSTRAN[ij] = DSTRAN[ij];
       };
    };
 
   *u_herezh_SSE = *SSE; *u_herezh_SPD = *SPD; *u_herezh_SCD = *SCD;
   *u_herezh_PNEWDT=  *PNEWDT;
   u_herezh_TIME[0]= TIME[0]; u_herezh_TIME[1]= TIME[1]; *u_herezh_DTIME = *DTIME;  
   *u_herezh_TemP =  *TemP;  *u_herezh_DTEMP = *DTEMP;  
   *u_herezh_NDI =  *NDI; *u_herezh_NSHR = *NSHR; *u_herezh_NTENS = *NTENS; *u_herezh_NSTATV = *NSTATV;
   int i;
   for (i=0;i<3;i++) 
      {u_herezh_COORDS[i]= COORDS[i];
	      int j;
       for (j=0;j<3;j++)
       	{int r=i*3+j;
       	 u_herezh_DROT[r]= DROT[r]; u_herezh_DFGRD0[r]=DFGRD0[r]; u_herezh_DFGRD1[r]=DFGRD1[r];
       	}
      };
   *u_herezh_CELENT = *CELENT; 
   *u_herezh_NOEL = *NOEL; *u_herezh_NPT = *NPT; *u_herezh_LAYER = *LAYER; *u_herezh_KSPT = *KSPT;
   *u_herezh_KSTEP = *KSTEP; *u_herezh_KINC = *KINC; 
   for (i=0;i<20;i++) u_herezh_CMNAME[i] = CMNAME[i];
    
/*cout << "\n *********** grandeurs expedier du sous prog c abaqus ************ ";
cout << "\n sigma_t "; for (int i=0;i<6;i++) cout << " ("<<i<<")=" << u_herezh_STRESS[i];
      cout << "\n def "; for (int i=0;i<6;i++) cout << " ("<<i<<")=" << u_herezh_STRAN[i];
      cout << "\n deltatdef "; for (int i=0;i<6;i++) cout << " ("<<i<<")=" << u_herezh_DSTRAN[i];
      cout << "\n rotation "; for (int i=0;i<9;i++) cout << " ("<<i<<")=" << u_herezh_DROT[i];
      cout << "\n gradiant_t "; for (int i=1;i<9;i++) cout << " ("<<i<<")=" << u_herezh_DFGRD0[i];
      cout << "\n gradiant_tdt "; for (int i=1;i<9;i++) cout << " ("<<i<<")=" << u_herezh_DFGRD1[i];
	  cout << endl; */
  /*   Creation d'un processus de pour l'ecriture des donnees */ 
  /* ouverture du tube nomme en ecriture */
  printf("\n on ouvre le tube pour l'ecriture: sp essai");
  int tub = open(reception,O_WRONLY);    
  /* ecriture dans le tampon  */
  /* en fait l'objectif est d'ecrire que les variables d'entrees ou  */
  /* d'entree sortie      */
  char* tampon_envoi =  &(t_car_x_n.tampon[384]);  
  write (tub,tampon_envoi,544); /*sizeof(tampon));  */  
  close (tub); /* fermeture du tampon */
  printf("\n fermeture du tampon: sp essai");
  return;
};
    
