!======================================================================!
!                                                                      !
!    Software Name : FrontCOMP_cure   Ver. 3.1                         !
!                                                                      !
!      Module Name : m_fstr                                            !
!      Category    : Library                                           !
!                                                                      !
!      Developed based on "FrontSTR" of RSS21 project                  !
!                                                                      !
!                     Written by Toshio Nagashima,   2006/06/01        !
!                                Yasuji Fukahori,    2006/06/01        !
!                                Noboru Imai,        2006/06/01        !
!                                Tomotaka Ogasawara, 2013/03/26        !
!                                                                      !
!     Contact address :  IIS,The University of Tokyo, CISS             !
!                                                                      !
!    "Composite Material Strength & Reliability Evaluation Simulator"  !
!                                                                      !
!======================================================================!
! If new header is supported, change according to following method.    !
!  1) Increase FSTR_CTRL_HEADER_NUMBER                                 !
!  2) Add new header name to fstr_ctrl_header_names                    !
!  3) Describe new function to get parameters from control file        !
!     in fstr_ctrl.f90                                                 !
!  4) Describe new subroutine to set values of the parameter           !
!     in fstr_setup.f90                                                !
!  5) If initial values are necessary, set the value                   !
!     in subroutine fstr_setup_init in fstr_setup.f90                  ! 
!                                                                      !
!======================================================================!

module m_fstr
use hecmw
use lczparm
public

!C
!C-- CONSTANTS
!C
        ! general
        integer(kind=kint),parameter :: kYES       =   1
        integer(kind=kint),parameter :: kNO        =   0
        integer(kind=kint),parameter :: kON        =   1
        integer(kind=kint),parameter :: kOFF       =   0
        integer(kind=kint),parameter :: kOK        =   1
        integer(kind=kint),parameter :: kFAIL      =   0
        integer(kind=kint),parameter :: kSUCCESS   =   1
        integer(kind=kint),parameter :: kEXIST     =   1
        integer(kind=kint),parameter :: kNOTEXIST  =   0

        ! solution type (st)
        integer(kind=kint),parameter :: kstPRECHECK =   0
        integer(kind=kint),parameter :: kstSTATIC   =   1
        integer(kind=kint),parameter :: kstEIGEN    =   2
        integer(kind=kint),parameter :: kstHEAT     =   3
        integer(kind=kint),parameter :: kstDYNAMIC  =   4

        ! solver method (sm)    !CAUTION : (<=100):indirect, (>100):direct
        integer(kind=kint),parameter :: ksmCG       =   1
        integer(kind=kint),parameter :: ksmBiCGSTAB =   2
        integer(kind=kint),parameter :: ksmGMRES    =   3
        integer(kind=kint),parameter :: ksmGPBiCG   =   4
        integer(kind=kint),parameter :: ksmDIRECT   = 101

        ! solver detail (iproc) (ip)
        integer(kind=kint),parameter :: kipSTANDARD =   0
        integer(kind=kint),parameter :: kipNLGEOM   =   1  ! for static analysis

        ! supported FSTR control file header names
        integer(kind=kint),parameter :: kFSTR_CTRL_HEADER_NUMBER = 32
        character( HECMW_NAME_LEN ) :: fstr_ctrl_header_names(kFSTR_CTRL_HEADER_NUMBER)
        data fstr_ctrl_header_names  / &
                '!SOLUTION', '!SOLVER',  '!STEP', '!WRITE', '!ECHO', &
                '!STATIC',   '!BOUNDARY', '!CLOAD', '!DLOAD', '!TEMPERATURE', '!REFTEMP',&
                '!HEAT','!FIXTEMP','!CFLUX','!DFLUX','!SFLUX','!FILM','!SFILM','!RADIATE','!SRADIATE', &
                '!MPC', '!VELOCITY', '!ACCELERATION', '!DYNAMIC', &
                '!EIGEN','!END', '!VISCO', '!ORTHO_HEAT', '!ORTHO_SOLID', '!RESIN_HEAT', & 
                '!RESIN_SOLID', '!HEAT_PLUS' /

        ! boundary condition file type (bcf)
        integer(kind=kint),parameter :: kbcfFSTR    =   0  ! BC described in fstr control file (default)
        integer(kind=kint),parameter :: kbcfNASTRAN =   1  ! nastran file

!C
!C-- PARALLEL EXECUTION
!C
        integer(kind = kint) :: myrank
        integer(kind = kint) :: nprocs
!C
!C-- FILE NAME
!C
        character(len=HECMW_FILENAME_LEN):: cntfilNAME
!C
!C-- FILE HANDLER
!C
        integer(kind=kint),parameter :: ILOG=16 ! log
        integer(kind=kint),parameter :: ISTA=17 ! status
        integer(kind=kint),parameter :: IMSG=51 ! message (myrank == 0 only)
        integer(kind=kint),parameter :: IDBG=52 ! debug
        integer(kind=kint),parameter :: IFVS=53 ! visual.ini file
        integer(kind=kint),parameter :: INEU=54 ! neutral file (heat)
!!! ---   20091003  ----
        integer(kind=kint),parameter :: heat_sta_IW1=91 ! heat_sta TEMP
        integer(kind=kint),parameter :: heat_sta_IW2=92 ! heat_sta CURE3D_nod
        integer(kind=kint),parameter :: matl_vec_IW1=93 ! matl_vec GBARU_ALL 
!!! ---   20091003  ----

!C
!C-- INDEX
!C
        integer(kind=kint),parameter :: kMaxDOFinElem = 1000
        integer(kind=kint), dimension(kMaxDOFinElem) :: NCOL1, NCOL2
