Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 49 additions & 63 deletions src/soca/LinearVariableChange/Balance/soca_balance_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ module soca_balance_mod
! ------------------------------------------------------------------------------


function soca_tanh_filt(l, l0) result (coef)
real(kind=kind_real), intent(in) :: l
real(kind=kind_real), intent(in) :: l0

real(kind=kind_real) :: coef

coef = 0.5_kind_real*(tanh(l-l0)+1.0_kind_real)

end function soca_tanh_filt

! ------------------------------------------------------------------------------
!> Initialization of the balance operator and its trajectory.
!!
Expand All @@ -75,16 +85,12 @@ subroutine soca_balance_setup(self, f_conf, traj, geom)
integer :: isc, iec, jsc, jec
integer :: isd, ied, jsd, jed
integer :: i, j, k, nl
real(kind=kind_real), allocatable :: jac(:)
real(kind=kind_real), allocatable :: jac(:), coef_mld, coef_layers
type(soca_field), pointer :: tocn, socn, hocn, cicen, mld, layer_depth

! declarations related to the dynamic height Jacobians
character(len=:), allocatable :: filename, mask_name
real(kind=kind_real), allocatable :: jac_mask(:,:) !> mask for Jacobian
character(len=:), allocatable :: filename
real(kind=kind_real) :: threshold
integer :: nlayers !> dynamic height Jac=0 in nlayers upper layers
logical :: mask_detadt = .false. !> if true, set deta/dt to 0
logical :: mask_detads = .false. !> if true, set deta/ds to 0

! declarations related to the sea-ice Jacobian
character(len=:), allocatable :: kct_name
Expand All @@ -98,33 +104,6 @@ subroutine soca_balance_setup(self, f_conf, traj, geom)
isd=geom%isd; ied=geom%ied
jsd=geom%jsd; jed=geom%jed

! Setup mask for Jacobians related to the dynamic height balance
allocate(jac_mask(isd:ied,jsd:jed))
jac_mask = 1.0_kind_real
nlayers = 0
if ( f_conf%has("jac_mask") ) then
jac_mask = 0.0_kind_real
call f_conf%get_or_die("jac_mask.filename", filename)
call f_conf%get_or_die("jac_mask.name", mask_name)
call f_conf%get_or_die("jac_mask.threshold", threshold)
call f_conf%get_or_die("jac_mask.nlayers", nlayers)
call f_conf%get_or_die("jac_mask.detadt", mask_detadt)
call f_conf%get_or_die("jac_mask.detads", mask_detads)
call fms_io_init()
call read_data(filename, mask_name, jac_mask, domain=geom%Domain%mpp_domain)
call fms_io_exit()
where(jac_mask<threshold)
jac_mask = 0.0_kind_real
end where
end if

! Get configuration for Kst
call f_conf%get_or_die("dsdtmax", self%kst%dsdtmax)
call f_conf%get_or_die("dsdzmin", self%kst%dsdzmin)
call f_conf%get_or_die("dtdzmin", self%kst%dtdzmin)
call f_conf%get_or_die("nlayers", self%kst%nlayers) ! Set jac to 0 in the
! nlayers top layers

! Get required fields
call traj%get("tocn", tocn)
call traj%get("socn", socn)
Expand All @@ -136,29 +115,43 @@ subroutine soca_balance_setup(self, f_conf, traj, geom)
! allocate space
nl = hocn%nz
allocate(self%kst%jacobian(isc:iec,jsc:jec,geom%nzo))
allocate(jac(nl))
self%kst%jacobian=0.0

! Compute and store Jacobian of Kst
do i = isc, iec
do j = jsc, jec
jac=0.0
call soca_soft_jacobian(jac,&
&tocn%val(i,j,:),&
&socn%val(i,j,:),&
&hocn%val(i,j,:),&
&self%kst%dsdtmax, self%kst%dsdzmin, self%kst%dtdzmin)
! Set Jacobian to 0 above mixed layer
do k=1,nl
if (layer_depth%val(i,j,k) < mld%val(i,j,1)) then
jac(k) = 0.0_kind_Real
end if
! Setup Kst if in the configuration
if ( f_conf%has("kst") ) then
allocate(jac(nl))
call f_conf%get_or_die("kst.dsdtmax", self%kst%dsdtmax)
call f_conf%get_or_die("kst.dsdzmin", self%kst%dsdzmin)
call f_conf%get_or_die("kst.dtdzmin", self%kst%dtdzmin)
call f_conf%get_or_die("kst.nlayers", self%kst%nlayers)

! Compute and store Jacobian of Kst
do i = isc, iec
do j = jsc, jec
! do nothing if on land
if ( geom%mask2d(i, j) == 0 ) cycle

! compute dS(T)/dT
call soca_soft_jacobian(jac,&
&tocn%val(i,j,:),&
&socn%val(i,j,:),&
&hocn%val(i,j,:),&
&self%kst%dsdtmax, self%kst%dsdzmin, self%kst%dtdzmin)

