64 INTEGER :: timeleft,cum_timestep
65 INTEGER,
SAVE :: stepcount=0, RealTimestep
66 LOGICAL :: SteadyStateReached=.FALSE.
68 REAL(KIND=dp) :: CumTime, MaxErr, AdaptiveLimit, &
69 AdaptiveMinTimestep, AdaptiveMaxTimestep, timePeriod
70 INTEGER :: SmallestCount, AdaptiveKeepSmallest, StepControl=-1
71 LOGICAL :: AdaptiveTime = .TRUE.
73 REAL(KIND=dp) :: newtime, prevtime=0, maxtime, exitcond
74 REAL(KIND=dp),
ALLOCATABLE :: xx(:,:), xxnrm(:), yynrm(:), PrevXX(:,:,:)
78 TYPE(valuelist_t
),
POINTER :: SolverParams
79 TYPE(variable_t
),
POINTER :: StressSol
80 CHARACTER(LEN=MAX_NAME_LEN) :: Equation
81 REAL(KIND=dp),
POINTER :: Displacement(:)
82 INTEGER :: BoundaryElementCount, ElementCount, body_id
83 INTEGER :: bc_id, nElementNodes, nt, nk
84 INTEGER,
POINTER :: MyIndex(:), MyNodeIndexes(:), MyPerm(:)
85 TYPE(element_t
),
POINTER :: Element, MyCurrentElement
86 TYPE(nodes_t
),
SAVE :: ElementNodes
87 TYPE(mesh_t
),
POINTER :: MyMesh
89 DOUBLE PRECISION :: FinalTime, PreviousTime
106 REAL(KIND=dp),
ALLOCATABLE :: f(:)
107 INTEGER :: myn, currentinterval
108 TYPE(valuelist_t
),
POINTER :: ptr
110 WRITE(6,*)
'MyTimeModule:UpdateLoads: Updating loads on the structure'
112 IF (myverbosity > 3)
THEN
113 WRITE(6,*)
'sTime(1) = ', stime(1)
114 WRITE(6,*)
'FinalTime = ', finaltime
115 WRITE(6,*)
'PreviousTime = ', previoustime
119 IF( myverbosity > 3)
THEN
120 WRITE(*,*)
'global%NodeLoads:'
121 DO t = 1, global%nNodes
122 WRITE(*,*) global%NodeLoads(3*(t-1) + 1), global%NodeLoads(3*(t-1) + 2), &
123 global%NodeLoads(3*(t-1) + 3)
126 IF( myverbosity > 3)
THEN
127 WRITE(*,*)
'global%PreviousLoads:'
128 DO t = 1, global%nNodes
130 WRITE(*,*) global%PreviousLoads(j,t)
137 WRITE(*,*)
'MyTimeModule:UpdateLoads: Time Step Summary '
138 WRITE(*,*)
' sTime(1) = ', stime(1)
139 WRITE(*,*)
' PreviousTime = ', previoustime
140 WRITE(*,*)
' FinalTime = ', finaltime
142 DO t = 1, global%nNodes
145 IF (global%IsLoadFreeNode(t))
THEN
148 currentmodel % NodeLoadsPass(j,t) = 0.d0
149 WRITE(*,*)
' Node #',t,
' is load free'
152 currentmodel % NodeLoadsPass(j,t) = global%PreviousLoads(j,t) + &
153 (global%NodeLoads(3*(t-1) + j) - global%PreviousLoads(j,t))&
154 *(stime(1) - previoustime)/(finaltime - previoustime)
171 IF( myverbosity > 3)
THEN
172 WRITE(*,*)
'CurrentModel % NodeLoadsPass:'
173 DO t = 1, global%nNodes
175 WRITE(*,*) currentmodel % NodeLoadsPass(j,t)
180 WRITE(6,*)
'MyTimeModule:UpdateLoads: Finishing'
197 DO interval = 1, timeintervals
198 stepcount = stepcount + timesteps(interval)
201 IF (myverbosity > 3)
THEN
202 WRITE(*,*)
'In TimeStepper'
203 WRITE(*,*)
'TimeIntervals = ', timeintervals
204 WRITE(*,*)
'global%nNodes = ', global%nNodes
209 DO interval = 1,timeintervals
211 IF (myverbosity > 3)
THEN
212 WRITE(*,*)
'interval = ', interval
215 IF ( transient .OR. scanning )
THEN
216 dt = timestepsizes(interval,1)
223 timeperiod = listgetcreal(currentmodel % Simulation,
'Time Period',gotit)
224 IF(.NOT.gotit) timeperiod = huge(timeperiod)
228 WRITE(*,*)
'MyTimeModule:TimeStepper: Timesteps(interval) = ', timesteps(interval)
229 DO timestep = 1,timesteps(interval)
231 cum_timestep = cum_timestep + 1
232 sstep(1) = cum_timestep
234 dtfunc = listgetconstreal( currentmodel % Simulation, &
235 'Timestep Function', gotit)
237 CALL warn(
'ExecSimulation',
'Obsolite keyword > Timestep Function < , use > Timestep Size < instead')
239 dtfunc = listgetcreal( currentmodel % Simulation, &
240 'Timestep Size', gotit)
242 IF(gotit) dt = dtfunc
245 stime(1) = stime(1) + dt
246 speriodic(1) = stime(1)
247 DO WHILE(speriodic(1) > timeperiod)
248 speriodic(1) = speriodic(1) - timeperiod
252 IF(timestep > 1 .OR. interval > 1)
THEN
253 DO i =
SIZE(sprevsizes,2),2,-1
254 sprevsizes(1,i) = sprevsizes(1,i-1)
256 sprevsizes(1,1) = ssize(1)
260 sinterval(1) = interval
261 IF (.NOT. transient ) steadyit(1) = steadyit(1) + 1
263 IF ( parenv % MyPE == 0 )
THEN
264 CALL info(
'MAIN',
' ', level=3 )
265 CALL info(
'MAIN',
'-------------------------------------', level=3 )
267 IF ( transient .OR. scanning )
THEN
268 WRITE( message, * )
'Time: ',trim(i2s(cum_timestep)),
'/', &
269 trim(i2s(stepcount)), stime(1)
270 CALL info(
'MAIN', message, level=3 )
274 IF( cum_timestep > 1 )
THEN
275 maxtime = listgetconstreal( currentmodel % Simulation,
'Real Time Max',gotit)
277 WRITE( message,
'(A,F8.3)')
'Fraction of real time left: ',&
278 1.0_dp-realtime() / maxtime
280 timeleft = nint((stepcount-(cum_timestep-1))*(newtime-prevtime)/60._dp);
281 IF (timeleft > 120)
THEN
282 WRITE( message, *)
'Estimated time left: ', &
283 trim(i2s(timeleft/60)),
' hours.'
284 ELSE IF(timeleft > 60)
THEN
285 WRITE( message, *)
'Estimated time left: 1 hour ', &
286 trim(i2s(mod(timeleft,60))),
' minutes.'
287 ELSE IF(timeleft >= 1)
THEN
288 WRITE( message, *)
'Estimated time left: ', &
289 trim(i2s(timeleft)),
' minutes.'
291 WRITE( message, *)
'Estimated time left: less than a minute.'
294 CALL info(
'MAIN', message, level=3 )
298 WRITE( message, * )
'Steady state iteration: ',cum_timestep
299 CALL info(
'MAIN', message, level=3 )
302 CALL info(
'MAIN',
'-------------------------------------', level=3 )
303 CALL info(
'MAIN',
' ', level=3 )
310 IF (myverbosity > 3)
THEN
311 WRITE(6,*)
'timestepper timestep = ', timestep
312 WRITE(6,*)
'sTime(1) = ', stime(1)
313 WRITE(6,*)
'dtfunc = ', dtfunc
314 WRITE(6,*)
'dt = ', dt
315 WRITE(*,*)
'TimeStepper Calling UpdateLoads'
321 adaptivetime = listgetlogical( currentmodel % Simulation, &
322 'Adaptive Timestepping', gotit )
324 IF ( transient .AND. adaptivetime )
THEN
325 adaptivelimit = listgetconstreal( currentmodel % Simulation, &
326 'Adaptive Time Error', gotit )
328 IF ( .NOT. gotit )
THEN
329 WRITE( message, * )
'Adaptive Time Limit must be given for' // &
330 'adaptive stepping scheme.'
331 CALL fatal(
'ElmerSolver', message )
334 adaptivemaxtimestep = listgetconstreal( currentmodel % Simulation, &
335 'Adaptive Max Timestep', gotit )
336 IF ( .NOT. gotit ) adaptivemaxtimestep = dt
337 adaptivemaxtimestep = min(adaptivemaxtimestep, dt)
339 adaptivemintimestep = listgetconstreal( currentmodel % Simulation, &
340 'Adaptive Min Timestep', gotit )
342 adaptivekeepsmallest = listgetinteger( currentmodel % Simulation, &
343 'Adaptive Keep Smallest', gotit, minv=0 )
345 n = currentmodel % NumberOfSolvers
349 solver => currentmodel % Solvers(i)
350 IF (
ASSOCIATED( solver % Variable % Values ) )
THEN
351 IF (
ASSOCIATED( solver % Variable % PrevValues ) )
THEN
352 j = max( j,
SIZE( solver % Variable % PrevValues,2 ) )
354 k = max( k,
SIZE( solver % Variable % Values ) )
357 ALLOCATE( xx(n,k), yynrm(n), xxnrm(n), prevxx( n,k,j ) )
360 IF ( ddt == 0.0d0 .OR. ddt > adaptivemaxtimestep ) ddt = adaptivemaxtimestep
364 DO WHILE( cumtime < dt-1.0d-12 )
365 ddt = min( dt - cumtime, ddt )
367 DO i=1,currentmodel % NumberOFSolvers
368 solver => currentmodel % Solvers(i)
369 IF (
ASSOCIATED( solver % Variable % Values ) )
THEN
370 n =
SIZE( solver % Variable % Values )
371 xx(i,1:n) = solver % Variable % Values
372 xxnrm(i) = solver % Variable % Norm
373 IF (
ASSOCIATED( solver % Variable % PrevValues ) )
THEN
374 DO j=1,
SIZE( solver % Variable % PrevValues,2 )
375 prevxx(i,1:n,j) = solver % Variable % PrevValues(:,j)
381 stime(1) = s + cumtime + ddt
383 CALL solveequations( currentmodel, ddt, transient, &
384 coupledminiter, coupledmaxiter, steadystatereached, realtimestep )
387 maxerr = listgetconstreal( currentmodel % Simulation, &
388 'Adaptive Error Measure', gotit )
390 DO i=1,currentmodel % NumberOFSolvers
391 solver => currentmodel % Solvers(i)
392 IF (
ASSOCIATED( solver % Variable % Values ) )
THEN
393 n =
SIZE(solver % Variable % Values)
394 yynrm(i) = solver % Variable % Norm
395 solver % Variable % Values = xx(i,1:n)
396 IF (
ASSOCIATED( solver % Variable % PrevValues ) )
THEN
397 DO j=1,
SIZE( solver % Variable % PrevValues,2 )
398 solver % Variable % PrevValues(:,j) = prevxx(i,1:n,j)
405 stime(1) = s + cumtime + ddt/2
406 CALL solveequations( currentmodel, ddt/2, transient, &
407 coupledminiter, coupledmaxiter, steadystatereached, realtimestep )
408 stime(1) = s + cumtime + ddt
409 CALL solveequations( currentmodel, ddt/2, transient, &
410 coupledminiter, coupledmaxiter, steadystatereached, realtimestep )
412 maxerr = abs( maxerr - listgetconstreal( currentmodel % Simulation, &
413 'Adaptive Error Measure', gotit ) )
415 IF ( .NOT. gotit )
THEN
417 DO i=1,currentmodel % NumberOFSolvers
418 solver => currentmodel % Solvers(i)
419 IF (
ASSOCIATED( solver % Variable % Values ) )
THEN
420 IF ( yynrm(i) /= solver % Variable % Norm )
THEN
421 maxerr = max(maxerr,abs(yynrm(i)-solver % Variable % Norm)/yynrm(i))
427 IF ( maxerr < adaptivelimit .OR. ddt <= adaptivemintimestep )
THEN
428 cumtime = cumtime + ddt
429 realtimestep = realtimestep+1
430 IF ( smallestcount >= adaptivekeepsmallest .OR. stepcontrol > 0 )
THEN
431 ddt = min( 2*ddt, adaptivemaxtimestep )
436 smallestcount = smallestcount + 1
439 DO i=1,currentmodel % NumberOFSolvers
440 solver => currentmodel % Solvers(i)
441 IF (
ASSOCIATED( solver % Variable % Values ) )
THEN
442 n =
SIZE(solver % Variable % Values)
443 solver % Variable % Norm = xxnrm(i)
444 solver % Variable % Values = xx(i,1:n)
445 IF (
ASSOCIATED( solver % Variable % PrevValues ) )
THEN
446 DO j=1,
SIZE( solver % Variable % PrevValues,2 )
447 solver % Variable % PrevValues(:,j) = prevxx(i,1:n,j)
455 WRITE(*,
'(a,3e20.12)')
'Adaptive(cum,ddt,err): ', cumtime, ddt, maxerr
460 DEALLOCATE( xx, xxnrm, yynrm, prevxx )
463 WRITE(*,*)
'MyTimeModule:TimeStepper: Calling SolveEquations'
464 WRITE(*,*)
' Transient = ', transient
466 CALL solveequations( currentmodel, dt, transient, &
467 coupledminiter, coupledmaxiter, steadystatereached, realtimestep )
468 realtimestep = realtimestep+1
475 IF( outputintervals(interval) /= 0 )
THEN
478 k = mod( timestep-1, outputintervals(interval) )
479 IF ( k == 0 .OR. steadystatereached )
THEN
481 DO i=1,currentmodel % NumberOfSolvers
482 solver => currentmodel % Solvers(i)
483 IF ( solver % PROCEDURE == 0 ) cycle
484 execthis = ( solver % SolverExecWhen == solver_exec_ahead_save)
485 when = listgetstring( solver % Values,
'Exec Solver', gotit )
486 IF ( gotit ) execthis = ( when ==
'before saving')
487 IF( execthis ) CALL solveractivate( currentmodel,solver,dt,transient )
493 DO i=1,currentmodel % NumberOfSolvers
494 solver => currentmodel % Solvers(i)
495 IF ( solver % PROCEDURE == 0 ) cycle
496 execthis = ( solver % SolverExecWhen == solver_exec_after_save)
497 when = listgetstring( solver % Values,
'Exec Solver', gotit )
498 IF ( gotit ) execthis = ( when ==
'after saving')
499 IF( execthis ) CALL solveractivate( currentmodel,solver,dt,transient )
505 maxtime = listgetcreal( currentmodel % Simulation,
'Real Time Max',gotit)
506 IF( gotit .AND. realtime() - rt0 > maxtime )
THEN
507 CALL info(
'ElmerSolver',
'Reached allowed maximum real time, exiting...')
511 exitcond = listgetcreal( currentmodel % Simulation,
'Exit Condition',gotit)
512 IF( gotit .AND. exitcond > 0.0_dp )
THEN
513 CALL info(
'ElmerSolver',
'Found a positive exit condition, exiting...')
519 IF ( steadystatereached .AND. .NOT. (transient .OR. scanning) )
THEN
520 IF ( timestep >= coupledminiter )
THEN
521 WRITE(6,*)
'SteadyStateReached, exiting'
533 IF (myverbosity > 3)
THEN
534 write(6,*)
'LastSaved = ', lastsaved
ElmerLib Elmer library routines
subroutine savecurrent(CurrentStep)
Saves current timestep to external files.
subroutine savetopost(CurrentStep)
Saves results file to post processing file of ElmerPost format, if requested.
subroutine timestepper(global, runs)
subroutine updateloads(global, runs)
ElmerLib Elmer library routines