One tracer plane of the linear_z target. Explicit-shape
dummies, dims declared first (decl-order hook). ref_tracer
is passed WHOLE and indexed by the scalar it inside the kernel
— never sliced by the caller (the descriptor-walk trap the
dc-assumed-shape hook exists to catch), matching
relax_map_tracer_impl.
The do concurrent is over CELLS only; k runs as an ordinary
inner DO because the depth recurrence is sequential from the
surface (k = nz) down. k is therefore construct-LOCAL, as
are the two accumulators — without local(...) they would be a
race.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | ref_tracer(nx,ny,nz,n_tr) | |||
| real(kind=wp), | intent(in) | :: | h_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | z_top(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | idamp_h(nx,ny) | |||
| integer, | intent(in) | :: | it | |||
| integer, | intent(in) | :: | n_tr | |||
| real(kind=wp), | intent(in) | :: | v_ref | |||
| real(kind=wp), | intent(in) | :: | dv_dz | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny | |||
| integer, | intent(in) | :: | nz |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| real(kind=wp), | private | :: | above | ||||
| integer, | private | :: | i | ||||
| integer, | private | :: | j | ||||
| integer, | private | :: | k | ||||
| real(kind=wp), | private | :: | z_ctr |
pure subroutine refresh_linear_z_impl(ref_tracer, h_layer, z_top, idamp_h, & it, n_tr, v_ref, dv_dz, nx, ny, nz) !! One tracer plane of the `linear_z` target. Explicit-shape !! dummies, dims declared first (`decl-order` hook). `ref_tracer` !! is passed WHOLE and indexed by the scalar `it` inside the kernel !! — never sliced by the caller (the descriptor-walk trap the !! `dc-assumed-shape` hook exists to catch), matching !! `relax_map_tracer_impl`. !! !! The `do concurrent` is over CELLS only; `k` runs as an ordinary !! inner DO because the depth recurrence is sequential from the !! surface (`k = nz`) down. `k` is therefore construct-LOCAL, as !! are the two accumulators — without `local(...)` they would be a !! race. integer, intent(in) :: it, n_tr, nx, ny, nz real(wp), intent(inout) :: ref_tracer(nx, ny, nz, n_tr) real(wp), intent(in) :: h_layer(nx, ny, nz) real(wp), intent(in) :: z_top(nx, ny) real(wp), intent(in) :: idamp_h(nx, ny) real(wp), intent(in) :: v_ref, dv_dz integer :: i, j, k real(wp) :: above, z_ctr do concurrent(j=1:ny, i=1:nx) local(k, above, z_ctr) if (idamp_h(i, j) > 0.0_wp) then ! `above` holds the depth of the TOP of layer k; bottom-up ! storage means the sweep runs k = nz (surface) down to 1. above = z_top(i, j) do k = nz, 1, -1 z_ctr = above + 0.5_wp*h_layer(i, j, k) above = above + h_layer(i, j, k) ref_tracer(i, j, k, it) = v_ref - dv_dz*z_ctr end do end if end do end subroutine refresh_linear_z_impl