10 use atlas_module,
only: atlas_field, atlas_fieldset, atlas_functionspace, atlas_real, &
11 atlas_functionspace_pointcloud
14 use fckit_mpi_module,
only: fckit_mpi_comm
17 use type_bump,
only: bump_type
32 type(bump_type) :: bump
33 integer :: isc, iec, jsc, jec
34 type(atlas_functionspace) :: afunctionspace
49 subroutine setup(self, comm, isc, iec, jsc, jec, npz, lon_in, lat_in, &
50 ngrid_ou, lon_ou_us, lat_ou_us, bumpid)
54 type(fckit_mpi_comm),
intent(in) :: comm
55 integer,
intent(in) :: isc, iec, jsc, jec, npz
56 real(kind=
kind_real),
intent(in) :: lon_in(isc:iec,jsc:jec)
57 real(kind=
kind_real),
intent(in) :: lat_in(isc:iec,jsc:jec)
58 integer,
intent(in) :: ngrid_ou
59 real(kind=
kind_real),
intent(in) :: lon_ou_us(ngrid_ou)
60 real(kind=
kind_real),
intent(in) :: lat_ou_us(ngrid_ou)
61 integer,
optional,
intent(in) :: bumpid
64 integer :: ngrid, jnode, jx, jy
65 real(kind=
kind_real),
allocatable :: lon_in_us(:)
66 real(kind=
kind_real),
allocatable :: lat_in_us(:)
67 character(len=5) :: cbumpcount
68 character(len=1024) :: bump_nam_prefix
70 real(kind=
kind_real),
pointer :: real_ptr(:,:)
71 type(atlas_functionspace) :: afunctionspace
72 type(atlas_fieldset) :: afieldset
73 type(atlas_field) :: afield
84 if (
present(bumpid))
then
85 write(cbumpcount,
"(I0.5)") bumpid
87 write(cbumpcount,
"(I0.5)") 99999
89 bump_nam_prefix =
'fv3jedi_bump_interp_data_'//cbumpcount
93 call self%bump%nam%init(comm%size())
95 self%bump%nam%prefix = trim(bump_nam_prefix)
96 self%bump%nam%new_obsop = .true.
97 self%bump%nam%write_obsop = .false.
98 self%bump%nam%verbosity =
"none"
99 self%bump%nam%nl = npz+1
101 self%bump%nam%variables(1) =
"var"
105 ngrid = (iec-isc+1)*(jec-jsc+1)
106 allocate(lon_in_us(ngrid))
107 allocate(lat_in_us(ngrid))
112 lon_in_us(jnode) = lon_in(jx,jy)*
rad2deg
113 lat_in_us(jnode) = lat_in(jx,jy)*
rad2deg
116 afield = atlas_field(name=
"lonlat", kind=atlas_real(
kind_real), shape=(/2, ngrid/))
117 call afield%data(real_ptr)
118 real_ptr(1,:) = lon_in_us
119 real_ptr(2,:) = lat_in_us
120 self%afunctionspace = atlas_functionspace_pointcloud(afield)
125 call self%bump%setup( comm, self%afunctionspace, nobs=ngrid_ou, lonobs=lon_ou_us, latobs=lat_ou_us)
126 call self%bump%run_drivers()
130 call self%bump%partial_dealloc()
131 call afunctionspace%final()
141 call self%afunctionspace%final()
142 call self%bump%dealloc()
148 subroutine apply( self, npz, field_in, ngrid_ou, field_ou)
154 integer,
intent(in) :: npz
155 real(kind=
kind_real),
intent(in) :: field_in(self%isc:self%iec,self%jsc:self%jec,npz)
156 integer,
intent(in) :: ngrid_ou
157 real(kind=
kind_real),
intent(inout) :: field_ou(ngrid_ou,npz)
161 real(kind_real),
pointer :: real_ptr_2(:,:)
162 type(atlas_field) :: afield
163 type(atlas_fieldset) :: afieldset
166 self%bump%geom%nl0 = npz
169 afieldset = atlas_fieldset()
170 afield = self%afunctionspace%create_field(name=
'var', kind=atlas_real(kind_real), levels=npz)
171 call afieldset%add(afield)
174 call afield%data(real_ptr_2)
176 real_ptr_2(jl,:) = pack(field_in(self%isc:self%iec,self%jsc:self%jec,jl),.true.)
180 call self%bump%apply_obsop(afieldset,field_ou)
183 call afieldset%final()
190 subroutine apply_ad( self, npz, field_in, ngrid_ou, field_ou )
196 integer,
intent(in) :: npz
197 real(kind=
kind_real),
intent(inout) :: field_in(self%isc:self%iec,self%jsc:self%jec,npz)
198 integer,
intent(in) :: ngrid_ou
199 real(kind=
kind_real),
intent(in) :: field_ou(ngrid_ou,npz)
203 real(kind_real),
pointer :: real_ptr_2(:,:)
204 logical :: umask(self%isc:self%iec,self%jsc:self%jec)
205 type(atlas_field) :: afield
206 type(atlas_fieldset) :: afieldset
209 self%bump%geom%nl0 = npz
212 afieldset = atlas_fieldset()
213 afield = self%afunctionspace%create_field(name=
'var', kind=atlas_real(kind_real), levels=npz)
214 call afieldset%add(afield)
217 call self%bump%apply_obsop_ad(field_ou,afieldset)
220 call afield%data(real_ptr_2)
223 field_in(self%isc:self%iec,self%jsc:self%jec,jl) = unpack(real_ptr_2(jl,:),umask, &
224 & field_in(self%isc:self%iec,self%jsc:self%jec,jl))
228 call afieldset%final()