8 use atlas_module,
only: atlas_field, atlas_fieldset, atlas_real
10 use fckit_configuration_module,
only: fckit_configuration
12 use oops_variables_mod,
only: oops_variables
28 use mpp_domains_mod,
only: mpp_global_sum, bitwise_efp_sum, center, east, north, center
54 #define LISTED_TYPE fv3jedi_increment
57 #include "oops/util/linkedList_i.f"
69 #include "oops/util/linkedList_c.f"
81 self%fields(var)%array = 1.0_kind_real
94 integer,
parameter :: rseed = 7
97 call normal_distribution(self%fields(var)%array, 0.0_kind_real, 1.0_kind_real, rseed)
109 type(oops_variables),
intent(in) :: vars
110 type(atlas_fieldset),
intent(inout) :: afieldset
114 type(atlas_field) :: afield
116 do jvar = 1,vars%nvars()
119 if (trim(vars%variable(jvar))==trim(self%fields(jf)%short_name))
then
120 if (.not.afieldset%has_field(vars%variable(jvar)))
then
122 afield = geom%afunctionspace%create_field(name=vars%variable(jvar),&
123 kind=atlas_real(
kind_real),levels=self%fields(jvar)%npz)
126 call afieldset%add(afield)
137 if (.not.var_found)
call abor1_ftn(
'Field '//trim(vars%variable(jvar))//
' not found in increment')
149 type(oops_variables),
intent(in) :: vars
150 type(atlas_fieldset),
intent(inout) :: afieldset
152 integer :: jvar, jf, jl
153 real(kind=
kind_real),
pointer :: real_ptr_2(:,:)
155 type(atlas_field) :: afield
157 do jvar = 1,vars%nvars()
160 if (trim(vars%variable(jvar))==trim(self%fields(jf)%short_name))
then
161 if (afieldset%has_field(vars%variable(jvar)))
then
163 afield = afieldset%field(vars%variable(jvar))
166 afield = geom%afunctionspace%create_field(name=vars%variable(jvar),&
167 kind=atlas_real(
kind_real),levels=self%fields(jvar)%npz)
170 call afieldset%add(afield)
174 call afield%data(real_ptr_2)
175 do jl=1,self%fields(jf)%npz
176 real_ptr_2(jl,:) = pack(self%fields(jf)%array(geom%isc:geom%iec,geom%jsc:geom%jec,jl),.true.)
187 if (.not.var_found)
call abor1_ftn(
'Field '//trim(vars%variable(jvar))//
' not found in increment')
199 type(oops_variables),
intent(in) :: vars
200 type(atlas_fieldset),
intent(in) :: afieldset
202 integer :: jvar, jf, jl
203 real(kind=
kind_real),
pointer :: real_ptr_2(:,:)
204 logical :: umask(geom%isc:geom%iec,geom%jsc:geom%jec),var_found
205 type(atlas_field) :: afield
210 do jvar = 1,vars%nvars()
213 if (trim(vars%variable(jvar))==trim(self%fields(jf)%short_name))
then
215 afield = afieldset%field(vars%variable(jvar))
218 call afield%data(real_ptr_2)
219 do jl=1,self%fields(jf)%npz
220 self%fields(jf)%array(geom%isc:geom%iec,geom%jsc:geom%jec,jl) = unpack(real_ptr_2(jl,:), &
221 & umask,self%fields(jf)%array(geom%isc:geom%iec,geom%jsc:geom%jec,jl))
232 if (.not.var_found)
call abor1_ftn(
'Field '//trim(vars%variable(jvar))//
' not found in increment')
247 call checksame(self%fields,rhs%fields,
"fv3jedi_increment_mod.self_add")
250 self%fields(var)%array = self%fields(var)%array + rhs%fields(var)%array
265 call checksame(self%fields,rhs%fields,
"fv3jedi_increment_mod.self_schur")
268 self%fields(var)%array = self%fields(var)%array * rhs%fields(var)%array
283 call checksame(self%fields,rhs%fields,
"fv3jedi_increment_mod.self_sub")
286 self%fields(var)%array = self%fields(var)%array - rhs%fields(var)%array
302 self%fields(var)%array = zz * self%fields(var)%array
314 real(kind=
kind_real),
intent(inout) :: zprod
320 call checksame(self%fields,other%fields,
"fv3jedi_increment_mod.dot_prod")
324 do k = 1,self%fields(var)%npz
325 do j = self%jsc,self%jec
326 do i = self%isc,self%iec
327 zp = zp + self%fields(var)%array(i,j,k) * other%fields(var)%array(i,j,k)
334 call self%f_comm%allreduce(zp,zprod,fckit_mpi_sum())
351 integer :: var, isc, iec, jsc, jec, npz
353 real(kind=
kind_real),
allocatable :: x1_ua(:,:,:), x1_va(:,:,:)
354 real(kind=
kind_real),
allocatable :: x2_ua(:,:,:), x2_va(:,:,:)
355 real(kind=
kind_real),
pointer :: x1_ud(:,:,:), x1_vd(:,:,:)
356 real(kind=
kind_real),
pointer :: x2_ud(:,:,:), x2_vd(:,:,:)
357 real(kind=
kind_real),
pointer :: x1_delp(:,:,:)
358 real(kind=
kind_real),
pointer :: x2_delp(:,:,:)
359 real(kind=
kind_real),
allocatable :: x1_ps(:,:,:), x2_ps(:,:,:)
362 call checksame(x1_fields, x2_fields,
"fv3jedi_increment_mod.diff_incr x1 vs x2")
373 if (self%has_field(
'ua'))
then
374 allocate(x1_ua(isc:iec,jsc:jec,1:npz))
375 allocate(x1_va(isc:iec,jsc:jec,1:npz))
376 allocate(x2_ua(isc:iec,jsc:jec,1:npz))
377 allocate(x2_va(isc:iec,jsc:jec,1:npz))
388 call d2a(geom, x1_ud, x1_vd, x1_ua, x1_va)
389 call d2a(geom, x2_ud, x2_vd, x2_ua, x2_va)
391 call abor1_ftn(
"fv3jedi_increment_mod.diff_incr: no way to determine A grid winds")
396 if (self%has_field(
'ps'))
then
398 allocate(x1_ps(isc:iec,jsc:jec,1))
399 allocate(x2_ps(isc:iec,jsc:jec,1))
402 call get_field(x1_fields,
'delp', x1_delp)
403 x1_ps(:,:,1) = sum(x1_delp,3)
407 call abor1_ftn(
"fv3jedi_increment_mod.diff_incr: problem getting ps from state x1")
411 call get_field(x2_fields,
'delp', x2_delp)
412 x2_ps(:,:,1) = sum(x2_delp,3)
416 call abor1_ftn(
"fv3jedi_increment_mod.diff_incr: problem getting ps from state x2")
424 if (self%fields(var)%fv3jedi_name ==
'ua')
then
426 self%fields(var)%array = x1_ua - x2_ua
428 elseif (self%fields(var)%fv3jedi_name ==
'va')
then
430 self%fields(var)%array = x1_va - x2_va
433 elseif (self%fields(var)%fv3jedi_name ==
'ps')
then
435 self%fields(var)%array = x1_ps - x2_ps
440 call get_field(x1_fields, self%fields(var)%fv3jedi_name, x1p)
441 call get_field(x2_fields, self%fields(var)%fv3jedi_name, x2p)
444 self%fields(var)%array = x1p%array - x2p%array
453 if (
allocated(x1_ua))
deallocate(x1_ua)
454 if (
allocated(x1_va))
deallocate(x1_va)
455 if (
allocated(x2_ua))
deallocate(x2_ua)
456 if (
allocated(x2_va))
deallocate(x2_va)
457 if (
allocated(x1_ps))
deallocate(x1_ps)
458 if (
allocated(x2_ps))
deallocate(x2_ps)
464 subroutine dirac(self, c_conf, geom)
468 type(c_ptr),
intent(in) :: c_conf
471 integer :: ndir,idir,var
473 integer,
allocatable :: ixdir(:),iydir(:),ildir(:),itdir(:)
474 character(len=32),
allocatable :: ifdir(:)
477 type(fckit_configuration) :: f_conf
478 character(len=:),
allocatable :: str
479 character(len=:),
allocatable :: str_array(:)
481 f_conf = fckit_configuration(c_conf)
484 call f_conf%get_or_die(
"ndir",ndir)
486 allocate(ixdir(ndir))
487 allocate(iydir(ndir))
488 allocate(ildir(ndir))
489 allocate(itdir(ndir))
491 if ((f_conf%get_size(
"ixdir")/=ndir) .or. &
492 (f_conf%get_size(
"iydir")/=ndir) .or. &
493 (f_conf%get_size(
"ildir")/=ndir) .or. &
494 (f_conf%get_size(
"itdir")/=ndir) .or. &
495 (f_conf%get_size(
"ifdir")/=ndir)) &
496 call abor1_ftn(
"fv3jedi_increment_mod.diracL=: dimension inconsistency")
498 call f_conf%get_or_die(
"ixdir",ixdir)
499 call f_conf%get_or_die(
"iydir",iydir)
500 call f_conf%get_or_die(
"ildir",ildir)
501 call f_conf%get_or_die(
"itdir",itdir)
503 call f_conf%get_or_die(
"ifdir",str_array)
505 deallocate(str_array)
516 if (geom%ntile == itdir(idir) .and. &
517 ixdir(idir) >= self%isc .and. ixdir(idir) <= self%iec .and. &
518 iydir(idir) >= self%jsc .and. iydir(idir) <= self%jec)
then
522 if (trim(self%fields(var)%fv3jedi_name) == trim(ifdir(idir)))
then
524 self%fields(var)%array(ixdir(idir),iydir(idir),ildir) = 1.0
528 if (.not.found)
call abor1_ftn(
"fv3jedi_increment_mod.dirac: dirac not found")
544 real(kind=
kind_real),
intent(inout) :: values(:)
546 integer :: var, nz, ii
550 nz = self%fields(var)%npz
551 values(ii+1:ii+nz) = self%fields(var)%array(geoiter%iind, geoiter%jind,:)
566 real(kind=
kind_real),
intent(in) :: values(:)
568 integer :: var, nz, ii
572 nz = self%fields(var)%npz
573 self%fields(var)%array(geoiter%iind, geoiter%jind,:) = values(ii+1:ii+nz)