Flat-impl x-face remap. East faces at i+1/2; u_face_x(1..nx+1) covers
west wall (I=1), interior (I=2..nx), east wall (I=nx+1).
conserve_ke (default .false.): rescale the baroclinic anomaly so column
anomaly KE matches pre-remap, barotropic mean preserved. See
rescale_anomaly_ke.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny | |||
| integer, | intent(in) | :: | nz | |||
| real(kind=wp), | intent(in) | :: | h_old(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | h_new(nx,ny,nz) | |||
| real(kind=wp), | intent(inout) | :: | u_face_x(nx+1,ny,nz) | |||
| integer, | intent(in) | :: | method | |||
| logical, | intent(in) | :: | conserve_ke | |||
| logical, | intent(in) | :: | zlevel_faces |
With the arithmetic mean a one-sided filler gives
|
||
| logical, | intent(in) | :: | bnd_extrap |
Linear-exact boundary-cell reconstruction in the column kernel. |
||
| logical, | intent(in) | :: | nonunif |
Non-uniform-grid PLM/PPM weights in the column kernel. |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | I | ||||
| real(kind=wp), | private | :: | h_new_face(NZ_STACK_MAX) | ||||
| real(kind=wp), | private | :: | h_old_face(NZ_STACK_MAX) | ||||
| integer, | private | :: | j | ||||
| integer, | private | :: | k | ||||
| real(kind=wp), | private | :: | u_new_col(NZ_STACK_MAX) | ||||
| real(kind=wp), | private | :: | u_old_col(NZ_STACK_MAX) |
pure subroutine remap_x_face_velocity(nx, ny, nz, h_old, h_new, u_face_x, method, & conserve_ke, zlevel_faces, bnd_extrap, nonunif) !! Flat-impl x-face remap. East faces at i+1/2; u_face_x(1..nx+1) covers !! west wall (I=1), interior (I=2..nx), east wall (I=nx+1). !! `conserve_ke` (default .false.): rescale the baroclinic anomaly so column !! anomaly KE matches pre-remap, barotropic mean preserved. See !! `rescale_anomaly_ke`. integer, intent(in) :: nx, ny, nz, method real(wp), intent(in) :: h_old(nx, ny, nz) real(wp), intent(in) :: h_new(nx, ny, nz) real(wp), intent(inout) :: u_face_x(nx + 1, ny, nz) logical, intent(in) :: conserve_ke logical, intent(in) :: zlevel_faces !! `&vcoord_nml zfixed_closed_faces` — z-level partial steps. !! Builds the face column as the OVERLAP of the two cell !! columns, `min(h_L, h_R)`, instead of their arithmetic mean, !! and then drops any layer at or below `H_VANISHED` from BOTH !! the source and the target column. A layer that is an inert !! filler on one side then has an exactly-zero target thickness, !! which is the one case every `remap_column` variant already !! short-circuits (`dz_new <= 0 ⇒ q_new = 0`), so no momentum is !! poured INTO a closed layer and none is carried OUT of one. !! !! With the arithmetic mean a one-sided filler gives !! `0.5·h_live > 0` — an ordinary half-thickness live layer as !! far as the column kernel is concerned — and the remap happily !! deposits momentum in a cell that geometrically holds no !! water. `min` is also the standard partial-cell face !! thickness, so this is not a special case bolted on: it is the !! face thickness a z-level model has all along. !! !! `.false.` (default) ⇒ every expression is textually the !! arithmetic-mean form ⇒ bit-identical. logical, intent(in) :: bnd_extrap !! Linear-exact boundary-cell reconstruction in the column kernel. logical, intent(in) :: nonunif !! Non-uniform-grid PLM/PPM weights in the column kernel. integer :: I, j, k real(wp) :: h_old_face(NZ_STACK_MAX), h_new_face(NZ_STACK_MAX) real(wp) :: u_old_col(NZ_STACK_MAX), u_new_col(NZ_STACK_MAX) do concurrent(j=1:ny, I=1:nx + 1) & local(k, h_old_face, h_new_face, u_old_col, u_new_col) do k = 1, nz if (I == 1) then h_old_face(k) = h_old(1, j, k) h_new_face(k) = h_new(1, j, k) else if (I == nx + 1) then h_old_face(k) = h_old(nx, j, k) h_new_face(k) = h_new(nx, j, k) else h_old_face(k) = 0.5_wp*(h_old(I - 1, j, k) + h_old(I, j, k)) h_new_face(k) = 0.5_wp*(h_new(I - 1, j, k) + h_new(I, j, k)) end if if (zlevel_faces) then if (I == 1) then h_old_face(k) = h_old(1, j, k) h_new_face(k) = h_new(1, j, k) else if (I == nx + 1) then h_old_face(k) = h_old(nx, j, k) h_new_face(k) = h_new(nx, j, k) else h_old_face(k) = min(h_old(I - 1, j, k), h_old(I, j, k)) h_new_face(k) = min(h_new(I - 1, j, k), h_new(I, j, k)) end if if (h_old_face(k) <= H_VANISHED .or. h_new_face(k) <= H_VANISHED) then h_old_face(k) = 0.0_wp h_new_face(k) = 0.0_wp end if end if u_old_col(k) = u_face_x(I, j, k) end do call remap_column(method, nz, & h_old_face(1:nz), h_new_face(1:nz), & u_old_col(1:nz), u_new_col(1:nz), bnd_extrap, nonunif) if (conserve_ke) then call rescale_anomaly_ke(nz, h_old_face, h_new_face, u_old_col, u_new_col) end if do k = 1, nz u_face_x(I, j, k) = u_new_col(k) end do end do end subroutine remap_x_face_velocity