subroutine dyn_mpas_read_namelist(self, namelist_path, &
cf_calendar, start_date_time, stop_date_time, run_duration, initial_run)
class(mpas_dynamical_core_type), intent(in) :: self
character(*), intent(in) :: namelist_path, cf_calendar
integer, intent(in) :: start_date_time(6), & ! YYYY, MM, DD, hh, mm, ss.
stop_date_time(6), & ! YYYY, MM, DD, hh, mm, ss.
run_duration(4) ! DD, hh, mm, ss.
logical, intent(in) :: initial_run
character(*), parameter :: subname = 'dyn_mpas_subdriver::dyn_mpas_read_namelist'
character(strkind) :: mpas_calendar
character(strkind), pointer :: config_pointer_c
integer :: ierr
logical, pointer :: config_pointer_l
call self % debug_print(log_level_debug, subname // ' entered')
nullify(config_pointer_c)
nullify(config_pointer_l)
call self % debug_print(log_level_info, 'Reading namelist at "' // trim(adjustl(namelist_path)) // '"')
! Override namelist filename so that we can rely on upstream MPAS functionality for reading its own namelist.
! The case of missing namelist groups (i.e., `iostat == iostat_end` or `iostat == iostat_eor`) will be handled gracefully.
! All namelist variables will have reasonable default values even if they are missing.
self % domain_ptr % namelist_filename = trim(adjustl(namelist_path))
ierr = self % domain_ptr % core % setup_namelist( &
self % domain_ptr % configs, self % domain_ptr % namelist_filename, self % domain_ptr % dminfo)
if (ierr /= 0) then
call self % model_error('Namelist setup failed for core ' // trim(self % domain_ptr % core % corename), &
subname, __LINE__)
end if
! Override designated namelist variables according to the information provided from CAM-SIMA.
! These include run-time settings that cannot be determined beforehand.
call self % debug_print(log_level_info, 'Overriding designated namelist variables')
! CAM-SIMA seems to follow "NetCDF Climate and Forecast (CF) Metadata Conventions" for calendar names. See
! CF-1.12, section "4.4.2. Calendar", in doi:10.5281/zenodo.14275599.
! However, this is not the case for MPAS. Translate calendar names between CF and MPAS.
select case (trim(adjustl(cf_calendar)))
case ('360_day')
mpas_calendar = '360day'
case ('365_day', 'noleap')
mpas_calendar = 'gregorian_noleap'
case ('gregorian', 'standard')
! "gregorian" is a deprecated alternative name for "standard".
mpas_calendar = 'gregorian'
case default
call self % model_error('Unsupported calendar type "' // trim(adjustl(cf_calendar)) // '"', &
subname, __LINE__)
end select
call self % get_variable_pointer(config_pointer_c, 'cfg', 'config_calendar_type')
config_pointer_c = trim(adjustl(mpas_calendar))
call self % debug_print(log_level_debug, 'config_calendar_type = ' // trim(config_pointer_c))
nullify(config_pointer_c)
! MPAS represents date and time in ISO 8601 format. However, the separator between date and time is "_"
! instead of standard "T".
! Format in "YYYY-MM-DD_hh:mm:ss" is acceptable.
call self % get_variable_pointer(config_pointer_c, 'cfg', 'config_start_time')
config_pointer_c = stringify(start_date_time(1:3), '-') // '_' // stringify(start_date_time(4:6), ':')
call self % debug_print(log_level_debug, 'config_start_time = ' // trim(config_pointer_c))
nullify(config_pointer_c)
call self % get_variable_pointer(config_pointer_c, 'cfg', 'config_stop_time')
config_pointer_c = stringify(stop_date_time(1:3), '-') // '_' // stringify(stop_date_time(4:6), ':')
call self % debug_print(log_level_debug, 'config_stop_time = ' // trim(config_pointer_c))
nullify(config_pointer_c)
! Format in "DD_hh:mm:ss" is acceptable.
call self % get_variable_pointer(config_pointer_c, 'cfg', 'config_run_duration')
config_pointer_c = stringify([run_duration(1)]) // '_' // stringify(run_duration(2:4), ':')
call self % debug_print(log_level_debug, 'config_run_duration = ' // trim(config_pointer_c))
nullify(config_pointer_c)
! Reflect current run type to MPAS.
call self % get_variable_pointer(config_pointer_l, 'cfg', 'config_do_restart')
if (initial_run) then
! Run type is initial run.
config_pointer_l = .false.
else
! Run type is branch or restart run.
config_pointer_l = .true.
end if
call self % debug_print(log_level_debug, 'config_do_restart = ' // stringify([config_pointer_l]))
nullify(config_pointer_l)
! At this point, we should be ready to follow up with the rest of MPAS framework initialization
! in `dyn_mpas_init_phase2`.
call self % debug_print(log_level_debug, subname // ' completed')
end subroutine dyn_mpas_read_namelist