Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "update_type" for joint assimilation of ASCAT SM and SMAP Tb #703

Merged
merged 30 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
4373200
the intention
amfox37 Jul 12, 2023
031911c
Merge branch 'feature/amfox/metop_sm' into feature/amfox/smap_ascat
amfox37 Jul 20, 2023
a6e3341
new update_type
amfox37 Jul 27, 2023
8c13068
fix if then
amfox37 Jul 27, 2023
3fc6ee1
apply ASCAT _OR_ SMAP increment
amfox37 Jul 27, 2023
4fb9e6a
Merge branch 'develop' into feature/amfox/smap_ascat
amfox37 Jul 28, 2023
af05a5c
fix check_compact_support
amfox37 Aug 11, 2023
6e079f8
test read decode_ASCAT_ssom.x
amfox37 Aug 17, 2023
ef970ab
added State_incr_cum
amfox37 Sep 13, 2023
3d6615f
combining obs
amfox37 Oct 4, 2023
0771402
Merge branch 'feature/amfox/smap_ascat' of github.com:GEOS-ESM/GEOSld…
amfox37 Nov 11, 2023
194fbbe
Merge branch 'feature/amfox/metop_sm' into feature/amfox/smap_ascat
amfox37 Nov 28, 2023
718a55a
add select_species_Tb
amfox37 Dec 6, 2023
b9dc1df
allocate(0)
amfox37 Dec 22, 2023
d8b8160
Merge branch 'develop' into feature/amfox/smap_ascat
amfox37 Feb 6, 2024
4b878f0
LDAS_App tidy up
amfox37 Feb 6, 2024
7cc3735
tidy up unused variables and debugging
amfox37 Feb 7, 2024
3f18420
more tidying
amfox37 Feb 7, 2024
9637304
remove white space
amfox37 Feb 7, 2024
687d17b
Merge branch 'develop' into feature/amfox/smap_ascat
amfox37 Feb 8, 2024
e79c437
Merge branch 'develop' into feature/amfox/smap_ascat
gmao-rreichle Feb 8, 2024
bc0cef5
minor edits for new update_type=13 (clsm_ensupd_upd_routines.F90):
gmao-rreichle Feb 9, 2024
d450550
Merge branch 'develop' into feature/amfox/smap_ascat
gmao-rreichle Feb 16, 2024
7e5b3c8
add trim when selecting by varname
amfox37 Feb 19, 2024
958233c
Merge branch 'feature/amfox/smap_ascat' of github.com:GEOS-ESM/GEOSld…
amfox37 Feb 19, 2024
f478091
Clarify comments in clsm_ensupd_enkf_update.F90
amfox37 Feb 19, 2024
e78cc6b
Fix issue with select_varnames
amfox37 Feb 20, 2024
47d4bb9
remove catdef from state for non-peatland tiles
amfox37 Feb 26, 2024
9f02392
disabled updated_type=[1,2]; cleanup of new update_type=13 (clsm_ensu…
gmao-rreichle Feb 27, 2024
175ccb5
Merge branch 'develop' into feature/amfox/smap_ascat
gmao-rreichle Feb 27, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
! update_type = 8: 3d soil moisture/Tskin/ght(1); TB obs
! update_type = 9: 1d Tskin/ght1 update; FT obs
! update_type = 10: 3d soil moisture/Tskin/ght(1) excl. catdef unless PEATCLSM tile; TB obs
! update_type = 13: Multivariate combination of 2 and 10; sfmc and TB obs

update_type = 0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1330,9 +1330,10 @@ subroutine apply_enkf_increments( N_catd, N_ens, update_type, &

cat_progn_has_changed = .false.

case (6,8,9,10) select_update_type ! soil moisture and temperature update
case (6,8,9,10,13) select_update_type ! soil moisture and temperature update

! for update_type 10, catdef increments may be zero by design
! for update_type 10, catdef increments may be zero by design
! for update_type 13, could be multiple zero increments
gmao-rreichle marked this conversation as resolved.
Show resolved Hide resolved

if (logit) write (logunit,*) &
'apply_enkf_increments(): applying soil moisture and Tskin/ght1 increments'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3363,6 +3363,7 @@ subroutine cat_enkf_increments( &
! reichle, 18 Oct 2005 - return increments (instead of updated cat_progn)
! reichle, 17 Oct 2011 - added "l2f" for revised (MPI) analysis
! reichle, 20 Feb 2022 - modified update_type 10 for PEATCLSM
! amfox, 6 Feb 2024 - added update type 13 for combination of ASCAT SM and SMAP Tb
!
! --------------------------------------------------------------

Expand Down Expand Up @@ -3422,9 +3423,9 @@ subroutine cat_enkf_increments( &

real, parameter :: tp1_threshold = -HUGE(1.) ! = 0.2 ! [CELSIUS]

integer :: n, n_e, kk, ii
integer :: n, n_e, kk, ii, jj

integer :: N_state_max, N_state, N_selected_obs, N_select_varnames, N_select_species
integer :: N_state_max, N_state, N_selected_obs, N_select_varnames, N_select_species, N_select_species_Tb

real :: halo_minlon, halo_maxlon, halo_minlat, halo_maxlat
real :: tmp_minlon, tmp_maxlon, tmp_minlat, tmp_maxlat
Expand All @@ -3441,7 +3442,7 @@ subroutine cat_enkf_increments( &

real, allocatable, dimension(:) :: State_lon, State_lat

integer, dimension(N_obs_param) :: select_species ! alloc max possible length
integer, dimension(N_obs_param) :: select_species, select_species_Tb ! alloc max possible length

character(40), dimension(N_obs_param) :: select_varnames ! alloc max possible length

Expand Down Expand Up @@ -3471,6 +3472,8 @@ subroutine cat_enkf_increments( &
real, dimension( N_catd) :: tp1_ensavg

type(obs_param_type) :: this_obs_param

logical :: found_Tb_obs

! -----------------------------------------------------------------------

Expand Down Expand Up @@ -3663,7 +3666,7 @@ subroutine cat_enkf_increments( &

end do

case (2) select_update_type ! 3d soil moisture analysis; sfmc and/or sfds obs
case (2) select_update_type ! 3d soil moisture analysis; sfmc+sfds obs

! update each tile separately using all observations within
! the customized halo around each tile
Expand Down Expand Up @@ -4403,6 +4406,194 @@ subroutine cat_enkf_increments( &
end do

! ----------------------------------

case (13) select_update_type ! 3d soil moisture/Tskin/ght(1) analysis; Tb+sfmc+sfds obs

! combines update_types 2 and 10
!
! update each tile separately using all observations within customized halo around each tile
!
! amfox, 14 September 2023

if (logit) write (logunit,*) 'get 3d soil moisture/Tskin/ght(1) increments; Tb+sfmc obs'

N_select_varnames = 0

if (any(obs_param%varname == 'Tb')) then
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need the "trim()" function here, and similarly in the next two blocks? I wonder if the "==" statement reliably produces the desired result across compilers, given that we should have trailing whitespace in %varname.
Note that obs_param is dimension(N_obs_param). Not sure if trim() works on such a 1d array.

N_select_varnames = N_select_varnames + 1
select_varnames(N_select_varnames) = 'Tb'
end if

if (any(obs_param%varname == 'sfmc')) then
N_select_varnames = N_select_varnames + 1
select_varnames(N_select_varnames) = 'sfmc'
end if

if (any(obs_param%varname == 'sfds')) then
N_select_varnames = N_select_varnames + 1
select_varnames(N_select_varnames) = 'sfds'
end if

! Will get all species associated with Tb or sfds observations

call get_select_species( &
N_select_varnames, select_varnames(1:N_select_varnames), &
N_obs_param, obs_param, N_select_species, select_species )

! Determine which species are Tb

call get_select_species(1, 'Tb', N_obs_param, obs_param, N_select_species_Tb, select_species_Tb )

N_state_max = 7

allocate( State_incr(N_state_max,N_ens))
allocate( State_lon( N_state_max ))
allocate( State_lat( N_state_max ))

do kk=1,N_catd

N_state = 3 ! for now, assume only sfmc and/or sfds obs

! compute increments only snow-free and non-frozen tiles

if ( (SWE_ensavg(kk) < SWE_threshold) .and. &
(tp1_ensavg(kk) > tp1_threshold)) then

! find observations within halo around tile kk

halo_minlon = tile_coord(kk)%com_lon - xcompact
halo_maxlon = tile_coord(kk)%com_lon + xcompact
halo_minlat = tile_coord(kk)%com_lat - ycompact
halo_maxlat = tile_coord(kk)%com_lat + ycompact

! simple approach to dateline issue (cut halo back to at most -180:180, -90:90)
! - reichle, 28 May 2013

halo_minlon = max(halo_minlon,-180.)
halo_maxlon = min(halo_maxlon, 180.)
halo_minlat = max(halo_minlat, -90.)
halo_maxlat = min(halo_maxlat, 90.)

call get_ind_obs_lat_lon_box( &
N_obs, Observations, &
halo_minlon, halo_maxlon, halo_minlat, halo_maxlat, &
N_select_species, select_species(1:N_select_species), &
N_selected_obs, ind_obs )

if (N_selected_obs>0) then

! Determine if Tb observations are present

do ii = 1,N_select_species_Tb
do jj = 1,N_selected_obs
if (select_species_Tb(ii) == Observations(ind_obs(jj))%species) then
found_Tb_obs = .true.
exit
end if
end do
if (found_Tb_obs) exit
end do
Comment on lines +4513 to +4521
Copy link
Contributor

Choose a reason for hiding this comment

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

We may want to simplify this block by teaching the get_ind_obs_lat_lon_box() (or the related get_ind_obs()) subroutine to (optionally) return a vector of the unique species numbers associated with the obs in ind_obs? This would be useful when we're adding new multi-sensor update_types in the future.


if (found_Tb_obs) then
if (cat_param(kk)%poros>=PEATCLSM_POROS_THRESHOLD) then
N_state = 7
else
N_state = 6
end if
end if

! assemble State_minus
! (on input, cat_progn contains cat_progn_minus)

if ( N_state==3 ) then

State_incr(1,:) = (cat_progn( kk,:)%srfexc/scale_srfexc)
State_incr(2,:) = (cat_progn( kk,:)%rzexc /scale_rzexc)
State_incr(3,:) = (cat_progn( kk,:)%catdef/scale_catdef)
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if we shouldn't look at the sensitivity of the ASCAT analysis to including/excluding catdef in the state vector. My gut feeling is that catdef shouldn't be included in the state vector, based on the history of the Tb assimilation. It's included in update_type=2 more for historical reasons than anything else. If catdef should be excluded from the state vector, we might want to settle this in the code sooner rather than later, and definitely before we start publishing results. Something to discuss on Monday.


elseif ( N_state==7 ) then

State_incr(1,:) = cat_progn( kk,:)%srfexc/scale_srfexc
State_incr(2,:) = cat_progn( kk,:)%rzexc /scale_rzexc
State_incr(3,:) = cat_progn( kk,:)%catdef/scale_catdef ! catdef in State

State_incr(4,:) = cat_progn( kk,:)%tc1 /scale_temp
State_incr(5,:) = cat_progn( kk,:)%tc2 /scale_temp
State_incr(6,:) = cat_progn( kk,:)%tc4 /scale_temp
State_incr(7,:) = cat_progn( kk,:)%ght(1)/scale_ght1

else

State_incr(1,:) = cat_progn( kk,:)%srfexc/scale_srfexc
State_incr(2,:) = cat_progn( kk,:)%rzexc /scale_rzexc

State_incr(3,:) = cat_progn( kk,:)%tc1 /scale_temp
State_incr(4,:) = cat_progn( kk,:)%tc2 /scale_temp
State_incr(5,:) = cat_progn( kk,:)%tc4 /scale_temp
State_incr(6,:) = cat_progn( kk,:)%ght(1)/scale_ght1

end if

State_lon( :) = tile_coord(kk )%com_lon
State_lat( :) = tile_coord(kk )%com_lat

allocate(Obs_cov(N_selected_obs,N_selected_obs))

call assemble_obs_cov( N_selected_obs, N_obs_param, obs_param, &
Observations(ind_obs(1:N_selected_obs)), Obs_cov )

call enkf_increments( &
N_state, N_selected_obs, N_ens, &
Observations(ind_obs(1:N_selected_obs)), &
Obs_pred(ind_obs(1:N_selected_obs),:), &
Obs_pert(ind_obs(1:N_selected_obs),:), &
Obs_cov, &
State_incr(1:N_state,:), &
State_lon( 1:N_state ), &
State_lat( 1:N_state ), &
xcompact, ycompact, &
fcsterr_inflation_fac )

deallocate(Obs_cov)

! assemble cat_progn increments

if ( N_state==3 ) then

cat_progn_incr(kk,:)%srfexc = State_incr(1,:)*scale_srfexc
cat_progn_incr(kk,:)%rzexc = State_incr(2,:)*scale_rzexc
cat_progn_incr(kk,:)%catdef = State_incr(3,:)*scale_catdef

elseif ( N_state==7 ) then

cat_progn_incr(kk,:)%srfexc = State_incr(1,:)*scale_srfexc
cat_progn_incr(kk,:)%rzexc = State_incr(2,:)*scale_rzexc
cat_progn_incr(kk,:)%catdef = State_incr(3,:)*scale_catdef ! catdef in State

cat_progn_incr(kk,:)%tc1 = State_incr(4,:)*scale_temp
cat_progn_incr(kk,:)%tc2 = State_incr(5,:)*scale_temp
cat_progn_incr(kk,:)%tc4 = State_incr(6,:)*scale_temp
cat_progn_incr(kk,:)%ght(1) = State_incr(7,:)*scale_ght1

else

cat_progn_incr(kk,:)%srfexc = State_incr(1,:)*scale_srfexc
cat_progn_incr(kk,:)%rzexc = State_incr(2,:)*scale_rzexc

cat_progn_incr(kk,:)%tc1 = State_incr(3,:)*scale_temp
cat_progn_incr(kk,:)%tc2 = State_incr(4,:)*scale_temp
cat_progn_incr(kk,:)%tc4 = State_incr(5,:)*scale_temp
cat_progn_incr(kk,:)%ght(1) = State_incr(6,:)*scale_ght1

end if

end if

end if ! thresholds

end do

! ----------------------------------

case default

Expand Down Expand Up @@ -4974,7 +5165,7 @@ subroutine check_compact_support( &
Iam // '(): reset for 1d update_type: ycompact = ', ycompact
if (logit) write (logunit,*)

case (2,7,8,10) ! "3d" updates, check consistency of xcompact, ycompact
case (2,7,8,10,13) ! "3d" updates, check consistency of xcompact, ycompact

! check xcompact/ycompact against corr scales of model error

Expand Down