! filter out the Jacobian as specified in the configuration
do k=1,nl
coef_mld = soca_tanh_filt(layer_depth%val(i,j,k),mld%val(i,j,1))
coef_layers = soca_tanh_filt(real(k, kind=kind_real), real(self%kst%nlayers, kind=kind_real))
self%kst%jacobian(i,j,k) = jac(k)*coef_mld*coef_layers
end do
end do
self%kst%jacobian(i,j,:) = jac(:)
self%kst%jacobian(i,j,1:self%kst%nlayers) = 0.0_kind_real
end do
end do
deallocate(jac)
deallocate(jac)
end if

! Get configuration for Ksshts
self%ksshts%nlayers = -999 ! No filtering by default
if ( f_conf%has("ksshts") ) call f_conf%get_or_die("ksshts.nlayers", self%ksshts%nlayers)

! Compute Jacobian of Ksshts
allocate(self%ksshts%kssht, mold=self%kst%jacobian)
Expand All @@ -176,21 +169,14 @@ subroutine soca_balance_setup(self, f_conf, traj, geom)
&hocn%val(i,j,k),&
&geom%lon(i,j),&
&geom%lat(i,j))
self%ksshts%kssht(i,j,k) = jac(1)*jac_mask(i,j)
self%ksshts%ksshs(i,j,k) = jac(2)*jac_mask(i,j)
end do
if (nlayers>0) then
self%ksshts%kssht(i,j,1:nlayers) = 0.0_kind_real
self%ksshts%ksshs(i,j,1:nlayers) = 0.0_kind_real
end if
coef_layers = soca_tanh_filt(real(k, kind=kind_real), real(self%ksshts%nlayers, kind=kind_real))
self%ksshts%kssht(i,j,k) = jac(1)*coef_layers
self%ksshts%ksshs(i,j,k) = jac(2)*coef_layers
end do
end do
end do
deallocate(jac)

! Zero-out Jacobians if required by configuration
if (mask_detadt) self%ksshts%kssht = 0.0_kind_real
if (mask_detads) self%ksshts%ksshs = 0.0_kind_real

! Compute Kct
if (traj%has("cicen")) then
! Setup dc/dT
Expand Down
1 change: 1 addition & 0 deletions src/soca/LinearVariableChange/Balance/soca_ksshts_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module soca_ksshts_mod
type, public :: soca_ksshts
real(kind=kind_real), allocatable :: kssht(:,:,:) !< deta(i,j)/dT(i,j,k)
real(kind=kind_real), allocatable :: ksshs(:,:,:) !< deta(i,j)/dS(i,j,k)
integer :: nlayers
end type soca_ksshts


Expand Down
14 changes: 5 additions & 9 deletions src/soca/LinearVariableChange/Balance/soca_kst_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ subroutine soca_soft_jacobian (jac, t, s, h, dsdtmax, dsdzmin, dtdzmin)

real(kind=kind_real), allocatable :: dtdz(:), dsdz(:)
integer :: nl, z
real(kind=kind_real) :: j

! Allocate
nl = size(t,1)
Expand All @@ -59,20 +58,17 @@ subroutine soca_soft_jacobian (jac, t, s, h, dsdtmax, dsdzmin, dtdzmin)

jac = 0.0
do z=1,nl
jac(z) = 0.0

! Limit application of soft according to configuration
if ( abs(dtdz(z)) < dtdzmin ) cycle
if ( abs(dsdz(z)) < dsdzmin ) cycle
if ( abs(dtdz(z)) < dtdzmin ) dtdz(z) = sign(dtdzmin, dtdz(z))

if ( abs(dsdz(z)) < dsdzmin ) dsdz(z) = sign(dsdzmin, dsdz(z))

! Jacobian of soft
j=dsdz(z)/dtdz(z)
jac(z)=dsdz(z)/dtdz(z)

! Limit application of soft according to configuration
if ( abs(j) > dsdtmax ) cycle

! if we reach this point in the code, the jacobian is usable
jac(z) = j;
if ( abs(jac(z)) > dsdtmax ) jac(z) = sign(dsdtmax, jac(z))
end do

end subroutine soca_soft_jacobian
Expand Down
11 changes: 7 additions & 4 deletions test/testinput/3dhyb.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,13 @@ cost function:
scale_layer_thick: 1.5

- linear variable change name: BalanceSOCA
dsdtmax: 0.1
dsdzmin: 3.0e-6
dtdzmin: 1.0e-6
nlayers: 2
kst:
dsdtmax: 0.1
dsdzmin: 3.0e-6
dtdzmin: 1.0e-6
nlayers: 2
ksshts:
nlayers: 2
dcdt:
filename: data_static/72x35x25/dcdt.nc
name: dcdt
Expand Down
11 changes: 7 additions & 4 deletions test/testinput/3dvar_godas.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,13 @@ cost function:
scale_layer_thick: 1.5

