Initialise a vertical coordinate definition. Allocates + populates
dsig_target for the given type. Unknown types: error stop.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(vcoord_t), | intent(inout) | :: | self | |||
| integer, | intent(in) | :: | nz |
Number of vertical layers |
||
| integer, | intent(in) | :: | coord_type |
Coordinate type constant (VCOORD_SIGMA, etc.) |
||
| integer, | intent(in) | :: | remap_method |
Remapping method constant (REMAP_PLM, etc.) |
subroutine vcoord_init(self, nz, coord_type, remap_method) !! Initialise a vertical coordinate definition. Allocates + populates !! `dsig_target` for the given type. Unknown types: error stop. class(vcoord_t), intent(inout) :: self integer, intent(in) :: nz !! Number of vertical layers integer, intent(in) :: coord_type !! Coordinate type constant (VCOORD_SIGMA, etc.) integer, intent(in) :: remap_method !! Remapping method constant (REMAP_PLM, etc.) self%nz = nz self%coord_type = coord_type self%remap_method = remap_method ! (Re)allocate target distribution if (allocated(self%dsig_target)) deallocate (self%dsig_target) allocate (self%dsig_target(nz)) ! (Re)allocate z_ref if needed if (allocated(self%z_ref)) deallocate (self%z_ref) select case (coord_type) case (VCOORD_SIGMA) self%dsig_target = 1.0_wp/real(nz, wp) case (VCOORD_ZSIGMA) ! z-sigma hybrid: dsig_target is used for the sigma component, ! z_ref defines the reference z-level interfaces. self%dsig_target = 1.0_wp/real(nz, wp) allocate (self%z_ref(0:nz)) ! Reference z-levels: uniform spacing over the blending depth. ! Columns shallower than depth_transition use pure sigma. ! Columns deeper blend toward these fixed horizontal levels. block real(wp) :: h_ref integer :: kk h_ref = self%depth_transition + self%blend_width self%z_ref(0) = 0.0_wp do kk = 1, nz self%z_ref(kk) = real(kk, wp)*h_ref/real(nz, wp) end do end block case (VCOORD_ZSTAR_FULL) ! Per-column z_ref built later by zstar_full_build_column from local ! bathymetry; this uniform template keeps allocated(z_ref) checks valid. self%dsig_target = 1.0_wp/real(nz, wp) allocate (self%z_ref(0:nz)) block real(wp) :: h_ref integer :: kk h_ref = self%depth_transition + self%blend_width self%z_ref(0) = 0.0_wp do kk = 1, nz self%z_ref(kk) = real(kk, wp)*h_ref/real(nz, wp) end do end block case (VCOORD_ZSTAR_SIGMA) ! z*/sigma hybrid: same template as VCOORD_ZSTAR / VCOORD_ZSIGMA. ! The blend is applied per-column in `vcoord_target_dz_column` ! based on the local H vs depth_transition / blend_width. self%dsig_target = 1.0_wp/real(nz, wp) allocate (self%z_ref(0:nz)) block real(wp) :: h_ref integer :: kk h_ref = self%depth_transition + self%blend_width self%z_ref(0) = 0.0_wp do kk = 1, nz self%z_ref(kk) = real(kk, wp)*h_ref/real(nz, wp) end do end block case (VCOORD_ZSTAR) ! z*-lite: uniform reference spacing over depth_transition+blend_width; ! stretched per column by H/z_ref(nz) in vcoord_target_dz_column. self%dsig_target = 1.0_wp/real(nz, wp) allocate (self%z_ref(0:nz)) block real(wp) :: h_ref integer :: kk h_ref = self%depth_transition + self%blend_width self%z_ref(0) = 0.0_wp do kk = 1, nz self%z_ref(kk) = real(kk, wp)*h_ref/real(nz, wp) end do end block case default call logger%error("vcoord_init: unknown coord_type "//to_string(coord_type)// & ". Valid options are 'sigma', 'zsigma', and 'zstar'.") error stop "vcoord_init: unknown coord_type" end select ! Defence in depth. `validate_config` refuses this outright, so a ! namelist-driven run never reaches here; this catches the FFI / ! two-phase `rdb_create` paths that build a vcoord without going ! through config validation. Threshold is `nz + 1` — see ! `nz_stack_required`. if (.not. nz_stack_is_sufficient(nz)) then call logger%warning("nz = "//to_string(nz)//" needs NZ_STACK_MAX >= "// & to_string(nz_stack_required(nz))//" but this binary was "// & "compiled with NZ_STACK_MAX = "//to_string(NZ_STACK_MAX)// & ". Per-column stack kernels (BPG, remap) will overrun "// & "thread-local storage and silently produce wrong answers. "// & "Rebuild with -DRDB_NZ_STACK_MAX="// & to_string(nz_stack_required(nz))//" (or larger).") end if end subroutine vcoord_init