C $Header: /u/gcmpack/MITgcm/pkg/cal/cal_stepsforday.F,v 1.3 2010/03/16 00:11:46 jmc Exp $ C $Name: $ #include "CAL_OPTIONS.h" subroutine CAL_STEPSFORDAY( I iday, O firststep, O laststep, O nsteps, I mythid & ) c ================================================================== c SUBROUTINE cal_StepsForDay c ================================================================== c c o Given the current day of the integration this routine returns c first, the last and the number of model steps the will have to c be performed. c c This routine also checks consistency of variables quite c extensively. c c started: Christian Eckert eckert@mit.edu 06-Apr-2000 c c changed: c c ================================================================== c SUBROUTINE cal_StepsForDay c ================================================================== implicit none c == global variables == #include "cal.h" c == routine arguments == integer iday integer firststep integer laststep integer nsteps integer mythid c == local variables == integer ierr integer mdstep integer numdays integer numsteps integer frac1 integer frac2 integer frac3 integer frac4 integer fullsteps integer firstyear integer firstmonth integer firstday integer lyfirst integer startsecs integer lastday integer endsecs c == external == external integer cal_IntDays external integer cal_IsLeap c == end of interface == numdays = cal_IntDays( mythid ) lyfirst = cal_IsLeap( firstyear, mythid ) mdstep = int(modelstep) firstyear = modelstartdate(1)/10000 firstmonth = mod(modelstartdate(1)/100,100) firstday = mod(modelstartdate(1),100) lastday = mod(modelenddate(1),100) startsecs = (modelstartdate(2)/10000)*secondsperhour + & mod(modelstartdate(2)/100,100)*secondsperminute + & mod(modelstartdate(2),100) endsecs = (modelenddate(2)/10000)*secondsperhour + & mod(modelenddate(2)/100,100)*secondsperminute + & mod(modelenddate(2),100) if ( numdays .eq. 1 ) then if ( iday .eq. firstday ) then c-- Get the number of steps in the first day. if ( firstday .eq. lastday ) then firststep = 1 laststep = modelintsteps else if ( mod(firstday+1,ndaymonth(firstmonth,lyfirst)) .eq. & lastday ) then c-- This can only happen if we end at midnight of the next day. if ( modelenddate(2) .eq. 0 ) then firststep = 1 laststep = modelintsteps c-- Note: This holds only if modelenddate was determined c-- such that it coincides with the model final time. else c-- We do not end at midnight of the first day of c-- the next month. ierr = 2604 call CAL_PRINTERROR( ierr, mythid ) stop ' stopped in cal_StepsForDay.' endif else c-- The first and the last day are inconsistent with iday. ierr = 2603 call CAL_PRINTERROR( ierr, mythid ) stop ' stopped in cal_StepsForDay.' endif else c-- The variables numdays and iday are inconsistent; c-- ( iday .gt. numdays ). ierr = 2602 call CAL_PRINTERROR( ierr, mythid ) stop ' stopped in cal_StepsForDay.' endif else if ( numdays .gt. 1 ) then c-- More than one day of integration. if ( iday .eq. 1 ) then firststep = 1 laststep = int((secondsperday - startsecs)/mdstep) else if ( ( iday .gt. 1 ) .and. & ( iday .lt. numdays) ) then c-- Somewhere between first and last month. c-- The first steps in iday. fullsteps = int((secondsperday - startsecs)/mdstep) numsteps = fullsteps c-- What is left in the first day (frac1). frac1 = (secondsperday - startsecs) - fullsteps*mdstep fullsteps = int(secondsperday/modelstep) c-- What is left in a complete day (frac2). frac2 = secondsperday - fullsteps*mdstep c-- What is left up to the current day (frac3). frac3 = frac1 + frac2*(iday - 1) numsteps = numsteps + (iday - 1)*fullsteps + & frac3/mdstep laststep = numsteps firststep = laststep - secondsperday/mdstep + 1 else if ( iday .eq. numdays ) then c-- The last day of integration. c-- The first step in iday. fullsteps = int((secondsperday - startsecs)/mdstep) numsteps = fullsteps c-- What is left in the first day (frac1). frac1 = (secondsperday - startsecs) - fullsteps*mdstep fullsteps = int(secondsperday/modelstep) c-- What is left in a complete day (frac2). frac2 = secondsperday - fullsteps*mdstep c-- What is left up to the day before the last (frac3). frac3 = frac1 + frac2*(iday - 2) numsteps = numsteps + (iday - 2)*fullsteps c-- The last step in iday. if ( modelenddate(2) .eq. 0 ) then c-- This can only happen if we end at midnight of the next day. laststep = numsteps + fullsteps firststep = numsteps + 1 c-- Note: There should be no fraction left c-- ( mod(frac3,mdstep) = frac3/mdstep ) if modelenddate c-- is based on an integral number of timesteps. else frac4 = frac3 + endsecs numsteps = numsteps + frac4/mdstep laststep = numsteps c-- Note: There should be no fraction left c-- ( mod(frac4,mdstep = frac4/mdstep ) if modelenddate c-- is based on an integral number of timesteps. firststep = laststep - endsecs/mdstep + 1 endif else c-- The variables iday and numdays are inconsistent. ierr = 2605 call CAL_PRINTERROR( ierr, mythid ) stop ' stopped in cal_DaysForMonth.' endif else c-- The number of days to integrate is wrong; check cal_IntDays. ierr = 2601 call CAL_PRINTERROR( ierr, mythid ) stop ' stopped in cal_StepsForDay.' endif c-- The number of days to integrate in the given month. nsteps = laststep - firststep + 1 return end