File: RELATIVE:/../../../mfix.git/model/adjust_dt_mod.f

1           MODULE ADJUST_DT
2     
3           CONTAINS
4     
5     !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv!
6     !                                                                      !
7     !  Module name: ADJUST_DT(IER, NIT)                                    !
8     !  Author: M. Syamlal                                 Date: FEB-10-97  !
9     !                                                                      !
10     !  Purpose: Automatically adjust time step.                            !
11     !                                                                      !
12     !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
13           LOGICAL FUNCTION ADJUSTDT (IER, NIT)
14     
15     ! Global Variables:
16     !---------------------------------------------------------------------//
17     ! User defined type of run: new or restart
18           use run, only: RUN_TYPE
19     ! User defined aximum number of iterations
20           use leqsol, only: MAX_NIT
21     ! User defined: min, max DT and adjustment factor
22           use run, only: DT_MIN, DT_MAX, DT_FAC
23     ! Flag: Use stored DT value for advancing TIME
24           use run, only: USE_DT_PREV
25     ! Flag: 2nd order time implementation
26           use run, only: CN_ON
27     ! Flag: Continue to run at DT_MIN
28           use run, only: PERSISTENT_MODE
29     ! Flag: Running in interactive mode
30           use run, only: INTERACTIVE_MODE
31     ! Flag: Interupt the code in interactive mode
32           use run, only: INTERUPT
33     ! The current number of time steps (value at restart).
34           use run, only: NSTEP, NSTEPRST
35     ! Current DT (1/DT) and direction of last change (+/-)
36           use run, only: DT, oDT, DT_DIR
37     
38     ! Global Parameters:
39     !---------------------------------------------------------------------//
40           use param1, only: ZERO, ONE, UNDEFINED
41     
42     
43     ! Module proceedures:
44     !---------------------------------------------------------------------//
45     ! Routine to break successive time step reductions.
46           use interactive, only: CHECK_TIMESTEP_FAIL_RATE
47           use error_manager
48     
49           IMPLICIT NONE
50     
51     ! Dummy Arguments:
52     !---------------------------------------------------------------------//
53     ! Integer flag: 0=Good, 100=initialize, otherwise bad.
54           INTEGER, INTENT(INOUT) :: IER
55     ! Number of iterations for current time step
56           INTEGER, INTENT(IN) :: NIT
57     
58     
59     ! Local Variables:
60     !---------------------------------------------------------------------//
61     ! Number of steps in between DT adjustments.
62           INTEGER, PARAMETER :: STEPS_MIN = 5
63     ! Number of time steps since last DT adjustment
64           INTEGER, SAVE :: STEPS_TOT=0
65     ! number of iterations since last DT adjustment
66           INTEGER, SAVE :: NIT_TOT=0
67     ! Iterations per second for last dt
68           DOUBLE PRECISION, SAVE :: NIToS=0.0
69     ! Current number of iterations per second
70           DOUBLE PRECISION :: NITOS_NEW
71     ! Flag to half/double the current time step
72           LOGICAL :: CN_ADJUST_DT
73     !......................................................................!
74     
75     ! Initialize the function result.
76           ADJUSTDT = .FALSE.
77           USE_DT_PREV = .FALSE.
78     
79     ! Steady-state simulation.
80           IF (DT==UNDEFINED .OR. DT<ZERO) RETURN
81     
82     ! Local flag for adjusting the time step for CN implementation.
83           CN_ADJUST_DT = CN_ON .AND. ((RUN_TYPE=='NEW' .AND. NSTEP>1) .OR. &
84              (RUN_TYPE/='NEW' .AND. NSTEP >= (NSTEPRST+1)))
85     
86     ! Stop sequential DT reductions by reseting the time-step and returning
87     ! control waiting for new user input.
88           IF(INTERACTIVE_MODE) &
89              CALL CHECK_TIMESTEP_FAIL_RATE(IER)
90     
91     ! Iterate successfully converged.
92     !---------------------------------------------------------------------//
93           IF(IER == 0) THEN
94     
95     ! Set back the timestep to original size which was halved previously for
96     ! 2nd order accurate time implementation.
97              IF(CN_ADJUST_DT) DT = 2.0D0*DT
98     
99     ! Calculate a new DT every STEPS_MIN time steps.
100              IF(STEPS_TOT >= STEPS_MIN) THEN
101                 NITOS_NEW = DBLE(NIT_TOT)/(STEPS_TOT*DT)
102                 IF (NITOS_NEW > NITOS) DT_DIR = DT_DIR*(-1)
103                 STEPS_TOT = 0
104                 NITOS = NITOS_NEW
105                 NIT_TOT = 0
106                 IF (DT_DIR > 0) THEN
107                    IF(NIT < MAX_NIT) DT = MIN(DT_MAX,DT/DT_FAC)
108                 ELSE
109                    DT = DT*DT_FAC
110                    IF(PERSISTENT_MODE) DT = max(DT, DT_MIN)
111                 ENDIF
112     
113     ! DT was modified. Use the stored DT should be used to update TIME.
114                 USE_DT_PREV = .TRUE.
115     
116     ! Write the convergence stats to the screen/log file.
117                 WRITE(ERR_MSG,"('DT=',g11.4,3x,'NIT/s=',A)")  &
118                    DT, trim(iVal(nint(NITOS)))
119                 CALL FLUSH_ERR_MSG(HEADER=.FALSE., &
120                    FOOTER=.FALSE., LOG=.FALSE.)
121     
122              ELSE
123                 STEPS_TOT = STEPS_TOT + 1
124                 NIT_TOT = NIT_TOT + NIT
125              ENDIF
126     ! No need to iterate again
127              ADJUSTDT = .FALSE.
128     ! Cut the timestep into half for 2nd order accurate time implementation.
129              IF(CN_ADJUST_DT) DT = 0.5d0*DT
130     
131     ! Iterate failed to converge.
132     !---------------------------------------------------------------------//
133           ELSE
134     
135     ! Clear the error flag.
136              IER = 0
137     
138     ! Reset the timestep to original size which was halved previously for
139     ! 2nd order accurate time implementation.
140              IF(CN_ADJUST_DT) DT = 2.0d0*DT
141     
142     ! Reset counters.
143              STEPS_TOT = 0
144              NITOS = 0.
145              NIT_TOT = 0
146     
147     ! Reduce the step size.
148              DT = DT*DT_FAC
149     
150     ! The step size has decreased to the minimum.
151              IF (DT_FAC >= ONE) THEN
152     
153                 IF(PERSISTENT_MODE) THEN
154                    ADJUSTDT = .FALSE.
155                 ELSE
156                    WRITE(ERR_MSG,"(3X,A)") &
157                       'DT_FAC >= 1. Recovery not possible!'
158                    CALL FLUSH_ERR_MSG(ABORT=.TRUE., &
159                       HEADER=.FALSE., FOOTER=.FALSE.)
160                 ENDIF
161     
162              ELSEIF (DT > DT_MIN) THEN
163     
164                 IF(.NOT.INTERUPT) THEN
165                    WRITE(ERR_MSG,"(3X,'Recovered: Dt=',G12.5,' :-)')") DT
166                    CALL FLUSH_ERR_MSG(HEADER=.FALSE., FOOTER=.FALSE.)
167                 ENDIF
168     
169                 CALL RESET_NEW
170     
171     ! Iterate again with new dt
172                 ADJUSTDT = .TRUE.
173     
174     ! Cut the timestep for 2nd order accurate time implementation.
175                 IF(CN_ADJUST_DT) DT = 0.5d0*DT
176     
177     ! Set the return flag stop iterating.
178              ELSE
179     
180     ! Prevent DT from dropping below DT_MIN.
181                 IF(PERSISTENT_MODE) DT = max(DT, DT_MIN)
182                 ADJUSTDT = .FALSE.
183              ENDIF
184     
185           ENDIF
186     
187     ! Update ONE/DT variable.
188           ODT = ONE/DT
189     
190     ! Break out of the iterate loop if INTERUPT signal is given
191           IF(INTERUPT) ADJUSTDT = .FALSE.
192     
193           RETURN
194           END FUNCTION ADJUSTDT
195     
196           END MODULE ADJUST_DT
197