remap_x_face_velocity Subroutine

private 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.

Arguments

Type IntentOptional 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

&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.


Calls

proc~~remap_x_face_velocity~~CallsGraph proc~remap_x_face_velocity remap_x_face_velocity local local proc~remap_x_face_velocity->local proc~remap_column remap_column proc~remap_x_face_velocity->proc~remap_column proc~rescale_anomaly_ke rescale_anomaly_ke proc~remap_x_face_velocity->proc~rescale_anomaly_ke proc~remap_column_pcm remap_column_pcm proc~remap_column->proc~remap_column_pcm proc~remap_column_plm remap_column_plm proc~remap_column->proc~remap_column_plm proc~remap_column_ppm remap_column_ppm proc~remap_column->proc~remap_column_ppm proc~remap_column_ppm_h4 remap_column_ppm_h4 proc~remap_column->proc~remap_column_ppm_h4 proc~remap_column_pqm remap_column_pqm proc~remap_column->proc~remap_column_pqm proc~boundary_half_jump boundary_half_jump proc~remap_column_plm->proc~boundary_half_jump proc~plm_slope_nonuniform plm_slope_nonuniform proc~remap_column_plm->proc~plm_slope_nonuniform proc~remap_column_ppm->proc~remap_column_plm proc~remap_column_ppm->proc~boundary_half_jump proc~ppm_edge_nonuniform ppm_edge_nonuniform proc~remap_column_ppm->proc~ppm_edge_nonuniform proc~ppm_edge_two_cell ppm_edge_two_cell proc~remap_column_ppm->proc~ppm_edge_two_cell proc~ppm_jump_nonuniform ppm_jump_nonuniform proc~remap_column_ppm->proc~ppm_jump_nonuniform proc~remap_column_ppm_h4->proc~remap_column_plm proc~remap_column_ppm_h4->proc~boundary_half_jump proc~remap_column_pqm->proc~remap_column_ppm proc~remap_column_pqm->proc~boundary_half_jump proc~pqm_end_value_h4 pqm_end_value_h4 proc~remap_column_pqm->proc~pqm_end_value_h4 proc~pqm_solve_diag_dominant pqm_solve_diag_dominant proc~remap_column_pqm->proc~pqm_solve_diag_dominant

Called by

proc~~remap_x_face_velocity~~CalledByGraph proc~remap_x_face_velocity remap_x_face_velocity proc~ocean_apply_ale_remap_faces ocean_apply_ale_remap_faces proc~ocean_apply_ale_remap_faces->proc~remap_x_face_velocity proc~ocean_apply_ale_remap_step ocean_apply_ale_remap_step proc~ocean_apply_ale_remap_step->proc~remap_x_face_velocity proc~ocean_dyn_step_split ocean_dyn_step_split proc~ocean_dyn_step_split->proc~ocean_apply_ale_remap_step proc~engine_step engine_step proc~engine_step->proc~ocean_dyn_step_split proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_step proc~rdb_ocean_step rdb_ocean_step proc~rdb_ocean_step->proc~engine_step proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean

Variables

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)

Source Code

   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