SOCA
soca_bkgerrfilt_mod.F90
Go to the documentation of this file.
1 ! (C) Copyright 2017-2021 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 !> variable transform: background error filtering
8 
9 use fckit_configuration_module, only: fckit_configuration
10 use kinds, only: kind_real
11 
12 ! soca modules
14 use soca_geom_mod, only: soca_geom
16 use soca_state_mod, only: soca_state
17 
18 implicit none
19 private
20 
21 
22 !> Variable transform for background error filtering
23 !!
24 !! Filter increments to only where the ocean is thick enough
25 !!
26 !! \note operates only on tocn, socn, and ssh
27 type, public :: soca_bkgerrfilt
28  type(soca_geom), pointer :: geom
29  type(soca_fields) :: filt
30 
31  ! private variables
32  real(kind=kind_real), private :: efold_z !< E-folding scale
33  real(kind=kind_real), private :: scale !< Rescaling factor
34  real(kind=kind_real), private :: ocn_depth_min !< Minimum depth
35 
36 contains
37 
38  !> \copybrief soca_bkgerrfilt_setup \see soca_bkgerrfilt_setup
39  procedure :: setup => soca_bkgerrfilt_setup
40 
41  !> \copybrief soca_bkgerrfilt_mult \see soca_bkgerrfilt_mult
42  procedure :: mult => soca_bkgerrfilt_mult
43 
44 end type soca_bkgerrfilt
45 
46 
47 ! ------------------------------------------------------------------------------
48 contains
49 ! ------------------------------------------------------------------------------
50 
51 
52 ! ------------------------------------------------------------------------------
53 !> Setup the static background error
54 !!
55 !! \relates soca_bkgerrfilt_mod::soca_bkgerrfilt
56 subroutine soca_bkgerrfilt_setup(self, f_conf, bkg, geom)
57  class(soca_bkgerrfilt) , intent(inout) :: self
58  type(fckit_configuration), intent(in) :: f_conf !< configuration
59  type(soca_state), intent(in) :: bkg !< background state
60  type(soca_geom), target, intent(in ) :: geom !< geometry
61 
62  integer :: isc, iec, jsc, jec, i, j, k
63  real(kind=kind_real) :: efold
64  character(len=800) :: fname = 'soca_bkgerrfilt.nc'
65  type(soca_field), pointer :: tocn, socn, ssh, hocn, layer_depth
66 
67  ! Allocate memory for bkgerrfiltor and set to zero
68  call self%filt%copy(bkg)
69  call self%filt%zeros()
70 
71  ! Read parameters from config
72  call f_conf%get_or_die("ocean_depth_min", self%ocn_depth_min)
73  call f_conf%get_or_die("rescale_bkgerr", self%scale)
74  call f_conf%get_or_die("efold_z", self%efold_z)
75 
76  ! Associate geometry
77  self%geom => geom
78 
79  call self%filt%get("tocn", tocn)
80  call self%filt%get("socn", socn)
81  call self%filt%get("ssh", ssh)
82  call bkg%get("hocn", hocn)
83  call bkg%get("layer_depth", layer_depth)
84 
85  ! Setup rescaling and masks
86  isc=geom%isc ; iec=geom%iec
87  jsc=geom%jsc ; jec=geom%jec
88  do i = isc, iec
89  do j = jsc, jec
90  if (sum(hocn%val(i,j,:)).gt.self%ocn_depth_min) then
91  ssh%val(i,j,:) = self%scale
92  do k = 1, hocn%nz
93  if (hocn%val(i,j,k).gt.1e-3_kind_real) then
94  ! Only apply if layer is thick enough
95  efold = self%scale*exp(-layer_depth%val(i,j,k)/self%efold_z)
96  else
97  ! Set to zero if layer is too thin
98  efold = 0.0_kind_real
99  end if
100  tocn%val(i,j,k) = efold
101  socn%val(i,j,k) = efold
102  end do
103  else
104  ! Set to zero if ocean is too shallow
105  ssh%val(i,j,:) = 0.0_kind_real
106  tocn%val(i,j,:) = 0.0_kind_real
107  socn%val(i,j,:) = 0.0_kind_real
108  end if
109  end do
110  end do
111 
112  ! set other things to 1
113  do i=1,size(self%filt%fields)
114  select case(self%filt%fields(i)%name)
115  case ('ssh','tocn','socn')
116  continue
117  case default
118  self%filt%fields(i)%val = 1.0_kind_real
119  end select
120  end do
121 
122  ! Save filtered background error
123  call self%filt%write_file(fname)
124 
125 end subroutine soca_bkgerrfilt_setup
126 
127 
128 ! ------------------------------------------------------------------------------
129 !> Apply background error: dxm = D dxa
130 !!
131 !! \relates soca_bkgerrfilt_mod::soca_bkgerrfilt
132 subroutine soca_bkgerrfilt_mult(self, dxa, dxm)
133  class(soca_bkgerrfilt), intent(in) :: self
134  type(soca_increment), intent(in) :: dxa !< input increment
135  type(soca_increment), intent(inout) :: dxm !< output increment
136 
137  integer :: i, j, n
138  type(soca_field), pointer :: field_f, field_a, field_m
139 
140  ! make sure fields are the right shape
141  call dxa%check_congruent(dxm)
142  call dxa%check_subset(self%filt)
143 
144  ! multiply
145  do n=1,size(dxa%fields)
146  field_a => dxa%fields(n)
147  call self%filt%get(field_a%name, field_f)
148  call dxm%get(field_a%name, field_m)
149  do i = self%geom%isc, self%geom%iec
150  do j = self%geom%jsc, self%geom%jec
151  if (self%geom%mask2d(i,j).eq.1) then
152  field_m%val(i,j,:) = field_f%val(i,j,:) * field_a%val(i,j,:)
153  else
154  field_m%val(i,j,:) = 0.0_kind_real
155  end if
156  end do
157  end do
158  end do
159 end subroutine soca_bkgerrfilt_mult
160 
161 ! ------------------------------------------------------------------------------
162 
163 end module soca_bkgerrfilt_mod
variable transform: background error filtering
Handle fields for the model.
Geometry module.
Increment fields.
State fields.
Variable transform for background error filtering.
Holds all data and metadata related to a single field variable.
A collection of soca_field types representing a collective state or increment.
Geometry data structure.