FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
fstr_Ctrl_TimeInc.f90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
2 ! Copyright (c) 2019 FrontISTR Commons
3 ! This software is released under the MIT License, see LICENSE.txt
4 !-------------------------------------------------------------------------------
6 
8  use m_fstr
9  use m_step
10  use m_timepoint
11 
12  implicit none
13 
14  real(kind=kreal), private :: current_time = 0.d0
15  real(kind=kreal), private :: time_inc = 0.d0
16  real(kind=kreal), private :: time_inc_base = 0.d0
17 
18 contains
19 
20  !! basic functions to get time/timeinc
21  real(kind=kreal) function fstr_get_time()
22  fstr_get_time = current_time
23  end function
24 
25  real(kind=kreal) function fstr_get_timeinc()
26  fstr_get_timeinc = time_inc
27  end function
28 
29  real(kind=kreal) function fstr_get_timeinc_base()
30  fstr_get_timeinc_base = time_inc_base
31  end function
32 
33  !! basic functions to set/update time/timeinc
34  subroutine fstr_set_time( time )
35  real(kind=kreal), intent(in) :: time
36  current_time = time
37  end subroutine
38 
39  subroutine fstr_set_timeinc( dtime )
40  real(kind=kreal), intent(in) :: dtime
41  time_inc = dtime
42  end subroutine
43 
44  subroutine fstr_set_timeinc_base( dtime_base )
45  real(kind=kreal), intent(in) :: dtime_base
46  time_inc_base = dtime_base
47  end subroutine
48 
49  subroutine fstr_proceed_time()
50  current_time = current_time + time_inc
51  end subroutine
52 
53  !! functions to print status
55  write(ista,'(A10,"-+-",A60,"-+-",A40)') repeat("-",10),repeat("-",60),repeat("-",40)
56  write(ista,'(2A5," | ",2A5,2A7,3A12," | ",A40)') ' ', ' ', ' ', ' # of', 'MAX #', 'TOT #', '','', '', ''
57  write(ista,'(2A5," | ",2A5,2A7,3A12," | ",A7,A33)') &
58  & 'STEP', 'SUB', 'STAT', ' CONT', 'NEWTON', 'NEWTON', 'START', 'TIME','END', 'MESSAGE',''
59  write(ista,'(2A5," | ",2A5,2A7,3A12," | ",A40)') &
60  & '', 'STEP', ' ', 'ITER', 'ITER', 'ITER', 'TIME', 'INC', 'TIME',''
61  write(ista,'(A10,"-+-",A60,"-+-",A40)') repeat("-",10),repeat("-",60),repeat("-",40)
62  end subroutine
63 
64  subroutine fstr_timeinc_printstatus( stepinfo, fstrPARAM, totstep, substep, NRstatI, NRstatR, AutoINC_stat, Cutback_stat )
65  type(step_info), intent(in) :: stepinfo
66  type(fstr_param), intent(in) :: fstrPARAM
67  integer(kind=kint), intent(in) :: totstep
68  integer(kind=kint), intent(in) :: substep
69  integer(kind=kint), intent(in) :: NRstatI(:) !previous Newton Raphson Iteration Log
70  real(kind=kreal), intent(in) :: nrstatr(:) !previous Newton Raphson Iteration Log
71  integer(kind=kint), intent(inout) :: AutoINC_stat
72  integer(kind=kint), intent(in) :: Cutback_stat
73 
74  character(len=5) :: cstep, csstep, cstate, ccont
75  character(len=7) :: cmaxn, ctotn
76  character(len=12) :: ctime, cdtime, etime
77  character(len=40) :: message
78  type(tparamautoinc) :: pAinc
79 
80  painc = fstrparam%ainc(stepinfo%AincParam_id)
81 
82  write(cstep,'(I5)') totstep
83  write(csstep,'(I5)') substep
84  write(ccont,'(I5)') nrstati(knstciter)
85  write(cmaxn,'(I7)') nrstati(knstmaxit)
86  write(ctotn,'(I7)') nrstati(knstsumit)
87  write(ctime,'(1pE12.4)') current_time
88  write(cdtime,'(1pE12.4)') time_inc
89 
90  if( cutback_stat > 0 ) then
91  write(etime,'(1pE12.4)') current_time
92  write(cstate,'(I4,A)') cutback_stat,'F'
93  if( nrstati(knstdresn) == 1 ) write(message,'(A)') 'Failed to converge due to MAXITER.'
94  if( nrstati(knstdresn) == 2 ) write(message,'(A)') 'Failed to converge due to MAXRES.'
95  if( nrstati(knstdresn) == 3 ) write(message,'(A)') 'Failed to converge due to MAXCONTITER.'
96  if( nrstati(knstdresn) == 4 ) write(message,'(A)') 'Failed to converge due to MatSolveError.'
97  if( nrstati(knstdresn) == 5 ) write(message,'(A)') 'Failed to converge due to MatNotConv.'
98  if( nrstati(knstdresn) == 6 ) write(message,'(A)') 'Failed to converge due to MatDiverged.'
99  if( cutback_stat == painc%CBbound ) write(message,'(A)') '# of successive cutback reached max.'
100  else
101  write(etime,'(1pE12.4)') current_time+time_inc
102  write(cstate,'(A5)') 'S'
103  write(message,'(A)') ''
104  endif
105 
106  write(ista,'(2A5," | ",2A5,2A7,3A12," | ",A40)') cstep, csstep, cstate, ccont, &
107  & cmaxn, ctotn, ctime, cdtime, etime, message
108 
109  end subroutine
110 
111  subroutine fstr_timeinc_printstatus_final(success_flag)
112  logical, intent(in) :: success_flag
113  write(ista,'(A10,"-+-",A60,"-+-",A40)') repeat("-",10),repeat("-",60),repeat("-",40)
114  if(success_flag) then
115  write(ista,'(A)') 'FSTR_SOLVE_NLGEOM HAS COMPLETED SUCCESSFULLY'
116  else
117  write(ista,'(A)') 'FSTR_SOLVE_NLGEOM HAS NOT COMPLETED SUCCESSFULLY'
118  end if
119  end subroutine
120 
121  !! true if step finished
122  logical function fstr_timeinc_isstepfinished( stepinfo )
123  type(step_info), intent(in) :: stepinfo
124 
125  real(kind=kreal) :: endtime, tolerance
126 
127  endtime = stepinfo%starttime + stepinfo%elapsetime
128  ! roundoff error of current_time scales with the absolute time, which can
129  ! exceed a tolerance based only on elapsetime when elapsetime << |endtime|
130  tolerance = 1.d-12 * max(stepinfo%elapsetime, dabs(endtime))
131  fstr_timeinc_isstepfinished = (endtime-current_time < tolerance)
132  end function
133 
134  !! true if current time is time point
135  logical function fstr_timeinc_istimepoint( stepinfo, fstrPARAM )
136  type(step_info), intent(in) :: stepinfo
137  type(fstr_param), intent(in) :: fstrparam
138 
139  fstr_timeinc_istimepoint = .false.
140  if( stepinfo%inc_type == stepfixedinc ) return
141  if( stepinfo%timepoint_id == 0 ) return
142 
143  fstr_timeinc_istimepoint = is_at_timepoints(current_time,stepinfo%starttime, &
144  & fstrparam%timepoints(stepinfo%timepoint_id))
145  end function
146 
147  !! set time_inc from stepinfo and Newton Raphson iteration status
148  subroutine fstr_timeinc_settimeincrement( stepinfo, fstrPARAM, substep, NRstatI, NRstatR, AutoINC_stat, Cutback_stat )
149  type(step_info), intent(in) :: stepinfo
150  type(fstr_param), intent(in) :: fstrPARAM
151  integer(kind=kint), intent(in) :: substep
152  integer(kind=kint), intent(in) :: NRstatI(:) !previous Newton Raphson Iteration Log
153  real(kind=kreal), intent(in) :: nrstatr(:) !previous Newton Raphson Iteration Log
154  integer(kind=kint), intent(inout) :: AutoINC_stat
155  integer(kind=kint), intent(in) :: Cutback_stat
156 
157  real(kind=kreal) :: timeinc0
158  real(kind=kreal) :: endtime, remain
159  logical :: to_be_decreased, to_be_increased
160  type(tparamautoinc) :: pAinc
161 
162  painc = fstrparam%ainc(stepinfo%AincParam_id)
163 
164  if( stepinfo%inc_type == stepfixedinc ) then
165  timeinc0 = stepinfo%initdt
166  else ! INCTYPE==AUTO
167  if( cutback_stat > 0 ) then
168  timeinc0 = painc%ainc_Rc*time_inc
169  if(myrank == 0) write(*,'(2(A,E10.3))') 'time increment is decreased from ', time_inc_base, ' to ', timeinc0
170  autoinc_stat = -1
171  else
172  if( substep == 1 ) then
173  timeinc0 = stepinfo%initdt
174  autoinc_stat = 0
175  else
176  timeinc0 = time_inc_base
177 
178  !decrease condition
179  to_be_decreased = .false.
180  if( nrstati(knstmaxit) > painc%NRbound_s(knstmaxit) ) to_be_decreased = .true.
181  if( nrstati(knstsumit) > painc%NRbound_s(knstsumit) ) to_be_decreased = .true.
182  if( nrstati(knstciter) > painc%NRbound_s(knstciter) ) to_be_decreased = .true.
183 
184  !increase condition
185  to_be_increased = .true.
186  if( nrstati(knstmaxit) > painc%NRbound_l(knstmaxit) ) to_be_increased = .false.
187  if( nrstati(knstsumit) > painc%NRbound_l(knstsumit) ) to_be_increased = .false.
188  if( nrstati(knstciter) > painc%NRbound_l(knstciter) ) to_be_increased = .false.
189 
190  ! count # of times that increase/decrease condition has been satisfied
191  ! AutoINC_stat < 0 ... decrease condition has been satisfied -AutoINC_stat times
192  ! AutoINC_stat > 0 ... increase condition has been satisfied AutoINC_stat times
193  if(to_be_decreased) then
194  autoinc_stat = min(autoinc_stat,0) - 1
195  else if(to_be_increased) then
196  autoinc_stat = max(autoinc_stat,0) + 1
197  else
198  autoinc_stat = 0
199  end if
200 
201  if( autoinc_stat <= -painc%NRtimes_s ) then
202  timeinc0 = painc%ainc_Rs*timeinc0
203  if(myrank == 0) write(*,'(2(A,E10.3))') 'time increment is decreased from ', time_inc_base, ' to ', timeinc0
204  else if( autoinc_stat >= painc%NRtimes_l ) then
205  timeinc0 = dmin1(painc%ainc_Rl*timeinc0,stepinfo%maxdt)
206  if(myrank == 0) write(*,'(2(A,E10.3))') 'time increment is increased from ', time_inc_base, ' to ', timeinc0
207  end if
208  end if
209  end if
210  end if
211 
212  if( timeinc0 < stepinfo%mindt ) then
213  if(myrank == 0) then
214  write(*,'(2(A,E10.3))') 'Error: current time increment ',timeinc0,' is smaller than lower bound',stepinfo%mindt
215  call fstr_timeinc_printstatus_final(.false.)
216  endif
217  stop
218  end if
219 
220  endtime = stepinfo%starttime + stepinfo%elapsetime
221  time_inc_base = dmin1(timeinc0,endtime-current_time)
222  if( stepinfo%timepoint_id > 0 ) then
223  remain = get_remain_to_next_timepoints(current_time,stepinfo%starttime,fstrparam%timepoints(stepinfo%timepoint_id))
224  time_inc = dmin1(time_inc_base,remain)
225  else
226  time_inc = time_inc_base
227  end if
228 
229  end subroutine
230 end module m_fstr_timeinc
This module provides functions to deal with time and increment of stress analysis.
real(kind=kreal) function fstr_get_timeinc()
logical function fstr_timeinc_istimepoint(stepinfo, fstrPARAM)
real(kind=kreal) function fstr_get_timeinc_base()
subroutine fstr_set_timeinc_base(dtime_base)
subroutine fstr_timeinc_settimeincrement(stepinfo, fstrPARAM, substep, NRstatI, NRstatR, AutoINC_stat, Cutback_stat)
real(kind=kreal) function fstr_get_time()
subroutine fstr_proceed_time()
subroutine fstr_timeinc_printstatus_final(success_flag)
subroutine fstr_timeinc_printstatus_init
subroutine fstr_set_time(time)
subroutine fstr_set_timeinc(dtime)
logical function fstr_timeinc_isstepfinished(stepinfo)
subroutine fstr_timeinc_printstatus(stepinfo, fstrPARAM, totstep, substep, NRstatI, NRstatR, AutoINC_stat, Cutback_stat)
This module defines common data and basic structures for analysis.
Definition: m_fstr.F90:15
integer(kind=kint) myrank
PARALLEL EXECUTION.
Definition: m_fstr.F90:103
integer(kind=kint), parameter ista
Definition: m_fstr.F90:115
This module manages step information.
Definition: m_step.f90:6
integer, parameter stepfixedinc
Definition: m_step.f90:14
integer(kind=kint), parameter knstmaxit
Definition: m_step.f90:20
integer(kind=kint), parameter knstdresn
Definition: m_step.f90:23
integer(kind=kint), parameter knstsumit
Definition: m_step.f90:21
integer(kind=kint), parameter knstciter
Definition: m_step.f90:22
This module manages timepoint information.
Definition: m_timepoint.f90:6
real(kind=kreal) function get_remain_to_next_timepoints(totaltime, starttime, tp)
Definition: m_timepoint.f90:44
logical function is_at_timepoints(totaltime, starttime, tp)
Definition: m_timepoint.f90:24
FSTR INNER CONTROL PARAMETERS (fstrPARAM)
Definition: m_fstr.F90:161
Step control such as active boundary condition, convergent condition etc.
Definition: m_step.f90:35