FV3-JEDI
fv3jedi_bump_interp_mod.f90
Go to the documentation of this file.
1 ! (C) Copyright 2019-2020 UCAR
2 !
3 ! This software is licensed under the terms of the Apache Licence Version 2.0
4 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5 
6 
8 
9 ! atlas
10 use atlas_module, only: atlas_field, atlas_fieldset, atlas_functionspace, atlas_real, &
11  atlas_functionspace_pointcloud
12 
13 ! fckit
14 use fckit_mpi_module, only: fckit_mpi_comm
15 
16 ! saber
17 use type_bump, only: bump_type
18 
19 ! fv3jedi
22 
23 ! --------------------------------------------------------------------------------------------------
24 
25 implicit none
26 private
28 
29 ! --------------------------------------------------------------------------------------------------
30 
32  type(bump_type) :: bump
33  integer :: isc, iec, jsc, jec
34  type(atlas_functionspace) :: afunctionspace
35  contains
36  procedure :: setup
37  procedure :: delete
38  procedure :: apply
39  procedure :: apply_ad
40  final :: dummy_final
41 end type fv3jedi_bump_interp
42 
43 ! --------------------------------------------------------------------------------------------------
44 
45 contains
46 
47 ! --------------------------------------------------------------------------------------------------
48 
49 subroutine setup(self, comm, isc, iec, jsc, jec, npz, lon_in, lat_in, &
50  ngrid_ou, lon_ou_us, lat_ou_us, bumpid)
51 
52 !Arguments
53 class(fv3jedi_bump_interp), intent(inout) :: self
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
62 
63 !Locals
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
69 
70 real(kind=kind_real), pointer :: real_ptr(:,:)
71 type(atlas_functionspace) :: afunctionspace
72 type(atlas_fieldset) :: afieldset
73 type(atlas_field) :: afield
74 
75 ! Save domain
76 ! -----------
77 self%isc = isc
78 self%iec = iec
79 self%jsc = jsc
80 self%jec = jec
81 
82 ! Each bump%nam%prefix must be distinct
83 ! -------------------------------------
84 if (present(bumpid)) then
85  write(cbumpcount,"(I0.5)") bumpid
86 else
87  write(cbumpcount,"(I0.5)") 99999
88 endif
89 bump_nam_prefix = 'fv3jedi_bump_interp_data_'//cbumpcount
90 
91 ! Namelist options
92 ! ----------------
93 call self%bump%nam%init(comm%size())
94 
95 self%bump%nam%prefix = trim(bump_nam_prefix) ! Prefix for files output
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
100 self%bump%nam%nv = 1
101 self%bump%nam%variables(1) = "var"
102 
103 ! Pack lonlat into atlas function space
104 ! -------------------------------------
105 ngrid = (iec-isc+1)*(jec-jsc+1)
106 allocate(lon_in_us(ngrid))
107 allocate(lat_in_us(ngrid))
108 jnode = 0
109 do jy = jsc,jec
110  do jx = isc,iec
111  jnode = jnode+1
112  lon_in_us(jnode) = lon_in(jx,jy)*rad2deg
113  lat_in_us(jnode) = lat_in(jx,jy)*rad2deg
114  end do
115 end do
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)
121 call afield%final()
122 
123 ! Initialize BUMP
124 ! -------------------
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()
127 
128 ! Release memory
129 ! --------------
130 call self%bump%partial_dealloc()
131 call afunctionspace%final()
132 
133 end subroutine setup
134 
135 ! --------------------------------------------------------------------------------------------------
136 
137 subroutine delete(self)
138 
139 class(fv3jedi_bump_interp), intent(inout) :: self
140 
141 call self%afunctionspace%final()
142 call self%bump%dealloc()
143 
144 end subroutine delete
145 
146 ! --------------------------------------------------------------------------------------------------
147 
148 subroutine apply( self, npz, field_in, ngrid_ou, field_ou)
149 
150 implicit none
151 
152 !Arguments
153 class(fv3jedi_bump_interp), intent(inout) :: self
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)
158 
159 !Locals
160 integer :: jl
161 real(kind_real), pointer :: real_ptr_2(:,:)
162 type(atlas_field) :: afield
163 type(atlas_fieldset) :: afieldset
164 
165 ! Set number of levels
166 self%bump%geom%nl0 = npz
167 
168 ! Define ATLAS fieldset
169 afieldset = atlas_fieldset()
170 afield = self%afunctionspace%create_field(name='var', kind=atlas_real(kind_real), levels=npz)
171 call afieldset%add(afield)
172 
173 ! Put input field into ATLAS fieldset
174 call afield%data(real_ptr_2)
175 do jl=1,npz
176  real_ptr_2(jl,:) = pack(field_in(self%isc:self%iec,self%jsc:self%jec,jl),.true.)
177 enddo
178 
179 ! Apply BUMP interpolation
180 call self%bump%apply_obsop(afieldset,field_ou)
181 
182 ! Release memory
183 call afieldset%final()
184 call afield%final()
185 
186 end subroutine apply
187 
188 ! --------------------------------------------------------------------------------------------------
189 
190 subroutine apply_ad( self, npz, field_in, ngrid_ou, field_ou )
191 
192 implicit none
193 
194 !Arguments
195 class(fv3jedi_bump_interp), intent(inout) :: self
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)
200 
201 !Locals
202 integer :: jl
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
207 
208 ! Set number of levels
209 self%bump%geom%nl0 = npz
210 
211 ! Define ATLAS fieldset
212 afieldset = atlas_fieldset()
213 afield = self%afunctionspace%create_field(name='var', kind=atlas_real(kind_real), levels=npz)
214 call afieldset%add(afield)
215 
216 ! Apply BUMP interpolation adjoint
217 call self%bump%apply_obsop_ad(field_ou,afieldset)
218 
219 ! Get output field from ATLAS fieldset
220 call afield%data(real_ptr_2)
221 umask = .true.
222 do jl=1,npz
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))
225 enddo
226 
227 ! Release memory
228 call afieldset%final()
229 call afield%final()
230 
231 end subroutine apply_ad
232 
233 ! --------------------------------------------------------------------------------------------------
234 
235 ! Not really needed but prevents gnu compiler bug
236 subroutine dummy_final(self)
237 type(fv3jedi_bump_interp), intent(inout) :: self
238 end subroutine dummy_final
239 
240 ! --------------------------------------------------------------------------------------------------
241 
242 end module fv3jedi_bump_interp_mod
fv3jedi_bump_interp_mod::delete
subroutine delete(self)
Definition: fv3jedi_bump_interp_mod.f90:138
fv3jedi_bump_interp_mod::setup
subroutine setup(self, comm, isc, iec, jsc, jec, npz, lon_in, lat_in, ngrid_ou, lon_ou_us, lat_ou_us, bumpid)
Definition: fv3jedi_bump_interp_mod.f90:51
fv3jedi_bump_interp_mod::fv3jedi_bump_interp
Definition: fv3jedi_bump_interp_mod.f90:31
fv3jedi_constants_mod::rad2deg
real(kind=kind_real), parameter, public rad2deg
Definition: fv3jedi_constants_mod.f90:13
fv3jedi_constants_mod
Definition: fv3jedi_constants_mod.f90:6
fv3jedi_bump_interp_mod::apply
subroutine apply(self, npz, field_in, ngrid_ou, field_ou)
Definition: fv3jedi_bump_interp_mod.f90:149
fv3jedi_bump_interp_mod
Definition: fv3jedi_bump_interp_mod.f90:7
fv3jedi_kinds_mod::kind_real
integer, parameter, public kind_real
Definition: fv3jedi_kinds_mod.f90:14
fv3jedi_kinds_mod
Definition: fv3jedi_kinds_mod.f90:6
fv3jedi_bump_interp_mod::apply_ad
subroutine apply_ad(self, npz, field_in, ngrid_ou, field_ou)
Definition: fv3jedi_bump_interp_mod.f90:191
fv3jedi_bump_interp_mod::dummy_final
subroutine dummy_final(self)
Definition: fv3jedi_bump_interp_mod.f90:237