!C
!C-- FLAG for ECHO/RESULT/POST
!C
        integer(kind=kint),pointer :: IECHO
        integer(kind=kint),pointer :: IRESULT
        integer(kind=kint),pointer :: IVISUAL
        ! for heat ...
        integer(kind=kint),pointer :: INEUTRAL  ! flag for femap neutral file
        integer(kind=kint),pointer :: IRRES     ! flag for restart, read
        integer(kind=kint),pointer :: IWRES     ! flag for restart, write
        integer(kind=kint),pointer :: NRRES     ! position of restart read
        integer(kind=kint),pointer :: NPRINT    ! interval of write
!C
!C-- REFTEMP
!C
        real(kind=kreal),pointer :: REF_TEMP
!C
!C-- ANALYSIS CONTROL for NLGEOM and HEAT
!C
        integer(kind=kint),pointer :: IPROC
        integer(kind=kint),pointer :: INCMAX

        !for static
        !CAUTION)
        !   DT,ETIME and EPS will be integrated in fstr_param
        !   when !STATIC supports mult-lines.
        real(kind=kreal)           :: DT    ! /=fstr_param%dtime
        real(kind=kreal)           :: ETIME ! /=fstr_param%etime
        integer(kind=kint)         :: ITMAX
        real(kind=kreal)           :: EPS   ! /=fstr_param%eps

        !Abolition (9/29)
        !for heat
        !integer(kind=kint) :: ISS
        real(kind=kreal)   :: TEMTOL
        !integer(kind=kint) :: ITEMAX  ! == ITMAX
!C
!C ----------------------------------------------------------------------------
!C
!C-- FSTR INNER CONTROL PARAMETERS  (fstrPARAM)
!C   Caution: global pointer parameter IECHO, IRESULT and IVISUAL, etc.
!C            points to corresponded parameter in the structure
!C
        type fstr_param
                integer(kind=kint) :: solution_type ! solution type number
                integer(kind=kint) :: solver_method ! solver method number

                !!STEP
                integer(kind=kint) :: incmax          ! (=INCMAX)
                integer(kind=kint) :: iproc           ! (=IPROC)

                !!STATIC !HEAT
                integer(kind=kint) :: analysis_n      ! Number of analysis
                real(kind=kreal),pointer  :: dtime(:) ! (=DT)    STEP_DLTIME
                real(kind=kreal),pointer  :: etime(:) ! (/=ETIME) STEP_EETIME
                real(kind=kreal),pointer  :: dtmin(:) ! (=DTMIN) STEP_DELMIN
                real(kind=kreal),pointer  :: delmax(:)! (=DTMAX) STEP_DELMAX
                integer(kind=kint),pointer:: itmax(:) ! (/=ITMAX)
                real(kind=kreal),pointer  :: eps(:)   ! (/=ESP)
                real(kind=kreal)          :: ref_temp ! (=REF_TEMP)

                ! output control
                integer(kind=kint) :: fg_echo       ! output echo   (kYES/kNO) (=IECHO)
                integer(kind=kint) :: fg_result     ! output result (kYES/kNO) (=IRESULT)
                integer(kind=kint) :: fg_visual     ! visualization (kYES/kNO) (=IVISUAL)

                ! for heat ...
                integer(kind=kint) :: fg_neutral    ! write by neutral (=INEUTRAL)
                integer(kind=kint) :: fg_irres      ! restart read     (=IRRES)
                integer(kind=kint) :: fg_iwres      ! restart write    (=IWRES)
                integer(kind=kint) :: nrres         ! NRRES
                integer(kind=kint) :: nprint        ! NPRINT

                ! index table for global node ID sorting
                integer(kind=kint) :: n_node        ! == hecMESH%n_node
                integer(kind=kint) :: nn_internal   ! == hecMESH%nn_internal
                integer(kind=kint),pointer :: global_local_ID(:,:)
                                 ! (2:nn_internal) (1,:):global, (2,:):local 

		! for couple analysis
		integer( kind=kint ) :: fg_couple          ! (default:0)
		integer( kind=kint ) :: fg_couple_first    ! (default:0)
        end type fstr_param

        ! **** GLOBAL VARIABLE INITIALIZED IN FSTR_SETUP *****
        type( fstr_param ),target :: fstrPR
!C
!C ----------------------------------------------------------------------------
!C
!C-- for STATIC ANSLYSIS  (fstrSOLID)
!C
        type fstr_solid 

                integer(kind=kint) :: file_type  ! kbcfFSTR or kbcfNASTRAN

                !!BOUNDARY
                integer(kind=kint) :: BOUNDARY_ngrp_tot
                integer(kind=kint), pointer :: BOUNDARY_ngrp_ID     (:)
                integer(kind=kint), pointer :: BOUNDARY_ngrp_type   (:)
