1!-------------------------------------------------------------------------------
2! Copyright (c) 2019 FrontISTR Commons
3! This software is released under the MIT License, see LICENSE.txt
4!-------------------------------------------------------------------------------
5!>   This module manages step infomation
6module m_step
7  use hecmw
8  implicit none
9
10  include 'fstr_ctrl_util_f.inc'
11
12  integer, parameter :: stepStatic = 1
13  integer, parameter :: stepVisco  = 2
14  integer, parameter :: stepFixedInc = 1
15  integer, parameter :: stepAutoInc  = 2
16
17  ! statistics of newton iteration
18  integer(kind=kint),parameter :: knstMAXIT  = 1 ! maximum number of newton iteration
19  integer(kind=kint),parameter :: knstSUMIT  = 2 ! total number of newton iteration
20  integer(kind=kint),parameter :: knstCITER  = 3 ! number of contact iteration
21  integer(kind=kint),parameter :: knstDRESN  = 4 ! reason of not to converged
22
23  !> Step control such as active boundary condition, convergent condition etc.
24  type step_info
25    integer             :: solution           !< solution type; 1: static;  2:visco
26    integer             :: inc_type           !< increment type; 1: fixed;  2:auto
27    character( len=80 ) :: CONTROL            !< control type, such as arclength etc
28    character( len=80 ) :: ConvControl        !< Judgement of convergency, such as nodal force residual
29    !< disp increment, energy
30    real(kind=kreal)    :: converg            !< value of convergent judgement
31    real(kind=kreal)    :: maxres             !< upper bound of NR residual
32
33    integer :: num_substep                    !< substeps user given
34    integer :: max_iter                       !< max number of iteration
35    integer :: max_contiter                   !< max number of contact iteration
36    integer :: amp_id                         !< id of amplitude definition
37    real(kind=kreal) :: initdt                !< time increment
38    real(kind=kreal) :: elapsetime            !< elapse time of this step
39    real(kind=kreal) :: mindt                 !< lower bound of time increment
40    real(kind=kreal) :: maxdt                 !< upper bound of time increment
41    real(kind=kreal) :: starttime             !< start time of this step
42    integer, pointer :: Boundary(:)=>null()   !< active group of boundary conditions of current step
43    integer, pointer :: Load(:)=>null()       !< active group of external load conditions of current step
44    integer, pointer :: Contact(:)=>null()    !< active group of contact conditions of current step
45    integer :: timepoint_id                   !< id of timepoint
46    integer :: AincParam_id                   !< id of auto increment paramter
47  end type
48
49  type tParamAutoInc
50    character(HECMW_NAME_LEN)  :: name
51    real(kind=kreal)     :: ainc_Rs            !< time increment decreasing ratio
52    real(kind=kreal)     :: ainc_Rl            !< time increment increasing ratio
53    integer( kind=kint ) :: NRbound_s(10)      !< # of NR iteration bound to decrease time increment
54    integer( kind=kint ) :: NRbound_l(10)      !< # of NR iteration bound to increase time increment
55    integer( kind=kint ) :: NRtimes_s          !< # of times that decreasing condition is satisfied
56    integer( kind=kint ) :: NRtimes_l          !< # of times that increasing condition is satisfied
57    real(kind=kreal)     :: ainc_Rc            !< time increment decreasing ratio for cutback
58    integer( kind=kint ) :: CBbound            !< maximum # of successive cutback
59  end type
60
61contains
62
63  !> Initializer
64  subroutine init_stepInfo( stepinfo )
65    type( step_info ), intent(out) :: stepinfo !< step info
66    stepinfo%solution = stepStatic
67    stepinfo%inc_type = stepFixedInc
68    stepinfo%num_substep = 1
69    stepinfo%max_iter = 50
70    stepinfo%max_contiter = 10
71    stepinfo%amp_id = -1
72    stepinfo%initdt = 1.d0
73    stepinfo%mindt = 1.d-4
74    stepinfo%maxdt = 1.d0
75    stepinfo%elapsetime = 1.d0
76    stepinfo%starttime = 0.d0
77    stepinfo%converg = 1.d-3
78    stepinfo%maxres = 1.d+10
79    stepinfo%timepoint_id = 0
80    stepinfo%AincParam_id = 0
81  end subroutine
82
83  subroutine setup_stepInfo_starttime( stepinfos )
84    type( step_info ), pointer, intent(inout) :: stepinfos(:) !< step info
85
86    integer :: i
87
88    stepinfos(1)%starttime = 0.d0
89    do i=1,size(stepinfos)-1
90      stepinfos(i+1)%starttime = stepinfos(i)%starttime + stepinfos(i)%elapsetime
91    end do
92  end subroutine
93
94  !> Is boundary condition in this step active
95  logical function isBoundaryActive( bnd, stepinfo )
96    integer, intent(in)           :: bnd      !< group number of boundary condition
97    type( step_info ), intent(in) :: stepinfo !< current step info
98    isBoundaryActive = .false.
99    if( .not. associated( stepinfo%Boundary ) ) return
100    if( any( stepinfo%Boundary== bnd ) ) isBoundaryActive = .true.
101  end function
102
103  !> Is external load in this step active
104  logical function isLoadActive( bnd, stepinfo )
105    integer, intent(in)           :: bnd      !< group number of boundary condition
106    type( step_info ), intent(in) :: stepinfo !< current step info
107    isLoadActive = .false.
108    if( .not. associated( stepinfo%Load ) ) return
109    if( any( stepinfo%Load == bnd ) ) isLoadActive = .true.
110  end function
111
112  !> Is contact condition in this step active
113  logical function isContactActive( bnd, stepinfo )
114    integer, intent(in)           :: bnd      !< group number of boundary condition
115    type( step_info ), intent(in) :: stepinfo !< current step info
116    isContactActive = .false.
117    if( .not. associated( stepinfo%Contact ) ) return
118    if( any( stepinfo%Contact== bnd ) ) isContactActive = .true.
119  end function
120
121  !> Finalizer
122  subroutine free_stepInfo( step )
123    type(step_info), intent(inout) :: step  !< step info
124    if( associated( step%Boundary ) ) deallocate( step%Boundary )
125    if( associated( step%Load ) )     deallocate( step%Load )
126    if( associated( step%Contact ) )  deallocate( step%Contact )
127  end subroutine
128
129  !> Print out step control
130  subroutine fstr_print_steps( nfile, steps )
131    integer, intent(in)         :: nfile     !< file number
132    type(step_info), intent(in) :: steps(:)  !< step info
133    integer :: i, j, nstep, nbc
134    nstep = size(steps)
135
136    write( nfile, * ) "-----Information of steps:",nstep
137
138    do i=1,nstep
139      write( nfile, * ) "  -----Step:",i
140      write(nfile,*) steps(i)%solution, steps(i)%elapsetime, steps(i)%converg, &
141        steps(i)%num_substep, steps(i)%max_iter
142      if( associated( steps(i)%Boundary ) ) then
143        nbc = size( steps(i)%Boundary )
144        write(nfile,*) "  Boundary conditions"
145        write(nfile,*) ( steps(i)%Boundary(j),j=1,nbc )
146      endif
147      if( associated( steps(i)%Load ) ) then
148        nbc = size( steps(i)%Load )
149        write(nfile,*) "  External load conditions"
150        write(nfile,*) ( steps(i)%Load(j),j=1,nbc )
151      endif
152      if( associated( steps(i)%Contact ) ) then
153        nbc = size( steps(i)%Contact )
154        write(nfile,*) "  Contact conditions"
155        write(nfile,*) ( steps(i)%Contact(j),j=1,nbc )
156      endif
157    enddo
158  end subroutine
159
160  !> Initializer
161  subroutine init_AincParam( aincparam )
162    type( tParamAutoInc ), intent(out) :: aincparam !< auto increment paramter
163
164    aincparam%name      = ''
165    aincparam%ainc_Rs   = 0.25d0
166    aincparam%ainc_Rl   = 1.25d0
167    aincparam%NRbound_s = 0
168    aincparam%NRbound_s(knstMAXIT) = 10
169    aincparam%NRbound_s(knstSUMIT) = 50
170    aincparam%NRbound_s(knstCITER) = 10
171    aincparam%NRbound_l = 0
172    aincparam%NRbound_l(knstMAXIT) = 1
173    aincparam%NRbound_l(knstSUMIT) = 1
174    aincparam%NRbound_l(knstCITER) = 1
175    aincparam%NRtimes_s = 1
176    aincparam%NRtimes_l = 2
177    aincparam%ainc_Rc   = 0.25d0
178    aincparam%CBbound   = 5
179  end subroutine
180
181end module
182