- linear variable change name: BalanceSOCA
dsdtmax: 0.1
dsdzmin: 3.0e-6
dtdzmin: 1.0e-6
nlayers: 2
kst:
dsdtmax: 0.1
dsdzmin: 3.0e-6
dtdzmin: 1.0e-6
nlayers: 999
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@guillaumevernieres I see several different values of nlayers depending on the tests here. What values would you recommend for the real-world config?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@travissluka We need to turn it off for the global until we properly test it and add a high latitude limit. 999 would turn it off. Omitting the kst config in the yaml to turnt kst off might be a better idea.
10 maybe in the hat10?

ksshts:
nlayers: 10
dcdt:
filename: data_static/72x35x25/dcdt.nc
name: dcdt
Expand Down
14 changes: 7 additions & 7 deletions test/testinput/3dvarbump.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,13 @@ cost function:
hicen_max: 100.0

- linear variable change name: BalanceSOCA
dsdtmax: 0.1
dsdzmin: 3.0e-6
dtdzmin: 1.0e-6
nlayers: 10
# dcdt:
# filename: data_static/72x35x25/dcdt.nc
# name: dcdt
kst:
dsdtmax: 0.1
dsdzmin: 3.0e-6
dtdzmin: 1.0e-6
nlayers: 2
ksshts:
nlayers: 2

observations:
observers:
Expand Down
11 changes: 7 additions & 4 deletions test/testinput/3dvarfgat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,13 @@ cost function:
scale_layer_thick: 1.5

- linear variable change name: BalanceSOCA
dsdtmax: 0.1
dsdzmin: 3.0e-6
dtdzmin: 1.0e-6
nlayers: 10
kst:
dsdtmax: 0.1
dsdzmin: 3.0e-6
dtdzmin: 1.0e-6
nlayers: 2
ksshts:
nlayers: 2
dcdt:
filename: data_static/72x35x25/dcdt.nc
name: dcdt
Expand Down
11 changes: 7 additions & 4 deletions test/testinput/3dvarfgat_pseudo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,13 @@ cost function:
scale_layer_thick: 1.5

- linear variable change name: BalanceSOCA
dsdtmax: 0.1
dsdzmin: 3.0e-6
dtdzmin: 1.0e-6
nlayers: 10
kst:
dsdtmax: 0.1
dsdzmin: 3.0e-6
dtdzmin: 1.0e-6
nlayers: 2
ksshts:
nlayers: 2
dcdt:
filename: data_static/72x35x25/dcdt.nc
name: dcdt
Expand Down
11 changes: 7 additions & 4 deletions test/testinput/3dvarlowres_soca.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,13 @@ cost function:
filter variables: *a_vars

- linear variable change name: BalanceSOCA
dsdtmax: 0.1
dsdzmin: 3.0e-6
dtdzmin: 1.0e-6
nlayers: 2
kst:
dsdtmax: 0.1
dsdzmin: 3.0e-6
dtdzmin: 1.0e-6
nlayers: 2
ksshts:
nlayers: 2

observations:
observers:
Expand Down
11 changes: 7 additions & 4 deletions test/testinput/convertincrement.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ linear variable change:
output variables: [tocn, socn, ssh, hocn]
linear variable changes:
- linear variable change name: BalanceSOCA
dsdtmax: 0.0
dsdzmin: 0.0
dtdzmin: 0.0
nlayers: 2
kst:
dsdtmax: 0.0
dsdzmin: 0.0
dtdzmin: 0.0
nlayers: 2
ksshts:
nlayers: 2

increments:
- date: 2018-04-15T00:00:00Z
Expand Down
11 changes: 7 additions & 4 deletions test/testinput/dirac_soca_cov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,13 @@ background error:
output variables: *soca_vars

- linear variable change name: BalanceSOCA
dsdtmax: 1
dsdzmin: 3.0e-6
dtdzmin: 1.0e-6
nlayers: 2
kst:
dsdtmax: 0.1
dsdzmin: 3.0e-6
dtdzmin: 1.0e-6
nlayers: 2
ksshts:
nlayers: 2
dcdt:
filename: data_static/72x35x25/dcdt.nc
name: dcdt
Expand Down
11 changes: 7 additions & 4 deletions test/testinput/dirac_socahyb_cov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,13 @@ background error:
input variables: *soca_vars
output variables: *soca_vars
- linear variable change name: BalanceSOCA
dsdtmax: 0.1
dsdzmin: 3.0e-6
dtdzmin: 1.0e-6
nlayers: 2
kst:
dsdtmax: 0.1
dsdzmin: 3.0e-6
dtdzmin: 1.0e-6
nlayers: 2
ksshts:
nlayers: 2
dcdt:
filename: data_static/72x35x25/dcdt.nc
name: dcdt
Expand Down
11 changes: 7 additions & 4 deletions test/testinput/enspert.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,13 @@ background error:
output variables: *soca_vars

- linear variable change name: BalanceSOCA
dsdtmax: 0.1
dsdzmin: 3.0e-6
dtdzmin: 1.0e-6
nlayers: 10
kst:
dsdtmax: 0.1
dsdzmin: 3.0e-6
dtdzmin: 1.0e-6
nlayers: 10
ksshts:
nlayers: 2
dcdt:
filename: data_static/72x35x25/dcdt.nc
name: dcdt
Expand Down
Loading