!               integer(kind=kint), pointer :: BOUNDARY_ngrp_iftype (:)
                integer(kind=kint), pointer :: BOUNDARY_ngrp_amp    (:)
                real(kind=kreal), pointer   :: BOUNDARY_ngrp_val    (:)

                !!VELOCITY
                integer(kind=kint) :: VELOCITY_ngrp_tot
                integer(kind=kint), pointer :: VELOCITY_ngrp_ID     (:)
                integer(kind=kint), pointer :: VELOCITY_ngrp_type   (:)
                integer(kind=kint), pointer :: VELOCITY_ngrp_amp    (:)
                real(kind=kreal), pointer   :: VELOCITY_ngrp_val    (:)

                !!ACCELERATION
                integer(kind=kint) :: ACCELERATION_ngrp_tot
                integer(kind=kint), pointer :: ACCELERATION_ngrp_ID     (:)
                integer(kind=kint), pointer :: ACCELERATION_ngrp_type   (:)
                integer(kind=kint), pointer :: ACCELERATION_ngrp_amp    (:)
                real(kind=kreal), pointer   :: ACCELERATION_ngrp_val    (:)

                !!CLOAD
                integer(kind=kint) :: CLOAD_ngrp_tot
                integer(kind=kint), pointer :: CLOAD_ngrp_ID        (:)
                integer(kind=kint), pointer :: CLOAD_ngrp_DOF       (:)
                integer(kind=kint), pointer :: CLOAD_ngrp_amp       (:)
                real(kind=kreal), pointer   :: CLOAD_ngrp_val       (:)

                !!DLOAD
                integer(kind=kint) :: DLOAD_ngrp_tot
                integer(kind=kint), pointer :: DLOAD_ngrp_ID        (:)
                integer(kind=kint), pointer :: DLOAD_ngrp_LID       (:)
                integer(kind=kint), pointer :: DLOAD_ngrp_amp       (:)
                real(kind=kreal), pointer   :: DLOAD_ngrp_params    (:,:)

                !!TEMPERATURE
                integer(kind=kint) :: TEMP_ngrp_tot
                integer(kind=kint), pointer :: TEMP_ngrp_ID  (:)
                real(kind=kreal), pointer   :: TEMP_ngrp_val (:)

                ! VALUE
                real(kind=kreal), pointer :: DISP  (:)
                real(kind=kreal), pointer :: STRESS(:)
                real(kind=kreal), pointer :: STRAIN(:)
                real(kind=kreal), pointer :: ESTRESS(:)
                real(kind=kreal), pointer :: ESTRAIN(:)

                ! ANALYSIS CONTROL for NLGEOM
                integer(kind=kint) :: NLSTATIC_ngrp_amp
                integer(kind=kint) :: restart_nout   ! output interval of restart file
                                                     ! (if  .gt.0) restart file write
                                                     ! (if  .lt.0) restart file read and write
                integer(kind=kint) :: nout           ! output interval of result
                integer(kind=kint) :: nout_monit     ! output interval of result monitoring
                integer(kind=kint) :: node_monit_1   ! node of monitoring result
                integer(kind=kint) :: elem_monit_1   ! element of monitoring result
                integer(kind=kint) :: intg_monit_1   ! integration point of monitoring result
                integer(kind=kint) :: iout_list(6)   ! 0:not output  1:output
                                                     ! iout_list(1): displacement
                                                     ! iout_list(2):  not used
                                                     ! iout_list(3):  not used
                                                     ! iout_list(4): reaction force
                                                     ! iout_list(5): strain
                                                     ! iout_list(6): stress
                integer(kind=kint) :: idx_stres      ! type of stress
                                                     !  0: 1st Piola-Kirchihoff stress
                                                     !  1: 2nd Piola-Kirchihoff stress
                                                     !  2: Cauchy stress
                integer(kind=kint) :: idx_stran      ! type of strain
                integer(kind=kint) :: idx_out_cood_st! type of output coord. sys. of stress & strain
                                                     !  0: global coord. sys.
                                                     !  1: material coord. sys.
                integer(kind=kint) :: idx_elpl       ! type of analysis
                                                     ! -1: elastic (geometrically linear   )
                                                     !  0: elastic (geometrically nonlinear)
                                                     !  1: plastic (geometrically nonlinear)
                                                     !  2: plastic (geometrically linear   )
                real(kind=kreal) :: sig_y0           ! yield stress
                real(kind=kreal) :: h_dash           ! hardening coefficient
                integer(kind=kint), pointer :: FLG_ELPL  (:,:,:,:)   ! flag of plasticity
                                                                     ! 0:elastic  1: plastic
                integer(kind=kint), pointer :: mat_iso  (:)   ! flag of mechanical properties
                real(kind=kreal), pointer :: STRESS_YLD  (:,:,:,:)   ! yield stress
                real(kind=kreal), pointer :: FACTOR      (:)     ! factor of incrementation
                                                                 ! 1:time t  2: time t+dt
                real(kind=kreal), pointer :: EP_BAR      (:,:,:,:)    ! equivalent plastic strain
                real(kind=kreal), pointer :: STRAIN3D_P    (:,:,:,:,:)  ! total strain(not plastic strain)
                real(kind=kreal), pointer :: STRAIN3D_P_nd (:,:,:)  ! total strain(not plastic strain)
                real(kind=kreal), pointer :: STRAIN_nd(:)
                real(kind=kreal), pointer :: STRAIN_PRIS(:)
                real(kind=kreal), pointer :: STRAIN3D_V1 (:,:,:,:,:)  ! total strain(Voigt element 1)
                real(kind=kreal), pointer :: STRAIN3D_V2 (:,:,:,:,:)  ! total strain(Voigt element 2)
                real(kind=kreal), pointer :: GL          (:)
                real(kind=kreal), pointer :: TOTAL_DISP  (:)
                real(kind=kreal), pointer :: QFORCE      (:)
                real(kind=kreal), pointer :: QFORCE_RES  (:)
                real(kind=kreal), pointer :: STRESS3D    (:,:,:,:,:)
                real(kind=kreal), pointer :: SURFF       (:,:,:,:,:)
                real(kind=kreal), pointer :: STRESS2D    (:,:,:,:)
                real(kind=kreal), pointer :: STRESS3D_nd   (:,:,:)
                real(kind=kreal), pointer :: STRESS3D_ndP1 (:,:,:)
                real(kind=kreal), pointer :: STRESS_nd(:)
                real(kind=kreal), pointer :: STRESS_PRIS(:)
                real(kind=kreal), pointer :: SURFF_nd      (:,:,:)
                real(kind=kreal), pointer :: STRSURF_nd    (:)
                real(kind=kreal), pointer :: CURE3D  (:,:,:,:)
                real(kind=kreal), pointer :: CURE3D_I(:,:,:,:)
                real(kind=kreal), pointer :: CURE3D_nod   (:)
                real(kind=kreal), pointer :: CURE3D_nod_I (:)
                real(kind=kreal), pointer :: DELCURE3D_nod(:)
                real(kind=kreal), pointer :: TEMPI   (:)
                real(kind=kreal), pointer :: TEMPC   (:)
                real(kind=kreal), pointer :: DELTEMP (:)
                real(kind=kreal), pointer :: GBARU    (:,:,:)  ! covariant base vector at node
                real(kind=kreal), pointer :: GBARU_ALL(:,:,:)  ! covariant base vector at node (all)
                real(kind=kreal)   :: GBARU_matrl(3,3,10)  ! covariant base vector in material coord.

                integer(kind=kint) :: idx_temp     ! couple with temperature (1) or not(0)
                integer(kind=kint) :: idx_young    ! 0: form. 1   1: form. 2  
                integer(kind=kint) :: idx_cte      ! 0: form. 1   1: form. 2  
                integer(kind=kint) :: sub_intvl    ! substep interval 
                integer(kind=kint) :: mat_iso_num(10) !  0: isotropic elasticity 
                                                      !  1: transversely isotropic elasticity 
                                                      !  2: orthotropic elasticity 
                                                      ! -1: read covariant base vector at node from file 
                real(kind=kreal) :: tempr          ! reference temperature ( not used)
                real(kind=kreal) :: mat_otho(9,10) ! E1,E2,E3,G12,G23,G31,nyu12,nyu23,nyu13 
                real(kind=kreal) :: mat_beta(3,10) ! beta1,beta2,beta3 
                real(kind=kreal) :: ccc_rl (12)     ! Cg(T,a),Ck(T,a) parameters real ,Maxwell 
                                   ! idx_young: form. 1,  idx_cte: form. 1 
                                   ! ccc_rl( 1)= c1 : E(T,a)=(c1*e**(-d1*T))*(c2*e**(d2*a)) 
                                   ! ccc_rl( 2)= d1 : E(T,a)=(c1*e**(-d1*T))*(c2*e**(d2*a)) 
                                   ! ccc_rl( 3)= c2 : E(T,a)=(c1*e**(-d1*T))*(c2*e**(d2*a)) 
                                   ! ccc_rl( 4)= d2 : E(T,a)=(c1*e**(-d1*T))*(c2*e**(d2*a)) 
                                   ! ccc_rl( 5)= e1 : alph0.0(T)=e1*T+f1 
                                   ! ccc_rl( 6)= f1 : alph0.0(T)=e1*T+f1 
                                   ! ccc_rl( 7)= e2 : alph1.0(T)=e2*T+f2 
                                   ! ccc_rl( 8)= f2 : alph1.0(T)=e2*T+f2 
                                   ! ccc_rl( 9)= Tg : yetag(T,a)=G*Tg 
                                   ! ccc_rl(10)= Tk : yetak(T,a)=K*Tk 
                real(kind=kreal) :: ccc_rl1(12)     ! Cg1(T,a),Ck1(T,a) parameters real ,Voigt1 
                real(kind=kreal) :: ccc_rl2(12)     ! Cg2(T,a),Ck2(T,a) parameters real ,Voigt2 
                real(kind=kreal) :: yeta   (14)     ! yetag(T,a),yetak(T,a) parameters real ,Maxwell
                                   ! yeta ( 1)= y0   : yetag(T,a)=y0*(e**(E1/(R0*T))*((agel/(agel-a))**(c1+c2*a)) 
                                   ! yeta ( 2)= E1   : yetag(T,a)=y0*(e**(E1/(R0*T))*((agel/(agel-a))**(c1+c2*a)) 
                                   ! yeta ( 3)= R0   : yetag(T,a)=y0*(e**(E1/(R0*T))*((agel/(agel-a))**(c1+c2*a)) 
                                   ! yeta ( 4)= agel : yetag(T,a)=y0*(e**(E1/(R0*T))*((agel/(agel-a))**(c1+c2*a)) 
                                   ! yeta ( 5)= c1   : yetag(T,a)=y0*(e**(E1/(R0*T))*((agel/(agel-a))**(c1+c2*a)) 
                                   ! yeta ( 6)= c2   : yetag(T,a)=y0*(e**(E1/(R0*T))*((agel/(agel-a))**(c1+c2*a)) 
                                   ! yeta ( 7)= ye   : yetag(T,a)=ye , a >= agel 

                real(kind=kreal) :: yeta1  (14)     ! yetag1(T,a),yetak1(T,a) parameters real ,Voigt1
                real(kind=kreal) :: yeta2  (14)     ! yetag2(T,a),yetak2(T,a) parameters real ,Voigt2

                real(kind=kreal) :: ramd_chm       ! ramda_chem
                integer(kind=kint) :: idx_visco      ! type of viscocity analysis
                                                     !  0: not include viscocity  (1 elements)
                                                     !  1: not include viscocity  (1 elements)
                                                     !  2: generalized Voigt model(2 elements)
                                                     !  3: generalized Voigt model(3 elements)
                                                     !  4: generalized Voigt model(4 elements)
                                                     !  5: generalized Voigt model(5 elements)
                                                     !  6: generalized Voigt model(6 elements)
                real(kind=kreal) :: ccf_rl (12)     ! for fiber , f(T) 
                                   ! ccf_rl( 1)= c1 : E(T,a)=(c1*e**(-d1*T))*(c2*e**(d2*a)) 
                                   ! ccf_rl( 2)= d1 : E(T,a)=(c1*e**(-d1*T))*(c2*e**(d2*a)) 
                                   ! ccf_rl( 3)= c2 : E(T,a)=(c1*e**(-d1*T))*(c2*e**(d2*a)) 
                                   ! ccf_rl( 4)= d2 : E(T,a)=(c1*e**(-d1*T))*(c2*e**(d2*a)) 
                                   ! ccf_rl( 5)= e1 : alph0.0(T)=e1*T+f1 
                                   ! ccf_rl( 6)= f1 : alph0.0(T)=e1*T+f1 
                                   ! ccf_rl( 7)= e2 : alph1.0(T)=e2*T+f2 
                                   ! ccf_rl( 8)= f2 : alph1.0(T)=e2*T+f2 

		! for couple analysis
		integer( kind=kint ) :: COUPLE_ngrp_tot
		integer( kind=kint ),pointer :: COUPLE_ngrp_ID(:)

        end type fstr_solid 


!C
!C ----------------------------------------------------------------------------
!C
!C-- for HEAT ANSLYSIS  (fstrHEAT)
!C
        type fstr_heat

                ! TIME CONTROL
                real(kind=kreal) :: TEMTOL
                integer :: STEPtot
                real(kind=kreal), pointer :: STEP_DLTIME(:),STEP_EETIME(:)
                real(kind=kreal), pointer :: STEP_DELMIN(:),STEP_DELMAX(:)

                ! MATERIAL
                integer :: MATERIALtot
                real(kind=kreal), pointer :: RHO(:,:), RHOtemp (:,:) 
                real(kind=kreal), pointer :: CP(:,:),  CPtemp (:,:) 
                real(kind=kreal), pointer :: COND(:,:),CONDtemp (:,:) 

                integer, pointer :: RHOtab(:), CPtab(:), CONDtab(:)

                real(kind=kreal), pointer :: RHOfuncA(:,:),  RHOfuncB(:,:)
                real(kind=kreal), pointer :: CPfuncA (:,:),  CPfuncB(:,:)
                real(kind=kreal), pointer :: CONDfuncA (:,:),CONDfuncB(:,:)

                ! AMPLITUDE
                integer :: AMPLITUDEtot
                real(kind=kreal), pointer :: AMPL(:,:), AMPLtime (:,:) 
                integer, pointer :: AMPLtab(:)
                real(kind=kreal), pointer :: AMPLfuncA(:,:),  AMPLfuncB(:,:)


                ! VALUE
                real(kind=kreal), pointer :: TEMP0(:)
                real(kind=kreal), pointer :: TEMPC(:)
                real(kind=kreal), pointer :: TEMP (:)
                real(kind=kreal), pointer :: TEMPW(:)
                real(kind=kreal), pointer :: D_TEMP(:)

                ! Residual
                real(kind=kreal), pointer :: RE(:)
                real(kind=kreal), pointer :: QV(:)
                real(kind=kreal), pointer :: RR(:)
                real(kind=kreal), pointer :: RL(:)
                real(kind=kreal), pointer :: RU(:)
                real(kind=kreal), pointer :: RD(:)
                real(kind=kreal), pointer :: IWKX(:,:)

                ! BOUNDARY CONDTIONS -------

                !!FIXTEMP
                integer :: T_FIX_tot
                integer, pointer          :: T_FIX_node(:)
                integer, pointer          :: T_FIX_ampl(:)
                real(kind=kreal), pointer :: T_FIX_val(:)

                !!CFLUX
                integer :: Q_NOD_tot
                integer, pointer          :: Q_NOD_node(:)
                integer, pointer          :: Q_NOD_ampl(:)
                real(kind=kreal), pointer :: Q_NOD_val(:)

                !!DFLUX (not used)
                integer :: Q_VOL_tot
                integer, pointer          :: Q_VOL_elem(:)
                integer, pointer          :: Q_VOL_ampl(:)
                real(kind=kreal), pointer :: Q_VOL_val(:)

                !!DFLUX, !SFLUX
                integer :: Q_SUF_tot
                integer, pointer          :: Q_SUF_elem(:)
                integer, pointer          :: Q_SUF_ampl(:)
                integer, pointer          :: Q_SUF_surf(:)
                real(kind=kreal), pointer :: Q_SUF_val(:)

                !!RADIATE, !SRADIATE
                integer :: R_SUF_tot
                integer, pointer          :: R_SUF_elem(:)
                integer, pointer          :: R_SUF_ampl(:,:)
                integer, pointer          :: R_SUF_surf(:)
                real(kind=kreal), pointer :: R_SUF_val(:,:)

                !!FILM, SFILM
                integer :: H_SUF_tot
                integer, pointer          :: H_SUF_elem(:)
                integer, pointer          :: H_SUF_ampl(:,:)
                integer, pointer          :: H_SUF_surf(:)
                real(kind=kreal), pointer :: H_SUF_val(:,:)

                ! CURE   ----  oga2009 ------
                integer(kind=kint) :: idx_cure       ! include cure(1) or not(0)  
                integer(kind=kint) :: idx_dadt       ! 0: 2terms   1: 3terms  
                integer(kind=kint) :: nout_sta       ! output interval of heat_sta_* file 
                integer(kind=kint) :: restart_nout   ! output interval of restart file
                                                     ! (if  .gt.0) restart file write
                                                     ! (if  .lt.0) restart file read and write
                integer(kind=kint) :: nout           ! output interval of result
                integer(kind=kint) :: nout_monit     ! output interval of result monitoring
                integer(kind=kint) :: node_monit_1   ! node of monitoring result
                integer(kind=kint) :: elem_monit_1   ! element of monitoring result
                integer(kind=kint) :: intg_monit_1   ! integration point of monitoring result
                integer(kind=kint) :: iout_list(6)   ! 0:not output  1:output
                                                     ! iout_list(1): temperature
                                                     ! iout_list(2): cure
                                                     ! iout_list(3): not used
                                                     ! iout_list(4): not used
                                                     ! iout_list(5): not used
                                                     ! iout_list(6): not used

                integer(kind=kint), pointer :: mat_iso  (:)     ! flag of mechanical properties
                integer(kind=kint), pointer :: idx_mat_node(:)  ! flag of material at node for post output 
                real(kind=kreal), pointer :: CURE3D  (:,:,:,:)
                real(kind=kreal), pointer :: CURE3D_I(:,:,:,:)
                real(kind=kreal), pointer :: CURE3D_nod  (:)
                real(kind=kreal), pointer :: CURE3D_nod_I(:)
                real(kind=kreal), pointer :: CURE3D_nod_cfrp(:)
                real(kind=kreal), pointer :: D_CURE3D_nod (:)
                real(kind=kreal), pointer :: GBARU    (:,:,:)  ! covariant base vector at node
                real(kind=kreal), pointer :: GBARU_ALL(:,:,:)  ! covariant base vector at node (all)
                real(kind=kreal)   :: GBARU_matrl(3,3,10)  ! covariant base vector in material coord.

                integer(kind=kint) :: mat_iso_num(10) !  0: isotropic elasticity 
                                                      !  1: transversely isotropic elasticity 
                                                      !  2: orthotropic elasticity 
                                                      ! -1: read covariant base vector at node from file 
                real(kind=kreal) :: mat_k(3,10) ! k11,k22,k33 

                real(kind=kreal) :: Hr       ! Hr(J/kg)
                real(kind=kreal) :: A1       ! A1(1/s)
                real(kind=kreal) :: A2       ! A2(1/s)
                real(kind=kreal) :: E1       ! E1(J/mol)
                real(kind=kreal) :: E2       ! E2(J/mol)
                real(kind=kreal) :: R0       ! R(J/(mol K))
                real(kind=kreal) :: m0       ! m
                real(kind=kreal) :: n0       ! n
                real(kind=kreal) :: ccc_rl (12)     ! parameters for da/dt 
                                   ! idx_dadt:  2terms  
                                   ! ccc_rl( 1)= Hr       : Hr(J/kg) 
                                   ! ccc_rl( 2)= A1       : A1(1/s)
                                   ! ccc_rl( 3)= A2       : A2(1/s)
                                   ! ccc_rl( 4)= E1       : E1(J/mol)
                                   ! ccc_rl( 5)= E2       : E2(J/mol)
                                   ! ccc_rl( 6)= R0       : R(J/(mol K))
                                   ! ccc_rl( 7)= m0       : m
                                   ! ccc_rl( 8)= n0       : n
                                   ! ccc_rl( 9)= CURE3D_0 : CURE3D_0

        end type fstr_heat


!C ---------------------------------------------------------------------------- 
!C
!C-- for DYNAMIC ANSLYSIS  (fstrDYNAMIC)
!C
        type fstr_dynamic

                !! control parameter

                ! ANALYSIS TYPE CONTROL
                integer(kind=kint) :: idx_eqa       ! implicit or explicit
                integer(kind=kint) :: idx_resp      ! time history or steady-state harmonic response analysis

                ! TIME CONTROL
                integer(kind=kint) :: n_step        ! total step number of analysis
                real(kind=kreal)   :: t_start       ! start time of analysis
                real(kind=kreal)   :: t_end         ! end time of analysis
                real(kind=kreal)   :: t_delta       ! time increment
                integer(kind=kint) :: restart_nout  ! output interval of restart file
                                                    ! (if  .gt.0) restart file write
                                                    ! (if  .lt.0) restart file read and write

                ! Newmark-beta parameter
                real(kind=kreal)   :: ganma         ! Newmark-beta parameter ganma
                real(kind=kreal)   :: beta          ! Newmark-beta parameter beta

                ! mass matrix control
                integer(kind=kint) :: idx_mas       ! mass matrix type

                ! damping control
                integer(kind=kint) :: idx_dmp       ! damping type
                real(kind=kreal)   :: ray_m         ! Rayleigh damping parameter Rm
                real(kind=kreal)   :: ray_k         ! Rayleigh damping parameter Rk

                ! OUTPUT CONTROL
                integer(kind=kint) :: nout           ! output interval of result
                integer(kind=kint) :: node_monit_1   ! node of monitoring result
                integer(kind=kint) :: nout_monit     ! output interval of result monitoring
                integer(kind=kint) :: i_step         ! step number
                integer(kind=kint) :: iout_list(6)   ! 0:not output  1:output
                                                     ! iout_list(1): displacement
                                                     ! iout_list(2): velocity
                                                     ! iout_list(3): acceleration
                                                     ! iout_list(4): reaction force
                                                     ! iout_list(5): strain
                                                     ! iout_list(6): stress
                real(kind=kreal)   :: d_time         ! time of i_step

                !! array for dynamic analysis

                ! VALUE
                real(kind=kreal), pointer :: DISP  (:,:)
                real(kind=kreal), pointer :: VEL   (:,:)
                real(kind=kreal), pointer :: ACC   (:,:)

                ! temporary quantity
                real(kind=kreal), pointer :: VEC1  (:)
                real(kind=kreal), pointer :: VEC2  (:)
                real(kind=kreal), pointer :: VEC3  (:)

        end type fstr_dynamic
!C ---------------------------------------------------------------------------- 
!C
!C-- COUPLE
!C
	type fstr_couple
		! for revocap
		integer( kind=kint )   :: dof              ! == 3
		integer( kind=kint )   :: ndof             ! total dof (coupled_node_n*dof)
		integer( kind=kint )   :: coupled_node_n
		! note) following types depend on revocap
		integer, pointer       :: coupled_node(:)  ! local node id sent from revocap
		real( kind=8 ),pointer :: trac(:)          ! input  (x,y,z,x,y,z ... )
		real( kind=8 ),pointer :: disp(:)          ! output (x,y,z,x,y,z ... )
		real( kind=8 ),pointer :: velo(:)          ! output (x,y,z,x,y,z ... )
		real( kind=8 ),pointer :: accel(:)          ! output (x,y,z,x,y,z ... )
		! for inner use
		integer( kind=kint ),pointer :: index(:)   ! size:total node num.
		!  -1:not relation, >1:index of coupled_node
	end type fstr_couple
!C ---------------------------------------------------------------------------- 
!C
!C-- MPC
!C
!        type fstr_mpc_rigid
!                integer( kind=kint ) :: nmpc
!                integer( kind=kint ),pointer :: node1(:) !local node ID
!                integer( kind=kint ),pointer :: node2(:)
!                integer( kind=kint ),pointer :: dof(:)
!        end type fstr_mpc_rigid

!C ----------------------------------------------------------------------------
!C-- GROBAL VARIABLES for MEMORY MANAGEMENT or TIME RECORDING
!C

        ! for memory management
        integer :: totalloc
        integer :: masbi,masbr,mlczi,mlczr,mreori,mreorr
        logical :: minit

        ! for time recording (for subroutine time_log )
        logical :: tinit,teachiter, tenditer
        real(kind=kint) :: tmaints,tmainte,tmainus,tmainue,tmainss,tmainse
        real(kind=kint) :: tasbts,tasbte,tasbus,tasbue,tasbss,tasbse
        real(kind=kint) :: tlczts,tlczte,tlczus,tlczue,tlczss,tlczse
        real(kind=kint) :: tlczavt,tlczavu,tlczavs
        real(kind=kint) :: treorts,treorte,treorus,treorue,treorss,treorse
        real(kind=kint) :: treavt,treavu,treavs
        real(kind=kint) :: tsolts,tsolte,tsolus,tsolue,tsolss,tsolse
        real(kind=kint) :: tsolavt,tsolavu,tsolavs

        integer :: idummy
        integer(kind=kint) :: iexit  ! for eigen ?

!C
!C ----------------------------------------------------------------------------
!C
!C-- INTERFACE
!C

      interface
        subroutine fstr_chk_alloc( imsg2, sub_name, ierr )
           use hecmw
           character(*) :: sub_name
           integer(kind=kint):: imsg2
           integer(kind=kint):: ierr
        end subroutine fstr_chk_alloc
      end interface

contains

!C ----------------------------------------------------------------------------
!C NULL POINTER SETTING TO AVOID RUNTIME ERROR
!C ----------------------------------------------------------------------------

        subroutine fstr_nullify_fstr_param( P )
        implicit none
        type( fstr_param ) :: P
        nullify( P%dtime )
        nullify( P%etime )
        nullify( P%dtmin )
        nullify( P%delmax )
        nullify( P%itmax )
        nullify( P%eps )
        nullify( P%global_local_ID)
        end subroutine fstr_nullify_fstr_param
!C ----------------------------------------------------------------------------
        subroutine fstr_nullify_fstr_solid( S )
        implicit none
        type( fstr_solid ) :: S
        nullify( S%BOUNDARY_ngrp_ID )
        nullify( S%BOUNDARY_ngrp_type )
!       nullify( S%BOUNDARY_ngrp_iftype )
        nullify( S%BOUNDARY_ngrp_amp )
        nullify( S%BOUNDARY_ngrp_val)
        nullify( S%CLOAD_ngrp_ID )
        nullify( S%CLOAD_ngrp_DOF )
        nullify( S%CLOAD_ngrp_amp )
        nullify( S%CLOAD_ngrp_val )
        nullify( S%DLOAD_ngrp_ID )
        nullify( S%DLOAD_ngrp_LID )
        nullify( S%DLOAD_ngrp_amp )
        nullify( S%DLOAD_ngrp_params )
        nullify( S%TEMP_ngrp_ID )
        nullify( S%TEMP_ngrp_val )
        nullify( S%DISP   )
        nullify( S%STRESS )
        nullify( S%STRAIN )
        nullify( S%ESTRESS )
        nullify( S%ESTRAIN )
        nullify( S%FLG_ELPL    )
        nullify( S%mat_iso     )
        nullify( S%STRESS_YLD  )
        nullify( S%FACTOR      )
        nullify( S%EP_BAR      )
        nullify( S%STRAIN3D_P    )
        nullify( S%STRAIN3D_P_nd )
        nullify( S%STRAIN_nd )
        nullify( S%STRAIN_PRIS )
        nullify( S%STRAIN3D_V1 )
        nullify( S%STRAIN3D_V2 )
        nullify( S%GL          )
        nullify( S%TOTAL_DISP  )
        nullify( S%QFORCE      )
        nullify( S%QFORCE_RES  )
        nullify( S%STRESS3D    )
        nullify( S%SURFF       )
        nullify( S%STRESS2D    )
        nullify( S%STRESS3D_nd   )
        nullify( S%STRESS3D_ndP1 )
        nullify( S%STRESS_nd )
        nullify( S%STRESS_PRIS )
        nullify( S%SURFF_nd    )
        nullify( S%STRSURF_nd  )
        nullify( S%CURE3D   )
        nullify( S%CURE3D_I )
        nullify( S%CURE3D_nod    )
        nullify( S%CURE3D_nod_I  )
        nullify( S%DELCURE3D_nod )
        nullify( S%TEMPI    )
        nullify( S%TEMPC    )
        nullify( S%DELTEMP  )
        nullify( S%GBARU    )
        nullify( S%GBARU_ALL)

        nullify( S%VELOCITY_ngrp_ID )
        nullify( S%VELOCITY_ngrp_type )
        nullify( S%VELOCITY_ngrp_amp )
        nullify( S%VELOCITY_ngrp_val )
        nullify( S%ACCELERATION_ngrp_ID )
        nullify( S%ACCELERATION_ngrp_type )
        nullify( S%ACCELERATION_ngrp_amp )
        nullify( S%ACCELERATION_ngrp_val )

	! for couple analysis
        nullify( S%COUPLE_ngrp_ID )

        end subroutine fstr_nullify_fstr_solid

!C ----------------------------------------------------------------------------
        subroutine fstr_nullify_fstr_heat( H )
        implicit none
        type( fstr_heat ) :: H

        nullify( H%STEP_DLTIME )
        nullify( H%STEP_EETIME )
        nullify( H%STEP_DELMIN )
        nullify( H%STEP_DELMAX )
        nullify( H%RHO )
        nullify( H%RHOtemp  ) 
        nullify( H%CP )
        nullify( H%CPtemp  ) 
        nullify( H%COND )
        nullify( H%CONDtemp  ) 
        nullify( H%RHOtab )
        nullify( H%CPtab )
        nullify( H%CONDtab )
        nullify( H%RHOfuncA )
        nullify( H%RHOfuncB )
        nullify( H%CPfuncA  )
        nullify( H%CPfuncB )
        nullify( H%CONDfuncA  )
        nullify( H%CONDfuncB )
        nullify( H%AMPL )
        nullify( H%AMPLtime  ) 
        nullify( H%AMPLtab )
        nullify( H%AMPLfuncA )
        nullify( H%AMPLfuncB )
        nullify( H%TEMP0 )
        nullify( H%TEMPC )
        nullify( H%TEMP  )
        nullify( H%TEMPW )
        nullify( H%D_TEMP)
        nullify( H%RE )
        nullify( H%QV )
        nullify( H%RR )
        nullify( H%RL )
        nullify( H%RU )
        nullify( H%RD )
        nullify( H%IWKX )
        nullify( H%T_FIX_node )
        nullify( H%T_FIX_ampl )
        nullify( H%T_FIX_val )
        nullify( H%Q_NOD_node )
        nullify( H%Q_NOD_ampl )
        nullify( H%Q_NOD_val )
        nullify( H%Q_VOL_elem )
        nullify( H%Q_VOL_ampl )
        nullify( H%Q_VOL_val )
        nullify( H%Q_SUF_elem )
        nullify( H%Q_SUF_ampl )
        nullify( H%Q_SUF_surf )
        nullify( H%Q_SUF_val )
        nullify( H%R_SUF_elem )
        nullify( H%R_SUF_ampl )
        nullify( H%R_SUF_surf )
        nullify( H%R_SUF_val )
        nullify( H%H_SUF_elem )
        nullify( H%H_SUF_ampl )
        nullify( H%H_SUF_surf )
        nullify( H%H_SUF_val )
  ! CURE   ----  oga2009 ------
        nullify( H%mat_iso  )
        nullify( H%idx_mat_node )
        nullify( H%CURE3D   )
        nullify( H%CURE3D_I )
        nullify( H%CURE3D_nod   )
        nullify( H%CURE3D_nod_I )
        nullify( H%CURE3D_nod_cfrp   )
        nullify( H%D_CURE3D_nod )
        nullify( H%GBARU   )
        nullify( H%GBARU_ALL)

        end subroutine fstr_nullify_fstr_heat
!C ----------------------------------------------------------------------------
        subroutine fstr_nullify_fstr_dynamic( DY )
        implicit none
        type( fstr_dynamic ) :: DY

!!         nullify( DY%iout_list )
         nullify( DY%DISP )
         nullify( DY%VEL  )
         nullify( DY%ACC  )
         nullify( DY%VEC1 )
         nullify( DY%VEC2 )
         nullify( DY%VEC3 )

        end subroutine fstr_nullify_fstr_dynamic
!C ----------------------------------------------------------------------------
        subroutine fstr_nullify_fstr_couple( C )
	implicit none
	type( fstr_couple ) :: C
        nullify( C%coupled_node )
        nullify( C%trac )
        nullify( C%velo )
        nullify( C%index )
        end subroutine fstr_nullify_fstr_couple
!C ----------------------------------------------------------------------------
!        subroutine fstr_nullify_fstr_mpc_rigid( M )
!        implicit none
!        type( fstr_mpc_rigid ) :: M
!
!         nullify( M%node1 )
!         nullify( M%node2 )
!         nullify( M%dof )
!
!        end subroutine fstr_nullify_fstr_mpc_rigid
!C ----------------------------------------------------------------------------


end module m_fstr



