9 use atlas_module,
only: atlas_fieldset, atlas_field, atlas_real
10 use fckit_configuration_module,
only: fckit_configuration
11 use kinds,
only: kind_real
12 use oops_variables_mod,
only: oops_variables
13 use random_mod,
only: normal_distribution
37 procedure :: getpoint => soca_increment_getpoint
40 procedure :: setpoint => soca_increment_setpoint
49 procedure :: set_atlas => soca_increment_set_atlas
52 procedure :: to_atlas => soca_increment_to_atlas
55 procedure :: from_atlas => soca_increment_from_atlas
64 procedure :: dirac => soca_increment_dirac
67 procedure :: random => soca_increment_random
70 procedure :: schur => soca_increment_schur
76 procedure :: convert => soca_increment_change_resol
92 subroutine soca_increment_random(self)
95 integer,
parameter :: rseed = 1
103 do i = 1,
size(self%fields)
104 field => self%fields(i)
107 if (field%name ==
'hocn') cycle
108 call normal_distribution(field%val, 0.0_kind_real, 1.0_kind_real, rseed)
112 do i=1,
size(self%fields)
113 field => self%fields(i)
114 if (.not.
associated(field%mask) ) cycle
116 field%val(:,:,jz) = field%val(:,:,jz) * field%mask(:,:)
121 call self%update_halos()
122 end subroutine soca_increment_random
129 subroutine soca_increment_schur(self,rhs)
135 call self%check_congruent(rhs)
138 do i=1,
size(self%fields)
139 self%fields(i)%val = self%fields(i)%val * rhs%fields(i)%val
141 end subroutine soca_increment_schur
149 subroutine soca_increment_getpoint(self, geoiter, values)
153 real(kind=kind_real),
intent(inout) :: values(:)
155 integer :: ff, ii, nz
161 do ff = 1,
size(self%fields)
162 field => self%fields(ff)
163 select case(field%name)
164 case(
"tocn",
"socn",
"ssh",
"uocn",
"vocn",
"hocn",
"cicen",
"hicen",
"hsnon",
"chl",
"biop")
166 values(ii+1:ii+nz) = field%val(geoiter%iind, geoiter%jind,:)
170 end subroutine soca_increment_getpoint
178 subroutine soca_increment_setpoint(self, geoiter, values)
182 real(kind=kind_real),
intent( in) :: values(:)
184 integer :: ff, ii, nz
190 do ff = 1,
size(self%fields)
191 field => self%fields(ff)
192 select case(field%name)
193 case(
"tocn",
"socn",
"ssh",
"uocn",
"vocn",
"hocn",
"cicen",
"hicen",
"hsnon",
"chl",
"biop")
195 field%val(geoiter%iind, geoiter%jind,:) = values(ii+1:ii+nz)
199 end subroutine soca_increment_setpoint
208 subroutine soca_increment_dirac(self, f_conf)
210 type(fckit_configuration),
value,
intent(in):: f_conf
212 integer :: isc, iec, jsc, jec
213 integer :: ndir,n, jz
214 integer,
allocatable :: ixdir(:),iydir(:),izdir(:),ifdir(:)
219 ndir = f_conf%get_size(
"ixdir")
220 if (( f_conf%get_size(
"iydir") /= ndir ) .or. &
221 ( f_conf%get_size(
"izdir") /= ndir ) .or. &
222 ( f_conf%get_size(
"ifdir") /= ndir )) &
223 call abor1_ftn(
'soca_fields_dirac: inconsistent sizes for ixdir, iydir, izdir, and ifdir')
226 allocate(ixdir(ndir))
227 allocate(iydir(ndir))
228 allocate(izdir(ndir))
229 allocate(ifdir(ndir))
232 call f_conf%get_or_die(
"ixdir", ixdir)
233 call f_conf%get_or_die(
"iydir", iydir)
234 call f_conf%get_or_die(
"izdir", izdir)
235 call f_conf%get_or_die(
"ifdir", ifdir)
238 isc = self%geom%isc ; iec = self%geom%iec
239 jsc = self%geom%jsc ; jec = self%geom%jec
245 if (ixdir(n) > iec .or. ixdir(n) < isc) cycle
246 if (iydir(n) > jec .or. iydir(n) < jsc) cycle
249 select case(ifdir(n))
251 call self%get(
"tocn", field)
253 call self%get(
"socn", field)
255 call self%get(
"ssh", field)
257 call self%get(
"cicen", field)
259 call self%get(
"hicen", field)
261 call self%get(
"chl", field)
263 call self%get(
"biop", field)
267 if (
associated(field))
then
269 if (field%nz > 1) jz = izdir(n)
270 field%val(ixdir(n),iydir(n),izdir(n)) = 1.0
273 end subroutine soca_increment_dirac
282 subroutine soca_increment_set_atlas(self, geom, vars, afieldset)
285 type(oops_variables),
intent(in) :: vars
286 type(atlas_fieldset),
intent(inout) :: afieldset
288 integer :: jvar, i, jz, nz
290 character(len=1024) :: fieldname
292 type(atlas_field) :: afield
294 do jvar = 1,vars%nvars()
296 do i=1,
size(self%fields)
297 field => self%fields(i)
298 if (trim(vars%variable(jvar))==trim(field%name))
then
299 if (.not.afieldset%has_field(vars%variable(jvar)))
then
305 afield = geom%afunctionspace%create_field(name=vars%variable(jvar),kind=atlas_real(kind_real),levels=nz)
308 call afieldset%add(afield)
318 if (.not.var_found)
call abor1_ftn(
'variable '//trim(vars%variable(jvar))//
' not found in increment')
321 end subroutine soca_increment_set_atlas
328 subroutine soca_increment_to_atlas(self, geom, vars, afieldset)
331 type(oops_variables),
intent(in) :: vars
332 type(atlas_fieldset),
intent(inout) :: afieldset
334 integer :: jvar, i, jz, nz
335 real(kind=kind_real),
pointer :: real_ptr_1(:), real_ptr_2(:,:)
337 character(len=1024) :: fieldname
339 type(atlas_field) :: afield
341 do jvar = 1,vars%nvars()
343 do i=1,
size(self%fields)
344 field => self%fields(i)
345 if (trim(vars%variable(jvar))==trim(field%name))
then
350 if (afieldset%has_field(vars%variable(jvar)))
then
352 afield = afieldset%field(vars%variable(jvar))
355 afield = geom%afunctionspace%create_field(name=vars%variable(jvar),kind=atlas_real(kind_real),levels=nz)
358 call afieldset%add(afield)
363 call afield%data(real_ptr_1)
364 real_ptr_1 = reshape(field%val(geom%isc:geom%iec,geom%jsc:geom%jec,1), &
365 & (/(geom%iec-geom%isc+1)*(geom%jec-geom%jsc+1)/))
367 call afield%data(real_ptr_2)
369 real_ptr_2(jz,:) = reshape(field%val(geom%isc:geom%iec,geom%jsc:geom%jec,jz), &
370 & (/(geom%iec-geom%isc+1)*(geom%jec-geom%jsc+1)/))
382 if (.not.var_found)
call abor1_ftn(
'variable '//trim(vars%variable(jvar))//
' not found in increment')
385 end subroutine soca_increment_to_atlas
392 subroutine soca_increment_from_atlas(self, geom, vars, afieldset)
395 type(oops_variables),
intent(in) :: vars
396 type(atlas_fieldset),
intent(in) :: afieldset
398 integer :: jvar, i, jz, nz
399 real(kind=kind_real),
pointer :: real_ptr_1(:), real_ptr_2(:,:)
401 character(len=1024) :: fieldname
403 type(atlas_field) :: afield
408 do jvar = 1,vars%nvars()
410 do i=1,
size(self%fields)
411 field => self%fields(i)
412 if (trim(vars%variable(jvar))==trim(field%name))
then
418 afield = afieldset%field(vars%variable(jvar))
422 call afield%data(real_ptr_1)
423 field%val(geom%isc:geom%iec,geom%jsc:geom%jec,1) = reshape(real_ptr_1, &
424 & (/geom%iec-geom%isc+1,geom%jec-geom%jsc+1/))
426 call afield%data(real_ptr_2)
428 field%val(geom%isc:geom%iec,geom%jsc:geom%jec,jz) = reshape(real_ptr_2(jz,:), &
429 & (/geom%iec-geom%isc+1,geom%jec-geom%jsc+1/))
441 if (.not.var_found)
call abor1_ftn(
'variable '//trim(vars%variable(jvar))//
' not found in increment')
444 end subroutine soca_increment_from_atlas
451 subroutine soca_increment_change_resol(self, rhs)
457 type(
soca_field),
pointer :: field1, field2, hocn1, hocn2
459 call rhs%get(
"hocn", hocn1)
460 call self%get(
"hocn", hocn2)
462 call convert_state%setup(rhs%geom, self%geom, hocn1, hocn2)
463 do n = 1,
size(rhs%fields)
464 if (trim(rhs%fields(n)%name)==
"hocn") cycle
465 field1 => rhs%fields(n)
466 call self%get(trim(field1%name),field2)
467 call convert_state%change_resol2d(field1, field2, rhs%geom, self%geom)
469 call convert_state%clean()
470 end subroutine soca_increment_change_resol
Handle fields for the model.
resolution change for fields
Holds all data and metadata related to a single field variable.
A collection of soca_field types representing a collective state or increment.