9 use fckit_configuration_module,
only: fckit_configuration
10 use tools_const,
only : pi
11 use kinds,
only: kind_real
34 real(kind=kind_real),
private :: t_dz
35 real(kind=kind_real),
private :: t_efold
36 real(kind=kind_real),
private :: ssh_phi_ex
41 procedure :: setup => soca_bkgerrgodas_setup
44 procedure :: mult => soca_bkgerrgodas_mult
57 subroutine soca_bkgerrgodas_setup(self, f_conf, bkg, geom)
59 type(fckit_configuration),
intent(in) :: f_conf
61 type(
soca_geom),
target,
intent(in) :: geom
65 character(len=800) :: fname =
'soca_bkgerrgodas.nc'
68 call self%std_bkgerr%copy(bkg)
72 call self%bounds%read(f_conf)
75 call f_conf%get_or_die(
"t_dz", self%t_dz)
76 call f_conf%get_or_die(
"t_efold", self%t_efold)
77 call f_conf%get_or_die(
"ssh_phi_ex", self%ssh_phi_ex)
84 call self%std_bkgerr%zeros()
88 call soca_bkgerrgodas_tocn(self)
89 call soca_bkgerrgodas_socn(self)
90 call soca_bkgerrgodas_ssh(self)
94 do i=1,
size(self%std_bkgerr%fields)
95 field => self%std_bkgerr%fields(i)
96 select case(field%name)
97 case (
'sw',
'lw',
'lhf',
'shf',
'us',
'swh')
98 call bkg%get(field%name, field_bkg)
99 field%val = abs(field_bkg%val)
100 field%val = 0.1_kind_real * field%val
102 call bkg%get(field%name, field_bkg)
103 field%val = abs(field_bkg%val) * 0.2_kind_real
108 call self%bounds%apply(self%std_bkgerr)
111 call self%std_bkgerr%write_file(fname)
113 end subroutine soca_bkgerrgodas_setup
120 subroutine soca_bkgerrgodas_mult(self, dxa, dxm)
125 type(
soca_field),
pointer :: field_m, field_e, field_a
126 integer :: isc, iec, jsc, jec, i, j, n
129 call dxa%check_congruent(dxm)
130 call dxa%check_subset(self%std_bkgerr)
133 isc = self%geom%isc ; iec = self%geom%iec
134 jsc = self%geom%jsc ; jec = self%geom%jec
136 do n=1,
size(dxa%fields)
137 field_a => dxa%fields(n)
138 call self%std_bkgerr%get(field_a%name, field_e)
139 call dxm%get(field_a%name, field_m)
142 if (self%geom%mask2d(i,j).eq.1)
then
143 field_m%val(i,j,:) = field_e%val(i,j,:) * field_a%val(i,j,:)
148 end subroutine soca_bkgerrgodas_mult
155 subroutine soca_bkgerrgodas_tocn(self)
158 real(kind=kind_real),
allocatable :: sig1(:), sig2(:)
161 integer :: iter, niter = 1
163 type(
soca_field),
pointer :: tocn_b, tocn_e, hocn, layer_depth
166 domain%is = self%geom%isc ; domain%ie = self%geom%iec
167 domain%js = self%geom%jsc ; domain%je = self%geom%jec
170 domain%isl = self%geom%iscl ; domain%iel = self%geom%iecl
171 domain%jsl = self%geom%jscl ; domain%jel = self%geom%jecl
174 allocate(sig1(self%geom%nzo), sig2(self%geom%nzo))
178 call sst%init(domain)
179 call sst%bin(self%geom%lon, self%geom%lat)
181 call self%bkg%get(
"tocn", tocn_b)
182 call self%std_bkgerr%get(
"tocn", tocn_e)
183 call self%bkg%get(
"hocn", hocn)
184 call self%bkg%get(
"layer_depth",layer_depth)
187 do i = domain%is, domain%ie
188 do j = domain%js, domain%je
189 if (self%geom%mask2d(i,j).eq.1)
then
192 call soca_diff(sig1(:), tocn_b%val(i,j,:), hocn%val(i,j,:))
193 sig1(:) = self%t_dz * abs(sig1)
196 sig2(:) = self%bounds%t_min + (sst%bgerr_model(i,j)-self%bounds%t_min)*&
197 &exp((layer_depth%val(i,j,1)-layer_depth%val(i,j,:))&
201 do k = 1, self%geom%nzo
202 tocn_e%val(i,j,k) = min( max(sig1(k), sig2(k)), &
208 do k = 2, self%geom%nzo-1
209 tocn_e%val(i,j,k) = &
210 &( tocn_e%val(i,j,k-1)*hocn%val(i,j,k-1) +&
211 & tocn_e%val(i,j,k)*hocn%val(i,j,k) +&
212 & tocn_e%val(i,j,k+1)*hocn%val(i,j,k+1) )/&
213 & (sum(hocn%val(i,j,k-1:k+1)))
223 deallocate(sig1, sig2)
225 end subroutine soca_bkgerrgodas_tocn
232 subroutine soca_bkgerrgodas_ssh(self)
239 domain%is = self%geom%isc ; domain%ie = self%geom%iec
240 domain%js = self%geom%jsc ; domain%je = self%geom%jec
242 call self%std_bkgerr%get(
"ssh", ssh)
245 do i = domain%is, domain%ie
246 do j = domain%js, domain%je
247 if (self%geom%mask2d(i,j) .ne. 1) cycle
249 if ( abs(self%geom%lat(i,j)) >= self%ssh_phi_ex)
then
251 ssh%val(i,j,:) = self%bounds%ssh_max
254 ssh%val(i,j,:) = self%bounds%ssh_min + 0.5 * &
255 (self%bounds%ssh_max - self%bounds%ssh_min) * &
256 (1 - cos(pi * self%geom%lat(i,j) / self%ssh_phi_ex))
260 end subroutine soca_bkgerrgodas_ssh
267 subroutine soca_bkgerrgodas_socn(self)
271 type(
soca_field),
pointer :: field, mld, layer_depth
273 real(kind=kind_real) :: r
277 domain%is = self%geom%isc ; domain%ie = self%geom%iec
278 domain%js = self%geom%jsc ; domain%je = self%geom%jec
281 domain%isl = self%geom%iscl ; domain%iel = self%geom%iecl
282 domain%jsl = self%geom%jscl ; domain%jel = self%geom%jecl
287 call self%std_bkgerr%get(
"socn", field)
288 call self%bkg%get(
"mld", mld)
289 call self%bkg%get(
"layer_depth", layer_depth)
291 do i = domain%is, domain%ie
292 do j = domain%js, domain%je
293 if (self%geom%mask2d(i,j) /= 1) cycle
295 do k = 1, self%geom%nzo
296 if ( layer_depth%val(i,j,k) <= mld%val(i,j,1))
then
298 field%val(i,j,k) = self%bounds%s_max
301 r = 0.1 + 0.45 * (1-tanh( 2 * log( &
302 & layer_depth%val(i,j,k) / mld%val(i,j,1) )))
303 field%val(i,j,k) = max(self%bounds%s_min, r*self%bounds%s_max)
308 end subroutine soca_bkgerrgodas_socn
variable transform: background error
Handle fields for the model.
surface background error used by soca_bkgerrgodas_mod
various utility functions
subroutine, public soca_diff(dvdz, v, h)
Variable transform for background error (D), GODAS version.
bounds for background error
Holds all data and metadata related to a single field variable.
A collection of soca_field types representing a collective state or increment.
domain indices used by soca_omb_stats
interpolate surface background error file to grid