<p><b>croesch@ucar.edu</b> 2011-08-22 16:28:31 -0600 (Mon, 22 Aug 2011)</p><p>BRANCH COMMIT<br>
<br>
Integrate mpas_time_timekeeping module with framework and dynamical cores<br>
<br>
M namelist.input.hyd_atmos<br>
M namelist.input.sw<br>
M src/core_hyd_atmos/module_mpas_core.F<br>
M src/core_hyd_atmos/Registry<br>
M src/core_hyd_atmos/module_time_integration.F<br>
M src/core_hyd_atmos/Makefile<br>
M src/core_sw/module_mpas_core.F<br>
M src/core_sw/Registry<br>
M src/core_sw/module_time_integration.F<br>
M src/core_sw/Makefile<br>
M src/driver/Makefile<br>
M src/driver/module_mpas_subdriver.F<br>
M src/core_ocean/module_global_diagnostics.F<br>
M src/core_ocean/module_mpas_core.F<br>
M src/core_ocean/Registry<br>
M src/core_ocean/module_time_integration.F<br>
M src/core_ocean/Makefile<br>
M src/framework/module_io_input.F<br>
M src/framework/module_io_output.F<br>
M src/framework/module_mpas_framework.F<br>
M src/framework/module_mpas_timekeeping.F<br>
M src/framework/Makefile<br>
M src/Makefile<br>
M namelist.input.ocean<br>
</p><hr noshade><pre><font color="gray">Modified: branches/time_manager/namelist.input.hyd_atmos
===================================================================
--- branches/time_manager/namelist.input.hyd_atmos        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/namelist.input.hyd_atmos        2011-08-22 22:28:31 UTC (rev 952)
@@ -2,8 +2,8 @@
config_test_case = 2
config_time_integration = 'SRK3'
config_dt = 3600
- config_ntimesteps = 240
- config_output_interval = 24
+ config_start_time = '0000-01-01_00:00:00'
+ config_run_duration = '10_00:00:00'
config_number_of_sub_steps = 4
config_h_mom_eddy_visc2 = 0.0
config_h_mom_eddy_visc4 = 0.0
@@ -24,10 +24,11 @@
config_input_name = 'grid.nc'
config_output_name = 'output.nc'
config_restart_name = 'restart.nc'
+ config_output_interval = '1_00:00:00'
+ config_frames_per_outfile = 0
/
&restart
- config_restart_interval = 3000
+ config_restart_interval = '1000_00:00:00'
config_do_restart = .false.
- config_restart_time = 1036800.0
/
Modified: branches/time_manager/namelist.input.ocean
===================================================================
--- branches/time_manager/namelist.input.ocean        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/namelist.input.ocean        2011-08-22 22:28:31 UTC (rev 952)
@@ -2,21 +2,22 @@
config_test_case = 0
config_time_integration = 'RK4'
config_dt = 90.0
- config_ntimesteps = 1920000
- config_output_interval = 19200
+ config_start_time = '0000-01-01_00:00:00'
+ config_run_duration = '2000_00:00:00'
config_stats_interval = 1920
/
&io
- config_input_name = grid.nc
- config_output_name = output.nc
- config_restart_name = restart.nc
+ config_input_name = 'grid.nc'
+ config_output_name = 'output.nc'
+ config_restart_name = 'restart.nc'
+ config_output_interval = '20_00:00:00'
+ config_frames_per_outfile = 0
/
&restart
- config_restart_interval = 115200
+ config_restart_interval = '120_00:00:00'
config_do_restart = .false.
- config_restart_time = 31104000
/
&grid
Modified: branches/time_manager/namelist.input.sw
===================================================================
--- branches/time_manager/namelist.input.sw        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/namelist.input.sw        2011-08-22 22:28:31 UTC (rev 952)
@@ -2,8 +2,8 @@
config_test_case = 5
config_time_integration = 'RK4'
config_dt = 172.8
- config_ntimesteps = 7500
- config_output_interval = 500
+ config_start_time = '0000-01-01_00:00:00'
+ config_run_duration = '15_00:00:00'
config_stats_interval = 0
config_h_ScaleWithMesh = .false.
config_h_mom_eddy_visc2 = 0.0
@@ -17,15 +17,17 @@
config_wind_stress = .false.
config_bottom_drag = .false.
/
+ config_stop_time = '0000-01-16_00:00:00'
&io
config_input_name = 'grid.nc'
config_output_name = 'output.nc'
config_restart_name = 'restart.nc'
+ config_output_interval = '1_00:00:00'
+ config_frames_per_outfile = 0
/
&restart
- config_restart_interval = 3000
+ config_restart_interval = '15_00:00:00'
config_do_restart = .false.
- config_restart_time = 1036800.0
/
Modified: branches/time_manager/src/Makefile
===================================================================
--- branches/time_manager/src/Makefile        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/Makefile        2011-08-22 22:28:31 UTC (rev 952)
@@ -3,7 +3,7 @@
all: mpas
mpas: reg_includes externals frame ops dycore drver
-        $(FC) $(LDFLAGS) -o $(CORE)_model.exe driver/*.o -L. -ldycore -lops -lframework $(LIBS) -I../external/esmf_time_f90 -Lexternal/esmf_time_f90 -lesmf_time
+        $(FC) $(LDFLAGS) -o $(CORE)_model.exe driver/*.o -L. -ldycore -lops -lframework $(LIBS) -I./external/esmf_time_f90 -L./external/esmf_time_f90 -lesmf_time
reg_includes:
        ( cd registry; make CC="$(SCC)" )
Modified: branches/time_manager/src/core_hyd_atmos/Makefile
===================================================================
--- branches/time_manager/src/core_hyd_atmos/Makefile        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/core_hyd_atmos/Makefile        2011-08-22 22:28:31 UTC (rev 952)
@@ -24,4 +24,4 @@
.F.o:
        $(RM) $@ $*.mod
        $(CPP) $(CPPFLAGS) $(CPPINCLUDES) $< > $*.f90
-        $(FC) $(FFLAGS) -c $*.f90 $(FCINCLUDES) -I../framework -I../operators
+        $(FC) $(FFLAGS) -c $*.f90 $(FCINCLUDES) -I../framework -I../operators -I../external/esmf_time_f90
Modified: branches/time_manager/src/core_hyd_atmos/Registry
===================================================================
--- branches/time_manager/src/core_hyd_atmos/Registry        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/core_hyd_atmos/Registry        2011-08-22 22:28:31 UTC (rev 952)
@@ -4,8 +4,10 @@
namelist integer sw_model config_test_case 5
namelist character sw_model config_time_integration SRK3
namelist real sw_model config_dt 172.8
-namelist integer sw_model config_ntimesteps 7500
-namelist integer sw_model config_output_interval 500
+namelist integer sw_model config_calendar_type MPAS_360DAY
+namelist character sw_model config_start_time 0000-01-01_00:00:00
+namelist character sw_model config_stop_time none
+namelist character sw_model config_run_duration none
namelist real sw_model config_h_mom_eddy_visc2 0.0
namelist real sw_model config_h_mom_eddy_visc4 0.0
namelist real sw_model config_v_mom_eddy_visc2 0.0
@@ -23,10 +25,11 @@
namelist character io config_input_name grid.nc
namelist character io config_output_name output.nc
namelist character io config_restart_name restart.nc
+namelist character io config_output_interval 06:00:00
+namelist integer io config_frames_per_outfile 0
namelist character io config_decomp_file_prefix graph.info.part.
-namelist integer restart config_restart_interval 0
namelist logical restart config_do_restart false
-namelist real restart config_restart_time 172800.0
+namelist character restart config_restart_interval none
#
# dim type name_in_file name_in_code
@@ -49,7 +52,7 @@
#
# var persistence type name_in_file ( dims ) time_levs iro- name_in_code struct super-array array_class
#
-var persistent real xtime ( Time ) 2 ro xtime state - -
+var persistent text xtime ( Time ) 2 ro xtime state - -
var persistent real latCell ( nCells ) 0 iro latCell mesh - -
var persistent real lonCell ( nCells ) 0 iro lonCell mesh - -
Modified: branches/time_manager/src/core_hyd_atmos/module_mpas_core.F
===================================================================
--- branches/time_manager/src/core_hyd_atmos/module_mpas_core.F        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/core_hyd_atmos/module_mpas_core.F        2011-08-22 22:28:31 UTC (rev 952)
@@ -1,15 +1,22 @@
module mpas_core
use mpas_framework
+ use mpas_timekeeping
type (io_output_object) :: restart_obj
integer :: restart_frame
-
+ integer :: current_outfile_frames
+
+ type (MPAS_Clock_type) :: clock
+
+ integer, parameter :: outputAlarmID = 1
+ integer, parameter :: restartAlarmID = 2
+
contains
- subroutine mpas_core_init(domain)
+ subroutine mpas_core_init(domain, startTimeStamp)
use configure
use grid_types
@@ -18,6 +25,7 @@
implicit none
type (domain_type), intent(inout) :: domain
+ character(len=*), intent(out) :: startTimeStamp
real (kind=RKIND) :: dt
type (block_type), pointer :: block
@@ -29,17 +37,72 @@
! Initialize core
!
dt = config_dt
+
+ call simulation_clock_init(domain, dt, startTimeStamp)
+
block => domain % blocklist
do while (associated(block))
call mpas_init_block(block, block % mesh, dt)
+ block % state % time_levs(1) % state % xtime % scalar = startTimeStamp
block => block % next
end do
restart_frame = 1
+ current_outfile_frames = 0
end subroutine mpas_core_init
-
+
+ subroutine simulation_clock_init(domain, dt, startTimeStamp)
+
+ implicit none
+
+ type (domain_type), intent(inout) :: domain
+ real (kind=RKIND), intent(in) :: dt
+ character(len=*), intent(out) :: startTimeStamp
+
+ type (MPAS_Time_Type) :: startTime, stopTime, alarmStartTime
+ type (MPAS_TimeInterval_type) :: runDuration, timeStep, alarmTimeStep
+ integer :: ierr
+
+ call MPAS_setTime(curr_time=startTime, dateTimeString=config_start_time, ierr=ierr)
+ call MPAS_setTimeInterval(timeStep, dt=dt, ierr=ierr)
+
+ if (trim(config_run_duration) /= "none") then
+ call MPAS_setTimeInterval(runDuration, timeString=config_run_duration, ierr=ierr)
+ call MPAS_createClock(clock, startTime=startTime, timeStep=timeStep, runDuration=runDuration, ierr=ierr)
+
+ if (trim(config_stop_time) /= "none") then
+ call MPAS_setTime(curr_time=stopTime, dateTimeString=config_stop_time, ierr=ierr)
+ if(startTime + runduration /= stopTime) then
+ write(0,*) 'Warning: config_run_duration and config_stop_time are inconsitent: using config_run_duration.'
+ end if
+ end if
+ else if (trim(config_stop_time) /= "none") then
+ call MPAS_setTime(curr_time=stopTime, dateTimeString=config_stop_time, ierr=ierr)
+ call MPAS_createClock(clock, startTime=startTime, timeStep=timeStep, stopTime=stopTime, ierr=ierr)
+ else
+ write(0,*) 'Error: Neither config_run_duration nor config_stop_time were specified.'
+ call dmpar_abort(domain % dminfo)
+ end if
+
+ ! set output alarm
+ call MPAS_setTimeInterval(alarmTimeStep, timeString=config_output_interval, ierr=ierr)
+ alarmStartTime = startTime + alarmTimeStep
+ call MPAS_addClockAlarm(clock, outputAlarmID, alarmStartTime, alarmTimeStep, ierr=ierr)
+
+ ! set restart alarm, if necessary
+ if (trim(config_restart_interval) /= "none") then
+ call MPAS_setTimeInterval(alarmTimeStep, timeString=config_restart_interval, ierr=ierr)
+ alarmStartTime = startTime + alarmTimeStep
+ call MPAS_addClockAlarm(clock, restartAlarmID, alarmStartTime, alarmTimeStep, ierr=ierr)
+ end if
+
+ call MPAS_getTime(curr_time=startTime, dateTimeString=startTimeStamp, ierr=ierr)
+
+ end subroutine simulation_clock_init
+
+
subroutine mpas_init_block(block, mesh, dt)
use grid_types
@@ -62,9 +125,7 @@
call rbfInterp_initialize(mesh)
call init_reconstruct(mesh)
call reconstruct(block % state % time_levs(1) % state, mesh)
-
- if (.not. config_do_restart) block % state % time_levs(1) % state % xtime % scalar = 0.0
-
+
end subroutine mpas_init_block
@@ -83,34 +144,52 @@
integer :: ntimesteps, itimestep
real (kind=RKIND) :: dt
type (block_type), pointer :: block_ptr
+
+ type (MPAS_Time_Type) :: currTime
+ character(len=32) :: timeStamp
+ integer :: ierr
! Eventually, dt should be domain specific
dt = config_dt
- ntimesteps = config_ntimesteps
-
+
+ currTime = MPAS_getClockTime(clock, MPAS_NOW, ierr)
+ call MPAS_getTime(curr_time=currTime, dateTimeString=timeStamp, ierr=ierr)
+ write(0,*) 'Initial time ', timeStamp
+
call write_output_frame(output_obj, output_frame, domain)
! During integration, time level 1 stores the model state at the beginning of the
! time step, and time level 2 stores the state advanced dt in time by timestep(...)
- do itimestep = 1,ntimesteps
- write(0,*) 'Doing timestep ', itimestep
+ do while (.not. MPAS_isClockStopTime(clock))
+
+ call MPAS_advanceClock(clock)
+
+ currTime = MPAS_getClockTime(clock, MPAS_NOW, ierr)
+ call MPAS_getTime(curr_time=currTime, dateTimeString=timeStamp, ierr=ierr)
+ write(0,*) 'Doing timestep ', timeStamp
+
call timer_start("time integration")
- call mpas_timestep(domain, itimestep, dt)
+ call mpas_timestep(domain, dt, timeStamp)
call timer_stop("time integration")
! Move time level 2 fields back into time level 1 for next time step
call shift_time_levels_state(domain % blocklist % state)
- if (mod(itimestep, config_output_interval) == 0) then
+ if (MPAS_isAlarmRinging(clock, outputAlarmID, ierr=ierr)) then
+ call MPAS_resetClockAlarm(clock, outputAlarmID, ierr=ierr)
+ if(output_frame == 1) call output_state_init(output_obj, domain, "OUTPUT", trim(timeStamp)) ! output_frame will always be > 1 here unless it is reset after the output file is finalized
call write_output_frame(output_obj, output_frame, domain)
end if
- if (mod(itimestep, config_restart_interval) == 0 .and. config_restart_interval > 0) then
+
+ if (MPAS_isAlarmRinging(clock, restartAlarmID, ierr=ierr)) then
+ call MPAS_resetClockAlarm(clock, restartAlarmID, ierr=ierr)
if (restart_frame == 1) call output_state_init(restart_obj, domain, "RESTART")
call output_state_for_domain(restart_obj, domain, restart_frame)
restart_frame = restart_frame + 1
end if
+
end do
-
+
end subroutine mpas_core_run
@@ -143,7 +222,17 @@
call output_state_for_domain(output_obj, domain, output_frame)
output_frame = output_frame + 1
-
+
+ ! if the maximum number of frames per outfile has been reached, finalize outfile and reset frame
+ if (config_frames_per_outfile > 0) then
+ current_outfile_frames = current_outfile_frames + 1
+ if(current_outfile_frames >= config_frames_per_outfile) then
+ current_outfile_frames = 0
+ call output_state_finalize(output_obj, domain % dminfo)
+ output_frame = 1
+ end if
+ end if
+
end subroutine write_output_frame
@@ -170,7 +259,7 @@
end subroutine compute_output_diagnostics
- subroutine mpas_timestep(domain, itimestep, dt)
+ subroutine mpas_timestep(domain, dt, timeStamp)
use grid_types
use time_integration
@@ -178,10 +267,10 @@
implicit none
type (domain_type), intent(inout) :: domain
- integer, intent(in) :: itimestep
real (kind=RKIND), intent(in) :: dt
+ character(len=*), intent(in) :: timeStamp
- call timestep(domain, dt)
+ call timestep(domain, dt, timeStamp)
end subroutine mpas_timestep
@@ -191,11 +280,15 @@
use grid_types
implicit none
-
+
+ integer :: ierr
+
type (domain_type), intent(inout) :: domain
if (restart_frame > 1) call output_state_finalize(restart_obj, domain % dminfo)
-
+
+ call MPAS_destroyClock(clock, ierr)
+
end subroutine mpas_core_finalize
end module mpas_core
Modified: branches/time_manager/src/core_hyd_atmos/module_time_integration.F
===================================================================
--- branches/time_manager/src/core_hyd_atmos/module_time_integration.F        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/core_hyd_atmos/module_time_integration.F        2011-08-22 22:28:31 UTC (rev 952)
@@ -10,7 +10,7 @@
contains
- subroutine timestep(domain, dt)
+ subroutine timestep(domain, dt, timeStamp)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Advance model state forward in time by the specified time step
!
@@ -24,6 +24,7 @@
type (domain_type), intent(inout) :: domain
real (kind=RKIND), intent(in) :: dt
+ character(len=*), intent(in) :: timeStamp
type (block_type), pointer :: block
@@ -37,7 +38,7 @@
block => domain % blocklist
do while (associated(block))
- block % state % time_levs(2) % state % xtime % scalar = block % state % time_levs(1) % state % xtime % scalar + dt
+ block % state % time_levs(2) % state % xtime % scalar = timeStamp
block => block % next
end do
Modified: branches/time_manager/src/core_ocean/Makefile
===================================================================
--- branches/time_manager/src/core_ocean/Makefile        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/core_ocean/Makefile        2011-08-22 22:28:31 UTC (rev 952)
@@ -27,4 +27,4 @@
.F.o:
        $(RM) $@ $*.mod
        $(CPP) $(CPPFLAGS) $(CPPINCLUDES) $< > $*.f90
-        $(FC) $(FFLAGS) -c $*.f90 $(FCINCLUDES) -I../framework -I../operators
+        $(FC) $(FFLAGS) -c $*.f90 $(FCINCLUDES) -I../framework -I../operators -I../external/esmf_time_f90
Modified: branches/time_manager/src/core_ocean/Registry
===================================================================
--- branches/time_manager/src/core_ocean/Registry        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/core_ocean/Registry        2011-08-22 22:28:31 UTC (rev 952)
@@ -1,43 +1,46 @@
#
# namelist type namelist_record name default_value
#
-namelist integer sw_model config_test_case 5
-namelist character sw_model config_time_integration RK4
-namelist real sw_model config_dt 172.8
-namelist integer sw_model config_ntimesteps 7500
-namelist integer sw_model config_output_interval 500
-namelist integer sw_model config_stats_interval 100
+namelist integer sw_model config_test_case 5
+namelist character sw_model config_time_integration RK4
+namelist real sw_model config_dt 172.8
+namelist integer sw_model config_calendar_type MPAS_360DAY
+namelist character sw_model config_start_time 0000-01-01_00:00:00
+namelist character sw_model config_stop_time none
+namelist character sw_model config_run_duration none
+namelist integer sw_model config_stats_interval 100
namelist character io config_input_name grid.nc
namelist character io config_output_name output.nc
namelist character io config_restart_name restart.nc
+namelist character io config_output_interval 24:00:00
+namelist integer io config_frames_per_outfile 0
namelist character io config_decomp_file_prefix graph.info.part.
-namelist integer restart config_restart_interval 0
-namelist logical restart config_do_restart false
-namelist real restart config_restart_time 172800.0
-namelist character grid config_vert_grid_type isopycnal
-namelist real grid config_rho0 1028
+namelist logical restart config_do_restart false
+namelist character restart config_restart_interval none
+namelist character grid config_vert_grid_type isopycnal
+namelist real grid config_rho0 1028
namelist real hmix config_h_mom_eddy_visc2 0.0
namelist real hmix config_h_mom_eddy_visc4 0.0
namelist real hmix config_h_tracer_eddy_diff2 0.0
namelist real hmix config_h_tracer_eddy_diff4 0.0
namelist real hmix config_apvm_upwinding 0.5
-namelist character vmix config_vert_visc_type const
-namelist character vmix config_vert_diff_type const
-namelist real vmix config_vert_viscosity 2.5e-4
-namelist real vmix config_vert_diffusion 2.5e-5
-namelist real vmix config_vmixTanhViscMax 2.5e-1
-namelist real vmix config_vmixTanhViscMin 1.0e-4
-namelist real vmix config_vmixTanhDiffMax 2.5e-2
-namelist real vmix config_vmixTanhDiffMin 1.0e-5
-namelist real vmix config_vmixTanhZMid -100
-namelist real vmix config_vmixTanhZWidth 100
-namelist character eos config_eos_type linear
-namelist character advection config_vert_tracer_adv stencil
+namelist character vmix config_vert_visc_type const
+namelist character vmix config_vert_diff_type const
+namelist real vmix config_vert_viscosity 2.5e-4
+namelist real vmix config_vert_diffusion 2.5e-5
+namelist real vmix config_vmixTanhViscMax 2.5e-1
+namelist real vmix config_vmixTanhViscMin 1.0e-4
+namelist real vmix config_vmixTanhDiffMax 2.5e-2
+namelist real vmix config_vmixTanhDiffMin 1.0e-5
+namelist real vmix config_vmixTanhZMid -100
+namelist real vmix config_vmixTanhZWidth 100
+namelist character eos config_eos_type linear
+namelist character advection config_vert_tracer_adv stencil
namelist integer advection config_vert_tracer_adv_order 4
-namelist integer advection config_tracer_adv_order 2
-namelist integer advection config_thickness_adv_order 2
-namelist logical advection config_positive_definite false
-namelist logical advection config_monotonic false
+namelist integer advection config_tracer_adv_order 2
+namelist integer advection config_thickness_adv_order 2
+namelist logical advection config_positive_definite false
+namelist logical advection config_monotonic false
#
# dim type name_in_file name_in_code
@@ -58,7 +61,7 @@
#
# var persistence type name_in_file ( dims ) time_levs iro- name_in_code struct super-array array_class
#
-var persistent real xtime ( Time ) 2 ro xtime state - -
+var persistent text xtime ( Time ) 2 ro xtime state - -
var persistent real latCell ( nCells ) 0 iro latCell mesh - -
var persistent real lonCell ( nCells ) 0 iro lonCell mesh - -
Modified: branches/time_manager/src/core_ocean/module_global_diagnostics.F
===================================================================
--- branches/time_manager/src/core_ocean/module_global_diagnostics.F        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/core_ocean/module_global_diagnostics.F        2011-08-22 22:28:31 UTC (rev 952)
@@ -322,7 +322,7 @@
write (fileID,'(100es24.16)') averages(1:nVariables)
close (fileID)
open(fileID,file='stats_time.txt',ACCESS='append')
- write (fileID,'(i5,100es24.16)') timeIndex, &
+ write (fileID,'(i5,10x,a,100es24.16)') timeIndex, &
state % xtime % scalar, dt, &
CFLNumberGlobal
close (fileID)
Modified: branches/time_manager/src/core_ocean/module_mpas_core.F
===================================================================
--- branches/time_manager/src/core_ocean/module_mpas_core.F        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/core_ocean/module_mpas_core.F        2011-08-22 22:28:31 UTC (rev 952)
@@ -1,24 +1,32 @@
module mpas_core
use mpas_framework
+ use mpas_timekeeping
use dmpar
- use test_cases
+ use test_cases
type (io_output_object) :: restart_obj
integer :: restart_frame
+ integer :: current_outfile_frames
+ type (MPAS_Clock_type) :: clock
+
+ integer, parameter :: outputAlarmID = 1
+ integer, parameter :: restartAlarmID = 2
+ integer, parameter :: statsAlarmID = 3
+
contains
+ subroutine mpas_core_init(domain, startTimeStamp)
- subroutine mpas_core_init(domain)
-
use configure
use grid_types
implicit none
type (domain_type), intent(inout) :: domain
+ character(len=*), intent(out) :: startTimeStamp
real (kind=RKIND) :: dt
type (block_type), pointer :: block
@@ -43,9 +51,13 @@
! Initialize core
!
dt = config_dt
+
+ call simulation_clock_init(domain, dt, startTimeStamp)
+
block => domain % blocklist
do while (associated(block))
call mpas_init_block(block, block % mesh, dt)
+ block % state % time_levs(1) % state % xtime % scalar = startTimeStamp
block => block % next
end do
@@ -60,10 +72,70 @@
! call write_output_frame(output_obj, domain)
restart_frame = 1
+ current_outfile_frames = 0
end subroutine mpas_core_init
+ subroutine simulation_clock_init(domain, dt, startTimeStamp)
+
+ implicit none
+
+ type (domain_type), intent(inout) :: domain
+ real (kind=RKIND), intent(in) :: dt
+ character(len=*), intent(out) :: startTimeStamp
+
+ type (MPAS_Time_Type) :: startTime, stopTime, alarmStartTime
+ type (MPAS_TimeInterval_type) :: runDuration, timeStep, alarmTimeStep
+ integer :: ierr
+
+ call MPAS_setTime(curr_time=startTime, dateTimeString=config_start_time, ierr=ierr)
+ call MPAS_setTimeInterval(timeStep, dt=dt, ierr=ierr)
+
+ if (trim(config_run_duration) /= "none") then
+ call MPAS_setTimeInterval(runDuration, timeString=config_run_duration, ierr=ierr)
+ call MPAS_createClock(clock, startTime=startTime, timeStep=timeStep, runDuration=runDuration, ierr=ierr)
+
+ if (trim(config_stop_time) /= "none") then
+ call MPAS_setTime(curr_time=stopTime, dateTimeString=config_stop_time, ierr=ierr)
+ if(startTime + runduration /= stopTime) then
+ write(0,*) 'Warning: config_run_duration and config_stop_time are inconsitent: using config_run_duration.'
+ end if
+ end if
+ else if (trim(config_stop_time) /= "none") then
+ call MPAS_setTime(curr_time=stopTime, dateTimeString=config_stop_time, ierr=ierr)
+ call MPAS_createClock(clock, startTime=startTime, timeStep=timeStep, stopTime=stopTime, ierr=ierr)
+ else
+ write(0,*) 'Error: Neither config_run_duration nor config_stop_time were specified.'
+ call dmpar_finalize(domain % dminfo)
+ end if
+
+ ! set output alarm
+ call MPAS_setTimeInterval(alarmTimeStep, timeString=config_output_interval, ierr=ierr)
+ alarmStartTime = startTime + alarmTimeStep
+ call MPAS_addClockAlarm(clock, outputAlarmID, alarmStartTime, alarmTimeStep, ierr=ierr)
+
+ ! set restart alarm, if necessary
+ if (trim(config_restart_interval) /= "none") then
+ call MPAS_setTimeInterval(alarmTimeStep, timeString=config_restart_interval, ierr=ierr)
+ alarmStartTime = startTime + alarmTimeStep
+ call MPAS_addClockAlarm(clock, restartAlarmID, alarmStartTime, alarmTimeStep, ierr=ierr)
+ end if
+
+ !TODO: use this code if we desire to convert config_stats_interval to alarms
+ !(must also change config_stats_interval type to character)
+ ! set stats alarm, if necessary
+ !if (trim(config_stats_interval) /= "none") then
+ ! call MPAS_setTimeInterval(alarmTimeStep, timeString=config_stats_interval, ierr=ierr)
+ ! alarmStartTime = startTime + alarmTimeStep
+ ! call MPAS_addClockAlarm(clock, statsAlarmID, alarmStartTime, alarmTimeStep, ierr=ierr)
+ !end if
+
+ call MPAS_getTime(curr_time=startTime, dateTimeString=startTimeStamp, ierr=ierr)
+
+ end subroutine simulation_clock_init
+
+
subroutine mpas_init_block(block, mesh, dt)
use grid_types
@@ -107,9 +179,7 @@
:block % mesh % nVertLevels,iCell) = -1e34
end do
- if (.not. config_do_restart) then
- block % state % time_levs(1) % state % xtime % scalar = 0.0
- else
+ if (config_do_restart) then
do i=2,nTimeLevs
call copy_state(block % state % time_levs(i) % state, &
block % state % time_levs(1) % state)
@@ -131,39 +201,55 @@
type (io_output_object), intent(inout) :: output_obj
integer, intent(inout) :: output_frame
- integer :: ntimesteps, itimestep
+ integer :: itimestep
real (kind=RKIND) :: dt
type (block_type), pointer :: block_ptr
+
+ type (MPAS_Time_Type) :: currTime
+ character(len=32) :: timeStamp
+ integer :: ierr
! Eventually, dt should be domain specific
dt = config_dt
- ntimesteps = config_ntimesteps
-
+
+ currTime = MPAS_getClockTime(clock, MPAS_NOW, ierr)
+ call MPAS_getTime(curr_time=currTime, dateTimeString=timeStamp, ierr=ierr)
+ write(0,*) 'Initial time ', timeStamp
+
call write_output_frame(output_obj, output_frame, domain)
! During integration, time level 1 stores the model state at the beginning of the
! time step, and time level 2 stores the state advanced dt in time by timestep(...)
- do itimestep = 1,ntimesteps
- write(0,*) 'Doing timestep ', itimestep
+ itimestep = 0
+ do while (.not. MPAS_isClockStopTime(clock))
+
+ itimestep = itimestep + 1
+ call MPAS_advanceClock(clock)
+
+ currTime = MPAS_getClockTime(clock, MPAS_NOW, ierr)
+ call MPAS_getTime(curr_time=currTime, dateTimeString=timeStamp, ierr=ierr)
+ write(0,*) 'Doing timestep ', timeStamp
+
call timer_start("time integration")
- call mpas_timestep(domain, itimestep, dt)
+ call mpas_timestep(domain, itimestep, dt, timeStamp)
call timer_stop("time integration")
! Move time level 2 fields back into time level 1 for next time step
call shift_time_levels_state(domain % blocklist % state)
-
- if (config_output_interval > 0) then
- if (mod(itimestep, config_output_interval) == 0) then
- call write_output_frame(output_obj, output_frame, domain)
- end if
- endif
- if (config_restart_interval > 0) then
- if (mod(itimestep, config_restart_interval) == 0) then
- if (restart_frame == 1) call output_state_init(restart_obj, domain, "RESTART")
- call output_state_for_domain(restart_obj, domain, restart_frame)
- restart_frame = restart_frame + 1
- end if
- endif
+
+ if (MPAS_isAlarmRinging(clock, outputAlarmID, ierr=ierr)) then
+ call MPAS_resetClockAlarm(clock, outputAlarmID, ierr=ierr)
+ if(output_frame == 1) call output_state_init(output_obj, domain, "OUTPUT", trim(timeStamp)) ! output_frame will always be > 1 here unless it is reset after the output file is finalized
+ call write_output_frame(output_obj, output_frame, domain)
+ end if
+
+ if (MPAS_isAlarmRinging(clock, restartAlarmID, ierr=ierr)) then
+ call MPAS_resetClockAlarm(clock, restartAlarmID, ierr=ierr)
+ if (restart_frame == 1) call output_state_init(restart_obj, domain, "RESTART")
+ call output_state_for_domain(restart_obj, domain, restart_frame)
+ restart_frame = restart_frame + 1
+ end if
+
end do
end subroutine mpas_core_run
@@ -198,6 +284,16 @@
call output_state_for_domain(output_obj, domain, output_frame)
output_frame = output_frame + 1
+
+ ! if the maximum number of frames per outfile has been reached, finalize outfile and reset frame
+ if (config_frames_per_outfile > 0) then
+ current_outfile_frames = current_outfile_frames + 1
+ if(current_outfile_frames >= config_frames_per_outfile) then
+ current_outfile_frames = 0
+ call output_state_finalize(output_obj, domain % dminfo)
+ output_frame = 1
+ end if
+ end if
end subroutine write_output_frame
@@ -225,7 +321,7 @@
end subroutine compute_output_diagnostics
- subroutine mpas_timestep(domain, itimestep, dt)
+ subroutine mpas_timestep(domain, itimestep, dt, timeStamp)
use grid_types
use time_integration
@@ -237,10 +333,13 @@
type (domain_type), intent(inout) :: domain
integer, intent(in) :: itimestep
real (kind=RKIND), intent(in) :: dt
+ character(len=*), intent(in) :: timeStamp
+
type (block_type), pointer :: block_ptr
+ integer :: ierr
- call timestep(domain, dt)
-
+ call timestep(domain, dt, timeStamp)
+
if (config_stats_interval > 0) then
if (mod(itimestep, config_stats_interval) == 0) then
block_ptr => domain % blocklist
@@ -248,7 +347,7 @@
write(0,*) 'Error: computeGlobalDiagnostics assumes ',&
'that there is only one block per processor.'
end if
-
+
call timer_start("global diagnostics")
call computeGlobalDiagnostics(domain % dminfo, &
block_ptr % state % time_levs(2) % state, block_ptr % mesh, &
@@ -256,7 +355,24 @@
call timer_stop("global diagnostics")
end if
end if
+
+ !TODO: replace the above code block with this if we desire to convert config_stats_interval to use alarms
+ !if (MPAS_isAlarmRinging(clock, statsAlarmID, ierr=ierr)) then
+ ! call MPAS_resetClockAlarm(clock, statsAlarmID, ierr=ierr)
+
+ ! block_ptr => domain % blocklist
+ ! if (associated(block_ptr % next)) then
+ ! write(0,*) 'Error: computeGlobalDiagnostics assumes ',&
+ ! 'that there is only one block per processor.'
+ ! end if
+ ! call timer_start("global diagnostics")
+ ! call computeGlobalDiagnostics(domain % dminfo, &
+ ! block_ptr % state % time_levs(2) % state, block_ptr % mesh, &
+ ! timeStamp, dt)
+ ! call timer_stop("global diagnostics")
+ !end if
+
end subroutine mpas_timestep
@@ -452,11 +568,15 @@
use grid_types
implicit none
-
+
+ integer :: ierr
+
type (domain_type), intent(inout) :: domain
if (restart_frame > 1) call output_state_finalize(restart_obj, domain % dminfo)
-
+
+ call MPAS_destroyClock(clock, ierr)
+
end subroutine mpas_core_finalize
end module mpas_core
Modified: branches/time_manager/src/core_ocean/module_time_integration.F
===================================================================
--- branches/time_manager/src/core_ocean/module_time_integration.F        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/core_ocean/module_time_integration.F        2011-08-22 22:28:31 UTC (rev 952)
@@ -9,7 +9,7 @@
contains
- subroutine timestep(domain, dt)
+ subroutine timestep(domain, dt, timeStamp)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Advance model state forward in time by the specified time step
!
@@ -23,6 +23,7 @@
type (domain_type), intent(inout) :: domain
real (kind=RKIND), intent(in) :: dt
+ character(len=*), intent(in) :: timeStamp
type (dm_info) :: dminfo
type (block_type), pointer :: block
@@ -38,8 +39,7 @@
block => domain % blocklist
do while (associated(block))
- block % state % time_levs(2) % state % xtime % scalar &
- = block % state % time_levs(1) % state % xtime % scalar + dt
+ block % state % time_levs(2) % state % xtime % scalar = timeStamp
if (isNaN(sum(block % state % time_levs(2) % state % u % array))) then
write(0,*) 'Abort: NaN detected'
Modified: branches/time_manager/src/core_sw/Makefile
===================================================================
--- branches/time_manager/src/core_sw/Makefile        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/core_sw/Makefile        2011-08-22 22:28:31 UTC (rev 952)
@@ -27,4 +27,4 @@
.F.o:
        $(RM) $@ $*.mod
        $(CPP) $(CPPFLAGS) $(CPPINCLUDES) $< > $*.f90
-        $(FC) $(FFLAGS) -c $*.f90 $(FCINCLUDES) -I../framework -I../operators
+        $(FC) $(FFLAGS) -c $*.f90 $(FCINCLUDES) -I../framework -I../operators -I../external/esmf_time_f90
Modified: branches/time_manager/src/core_sw/Registry
===================================================================
--- branches/time_manager/src/core_sw/Registry        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/core_sw/Registry        2011-08-22 22:28:31 UTC (rev 952)
@@ -1,31 +1,34 @@
#
# namelist type namelist_record name default_value
#
-namelist integer sw_model config_test_case 5
-namelist character sw_model config_time_integration RK4
-namelist real sw_model config_dt 172.8
-namelist integer sw_model config_ntimesteps 7500
-namelist integer sw_model config_output_interval 500
-namelist integer sw_model config_stats_interval 100
-namelist logical sw_model config_h_ScaleWithMesh false
-namelist real sw_model config_h_mom_eddy_visc2 0.0
-namelist real sw_model config_h_mom_eddy_visc4 0.0
-namelist real sw_model config_h_tracer_eddy_diff2 0.0
-namelist real sw_model config_h_tracer_eddy_diff4 0.0
-namelist integer sw_model config_thickness_adv_order 2
-namelist integer sw_model config_tracer_adv_order 2
-namelist logical sw_model config_positive_definite false
-namelist logical sw_model config_monotonic false
-namelist logical sw_model config_wind_stress                        false
-namelist logical sw_model config_bottom_drag                        false
-namelist real sw_model config_apvm_upwinding 0.5
-namelist character io config_input_name grid.nc
-namelist character io config_output_name output.nc
-namelist character io config_restart_name restart.nc
-namelist character io config_decomp_file_prefix graph.info.part.
-namelist integer restart config_restart_interval 0
-namelist logical restart config_do_restart false
-namelist real restart config_restart_time 172800.0
+namelist integer sw_model config_test_case 5
+namelist character sw_model config_time_integration RK4
+namelist real sw_model config_dt 172.8
+namelist integer sw_model config_calendar_type MPAS_360DAY
+namelist character sw_model config_start_time 0000-01-01_00:00:00
+namelist character sw_model config_stop_time none
+namelist character sw_model config_run_duration none
+namelist integer sw_model config_stats_interval 100
+namelist logical sw_model config_h_ScaleWithMesh false
+namelist real sw_model config_h_mom_eddy_visc2 0.0
+namelist real sw_model config_h_mom_eddy_visc4 0.0
+namelist real sw_model config_h_tracer_eddy_diff2 0.0
+namelist real sw_model config_h_tracer_eddy_diff4 0.0
+namelist integer sw_model config_thickness_adv_order 2
+namelist integer sw_model config_tracer_adv_order 2
+namelist logical sw_model config_positive_definite false
+namelist logical sw_model config_monotonic false
+namelist logical sw_model config_wind_stress false
+namelist logical sw_model config_bottom_drag false
+namelist real sw_model config_apvm_upwinding 0.5
+namelist character io config_input_name grid.nc
+namelist character io config_output_name output.nc
+namelist character io config_restart_name restart.nc
+namelist character io config_output_interval 06:00:00
+namelist integer io config_frames_per_outfile 0
+namelist character io config_decomp_file_prefix graph.info.part.
+namelist logical restart config_do_restart false
+namelist character restart config_restart_interval none
#
# dim type name_in_file name_in_code
@@ -46,7 +49,7 @@
#
# var persistence type name_in_file ( dims ) time_levs iro- name_in_code struct super-array array_class
#
-var persistent real xtime ( Time ) 2 ro xtime state - -
+var persistent text xtime ( Time ) 2 ro xtime state - -
var persistent real latCell ( nCells ) 0 iro latCell mesh - -
var persistent real lonCell ( nCells ) 0 iro lonCell mesh - -
@@ -152,5 +155,5 @@
var persistent real circulation ( nVertLevels nVertices Time ) 2 - circulation state - -
var persistent real gradPVt ( nVertLevels nEdges Time ) 2 - gradPVt state - -
var persistent real gradPVn ( nVertLevels nEdges Time ) 2 - gradPVn state - -
-var persistent real        h_vertex ( nVertLevels nVertices Time ) 2 - h_vertex state - -
+var persistent real h_vertex ( nVertLevels nVertices Time ) 2 - h_vertex state - -
Modified: branches/time_manager/src/core_sw/module_mpas_core.F
===================================================================
--- branches/time_manager/src/core_sw/module_mpas_core.F        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/core_sw/module_mpas_core.F        2011-08-22 22:28:31 UTC (rev 952)
@@ -1,15 +1,21 @@
module mpas_core
use mpas_framework
+ use mpas_timekeeping
type (io_output_object) :: restart_obj
integer :: restart_frame
+ integer :: current_outfile_frames
+ type (MPAS_Clock_type) :: clock
+ integer, parameter :: outputAlarmID = 1
+ integer, parameter :: restartAlarmID = 2
+ !integer, parameter :: statsAlarmID = 3
+
contains
-
- subroutine mpas_core_init(domain)
+ subroutine mpas_core_init(domain, startTimeStamp)
use configure
use grid_types
@@ -18,6 +24,7 @@
implicit none
type (domain_type), intent(inout) :: domain
+ character(len=*), intent(out) :: startTimeStamp
real (kind=RKIND) :: dt
type (block_type), pointer :: block
@@ -29,17 +36,81 @@
! Initialize core
!
dt = config_dt
+
+ call simulation_clock_init(domain, dt, startTimeStamp)
+
block => domain % blocklist
do while (associated(block))
call mpas_init_block(block, block % mesh, dt)
+ block % state % time_levs(1) % state % xtime % scalar = startTimeStamp
block => block % next
end do
restart_frame = 1
-
+ current_outfile_frames = 0
+
end subroutine mpas_core_init
-
-
+
+
+ subroutine simulation_clock_init(domain, dt, startTimeStamp)
+
+ implicit none
+
+ type (domain_type), intent(inout) :: domain
+ real (kind=RKIND), intent(in) :: dt
+ character(len=*), intent(out) :: startTimeStamp
+
+ type (MPAS_Time_Type) :: startTime, stopTime, alarmStartTime
+ type (MPAS_TimeInterval_type) :: runDuration, timeStep, alarmTimeStep
+ integer :: ierr
+
+ call MPAS_setTime(curr_time=startTime, dateTimeString=config_start_time, ierr=ierr)
+ call MPAS_setTimeInterval(timeStep, dt=dt, ierr=ierr)
+
+ if (trim(config_run_duration) /= "none") then
+ call MPAS_setTimeInterval(runDuration, timeString=config_run_duration, ierr=ierr)
+ call MPAS_createClock(clock, startTime=startTime, timeStep=timeStep, runDuration=runDuration, ierr=ierr)
+
+ if (trim(config_stop_time) /= "none") then
+ call MPAS_setTime(curr_time=stopTime, dateTimeString=config_stop_time, ierr=ierr)
+ if(startTime + runduration /= stopTime) then
+ write(0,*) 'Warning: config_run_duration and config_stop_time are inconsitent: using config_run_duration.'
+ end if
+ end if
+ else if (trim(config_stop_time) /= "none") then
+ call MPAS_setTime(curr_time=stopTime, dateTimeString=config_stop_time, ierr=ierr)
+ call MPAS_createClock(clock, startTime=startTime, timeStep=timeStep, stopTime=stopTime, ierr=ierr)
+ else
+ write(0,*) 'Error: Neither config_run_duration nor config_stop_time were specified.'
+ call dmpar_abort(domain % dminfo)
+ end if
+
+ ! set output alarm
+ call MPAS_setTimeInterval(alarmTimeStep, timeString=config_output_interval, ierr=ierr)
+ alarmStartTime = startTime + alarmTimeStep
+ call MPAS_addClockAlarm(clock, outputAlarmID, alarmStartTime, alarmTimeStep, ierr=ierr)
+
+ ! set restart alarm, if necessary
+ if (trim(config_restart_interval) /= "none") then
+ call MPAS_setTimeInterval(alarmTimeStep, timeString=config_restart_interval, ierr=ierr)
+ alarmStartTime = startTime + alarmTimeStep
+ call MPAS_addClockAlarm(clock, restartAlarmID, alarmStartTime, alarmTimeStep, ierr=ierr)
+ end if
+
+ !TODO: use this code if we desire to convert config_stats_interval to alarms
+ !(must also change config_stats_interval type to character)
+ ! set stats alarm, if necessary
+ !if (trim(config_stats_interval) /= "none") then
+ ! call MPAS_setTimeInterval(alarmTimeStep, timeString=config_stats_interval, ierr=ierr)
+ ! alarmStartTime = startTime + alarmTimeStep
+ ! call MPAS_addClockAlarm(clock, statsAlarmID, alarmStartTime, alarmTimeStep, ierr=ierr)
+ !end if
+
+ call MPAS_getTime(curr_time=startTime, dateTimeString=startTimeStamp, ierr=ierr)
+
+ end subroutine simulation_clock_init
+
+
subroutine mpas_init_block(block, mesh, dt)
use grid_types
@@ -53,7 +124,7 @@
type (mesh_type), intent(inout) :: mesh
real (kind=RKIND), intent(in) :: dt
-
+
call compute_solve_diagnostics(dt, block % state % time_levs(1) % state, mesh)
call compute_mesh_scaling(mesh)
@@ -61,8 +132,6 @@
call init_reconstruct(mesh)
call reconstruct(block % state % time_levs(1) % state, mesh)
- if (.not. config_do_restart) block % state % time_levs(1) % state % xtime % scalar = 0.0
-
end subroutine mpas_init_block
@@ -77,36 +146,58 @@
type (domain_type), intent(inout) :: domain
type (io_output_object), intent(inout) :: output_obj
integer, intent(inout) :: output_frame
-
- integer :: ntimesteps, itimestep
+
+ integer :: itimestep
real (kind=RKIND) :: dt
type (block_type), pointer :: block_ptr
+
+ type (MPAS_Time_Type) :: currTime
+ character(len=32) :: timeStamp
+ integer :: ierr
! Eventually, dt should be domain specific
dt = config_dt
- ntimesteps = config_ntimesteps
-
+
+ currTime = MPAS_getClockTime(clock, MPAS_NOW, ierr)
+ call MPAS_getTime(curr_time=currTime, dateTimeString=timeStamp, ierr=ierr)
+ write(0,*) 'Initial timestep ', timeStamp
+
call write_output_frame(output_obj, output_frame, domain)
-
+
! During integration, time level 1 stores the model state at the beginning of the
! time step, and time level 2 stores the state advanced dt in time by timestep(...)
- do itimestep = 1,ntimesteps
- write(0,*) 'Doing timestep ', itimestep
+ itimestep = 0
+ do while (.not. MPAS_isClockStopTime(clock))
+
+ itimestep = itimestep + 1
+ call MPAS_advanceClock(clock)
+
+ currTime = MPAS_getClockTime(clock, MPAS_NOW, ierr)
+ call MPAS_getTime(curr_time=currTime, dateTimeString=timeStamp, ierr=ierr)
+ write(0,*) 'Doing timestep ', timeStamp
+
call timer_start("time integration")
- call mpas_timestep(domain, itimestep, dt)
+ call mpas_timestep(domain, itimestep, dt, timeStamp)
call timer_stop("time integration")
-
+
! Move time level 2 fields back into time level 1 for next time step
call shift_time_levels_state(domain % blocklist % state)
-
- if (mod(itimestep, config_output_interval) == 0) then
+
+ !TODO: MPAS_getClockRingingAlarms is probably faster than multiple MPAS_isAlarmRinging...
+
+ if (MPAS_isAlarmRinging(clock, outputAlarmID, ierr=ierr)) then
+ call MPAS_resetClockAlarm(clock, outputAlarmID, ierr=ierr)
+ if(output_frame == 1) call output_state_init(output_obj, domain, "OUTPUT", trim(timeStamp)) ! output_frame will always be > 1 here unless it is reset after the output file is finalized
call write_output_frame(output_obj, output_frame, domain)
end if
- if (mod(itimestep, config_restart_interval) == 0 .and. config_restart_interval > 0) then
+
+ if (MPAS_isAlarmRinging(clock, restartAlarmID, ierr=ierr)) then
+ call MPAS_resetClockAlarm(clock, restartAlarmID, ierr=ierr)
if (restart_frame == 1) call output_state_init(restart_obj, domain, "RESTART")
call output_state_for_domain(restart_obj, domain, restart_frame)
restart_frame = restart_frame + 1
end if
+
end do
end subroutine mpas_core_run
@@ -124,10 +215,10 @@
use io_output
implicit none
-
+
+ type (io_output_object), intent(inout) :: output_obj
integer, intent(inout) :: output_frame
type (domain_type), intent(inout) :: domain
- type (io_output_object), intent(inout) :: output_obj
integer :: i, j, k
integer :: eoe
@@ -141,7 +232,17 @@
call output_state_for_domain(output_obj, domain, output_frame)
output_frame = output_frame + 1
-
+
+ ! if the maximum number of frames per outfile has been reached, finalize outfile and reset frame
+ if (config_frames_per_outfile > 0) then
+ current_outfile_frames = current_outfile_frames + 1
+ if(current_outfile_frames >= config_frames_per_outfile) then
+ current_outfile_frames = 0
+ call output_state_finalize(output_obj, domain % dminfo)
+ output_frame = 1
+ end if
+ end if
+
end subroutine write_output_frame
@@ -168,7 +269,7 @@
end subroutine compute_output_diagnostics
- subroutine mpas_timestep(domain, itimestep, dt)
+ subroutine mpas_timestep(domain, itimestep, dt, timeStamp)
use grid_types
use time_integration
@@ -180,9 +281,12 @@
type (domain_type), intent(inout) :: domain
integer, intent(in) :: itimestep
real (kind=RKIND), intent(in) :: dt
+ character(len=*), intent(in) :: timeStamp
+
type (block_type), pointer :: block_ptr
+ integer :: ierr
- call timestep(domain, dt)
+ call timestep(domain, dt, timeStamp)
if(config_stats_interval .gt. 0) then
if(mod(itimestep, config_stats_interval) == 0) then
@@ -199,6 +303,23 @@
call timer_stop("global_diagnostics")
end if
end if
+
+ !TODO: replace the above code block with this if we desire to convert config_stats_interval to use alarms
+ !if (MPAS_isAlarmRinging(clock, statsAlarmID, ierr=ierr)) then
+ ! call MPAS_resetClockAlarm(clock, statsAlarmID, ierr=ierr)
+
+ ! block_ptr => domain % blocklist
+ ! if(associated(block_ptr % next)) then
+ ! write(0,*) 'Error: computeGlobalDiagnostics assumes ',&
+ ! 'that there is only one block per processor.'
+ ! end if
+
+ ! call timer_start("global_diagnostics")
+ ! call computeGlobalDiagnostics(domain % dminfo, &
+ ! block_ptr % state % time_levs(2) % state, block_ptr % mesh, &
+ ! timeStamp, dt)
+ ! call timer_stop("global_diagnostics")
+ !end if
end subroutine mpas_timestep
@@ -208,11 +329,15 @@
use grid_types
implicit none
-
+
+ integer :: ierr
+
type (domain_type), intent(inout) :: domain
if (restart_frame > 1) call output_state_finalize(restart_obj, domain % dminfo)
-
+
+ call MPAS_destroyClock(clock, ierr)
+
end subroutine mpas_core_finalize
Modified: branches/time_manager/src/core_sw/module_time_integration.F
===================================================================
--- branches/time_manager/src/core_sw/module_time_integration.F        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/core_sw/module_time_integration.F        2011-08-22 22:28:31 UTC (rev 952)
@@ -10,7 +10,7 @@
contains
- subroutine timestep(domain, dt)
+ subroutine timestep(domain, dt, timeStamp)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Advance model state forward in time by the specified time step
!
@@ -24,6 +24,7 @@
type (domain_type), intent(inout) :: domain
real (kind=RKIND), intent(in) :: dt
+ character(len=*), intent(in) :: timeStamp
type (block_type), pointer :: block
@@ -37,7 +38,7 @@
block => domain % blocklist
do while (associated(block))
- block % state % time_levs(2) % state % xtime % scalar = block % state % time_levs(1) % state % xtime % scalar + dt
+ block % state % time_levs(2) % state % xtime % scalar = timeStamp
block => block % next
end do
Modified: branches/time_manager/src/driver/Makefile
===================================================================
--- branches/time_manager/src/driver/Makefile        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/driver/Makefile        2011-08-22 22:28:31 UTC (rev 952)
@@ -15,4 +15,4 @@
.F.o:
        $(RM) $@ $*.mod
        $(CPP) $(CPPFLAGS) $(CPPINCLUDES) $< > $*.f90
-        $(FC) $(FFLAGS) -c $*.f90 $(FCINCLUDES) -I../framework -I../core_$(CORE)
+        $(FC) $(FFLAGS) -c $*.f90 $(FCINCLUDES) -I../framework -I../core_$(CORE) -I../external/esmf_time_f90
Modified: branches/time_manager/src/driver/module_mpas_subdriver.F
===================================================================
--- branches/time_manager/src/driver/module_mpas_subdriver.F        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/driver/module_mpas_subdriver.F        2011-08-22 22:28:31 UTC (rev 952)
@@ -17,6 +17,7 @@
implicit none
real (kind=RKIND) :: dt
+ character(len=32) :: timeStamp
call timer_start("total time")
call timer_start("initialize")
@@ -34,7 +35,7 @@
!
! Initialize core
!
- call mpas_core_init(domain)
+ call mpas_core_init(domain, timeStamp)
call timer_stop("initialize")
@@ -43,8 +44,14 @@
! Set up output streams to be written to by the MPAS core
!
output_frame = 1
- call output_state_init(output_obj, domain, "OUTPUT")
+ if(config_frames_per_outfile > 0) then
+ call output_state_init(output_obj, domain, "OUTPUT", trim(timeStamp))
+ else
+ call output_state_init(output_obj, domain, "OUTPUT")
+ end if
+
+
end subroutine mpas_init
Modified: branches/time_manager/src/framework/Makefile
===================================================================
--- branches/time_manager/src/framework/Makefile        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/framework/Makefile        2011-08-22 22:28:31 UTC (rev 952)
@@ -34,7 +34,7 @@
module_block_decomp.o: module_grid_types.o module_hash.o module_configure.o
-module_io_input.o: module_grid_types.o module_dmpar.o module_block_decomp.o module_sort.o module_configure.o $(ZOLTANOBJ)
+module_io_input.o: module_grid_types.o module_dmpar.o module_block_decomp.o module_sort.o module_configure.o module_mpas_timekeeping.o $(ZOLTANOBJ)
module_io_output.o: module_grid_types.o module_dmpar.o module_sort.o module_configure.o
Modified: branches/time_manager/src/framework/module_io_input.F
===================================================================
--- branches/time_manager/src/framework/module_io_input.F        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/framework/module_io_input.F        2011-08-22 22:28:31 UTC (rev 952)
@@ -5,7 +5,9 @@
use block_decomp
use sort
use configure
+ use mpas_timekeeping
+
#ifdef HAVE_ZOLTAN
use zoltan_interface
#endif
@@ -80,7 +82,7 @@
#endif
#endif
- type (field1dReal) :: xtime
+ type (field1DChar) :: xtime
integer, dimension(:), pointer :: indexToCellID_0Halo
integer, dimension(:), pointer :: nEdgesOnCell_0Halo
@@ -117,8 +119,11 @@
type (graph) :: block_graph_0Halo, block_graph_1Halo, block_graph_2Halo
integer :: ghostEdgeStart, ghostVertexStart
- real (kind=RKIND) :: tdiff
- integer :: idxTdiff
+ type (MPAS_Time_type) :: startTime
+ type (MPAS_Time_type) :: sliceTime
+ type (MPAS_TimeInterval_type) :: timeDiff
+ type (MPAS_TimeInterval_type) :: minTimeDiff
+ character(len=32) :: timeStamp
if (config_do_restart) then
input_obj % filename = trim(config_restart_name)
@@ -770,25 +775,29 @@
xtime % ioinfo % fieldName = 'xtime'
call io_input_field(input_obj, xtime)
- tdiff = 1.E20
+ call MPAS_setTimeInterval(interval=minTimeDiff, DD=10000)
+ call MPAS_setTime(curr_time=startTime, dateTimeString=config_start_time)
+
do i=1,input_obj % rdLocalTime
- if (abs(xtime % array(i) - config_restart_time) < tdiff) then
+ call MPAS_setTime(curr_time=sliceTime, dateTimeString=xtime % array(i))
+ timeDiff = abs(sliceTime - startTime)
+ if (timeDiff < minTimeDiff) then
+ minTimeDiff = timeDiff
input_obj % time = i
- tdiff = abs(xtime % array(i) - config_restart_time)
end if
end do
- tdiff = xtime % array(input_obj % time)
+ timeStamp = xtime % array(input_obj % time)
deallocate(xtime % ioinfo)
deallocate(xtime % array)
end if
call dmpar_bcast_int(domain % dminfo, input_obj % time)
- call dmpar_bcast_real(domain % dminfo, tdiff)
+ call dmpar_bcast_char(domain % dminfo, timeStamp)
- write(0,*) 'Restarting model from time ', tdiff
-
+ write(0,*) 'Restarting model from time ', timeStamp
+
end if
Modified: branches/time_manager/src/framework/module_io_output.F
===================================================================
--- branches/time_manager/src/framework/module_io_output.F        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/framework/module_io_output.F        2011-08-22 22:28:31 UTC (rev 952)
@@ -52,14 +52,17 @@
contains
- subroutine output_state_init(output_obj, domain, stream)
+ subroutine output_state_init(output_obj, domain, stream, outputSuffix)
implicit none
type (io_output_object), intent(inout) :: output_obj
type (domain_type), intent(in) :: domain
character (len=*) :: stream
+ character (len=*), optional :: outputSuffix
+ character (len=128) :: tempfilename
+
type (block_type), pointer :: block_ptr
#include "output_dim_actual_decls.inc"
@@ -84,7 +87,12 @@
nVertLevelsGlobal = block_ptr % mesh % nVertLevels
if (trim(stream) == 'OUTPUT') then
- output_obj % filename = trim(config_output_name)
+ if(present(outputSuffix)) then
+ call insert_string_suffix(config_output_name, outputSuffix, tempfilename)
+ else
+ tempfilename = config_output_name
+ end if
+ output_obj % filename = trim(tempfilename)
output_obj % stream = OUTPUT
else if (trim(stream) == 'RESTART') then
output_obj % filename = trim(config_restart_name)
@@ -98,10 +106,32 @@
block_ptr % mesh, &
#include "output_dim_actual_args.inc"
)
-
+
end subroutine output_state_init
+ subroutine insert_string_suffix(stream, suffix, filename)
+
+ implicit none
+
+ character (len=*), intent(in) :: stream
+ character (len=*), intent(in) :: suffix
+ character (len=*), intent(out) :: filename
+ integer :: length, i
+
+ filename = trim(stream) // '.' // trim(suffix)
+
+ length = len_trim(stream)
+ do i=length-1,1,-1
+ if(stream(i:i) == '.') then
+ filename = trim(stream(:i)) // trim(suffix) // trim(stream(i:))
+ exit
+ end if
+ end do
+
+ end subroutine insert_string_suffix
+
+
subroutine output_state_for_domain(output_obj, domain, itime)
implicit none
Modified: branches/time_manager/src/framework/module_mpas_framework.F
===================================================================
--- branches/time_manager/src/framework/module_mpas_framework.F        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/framework/module_mpas_framework.F        2011-08-22 22:28:31 UTC (rev 952)
@@ -6,6 +6,7 @@
use io_output
use configure
use timer
+ use mpas_timekeeping
contains
@@ -24,6 +25,8 @@
call read_namelist(dminfo)
call allocate_domain(domain, dminfo)
+
+ call mpas_timekeeping_init(config_calendar_type)
end subroutine mpas_framework_init
@@ -39,6 +42,8 @@
call dmpar_finalize(dminfo)
+ call mpas_timekeeping_finalize()
+
end subroutine mpas_framework_finalize
end module mpas_framework
Modified: branches/time_manager/src/framework/module_mpas_timekeeping.F
===================================================================
--- branches/time_manager/src/framework/module_mpas_timekeeping.F        2011-08-22 17:36:53 UTC (rev 951)
+++ branches/time_manager/src/framework/module_mpas_timekeeping.F        2011-08-22 22:28:31 UTC (rev 952)
@@ -101,7 +101,11 @@
module procedure ge_ti_ti
end interface
+ interface abs
+ module procedure abs_ti
+ end interface
+
contains
@@ -1002,7 +1006,6 @@
subroutine MPAS_setTimeInterval(interval, DD, H, M, S, S_n, S_d, timeString, dt, ierr)
-! TODO: add double-precision seconds
implicit none
@@ -1186,7 +1189,7 @@
end subroutine MPAS_setTimeInterval
- subroutine MPAS_getTimeInterval(interval, DD, H, M, S, S_n, S_d, timeString, ierr)
+ subroutine MPAS_getTimeInterval(interval, DD, H, M, S, S_n, S_d, timeString, dt, ierr)
! TODO: add double-precision seconds
implicit none
@@ -1199,6 +1202,7 @@
integer, intent(out), optional :: S_n
integer, intent(out), optional :: S_d
character (len=32), intent(out), optional :: timeString
+ real (kind=RKIND), intent(out), optional :: dt
integer, intent(out), optional :: ierr
integer :: days, seconds, sn, sd
@@ -1207,6 +1211,10 @@
call ESMF_TimeIntervalGet(interval % ti, D=days, S=seconds, Sn=sn, Sd=sd, rc=ierr)
+ if (present(dt)) then
+ dt = (days * 24 * 60 * 60) + seconds + (sn / sd)
+ end if
+
if (present(DD)) then
DD = days
days = 0
@@ -1480,6 +1488,31 @@
end function neg_ti
+ type (MPAS_TimeInterval_type) function abs_ti(ti)
+
+ implicit none
+
+ type (MPAS_TimeInterval_type), intent(in) :: ti
+
+ type (MPAS_TimeInterval_type) :: zeroInterval
+ integer :: rc
+ integer :: D, S, Sn, Sd
+
+ call ESMF_TimeIntervalSet(zeroInterval % ti, D=0, H=0, M=0, S=0, rc=rc)
+
+ if(ti < zeroInterval) then
+ call ESMF_TimeIntervalGet(ti % ti, D=D, S=S, Sn=Sn, Sd=Sd, rc=rc)
+ D = -D
+ S = -S
+ Sn = -Sn
+ call ESMF_TimeIntervalSet(abs_ti % ti, D=D, S=S, Sn=Sn, Sd=Sd, rc=rc)
+ else
+ abs_ti = ti
+ end if
+
+ end function abs_ti
+
+
! TODO: Implement this function
! type (MPAS_TimeInterval_type) function mod(ti1, ti2)
!
</font>
</pre>