subroutine ocean_restart_read_local(filename, reg, decomp, meta, t, step, &
outer_step_count, ierr)
!! Read a per-rank ocean restart into the registry's host arrays
!! (FULL local extent) + return the scalar metadata. Validates
!! decomp + grid/vcoord/tracer metadata first and error-stops on
!! mismatch unless `ierr` is present. A REQUIRED field absent from
!! the file is FATAL; only `optional` entries warn-and-seed. Must
!! run BEFORE `ocean_state_enter_data` so the H->D copy carries the
!! restored values up.
character(len=*), intent(in) :: filename
type(restart_registry_t), intent(inout) :: reg
type(decomp_t), intent(in) :: decomp
type(ocean_restart_metadata_t), intent(in) :: meta
real(wp), intent(out) :: t
integer, intent(out) :: step
integer, intent(out) :: outer_step_count
integer, intent(out), optional :: ierr
integer :: ncid, e, varid, status, check_err
character(len=:), allocatable :: msg
t = 0.0_wp
step = 0
outer_step_count = 0
if (present(ierr)) ierr = 0
call logger%info("Reading ocean restart file: "//trim(filename))
call ocean_restart_check_decomp(filename, decomp, check_err, meta=meta)
if (check_err /= 0) then
if (present(ierr)) then
ierr = check_err
return
end if
error stop "ocean_restart_read_local: restart metadata mismatch (see log)"
end if
call nc_open_read(filename, ncid)
do e = 1, reg%n
associate (en => reg%entries(e))
status = nf90_inq_varid(ncid, trim(en%tag), varid)
if (status /= nf90_noerr) then
if (en%optional) then
call logger%warning("Restart file lacks optional field "// &
trim(en%tag)//"; leaving it at its seeded value")
cycle
end if
msg = "Restart file "//trim(filename)// &
" is missing REQUIRED field "//trim(en%tag)// &
"; refusing to cold-start half the state."
call error_ring_push(msg)
call logger%error(msg)
call nc_close(ncid)
error stop "ocean_restart_read_local: missing required field"
end if
en%found = .true.
select case (en%rank)
case (0)
call nc_check(nf90_get_var(ncid, varid, en%p0), &
"reading restart scalar "//trim(en%tag))
case (2)
call nc_check(nf90_get_var(ncid, varid, &
en%p2(en%ng + 1:en%ng + en%nx_phys, en%ng + 1:en%ng + en%ny_phys)), &
"reading restart "//trim(en%tag))
case default
call nc_check(nf90_get_var(ncid, varid, &
en%p3(en%ng + 1:en%ng + en%nx_phys, en%ng + 1:en%ng + en%ny_phys, 1:en%nk)), &
"reading restart "//trim(en%tag))
end select
end associate
end do
call nc_get_varid(ncid, "time", varid)
call nc_check(nf90_get_var(ncid, varid, t), "reading restart time")
call nc_get_varid(ncid, "n_steps", varid)
call nc_check(nf90_get_var(ncid, varid, step), "reading restart n_steps")
call nc_get_varid(ncid, "outer_step_count", varid)
call nc_check(nf90_get_var(ncid, varid, outer_step_count), &
"reading restart outer_step_count")
call nc_close(ncid)
call logger%info("Ocean restart loaded: t = "//to_string(t)//" s, step = "// &
to_string(step))
end subroutine ocean_restart_read_local