subroutine ocean_restart_check_decomp(filename, decomp, ierr, meta)
!! Validate schema + decomposition (+ optional grid/vcoord/tracer)
!! metadata in `filename` against the live `decomp`/`meta`.
!! `ierr` = 0 on match; 1 = schema, 2 = decomposition,
!! 3 = grid/vcoord/tracer mismatch.
character(len=*), intent(in) :: filename
type(decomp_t), intent(in) :: decomp
integer, intent(out) :: ierr
type(ocean_restart_metadata_t), intent(in), optional :: meta
integer :: ncid, file_schema, fpx, fpy, fnxg, fnyg, fnxl, fnyl
integer :: fis, fjs
integer :: fnz, fng, fvc, fntr, fidxs, fidxt
character(len=:), allocatable :: msg
ierr = 0
call nc_open_read(filename, ncid)
call nc_get_att_int(ncid, "schema_version", file_schema)
if (file_schema /= RESTART_SCHEMA_VERSION) then
msg = "Restart schema mismatch: file v"//to_string(file_schema)// &
" but build expects v"//to_string(RESTART_SCHEMA_VERSION)
call error_ring_push(msg)
call logger%error(msg)
ierr = 1
call nc_close(ncid)
return
end if
call nc_get_att_int(ncid, "px", fpx)
call nc_get_att_int(ncid, "py", fpy)
call nc_get_att_int(ncid, "i_start", fis)
call nc_get_att_int(ncid, "j_start", fjs)
call nc_get_att_int(ncid, "nx_global", fnxg)
call nc_get_att_int(ncid, "ny_global", fnyg)
call nc_get_att_int(ncid, "nx_local", fnxl)
call nc_get_att_int(ncid, "ny_local", fnyl)
if (fpx /= decomp%px .or. fpy /= decomp%py .or. &
fis /= decomp%i_start .or. fjs /= decomp%j_start .or. &
fnxg /= decomp%nx_global .or. fnyg /= decomp%ny_global .or. &
fnxl /= decomp%nx_local .or. fnyl /= decomp%ny_local) then
msg = "Restart decomposition mismatch: file px="// &
to_string(fpx)//" py="//to_string(fpy)// &
" i_start="//to_string(fis)//" j_start="//to_string(fjs)// &
" nx_local="//to_string(fnxl)//" ny_local="//to_string(fnyl)// &
" but run has px="//to_string(decomp%px)// &
" py="//to_string(decomp%py)// &
" i_start="//to_string(decomp%i_start)// &
" j_start="//to_string(decomp%j_start)// &
" nx_local="//to_string(decomp%nx_local)// &
" ny_local="//to_string(decomp%ny_local)// &
". File: "//trim(filename)// &
". Same-decomp resume only; use the offline "// &
"redistribute tool to change rank count."
call error_ring_push(msg)
call logger%error(msg)
ierr = 2
call nc_close(ncid)
return
end if
if (present(meta)) then
call nc_get_att_int(ncid, "nz_ml", fnz)
call nc_get_att_int(ncid, "nghost", fng)
call nc_get_att_int(ncid, "vcoord_type", fvc)
call nc_get_att_int(ncid, "n_tracers", fntr)
call nc_get_att_int(ncid, "idx_salinity", fidxs)
call nc_get_att_int(ncid, "idx_temperature", fidxt)
if (fnz /= meta%nz_ml .or. fng /= meta%nghost .or. &
fvc /= meta%vcoord_type .or. fntr /= meta%n_tracers .or. &
fidxs /= meta%idx_salinity .or. fidxt /= meta%idx_temperature) then
msg = "Restart grid/vcoord/tracer mismatch: file nz_ml="// &
to_string(fnz)//" nghost="//to_string(fng)// &
" vcoord_type="//to_string(fvc)// &
" n_tracers="//to_string(fntr)// &
" idx_S="//to_string(fidxs)//" idx_T="//to_string(fidxt)// &
" but run has nz_ml="//to_string(meta%nz_ml)// &
" nghost="//to_string(meta%nghost)// &
" vcoord_type="//to_string(meta%vcoord_type)// &
" ("//trim(meta%vcoord_name)//")"// &
" n_tracers="//to_string(meta%n_tracers)// &
" idx_S="//to_string(meta%idx_salinity)// &
" idx_T="//to_string(meta%idx_temperature)// &
". File: "//trim(filename)
call error_ring_push(msg)
call logger%error(msg)
ierr = 3
end if
end if
call nc_close(ncid)
end subroutine ocean_restart_check_decomp