9 use fckit_configuration_module,
only: fckit_configuration
10 use kinds,
only: kind_real
11 use tools_func,
only: fit_func
12 use type_mpl,
only: mpl_type
13 use type_probe,
only: probe
28 real(kind=kind_real) :: lz_min
29 real(kind=kind_real) :: lz_mld
30 real(kind=kind_real) :: lz_mld_max
31 real(kind=kind_real) :: scale_layer_thick
35 integer :: isc, iec, jsc, jec
39 procedure :: setup => soca_conv_setup
42 procedure :: mult => soca_conv_mult
45 procedure :: mult_ad => soca_conv_mult_ad
59 subroutine soca_conv_setup (self, bkg, geom, f_conf)
62 type(fckit_configuration),
intent(in) :: f_conf
63 type(
soca_geom),
target,
intent(in) :: geom
66 call f_conf%get_or_die(
"Lz_min", self%lz_min )
67 call f_conf%get_or_die(
"Lz_mld", self%lz_mld )
68 if ( self%lz_mld /= 0) &
69 call f_conf%get_or_die(
"Lz_mld_max", self%lz_mld_max )
70 call f_conf%get_or_die(
"scale_layer_thick", self%scale_layer_thick )
77 self%isc=geom%isc; self%iec=geom%iec
78 self%jsc=geom%jsc; self%jec=geom%jec
80 end subroutine soca_conv_setup
87 subroutine soca_calc_lz(self, i, j, lz)
89 integer,
intent(in) :: i
90 integer,
intent(in) :: j
91 real(kind=kind_real),
intent(inout) :: lz(:)
93 real(kind=kind_real) :: mld, z
95 type(
soca_field),
pointer :: hocn, mld_fld, layer_depth
98 call self%bkg%get(
"hocn", hocn)
99 call self%bkg%get(
"mld", mld_fld)
100 call self%bkg%get(
"layer_depth", layer_depth)
102 lz = max(lz, self%scale_layer_thick*abs(hocn%val(i,j,:)))
106 if ( self%lz_mld /= 0 )
then
107 mld = mld_fld%val(i,j, 1)
108 mld = min( mld, self%lz_mld_max)
109 mld = max( mld, self%lz_min)
111 z = layer_depth%val(i,j, k)
113 lz(k) = max(lz(k), lz(k) + (mld - lz(k)) * (1.0 - z/mld))
117 end subroutine soca_calc_lz
124 subroutine soca_conv_mult (self, convdx, dx)
129 real(kind=kind_real),
allocatable :: z(:), lz(:)
130 real(kind=kind_real) :: dist2, coef
131 integer :: nl, j, k, id, jd, n
132 type(mpl_type) :: mpl
134 type(
soca_field),
pointer :: field_dx, field_convdx, layer_depth
136 call probe%get_instance(
'soca')
138 call self%bkg%get(
"layer_depth", layer_depth)
141 allocate(z(nl), lz(nl))
143 do n=1,
size(dx%fields)
145 select case(dx%fields(n)%name)
146 case (
"tocn",
"socn")
147 call dx%get(dx%fields(n)%name, field_dx)
148 call convdx%get(dx%fields(n)%name, field_convdx)
149 do id = self%isc, self%iec
150 do jd = self%jsc, self%jec
152 if (self%geom%mask2d(id,jd) /= 1) cycle
155 call soca_calc_lz(self, id, jd, lz)
158 z(:) = layer_depth%val(id,jd,:)
160 field_convdx%val(id,jd,j) = 0.0d0
162 dist2 = abs(z(j)-z(k))
163 coef = fit_func(mpl, dist2/lz(k))
164 field_convdx%val(id,jd,j) = field_convdx%val(id,jd,j) &
165 &+ field_dx%val(id,jd,k)*coef
173 end subroutine soca_conv_mult
180 subroutine soca_conv_mult_ad (self, convdx, dx)
185 real(kind=kind_real),
allocatable :: z(:), lz(:)
186 real(kind=kind_real) :: dist2, coef
187 integer :: nl, j, k, id, jd, n
188 type(mpl_type) :: mpl
189 type(
soca_field),
pointer :: field_dx, field_convdx, layer_depth
191 call probe%get_instance(
'soca')
193 call self%bkg%get(
"layer_depth", layer_depth)
195 allocate(z(nl), lz(nl))
197 do n=1,
size(dx%fields)
198 select case(dx%fields(n)%name)
200 case (
"tocn",
"socn")
201 call dx%get(dx%fields(n)%name, field_dx)
202 call convdx%get(dx%fields(n)%name, field_convdx)
203 do id = self%isc, self%iec
204 do jd = self%jsc, self%jec
206 if (self%geom%mask2d(id,jd) /= 1) cycle
209 call soca_calc_lz(self, id, jd, lz)
212 z(:) = layer_depth%val(id,jd,:)
213 field_dx%val(id,jd,:) = 0.0d0
216 dist2 = abs(z(j)-z(k))
217 coef = fit_func(mpl, dist2/lz(k))
218 field_dx%val(id,jd,k) = field_dx%val(id,jd,k) + coef*field_convdx%val(id,jd,j)
227 end subroutine soca_conv_mult_ad
Handle fields for the model.
variable transform: vertical convolution
Holds all data and metadata related to a single field variable.
Variable transform for vertical convolution.