FV3 Bundle
ufo_seaicethick_tlad_mod.F90
Go to the documentation of this file.
1 ! (C) Copyright 2017-2018 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 !> Fortran module to handle ice concentration observations
7 
9 
10 use iso_c_binding
11 use ufo_vars_mod
13 use kinds
14 
15 implicit none
16 public :: ufo_seaicethick_tlad
21 private
22 integer, parameter :: max_string=800
23 
24 !> Fortran derived type for sea ice fraction observation operator
26  type(ufo_geoval) :: icethick !< ice thickness (traj)
27  type(ufo_geoval) :: icefrac !< ice fraction (traj)
28  logical :: ltraj = .false. !< trajectory set?
29 end type ufo_seaicethick_tlad
30 
31 
32 ! ------------------------------------------------------------------------------
33 
34 contains
35 
36 ! ------------------------------------------------------------------------------
37 
38 subroutine ufo_seaicethick_tlad_delete(self)
39 implicit none
40 type(ufo_seaicethick_tlad), intent(inout) :: self
41 
42 self%ltraj = .false.
43 
44 end subroutine ufo_seaicethick_tlad_delete
45 
46 ! ------------------------------------------------------------------------------
47 
48 subroutine ufo_seaicethick_tlad_settraj(self, geovals)
49 implicit none
50 type(ufo_seaicethick_tlad), intent(inout) :: self
51 type(ufo_geovals), intent(in) :: geovals
52 
53 character(len=*), parameter :: myname_="ufo_seaicethick_tlad_settraj"
54 character(max_string) :: err_msg
55 
56 type(ufo_geoval), pointer :: icethick, icefrac
57 
58 ! check if sea ice thickness variables is in geovals and get it
59 call ufo_geovals_get_var(geovals, var_seaicethick, icethick)
60 
61 ! check if sea ice fraction variables is in geovals and get it
62 call ufo_geovals_get_var(geovals, var_seaicefrac, icefrac)
63 
64 self%icethick = icethick
65 self%icefrac = icefrac
66 self%ltraj = .true.
67 
68 end subroutine ufo_seaicethick_tlad_settraj
69 
70 
71 ! ------------------------------------------------------------------------------
72 
73 subroutine ufo_seaicethick_simobs_tl(self, geovals, hofx)
74 implicit none
75 type(ufo_seaicethick_tlad), intent(in) :: self
76 type(ufo_geovals), intent(in) :: geovals
77 real(c_double), intent(inout) :: hofx(:)
78 
79 character(len=*), parameter :: myname_="ufo_seaicethick_simobs_tl"
80 character(max_string) :: err_msg
81 
82 integer :: iobs, icat, ncat
83 type(ufo_geoval), pointer :: icethick_d, icefrac_d
84 
85 print *, myname_, ' nobs: ', geovals%nobs, size(hofx,1)
86 
87 ! check if trajectory was set
88 if (.not. self%ltraj) then
89  write(err_msg,*) myname_, ' trajectory wasnt set!'
90  call abor1_ftn(err_msg)
91 endif
92 
93 ! check if nobs is consistent in geovals & hofx
94 if (geovals%nobs /= size(hofx,1)) then
95  write(err_msg,*) myname_, ' error: nobs inconsistent!'
96  call abor1_ftn(err_msg)
97 endif
98 
99 ! check if sea ice fraction variable is in geovals and get it
100 call ufo_geovals_get_var(geovals, var_seaicefrac, icefrac_d)
101 
102 ! check if sea ice thickness variable is in geovals and get it
103 call ufo_geovals_get_var(geovals, var_seaicethick, icethick_d)
104 
105 ! sea ice thickness obs operator
106 ncat = icefrac_d%nval
107 hofx = 0.0
108 do iobs = 1, size(hofx,1)
109  do icat = 1, ncat
110  hofx(iobs) = hofx(iobs) + &
111  self%icefrac%vals(icat,iobs) * icethick_d%vals(icat,iobs) / 905.0 + &
112  icefrac_d%vals(icat,iobs) * self%icethick%vals(icat,iobs) /905.0
113  enddo
114 enddo
115 
116 end subroutine ufo_seaicethick_simobs_tl
117 
118 ! ------------------------------------------------------------------------------
119 
120 subroutine ufo_seaicethick_simobs_ad(self, geovals, hofx)
121 implicit none
122 type(ufo_seaicethick_tlad), intent(in) :: self
123 type(ufo_geovals), intent(inout) :: geovals
124 real(c_double), intent(inout) :: hofx(:)
125 
126 character(len=*), parameter :: myname_="ufo_seaicethick_simobs_ad"
127 character(max_string) :: err_msg
128 
129 integer :: iobs, icat, ncat
130 type(ufo_geoval), pointer :: icefrac_d, icethick_d
131 
132 ! check if trajectory was set
133 if (.not. self%ltraj) then
134  write(err_msg,*) myname_, ' trajectory wasnt set!'
135  call abor1_ftn(err_msg)
136 endif
137 
138 ! check if nobs is consistent in geovals & hofx
139 if (geovals%nobs /= size(hofx,1)) then
140  write(err_msg,*) myname_, ' error: nobs inconsistent!'
141  call abor1_ftn(err_msg)
142 endif
143 
144 if (.not. geovals%linit ) geovals%linit=.true.
145 
146 ! check if sea ice fraction variable is in geovals and get it
147 call ufo_geovals_get_var(geovals, var_seaicefrac, icefrac_d)
148 
149 ! check if sea ice thickness variable is in geovals and get it
150 call ufo_geovals_get_var(geovals, var_seaicethick, icethick_d)
151 
152 ncat = self%icethick%nval
153 if (.not.(allocated(icefrac_d%vals) .or. .not. allocated(icethick_d%vals))) then
154  if (ncat < 1) then
155  write(err_msg,*) myname_, ' unknown number of categories'
156  call abor1_ftn(err_msg)
157  endif
158  if (.not. allocated(icefrac_d%vals)) allocate(icefrac_d%vals(ncat,size(hofx,1)))
159  if (.not. allocated(icethick_d%vals)) allocate(icethick_d%vals(ncat, size(hofx,1)))
160 end if
161 
162 !print *, 'in ad: hofx=', hofx
163 
164 ! backward sea ice thickness obs operator
165 
166 print *,'ncat=',ncat
167 if (.not. allocated(icefrac_d%vals)) allocate(icefrac_d%vals(ncat,size(hofx,1)))
168 if (.not. allocated(icethick_d%vals)) allocate(icethick_d%vals(ncat, size(hofx,1)))
169 
170 icethick_d%vals = 0.0
171 icefrac_d%vals = 0.0
172 do iobs = 1, size(hofx,1)
173  do icat = 1, ncat
174  icefrac_d%vals(icat,iobs) = icefrac_d%vals(icat,iobs) + self%icethick%vals(icat,iobs) * hofx(iobs) / 905.0
175  icethick_d%vals(icat,iobs) = icethick_d%vals(icat,iobs) + self%icefrac%vals(icat,iobs) * hofx(iobs) / 905.0
176  !print *, 'in ad: thick=', icethick_d%vals(:,iobs)
177  !print *, 'in ad: frac=', icefrac_d%vals(:,iobs)
178  enddo
179 enddo
180 !hofx = 0.0
181 
182 !call abor1_ftn("end adjoint")
183 end subroutine ufo_seaicethick_simobs_ad
184 
185 end module ufo_seaicethick_tlad_mod
character(len=maxvarlen), public var_seaicethick
subroutine, public ufo_geovals_get_var(self, varname, geoval, status)
integer, parameter max_string
subroutine, public ufo_seaicethick_simobs_ad(self, geovals, hofx)
subroutine, public ufo_seaicethick_simobs_tl(self, geovals, hofx)
Fortran module to handle ice concentration observations.
Fortran derived type for sea ice fraction observation operator.
type to hold interpolated fields required by the obs operators
subroutine, public ufo_seaicethick_tlad_delete(self)
subroutine, public ufo_seaicethick_tlad_settraj(self, geovals)
character(len=maxvarlen), public var_seaicefrac
type to hold interpolated field for one variable, one observation