subroutine dyn_init(cam_runtime_opts, dyn_in, dyn_out)
! Module(s) from CAM-SIMA.
use air_composition, only: thermodynamic_active_species_num, &
thermodynamic_active_species_liq_num, &
thermodynamic_active_species_ice_num, &
thermodynamic_active_species_idx, thermodynamic_active_species_idx_dycore, &
thermodynamic_active_species_liq_idx, thermodynamic_active_species_liq_idx_dycore, &
thermodynamic_active_species_ice_idx, thermodynamic_active_species_ice_idx_dycore
use cam_abortutils, only: check_allocate
use cam_constituents, only: const_name, const_is_water_species, num_advected, readtrace
use cam_control_mod, only: initial_run
use cam_initfiles, only: initial_file_get_id, topo_file_get_id
use cam_logfile, only: debugout_debug, debugout_info
use cam_pio_utils, only: clean_iodesc_list
use cam_thermo_formula, only: energy_formula_dycore, energy_formula_dycore_mpas
use inic_analytic, only: analytic_ic_active
use physics_types, only: dycore_energy_consistency_adjust
use runtime_obj, only: runtime_options
use string_utils, only: stringify
use time_manager, only: get_step_size
! Module(s) from CCPP.
use phys_vars_init_check, only: std_name_len
! Module(s) from external libraries.
use pio, only: file_desc_t
type(runtime_options), intent(in) :: cam_runtime_opts
type(dyn_import_t), intent(in) :: dyn_in
type(dyn_export_t), intent(in) :: dyn_out
character(*), parameter :: subname = 'dyn_comp::dyn_init'
character(std_name_len), allocatable :: constituent_name(:)
integer :: coupling_time_interval
integer :: i
integer :: ierr
logical, allocatable :: is_water_species(:)
type(file_desc_t), pointer :: pio_init_file
type(file_desc_t), pointer :: pio_topo_file
call dyn_debug_print(debugout_debug, subname // ' entered')
nullify(pio_init_file)
nullify(pio_topo_file)
! Set the energy formula of dynamical core to MPAS for use in `cam_thermo`.
energy_formula_dycore = energy_formula_dycore_mpas
! The total energy of dynamical core, which uses "MPAS formula" as set above, is not consistent with
! that of CAM physics, which uses "FV formula". Therefore, temperature and temperature tendency adjustments
! are needed at the end of each physics time step.
dycore_energy_consistency_adjust = .true.
allocate(constituent_name(num_advected), stat=ierr)
call check_allocate(ierr, subname, 'constituent_name(num_advected)', 'dyn_comp', __LINE__)
allocate(is_water_species(num_advected), stat=ierr)
call check_allocate(ierr, subname, 'is_water_species(num_advected)', 'dyn_comp', __LINE__)
do i = 1, num_advected
constituent_name(i) = const_name(i)
is_water_species(i) = const_is_water_species(i)
end do
call dyn_debug_print(debugout_info, 'Defining MPAS scalars and scalar tendencies')
! Inform MPAS about constituent names and their corresponding waterness.
call mpas_dynamical_core % define_scalar(constituent_name, is_water_species)
deallocate(constituent_name)
deallocate(is_water_species)
! Provide mapping information between MPAS scalars and constituent names to CAM-SIMA.
do i = 1, thermodynamic_active_species_num
thermodynamic_active_species_idx_dycore(i) = &
mpas_dynamical_core % map_mpas_scalar_index(thermodynamic_active_species_idx(i))
end do
do i = 1, thermodynamic_active_species_liq_num
thermodynamic_active_species_liq_idx_dycore(i) = &
mpas_dynamical_core % map_mpas_scalar_index(thermodynamic_active_species_liq_idx(i))
end do
do i = 1, thermodynamic_active_species_ice_num
thermodynamic_active_species_ice_idx_dycore(i) = &
mpas_dynamical_core % map_mpas_scalar_index(thermodynamic_active_species_ice_idx(i))
end do
call dyn_debug_print(debugout_debug, 'thermodynamic_active_species_num = ' // &
stringify([thermodynamic_active_species_num]))
call dyn_debug_print(debugout_debug, 'thermodynamic_active_species_liq_num = ' // &
stringify([thermodynamic_active_species_liq_num]))
call dyn_debug_print(debugout_debug, 'thermodynamic_active_species_ice_num = ' // &
stringify([thermodynamic_active_species_ice_num]))
call dyn_debug_print(debugout_debug, 'thermodynamic_active_species_idx_dycore = [' // &
stringify(thermodynamic_active_species_idx_dycore) // ']')
call dyn_debug_print(debugout_debug, 'thermodynamic_active_species_liq_idx_dycore = [' // &
stringify(thermodynamic_active_species_liq_idx_dycore) // ']')
call dyn_debug_print(debugout_debug, 'thermodynamic_active_species_ice_idx_dycore = [' // &
stringify(thermodynamic_active_species_ice_idx_dycore) // ']')
pio_init_file => initial_file_get_id()
pio_topo_file => topo_file_get_id()
if (initial_run) then
! Run type is initial run.
call dyn_debug_print(debugout_info, 'Checking for consistency in topography data')
call check_topography_data(pio_topo_file)
if (analytic_ic_active()) then
call dyn_debug_print(debugout_info, 'Initializing MPAS state variables by setting analytic initial condition')
call set_analytic_initial_condition()
else
call dyn_debug_print(debugout_info, 'Initializing MPAS state variables by reading initial condition from a file')
! Perform default initialization for all constituents.
! Subsequently, they can be overridden depending on the namelist option (below) and
! the actual availability (checked and handled by MPAS).
call dyn_exchange_constituent_states(direction='e', exchange=.true., conversion=.false.)
! Namelist option that controls if constituents are to be read from a file.
if (readtrace) then
! Read variables that belong to the "input" stream in MPAS.
call mpas_dynamical_core % read_write_stream(pio_init_file, 'r', 'input')
else
! Read variables that belong to the "input" stream in MPAS, excluding constituents.
call mpas_dynamical_core % read_write_stream(pio_init_file, 'r', 'input-scalars')
end if
end if
else
! Run type is branch or restart run.
call dyn_debug_print(debugout_info, 'Initializing MPAS state variables by restarting from a file')
! Read variables that belong to the "input" and "restart" streams in MPAS.
call mpas_dynamical_core % read_write_stream(pio_init_file, 'r', 'input+restart')
end if
call clean_iodesc_list()
call mark_variables_as_initialized()
nullify(pio_init_file)
nullify(pio_topo_file)
! This is the time interval for dynamics-physics coupling in CAM-SIMA.
! Each time MPAS dynamical core is called to run, it will integrate with time for this specific interval,
! then yield control back to the caller.
coupling_time_interval = get_step_size()
call dyn_debug_print(debugout_info, 'Initializing MPAS dynamical core (Phase 4/4)')
! Finish MPAS dynamical core initialization. After this point, MPAS dynamical core is ready for time integration.
call mpas_dynamical_core % init_phase4(coupling_time_interval)
call dyn_debug_print(debugout_debug, subname // ' completed')
end subroutine dyn_init