MOM6
MOM_driver.F90
Go to the documentation of this file.
1 program mom_main
2 
3 ! This file is part of MOM6. See LICENSE.md for the license.
4 
5 !********+*********+*********+*********+*********+*********+*********+**
6 !* *
7 !* The Modular Ocean Model, version 6 *
8 !* MOM6 *
9 !* *
10 !* By Alistair Adcroft, Stephen Griffies and Robert Hallberg *
11 !* *
12 !* This file is the ocean-only driver for Version 6 of the Modular *
13 !* Ocean Model (MOM). A separate ocean interface for use with *
14 !* coupled models is provided in ocean_model_MOM.F90. These two *
15 !* drivers are kept in separate directories for convenience of code *
16 !* selection during compiling. This file orchestrates the calls to *
17 !* the MOM initialization routines, to the subroutine that steps *
18 !* the model, and coordinates the output and saving restarts. A *
19 !* description of all of the files that constitute MOM is found in *
20 !* the comments at the beginning of MOM.F90. The arguments of each *
21 !* subroutine are described where the subroutine is defined. *
22 !* *
23 !* Macros written all in capital letters are defined in MOM_memory.h. *
24 !* *
25 !********+*********+*********+*********+*********+*********+*********+**
26 
27  use mom_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end
28  use mom_cpu_clock, only : clock_component
34  use mom, only : step_offline
35  use mom_domains, only : mom_infra_init, mom_infra_end
36  use mom_error_handler, only : mom_error, mom_mesg, warning, fatal, is_root_pe
42  use mom_get_input, only : directories
43  use mom_grid, only : ocean_grid_type
44  use mom_io, only : file_exists, open_file, close_file
45  use mom_io, only : check_nml_error, io_infra_init, io_infra_end
46  use mom_io, only : append_file, ascii_file, readonly_file, single_file
51  use mom_time_manager, only : time_type, set_date, get_date
52  use mom_time_manager, only : real_to_time, time_type_to_real
53  use mom_time_manager, only : operator(+), operator(-), operator(*), operator(/)
54  use mom_time_manager, only : operator(>), operator(<), operator(>=)
55  use mom_time_manager, only : increment_date, set_calendar_type, month_name
56  use mom_time_manager, only : julian, gregorian, noleap, thirty_day_months
57  use mom_time_manager, only : no_calendar
60  use mom_variables, only : surface
64 
65  use ensemble_manager_mod, only : ensemble_manager_init, get_ensemble_size
66  use ensemble_manager_mod, only : ensemble_pelist_setup
67  use mpp_mod, only : set_current_pelist => mpp_set_current_pelist
68  use time_interp_external_mod, only : time_interp_external_init
69 
72 ! , add_shelf_flux_forcing, add_shelf_flux_IOB
73 
76 
77  implicit none
78 
79 #include <MOM_memory.h>
80 
81  ! A structure with the driving mechanical surface forces
82  type(mech_forcing) :: forces
83  ! A structure containing pointers to the thermodynamic forcing fields
84  ! at the ocean surface.
85  type(forcing) :: fluxes
86 
87  ! A structure containing pointers to the ocean surface state fields.
88  type(surface) :: sfc_state
89 
90  ! A pointer to a structure containing metrics and related information.
91  type(ocean_grid_type), pointer :: grid
92  type(verticalgrid_type), pointer :: gv
93  ! A pointer to a structure containing dimensional unit scaling factors.
94  type(unit_scale_type), pointer :: us
95 
96  ! If .true., use the ice shelf model for part of the domain.
97  logical :: use_ice_shelf
98 
99  ! If .true., use surface wave coupling
100  logical :: use_waves = .false.
101 
102  ! This is .true. if incremental restart files may be saved.
103  logical :: permit_incr_restart = .true.
104 
105  integer :: ns
106 
107  ! nmax is the number of iterations after which to stop so that the
108  ! simulation does not exceed its CPU time limit. nmax is determined by
109  ! evaluating the CPU time used between successive calls to write_cputime.
110  ! Initially it is set to be very large.
111  integer :: nmax=2000000000
112 
113  ! A structure containing several relevant directory paths.
114  type(directories) :: dirs
115 
116  ! A suite of time types for use by MOM
117  type(time_type), target :: time ! A copy of the ocean model's time.
118  ! Other modules can set pointers to this and
119  ! change it to manage diagnostics.
120  type(time_type) :: master_time ! The ocean model's master clock. No other
121  ! modules are ever given access to this.
122  type(time_type) :: time1 ! The value of the ocean model's time at the
123  ! start of a call to step_MOM.
124  type(time_type) :: start_time ! The start time of the simulation.
125  type(time_type) :: segment_start_time ! The start time of this run segment.
126  type(time_type) :: time_end ! End time for the segment or experiment.
127  type(time_type) :: restart_time ! The next time to write restart files.
128  type(time_type) :: time_step_ocean ! A time_type version of dt_forcing.
129 
130  real :: elapsed_time = 0.0 ! Elapsed time in this run [s].
131  logical :: elapsed_time_master ! If true, elapsed time is used to set the
132  ! model's master clock (Time). This is needed
133  ! if Time_step_ocean is not an exact
134  ! representation of dt_forcing.
135  real :: dt_forcing ! The coupling time step [s].
136  real :: dt ! The nominal baroclinic dynamics time step [s].
137  real :: dt_off ! Offline time step [s].
138  integer :: ntstep ! The number of baroclinic dynamics time steps
139  ! within dt_forcing.
140  real :: dt_therm ! The thermodynamic timestep [s]
141  real :: dt_dyn ! The actual dynamic timestep used [s]. The value of dt_dyn is
142  ! chosen so that dt_forcing is an integer multiple of dt_dyn.
143  real :: dtdia ! The diabatic timestep [s]
144  real :: t_elapsed_seg ! The elapsed time in this run segment [s]
145  integer :: n, n_max, nts, n_last_thermo
146  logical :: diabatic_first, single_step_call
147  type(time_type) :: time2, time_chg
148 
149  integer :: restart_control ! An integer that is bit-tested to determine whether
150  ! incremental restart files are saved and whether they
151  ! have a time stamped name. +1 (bit 0) for generic
152  ! files and +2 (bit 1) for time-stamped files. A
153  ! restart file is saved at the end of a run segment
154  ! unless Restart_control is negative.
155 
156  real :: time_unit ! The time unit for the following input fields [s].
157  type(time_type) :: restint ! The time between saves of the restart file.
158  type(time_type) :: daymax ! The final day of the simulation.
159 
160  integer :: cpu_steps ! The number of steps between writing CPU time.
161  integer :: date_init(6)=0 ! The start date of the whole simulation.
162  integer :: date(6)=-1 ! Possibly the start date of this run segment.
163  integer :: years=0, months=0, days=0 ! These may determine the segment run
164  integer :: hours=0, minutes=0, seconds=0 ! length, if read from a namelist.
165  integer :: yr, mon, day, hr, mins, sec ! Temp variables for writing the date.
166  type(param_file_type) :: param_file ! The structure indicating the file(s)
167  ! containing all run-time parameters.
168  character(len=9) :: month
169  character(len=16) :: calendar = 'julian'
170  integer :: calendar_type=-1
171 
172  integer :: unit, io_status, ierr
173  integer :: ensemble_size, npes_per, ensemble_info(6)
174 
175  integer, dimension(0) :: atm_pelist, land_pelist, ice_pelist
176  integer, dimension(:), allocatable :: ocean_pelist
177  logical :: unit_in_use
178  integer :: initclock, mainclock, termclock
179 
180  logical :: debug ! If true, write verbose checksums for debugging purposes.
181  logical :: offline_tracer_mode ! If false, use the model in prognostic mode where
182  ! the barotropic and baroclinic dynamics, thermodynamics,
183  ! etc. are stepped forward integrated in time.
184  ! If true, then all of the above are bypassed with all
185  ! fields necessary to integrate only the tracer advection
186  ! and diffusion equation are read in from files stored from
187  ! a previous integration of the prognostic model
188 
189  type(mom_control_struct), pointer :: mom_csp => null()
190  !> A pointer to the tracer flow control structure.
191  type(tracer_flow_control_cs), pointer :: &
192  tracer_flow_csp => null() !< A pointer to the tracer flow control structure
193  type(surface_forcing_cs), pointer :: surface_forcing_csp => null()
194  type(write_cputime_cs), pointer :: write_cpu_csp => null()
195  type(ice_shelf_cs), pointer :: ice_shelf_csp => null()
196  type(wave_parameters_cs), pointer :: waves_csp => null()
197  type(mom_restart_cs), pointer :: &
198  restart_csp => null() !< A pointer to the restart control structure
199  !! that will be used for MOM restart files.
200  type(diag_ctrl), pointer :: &
201  diag => null() !< A pointer to the diagnostic regulatory structure
202  !-----------------------------------------------------------------------
203 
204  character(len=4), parameter :: vers_num = 'v2.0'
205 ! This include declares and sets the variable "version".
206 #include "version_variable.h"
207  character(len=40) :: mod_name = "MOM_main (MOM_driver)" ! This module's name.
208 
209  integer :: ocean_nthreads = 1
210  integer :: ncores_per_node = 36
211  logical :: use_hyper_thread = .false.
212  integer :: omp_get_num_threads,omp_get_thread_num,get_cpu_affinity,adder,base_cpu
213  namelist /ocean_solo_nml/ date_init, calendar, months, days, hours, minutes, seconds,&
214  ocean_nthreads, ncores_per_node, use_hyper_thread
215 
216  !=====================================================================
217 
218  call write_cputime_start_clock(write_cpu_csp)
219 
220  call mom_infra_init() ; call io_infra_init()
221 
222  ! Initialize the ensemble manager. If there are no settings for ensemble_size
223  ! in input.nml(ensemble.nml), these should not do anything. In coupled
224  ! configurations, this all occurs in the external driver.
225  call ensemble_manager_init() ; ensemble_info(:) = get_ensemble_size()
226  ensemble_size=ensemble_info(1) ; npes_per=ensemble_info(2)
227  if (ensemble_size > 1) then ! There are multiple ensemble members.
228  allocate(ocean_pelist(npes_per))
229  call ensemble_pelist_setup(.true., 0, npes_per, 0, 0, atm_pelist, ocean_pelist, &
230  land_pelist, ice_pelist)
231  call set_current_pelist(ocean_pelist)
232  deallocate(ocean_pelist)
233  endif
234 
235  ! These clocks are on the global pelist.
236  initclock = cpu_clock_id( 'Initialization' )
237  mainclock = cpu_clock_id( 'Main loop' )
238  termclock = cpu_clock_id( 'Termination' )
239  call cpu_clock_begin(initclock)
240 
241  call mom_mesg('======== Model being driven by MOM_driver ========', 2)
242  call calltree_waypoint("Program MOM_main, MOM_driver.F90")
243 
244  if (file_exists('input.nml')) then
245  ! Provide for namelist specification of the run length and calendar data.
246  call open_file(unit, 'input.nml', form=ascii_file, action=readonly_file)
247  read(unit, ocean_solo_nml, iostat=io_status)
248  call close_file(unit)
249  ierr = check_nml_error(io_status,'ocean_solo_nml')
250  if (years+months+days+hours+minutes+seconds > 0) then
251  if (is_root_pe()) write(*,ocean_solo_nml)
252  endif
253  endif
254 
255 !$ call omp_set_num_threads(ocean_nthreads)
256 !$ base_cpu = get_cpu_affinity()
257 !$OMP PARALLEL private(adder)
258 !$ if (use_hyper_thread) then
259 !$ if (mod(omp_get_thread_num(),2) == 0) then
260 !$ adder = omp_get_thread_num()/2
261 !$ else
262 !$ adder = ncores_per_node + omp_get_thread_num()/2
263 !$ endif
264 !$ else
265 !$ adder = omp_get_thread_num()
266 !$ endif
267 !$ call set_cpu_affinity (base_cpu + adder)
268 !$ write(6,*) " ocean ", base_cpu, get_cpu_affinity(), adder, omp_get_thread_num(), omp_get_num_threads()
269 !$ call flush(6)
270 !$OMP END PARALLEL
271 
272  ! Read ocean_solo restart, which can override settings from the namelist.
273  if (file_exists(trim(dirs%restart_input_dir)//'ocean_solo.res')) then
274  call open_file(unit,trim(dirs%restart_input_dir)//'ocean_solo.res', &
275  form=ascii_file,action=readonly_file)
276  read(unit,*) calendar_type
277  read(unit,*) date_init
278  read(unit,*) date
279  call close_file(unit)
280  else
281  calendar = uppercase(calendar)
282  if (calendar(1:6) == 'JULIAN') then ; calendar_type = julian
283  elseif (calendar(1:9) == 'GREGORIAN') then ; calendar_type = gregorian
284  elseif (calendar(1:6) == 'NOLEAP') then ; calendar_type = noleap
285  elseif (calendar(1:10)=='THIRTY_DAY') then ; calendar_type = thirty_day_months
286  elseif (calendar(1:11)=='NO_CALENDAR') then; calendar_type = no_calendar
287  elseif (calendar(1:1) /= ' ') then
288  call mom_error(fatal,'MOM_driver: Invalid namelist value '//trim(calendar)//' for calendar')
289  else
290  call mom_error(fatal,'MOM_driver: No namelist value for calendar')
291  endif
292  endif
293  call set_calendar_type(calendar_type)
294 
295 
296  if (sum(date_init) > 0) then
297  start_time = set_date(date_init(1),date_init(2), date_init(3), &
298  date_init(4),date_init(5),date_init(6))
299  else
300  start_time = real_to_time(0.0)
301  endif
302 
303  call time_interp_external_init
304 
305  if (sum(date) >= 0) then
306  ! In this case, the segment starts at a time fixed by ocean_solo.res
307  segment_start_time = set_date(date(1),date(2),date(3),date(4),date(5),date(6))
308  time = segment_start_time
309  call initialize_mom(time, start_time, param_file, dirs, mom_csp, restart_csp, &
310  segment_start_time, offline_tracer_mode=offline_tracer_mode, &
311  diag_ptr=diag, tracer_flow_csp=tracer_flow_csp)
312  else
313  ! In this case, the segment starts at a time read from the MOM restart file
314  ! or left as Start_time by MOM_initialize.
315  time = start_time
316  call initialize_mom(time, start_time, param_file, dirs, mom_csp, restart_csp, &
317  offline_tracer_mode=offline_tracer_mode, diag_ptr=diag, &
318  tracer_flow_csp=tracer_flow_csp)
319  endif
320 
321  call get_mom_state_elements(mom_csp, g=grid, gv=gv, us=us, c_p=fluxes%C_p)
322  master_time = time
323 
324  call calltree_waypoint("done initialize_MOM")
325 
326  call extract_surface_state(mom_csp, sfc_state)
327 
328  call surface_forcing_init(time, grid, us, param_file, diag, &
329  surface_forcing_csp, tracer_flow_csp)
330  call calltree_waypoint("done surface_forcing_init")
331 
332  call get_param(param_file, mod_name, "ICE_SHELF", use_ice_shelf, &
333  "If true, enables the ice shelf model.", default=.false.)
334  if (use_ice_shelf) then
335  ! These arrays are not initialized in most solo cases, but are needed
336  ! when using an ice shelf
337  call initialize_ice_shelf(param_file, grid, time, ice_shelf_csp, &
338  diag, forces, fluxes)
339  endif
340 
341  call get_param(param_file,mod_name,"USE_WAVES",use_waves,&
342  "If true, enables surface wave modules.",default=.false.)
343  if (use_waves) then
344  call mom_wave_interface_init(time, grid, gv, us, param_file, waves_csp, diag)
345  else
346  call mom_wave_interface_init_lite(param_file)
347  endif
348 
349  segment_start_time = time
350  elapsed_time = 0.0
351 
352  ! Read all relevant parameters and write them to the model log.
353  call log_version(param_file, mod_name, version, "")
354  call get_param(param_file, mod_name, "DT", dt, fail_if_missing=.true.)
355  call get_param(param_file, mod_name, "DT_FORCING", dt_forcing, &
356  "The time step for changing forcing, coupling with other "//&
357  "components, or potentially writing certain diagnostics. "//&
358  "The default value is given by DT.", units="s", default=dt)
359  if (offline_tracer_mode) then
360  call get_param(param_file, mod_name, "DT_OFFLINE", dt_forcing, &
361  "Time step for the offline time step")
362  dt = dt_forcing
363  endif
364  ntstep = max(1,ceiling(dt_forcing/dt - 0.001))
365 
366  time_step_ocean = real_to_time(dt_forcing)
367  elapsed_time_master = (abs(dt_forcing - time_type_to_real(time_step_ocean)) > 1.0e-12*dt_forcing)
368  if (elapsed_time_master) &
369  call mom_mesg("Using real elapsed time for the master clock.", 2)
370 
371  ! Determine the segment end time, either from the namelist file or parsed input file.
372  call get_param(param_file, mod_name, "TIMEUNIT", time_unit, &
373  "The time unit for DAYMAX, ENERGYSAVEDAYS, and RESTINT.", &
374  units="s", default=86400.0)
375  if (years+months+days+hours+minutes+seconds > 0) then
376  time_end = increment_date(time, years, months, days, hours, minutes, seconds)
377  call mom_mesg('Segment run length determined from ocean_solo_nml.', 2)
378  call get_param(param_file, mod_name, "DAYMAX", daymax, timeunit=time_unit, &
379  default=time_end, do_not_log=.true.)
380  call log_param(param_file, mod_name, "DAYMAX", daymax, &
381  "The final time of the whole simulation, in units of "//&
382  "TIMEUNIT seconds. This also sets the potential end "//&
383  "time of the present run segment if the end time is "//&
384  "not set via ocean_solo_nml in input.nml.", &
385  timeunit=time_unit)
386  else
387  call get_param(param_file, mod_name, "DAYMAX", daymax, &
388  "The final time of the whole simulation, in units of "//&
389  "TIMEUNIT seconds. This also sets the potential end "//&
390  "time of the present run segment if the end time is "//&
391  "not set via ocean_solo_nml in input.nml.", &
392  timeunit=time_unit, fail_if_missing=.true.)
393  time_end = daymax
394  endif
395 
396  call get_param(param_file, mod_name, "SINGLE_STEPPING_CALL", single_step_call, &
397  "If true, advance the state of MOM with a single step "//&
398  "including both dynamics and thermodynamics. If false "//&
399  "the two phases are advanced with separate calls.", default=.true.)
400  call get_param(param_file, mod_name, "DT_THERM", dt_therm, &
401  "The thermodynamic and tracer advection time step. "//&
402  "Ideally DT_THERM should be an integer multiple of DT "//&
403  "and less than the forcing or coupling time-step, unless "//&
404  "THERMO_SPANS_COUPLING is true, in which case DT_THERM "//&
405  "can be an integer multiple of the coupling timestep. By "//&
406  "default DT_THERM is set to DT.", units="s", default=dt)
407  call get_param(param_file, mod_name, "DIABATIC_FIRST", diabatic_first, &
408  "If true, apply diabatic and thermodynamic processes, "//&
409  "including buoyancy forcing and mass gain or loss, "//&
410  "before stepping the dynamics forward.", default=.false.)
411 
412 
413  if (time >= time_end) call mom_error(fatal, &
414  "MOM_driver: The run has been started at or after the end time of the run.")
415 
416  call get_param(param_file, mod_name, "RESTART_CONTROL", restart_control, &
417  "An integer whose bits encode which restart files are "//&
418  "written. Add 2 (bit 1) for a time-stamped file, and odd "//&
419  "(bit 0) for a non-time-stamped file. A non-time-stamped "//&
420  "restart file is saved at the end of the run segment "//&
421  "for any non-negative value.", default=1)
422  call get_param(param_file, mod_name, "RESTINT", restint, &
423  "The interval between saves of the restart file in units "//&
424  "of TIMEUNIT. Use 0 (the default) to not save "//&
425  "incremental restart files at all.", default=real_to_time(0.0), &
426  timeunit=time_unit)
427  call get_param(param_file, mod_name, "WRITE_CPU_STEPS", cpu_steps, &
428  "The number of coupled timesteps between writing the cpu "//&
429  "time. If this is not positive, do not check cpu time, and "//&
430  "the segment run-length can not be set via an elapsed CPU time.", &
431  default=1000)
432  call get_param(param_file, "MOM", "DEBUG", debug, &
433  "If true, write out verbose debugging data.", &
434  default=.false., debuggingparam=.true.)
435 
436  call log_param(param_file, mod_name, "ELAPSED TIME AS MASTER", elapsed_time_master)
437 
438  if (cpu_steps > 0) &
439  call mom_write_cputime_init(param_file, dirs%output_directory, start_time, &
440  write_cpu_csp)
441 
442  ! Close the param_file. No further parsing of input is possible after this.
443  call close_param_file(param_file)
445 
446  ! Write out a time stamp file.
447  if (calendar_type /= no_calendar) then
448  call open_file(unit, 'time_stamp.out', form=ascii_file, action=append_file, &
449  threading=single_file)
450  call get_date(time, date(1), date(2), date(3), date(4), date(5), date(6))
451  month = month_name(date(2))
452  if (is_root_pe()) write(unit,'(6i4,2x,a3)') date, month(1:3)
453  call get_date(time_end, date(1), date(2), date(3), date(4), date(5), date(6))
454  month = month_name(date(2))
455  if (is_root_pe()) write(unit,'(6i4,2x,a3)') date, month(1:3)
456  call close_file(unit)
457  endif
458 
459  if (cpu_steps > 0) call write_cputime(time, 0, nmax, write_cpu_csp)
460 
461  if (((.not.btest(restart_control,1)) .and. (.not.btest(restart_control,0))) &
462  .or. (restart_control < 0)) permit_incr_restart = .false.
463 
464  if (restint > real_to_time(0.0)) then
465  ! restart_time is the next integral multiple of restint.
466  restart_time = start_time + restint * &
467  (1 + ((time + time_step_ocean) - start_time) / restint)
468  else
469  ! Set the time so late that there is no intermediate restart.
470  restart_time = time_end + time_step_ocean
471  permit_incr_restart = .false.
472  endif
473 
474  call cpu_clock_end(initclock) !end initialization
475 
476  call cpu_clock_begin(mainclock) !begin main loop
477 
478  ns = 1
479  do while ((ns < nmax) .and. (time < time_end))
480  call calltree_enter("Main loop, MOM_driver.F90",ns)
481 
482  ! Set the forcing for the next steps.
483  if (.not. offline_tracer_mode) then
484  call set_forcing(sfc_state, forces, fluxes, time, time_step_ocean, grid, us, &
485  surface_forcing_csp)
486  endif
487  if (debug) then
488  call mom_mech_forcing_chksum("After set forcing", forces, grid, us, haloshift=0)
489  call mom_forcing_chksum("After set forcing", fluxes, grid, us, haloshift=0)
490  endif
491 
492  if (use_ice_shelf) then
493  call shelf_calc_flux(sfc_state, fluxes, time, dt_forcing, ice_shelf_csp)
494  call add_shelf_forces(grid, us, ice_shelf_csp, forces)
495  endif
496  fluxes%fluxes_used = .false.
497  fluxes%dt_buoy_accum = us%s_to_T*dt_forcing
498 
499  if (use_waves) then
500  call update_surface_waves(grid, gv, us, time, time_step_ocean, waves_csp)
501  endif
502 
503  if (ns==1) then
504  call finish_mom_initialization(time, dirs, mom_csp, restart_csp)
505  endif
506 
507  ! This call steps the model over a time dt_forcing.
508  time1 = master_time ; time = master_time
509  if (offline_tracer_mode) then
510  call step_offline(forces, fluxes, sfc_state, time1, dt_forcing, mom_csp)
511  elseif (single_step_call) then
512  call step_mom(forces, fluxes, sfc_state, time1, dt_forcing, mom_csp, waves=waves_csp)
513  else
514  n_max = 1 ; if (dt_forcing > dt) n_max = ceiling(dt_forcing/dt - 0.001)
515  dt_dyn = dt_forcing / real(n_max)
516 
517  nts = max(1,min(n_max,floor(dt_therm/dt_dyn + 0.001)))
518  n_last_thermo = 0
519 
520  time2 = time1 ; t_elapsed_seg = 0.0
521  do n=1,n_max
522  if (diabatic_first) then
523  if (modulo(n-1,nts)==0) then
524  dtdia = dt_dyn*min(ntstep,n_max-(n-1))
525  call step_mom(forces, fluxes, sfc_state, time2, dtdia, mom_csp, &
526  do_dynamics=.false., do_thermodynamics=.true., &
527  start_cycle=(n==1), end_cycle=.false., cycle_length=dt_forcing)
528  endif
529 
530  call step_mom(forces, fluxes, sfc_state, time2, dt_dyn, mom_csp, &
531  do_dynamics=.true., do_thermodynamics=.false., &
532  start_cycle=.false., end_cycle=(n==n_max), cycle_length=dt_forcing)
533  else
534  call step_mom(forces, fluxes, sfc_state, time2, dt_dyn, mom_csp, &
535  do_dynamics=.true., do_thermodynamics=.false., &
536  start_cycle=(n==1), end_cycle=.false., cycle_length=dt_forcing)
537 
538  if ((modulo(n,nts)==0) .or. (n==n_max)) then
539  dtdia = dt_dyn*(n - n_last_thermo)
540  ! Back up Time2 to the start of the thermodynamic segment.
541  if (n > n_last_thermo+1) &
542  time2 = time2 - real_to_time(dtdia - dt_dyn)
543  call step_mom(forces, fluxes, sfc_state, time2, dtdia, mom_csp, &
544  do_dynamics=.false., do_thermodynamics=.true., &
545  start_cycle=.false., end_cycle=(n==n_max), cycle_length=dt_forcing)
546  n_last_thermo = n
547  endif
548  endif
549 
550  t_elapsed_seg = t_elapsed_seg + dt_dyn
551  time2 = time1 + real_to_time(t_elapsed_seg)
552  enddo
553  endif
554 
555 ! Time = Time + Time_step_ocean
556 ! This is here to enable fractional-second time steps.
557  elapsed_time = elapsed_time + dt_forcing
558  if (elapsed_time > 2e9) then
559  ! This is here to ensure that the conversion from a real to an integer can be accurately
560  ! represented in long runs (longer than ~63 years). It will also ensure that elapsed time
561  ! does not lose resolution of order the timetype's resolution, provided that the timestep and
562  ! tick are larger than 10-5 seconds. If a clock with a finer resolution is used, a smaller
563  ! value would be required.
564  time_chg = real_to_time(elapsed_time)
565  segment_start_time = segment_start_time + time_chg
566  elapsed_time = elapsed_time - time_type_to_real(time_chg)
567  endif
568  if (elapsed_time_master) then
569  master_time = segment_start_time + real_to_time(elapsed_time)
570  else
571  master_time = master_time + time_step_ocean
572  endif
573  time = master_time
574 
575  if (cpu_steps > 0) then ; if (mod(ns, cpu_steps) == 0) then
576  call write_cputime(time, ns+ntstep-1, nmax, write_cpu_csp)
577  endif ; endif
578 
579  call mech_forcing_diags(forces, dt_forcing, grid, time, diag, surface_forcing_csp%handles)
580 
581  if (.not. offline_tracer_mode) then
582  if (fluxes%fluxes_used) then
583  call forcing_diagnostics(fluxes, sfc_state, grid, us, time, &
584  diag, surface_forcing_csp%handles)
585  else
586  call mom_error(fatal, "The solo MOM_driver is not yet set up to handle "//&
587  "thermodynamic time steps that are longer than the coupling timestep.")
588  endif
589  endif
590 
591 ! See if it is time to write out a restart file - timestamped or not.
592  if ((permit_incr_restart) .and. (fluxes%fluxes_used) .and. &
593  (time + (time_step_ocean/2) > restart_time)) then
594  if (btest(restart_control,1)) then
595  call save_restart(dirs%restart_output_dir, time, grid, &
596  restart_csp, .true., gv=gv)
597  call forcing_save_restart(surface_forcing_csp, grid, time, &
598  dirs%restart_output_dir, .true.)
599  if (use_ice_shelf) call ice_shelf_save_restart(ice_shelf_csp, time, &
600  dirs%restart_output_dir, .true.)
601  endif
602  if (btest(restart_control,0)) then
603  call save_restart(dirs%restart_output_dir, time, grid, &
604  restart_csp, gv=gv)
605  call forcing_save_restart(surface_forcing_csp, grid, time, &
606  dirs%restart_output_dir)
607  if (use_ice_shelf) call ice_shelf_save_restart(ice_shelf_csp, time, &
608  dirs%restart_output_dir)
609  endif
610  restart_time = restart_time + restint
611  endif
612 
613  ns = ns + ntstep
614  call calltree_leave("Main loop")
615  enddo
616 
617  call cpu_clock_end(mainclock)
618  call cpu_clock_begin(termclock)
619  if (restart_control>=0) then
620  if (.not.mom_state_is_synchronized(mom_csp)) &
621  call mom_error(warning, "End of MOM_main reached with inconsistent "//&
622  "dynamics and advective times. Additional restart fields "//&
623  "that have not been coded yet would be required for reproducibility.")
624  if (.not.fluxes%fluxes_used .and. .not.offline_tracer_mode) call mom_error(fatal, &
625  "End of MOM_main reached with unused buoyancy fluxes. "//&
626  "For conservation, the ocean restart files can only be "//&
627  "created after the buoyancy forcing is applied.")
628 
629  call save_restart(dirs%restart_output_dir, time, grid, restart_csp, gv=gv)
630  if (use_ice_shelf) call ice_shelf_save_restart(ice_shelf_csp, time, &
631  dirs%restart_output_dir)
632  ! Write ocean solo restart file.
633  call open_file(unit, trim(dirs%restart_output_dir)//'ocean_solo.res', nohdrs=.true.)
634  if (is_root_pe())then
635  write(unit, '(i6,8x,a)') calendar_type, &
636  '(Calendar: no_calendar=0, thirty_day_months=1, julian=2, gregorian=3, noleap=4)'
637 
638  call get_date(start_time, yr, mon, day, hr, mins, sec)
639  write(unit, '(6i6,8x,a)') yr, mon, day, hr, mins, sec, &
640  'Model start time: year, month, day, hour, minute, second'
641  call get_date(time, yr, mon, day, hr, mins, sec)
642  write(unit, '(6i6,8x,a)') yr, mon, day, hr, mins, sec, &
643  'Current model time: year, month, day, hour, minute, second'
644  endif
645  call close_file(unit)
646  endif
647 
648  if (is_root_pe()) then
649  do unit=10,1967
650  INQUIRE(unit,opened=unit_in_use)
651  if (.not.unit_in_use) exit
652  enddo
653  open(unit,file="exitcode",form="FORMATTED",status="REPLACE",action="WRITE")
654  if (time < daymax) then
655  write(unit,*) 9
656  else
657  write(unit,*) 0
658  endif
659  close(unit)
660  endif
661 
662  call calltree_waypoint("End MOM_main")
663  call diag_mediator_end(time, diag, end_diag_manager=.true.)
664  call cpu_clock_end(termclock)
665 
666  call io_infra_end ; call mom_infra_end
667 
668  call mom_end(mom_csp)
669  if (use_ice_shelf) call ice_shelf_end(ice_shelf_csp)
670 
671 end program mom_main
mom_time_manager
Wraps the FMS time manager functions.
Definition: MOM_time_manager.F90:2
mom_ice_shelf::ice_shelf_end
subroutine, public ice_shelf_end(CS)
Deallocates all memory associated with this module.
Definition: MOM_ice_shelf.F90:1744
mom_forcing_type::mech_forcing
Structure that contains pointers to the mechanical forcing at the surface used to drive the liquid oc...
Definition: MOM_forcing_type.F90:187
mom_variables::surface
Pointers to various fields which may be used describe the surface state of MOM, and which will be ret...
Definition: MOM_variables.F90:38
mom::step_mom
subroutine, public step_mom(forces, fluxes, sfc_state, Time_start, time_int_in, CS, Waves, do_dynamics, do_thermodynamics, start_cycle, end_cycle, cycle_length, reset_therm)
This subroutine orchestrates the time stepping of MOM. The adiabatic dynamics are stepped by calls to...
Definition: MOM.F90:399
mom_forcing_type::mom_mech_forcing_chksum
subroutine, public mom_mech_forcing_chksum(mesg, forces, G, US, haloshift)
Write out chksums for the driving mechanical forces.
Definition: MOM_forcing_type.F90:1104
mom_write_cputime
A module to monitor the overall CPU time used by MOM6 and project when to stop the model.
Definition: MOM_write_cputime.F90:2
mom_forcing_type::forcing_diagnostics
subroutine, public forcing_diagnostics(fluxes, sfc_state, G, US, time_end, diag, handles)
Offer buoyancy forcing fields for diagnostics for those fields registered as part of register_forcing...
Definition: MOM_forcing_type.F90:2238
mom_ice_shelf
Implements the thermodynamic aspects of ocean / ice-shelf interactions, along with a crude placeholde...
Definition: MOM_ice_shelf.F90:4
mom_verticalgrid
Provides a transparent vertical ocean grid type and supporting routines.
Definition: MOM_verticalGrid.F90:2
mom_surface_forcing::surface_forcing_cs
Structure containing pointers to the forcing fields that may be used to drive MOM....
Definition: MOM_surface_forcing.F90:71
mom_file_parser::log_version
An overloaded interface to log version information about modules.
Definition: MOM_file_parser.F90:109
mom::mom_end
subroutine, public mom_end(CS)
End of ocean model, including memory deallocation.
Definition: MOM.F90:3132
mom_diag_mediator
The subroutines here provide convenient wrappers to the fms diag_manager interfaces with additional d...
Definition: MOM_diag_mediator.F90:3
mom_get_input::directories
Container for paths and parameter file names.
Definition: MOM_get_input.F90:20
mom_string_functions
Handy functions for manipulating strings.
Definition: MOM_string_functions.F90:2
mom_wave_interface::update_surface_waves
subroutine, public update_surface_waves(G, GV, US, Day, dt, CS)
Subroutine that handles updating of surface wave/Stokes drift related properties.
Definition: MOM_wave_interface.F90:437
mom_error_handler::mom_mesg
subroutine, public mom_mesg(message, verb, all_print)
This provides a convenient interface for writing an informative comment.
Definition: MOM_error_handler.F90:53
mom::mom_control_struct
Control structure for the MOM module, including the variables that describe the state of the ocean.
Definition: MOM.F90:153
mom_file_parser::param_file_type
A structure that can be parsed to read and document run-time parameters.
Definition: MOM_file_parser.F90:54
mom_file_parser::get_param
An overloaded interface to read and log the values of various types of parameters.
Definition: MOM_file_parser.F90:102
mom_diag_mediator::diag_mediator_close_registration
subroutine, public diag_mediator_close_registration(diag_CS)
Definition: MOM_diag_mediator.F90:3284
mom_io
This module contains I/O framework code.
Definition: MOM_io.F90:2
mom_string_functions::uppercase
character(len=len(input_string)) function, public uppercase(input_string)
Return a string in which all uppercase letters have been replaced by their lowercase counterparts.
Definition: MOM_string_functions.F90:42
mom_restart::mom_restart_cs
A restart registry and the control structure for restarts.
Definition: MOM_restart.F90:72
mom_forcing_type::mech_forcing_diags
subroutine, public mech_forcing_diags(forces, dt, G, time_end, diag, handles)
Offer mechanical forcing fields for diagnostics for those fields registered as part of register_forci...
Definition: MOM_forcing_type.F90:2201
mom_get_input
Reads the only Fortran name list needed to boot-strap the model.
Definition: MOM_get_input.F90:6
mom_unit_scaling::unit_scale_type
Describes various unit conversion factors.
Definition: MOM_unit_scaling.F90:14
mom_ice_shelf::ice_shelf_save_restart
subroutine, public ice_shelf_save_restart(CS, Time, directory, time_stamped, filename_suffix)
Save the ice shelf restart file.
Definition: MOM_ice_shelf.F90:1721
mom_wave_interface::mom_wave_interface_init
subroutine, public mom_wave_interface_init(time, G, GV, US, param_file, CS, diag)
Initializes parameters related to MOM_wave_interface.
Definition: MOM_wave_interface.F90:193
mom_forcing_type
This module implements boundary forcing for MOM6.
Definition: MOM_forcing_type.F90:2
mom_diag_mediator::diag_mediator_end
subroutine, public diag_mediator_end(time, diag_CS, end_diag_manager)
Definition: MOM_diag_mediator.F90:3299
mom_wave_interface
Interface for surface waves.
Definition: MOM_wave_interface.F90:2
mom_wave_interface::wave_parameters_cs
Container for all surface wave related parameters.
Definition: MOM_wave_interface.F90:47
mom_ice_shelf::ice_shelf_cs
Control structure that contains ice shelf parameters and diagnostics handles.
Definition: MOM_ice_shelf.F90:71
mom_surface_forcing
Functions that calculate the surface wind stresses and fluxes of buoyancy or temperature/salinity and...
Definition: MOM_surface_forcing.F90:8
mom_verticalgrid::verticalgrid_type
Describes the vertical ocean grid, including unit conversion factors.
Definition: MOM_verticalGrid.F90:24
mom_restart
The MOM6 facility for reading and writing restart files, and querying what has been read.
Definition: MOM_restart.F90:2
mom::step_offline
subroutine, public step_offline(forces, fluxes, sfc_state, Time_start, time_interval, CS)
step_offline is the main driver for running tracers offline in MOM6. This has been primarily develope...
Definition: MOM.F90:1310
mom_domains
Describes the decomposed MOM domain and has routines for communications across PEs.
Definition: MOM_domains.F90:2
mom_variables
Provides transparent structures with groups of MOM6 variables and supporting routines.
Definition: MOM_variables.F90:2
mom::finish_mom_initialization
subroutine, public finish_mom_initialization(Time, dirs, CS, restart_CSp)
Finishes initializing MOM and writes out the initial conditions.
Definition: MOM.F90:2484
mom_forcing_type::mom_forcing_chksum
subroutine, public mom_forcing_chksum(mesg, fluxes, G, US, haloshift)
Write out chksums for thermodynamic fluxes.
Definition: MOM_forcing_type.F90:1012
mom_surface_forcing::surface_forcing_init
subroutine, public surface_forcing_init(Time, G, US, param_file, diag, CS, tracer_flow_CSp)
Initialize the surface forcing module.
Definition: MOM_surface_forcing.F90:1398
mom_surface_forcing::forcing_save_restart
subroutine, public forcing_save_restart(CS, G, Time, directory, time_stamped, filename_suffix)
Save a restart file for the forcing fields.
Definition: MOM_surface_forcing.F90:1379
mom_time_manager::real_to_time
type(time_type) function, public real_to_time(x, err_msg)
This is an alternate implementation of the FMS function real_to_time_type that is accurate over a lar...
Definition: MOM_time_manager.F90:47
mom::initialize_mom
subroutine, public initialize_mom(Time, Time_init, param_file, dirs, CS, restart_CSp, Time_in, offline_tracer_mode, input_restart_file, diag_ptr, count_calls, tracer_flow_CSp)
Initialize MOM, including memory allocation, setting up parameters and diagnostics,...
Definition: MOM.F90:1506
mom_cpu_clock
Wraps the MPP cpu clock functions.
Definition: MOM_cpu_clock.F90:2
mom_file_parser
The MOM6 facility to parse input files for runtime parameters.
Definition: MOM_file_parser.F90:2
mom_error_handler::calltree_leave
subroutine, public calltree_leave(mesg)
Writes a message about leaving a subroutine if call tree reporting is active.
Definition: MOM_error_handler.F90:151
mom_write_cputime::write_cputime
subroutine, public write_cputime(day, n, nmax, CS)
This subroutine assesses how much CPU time the model has taken and determines how long the model shou...
Definition: MOM_write_cputime.F90:100
mom_wave_interface::mom_wave_interface_init_lite
subroutine, public mom_wave_interface_init_lite(param_file)
A 'lite' init subroutine to initialize a few inputs needed if using wave information with the wind-sp...
Definition: MOM_wave_interface.F90:410
mom_tracer_flow_control
Orchestrates the registration and calling of tracer packages.
Definition: MOM_tracer_flow_control.F90:2
mom_write_cputime::mom_write_cputime_init
subroutine, public mom_write_cputime_init(param_file, directory, Input_start_time, CS)
Initialize the MOM_write_cputime module.
Definition: MOM_write_cputime.F90:55
mom_main
program mom_main
Definition: MOM_driver.F90:1
mom_grid
Provides the ocean grid type.
Definition: MOM_grid.F90:2
mom_diag_mediator::disable_averaging
subroutine, public disable_averaging(diag_cs)
Call this subroutine to avoid averaging any offered fields.
Definition: MOM_diag_mediator.F90:1840
mom_unit_scaling
Provides a transparent unit rescaling type to facilitate dimensional consistency testing.
Definition: MOM_unit_scaling.F90:2
mom_tracer_flow_control::tracer_flow_control_cs
The control structure for orchestrating the calling of tracer packages.
Definition: MOM_tracer_flow_control.F90:75
mom_error_handler::is_root_pe
logical function, public is_root_pe()
This returns .true. if the current PE is the root PE.
Definition: MOM_error_handler.F90:44
mom
The central module of the MOM6 ocean model.
Definition: MOM.F90:2
mom_file_parser::close_param_file
subroutine, public close_param_file(CS, quiet_close, component)
Close any open input files and deallocate memory associated with this param_file_type....
Definition: MOM_file_parser.F90:242
mom_forcing_type::forcing
Structure that contains pointers to the boundary forcing used to drive the liquid ocean simulated by ...
Definition: MOM_forcing_type.F90:50
mom_io::file_exists
Indicate whether a file exists, perhaps with domain decomposition.
Definition: MOM_io.F90:68
mom::get_mom_state_elements
subroutine, public get_mom_state_elements(CS, G, GV, US, C_p, use_temp)
This subroutine offers access to values or pointers to other types from within the MOM_control_struct...
Definition: MOM.F90:3096
mom_error_handler::mom_error
subroutine, public mom_error(level, message, all_print)
This provides a convenient interface for writing an mpp_error message with run-time filter based on a...
Definition: MOM_error_handler.F90:72
mom_restart::save_restart
subroutine, public save_restart(directory, time, G, CS, time_stamped, filename, GV)
save_restart saves all registered variables to restart files.
Definition: MOM_restart.F90:781
mom_error_handler::calltree_waypoint
subroutine, public calltree_waypoint(mesg, n)
Writes a message about reaching a milestone if call tree reporting is active.
Definition: MOM_error_handler.F90:161
mom_write_cputime::write_cputime_start_clock
subroutine, public write_cputime_start_clock(CS)
Evaluate the CPU time returned by SYSTEM_CLOCK at the start of a run.
Definition: MOM_write_cputime.F90:44
mom_ice_shelf::initialize_ice_shelf
subroutine, public initialize_ice_shelf(param_file, ocn_grid, Time, CS, diag, forces, fluxes, Time_in, solo_ice_sheet_in)
Initializes shelf model data, parameters and diagnostics.
Definition: MOM_ice_shelf.F90:1082
mom_ice_shelf::add_shelf_forces
subroutine, public add_shelf_forces(G, US, CS, forces, do_shelf_area)
This subroutine adds the mechanical forcing fields and perhaps shelf areas, based on the ice state in...
Definition: MOM_ice_shelf.F90:760
mom_write_cputime::write_cputime_cs
A control structure that regulates the writing of CPU time.
Definition: MOM_write_cputime.F90:22
mom_file_parser::log_param
An overloaded interface to log the values of various types of parameters.
Definition: MOM_file_parser.F90:96
mom_diag_mediator::enable_averaging
subroutine, public enable_averaging(time_int_in, time_end_in, diag_cs)
This subroutine enables the accumulation of time averages over the specified time interval.
Definition: MOM_diag_mediator.F90:1805
mom_surface_forcing::set_forcing
subroutine, public set_forcing(sfc_state, forces, fluxes, day_start, day_interval, G, US, CS)
Calls subroutines in this file to get surface forcing fields.
Definition: MOM_surface_forcing.F90:221
mom_error_handler
Routines for error handling and I/O management.
Definition: MOM_error_handler.F90:2
mom_ice_shelf::shelf_calc_flux
subroutine, public shelf_calc_flux(state, fluxes, Time, time_step, CS, forces)
Calculates fluxes between the ocean and ice-shelf using the three-equations formulation (optional to ...
Definition: MOM_ice_shelf.F90:193
mom_error_handler::calltree_enter
subroutine, public calltree_enter(mesg, n)
Writes a message about entering a subroutine if call tree reporting is active.
Definition: MOM_error_handler.F90:130
mom::extract_surface_state
subroutine, public extract_surface_state(CS, sfc_state)
Set the surface (return) properties of the ocean model by setting the appropriate fields in sfc_state...
Definition: MOM.F90:2712
mom::mom_state_is_synchronized
logical function, public mom_state_is_synchronized(CS, adv_dyn)
Return true if all phases of step_MOM are at the same point in time.
Definition: MOM.F90:3075
mom_grid::ocean_grid_type
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:26
mom_diag_mediator::diag_ctrl
The following data type a list of diagnostic fields an their variants, as well as variables that cont...
Definition: MOM_diag_mediator.F90:239
mom_file_parser::read_param
An overloaded interface to read various types of parameters.
Definition: MOM_file_parser.F90:90