Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
861e187
GRACE-DA: Add input variables in `read_enkfpar`
jjokella Jul 24, 2025
9c8f427
GRACE-DA: Refactored interface routines
jjokella Jul 25, 2025
ee25df1
GRACE-DA: UN-refactored interface routines
jjokella Jul 25, 2025
9269451
GRACE-DA: refactor all framwork routines
jjokella Jul 26, 2025
6493c5e
Merge branch 'tsmp-pdaf-patched' into tsmp-pdaf-patched-grace-da
jjokella Jul 28, 2025
21099e6
refactor model routines
jjokella Jul 28, 2025
fe47bb8
refactor `domain_def_clm`, introduce TWS-specific routine
jjokella Jul 28, 2025
bb3467b
init_dim_obs_f: non-GRACE-DA if conditions
jjokella Jul 28, 2025
49db8be
init_dim_obs_pdaf: adopt TWS-section from init_dim_obs_f_pdaf
jjokella Jul 28, 2025
f29971e
warning-fix: '/*' within block comment
jjokella Jul 29, 2025
29e1456
bugfix: enkf_clm_mod_5.F90(98): #error: #endif without #if.
jjokella Jul 29, 2025
6e5d807
init_dim_obs: typo fixes
jjokella Jul 29, 2025
42695e0
bugfix: clmupdate_tws does not exist for CLM3.5
jjokella Jul 29, 2025
2299141
bugfix: set `domain_def_clm_tws` under `CLMFIVE`
jjokella Jul 29, 2025
c2ecce9
bugfix: add comment
jjokella Jul 31, 2025
faaa8c6
bugfix: duplicate line `use shr_kind_mod`
jjokella Jul 31, 2025
bab13b6
bugfix: clm-mod cannot open mod_read_obs
jjokella Jul 31, 2025
219e674
bugfix: mutable `varname`
jjokella Jul 31, 2025
d36ef33
bugfix: remove `da_interval` from CLM-mode
jjokella Jul 31, 2025
5460a12
bugfix: set_averaging_to_zero only for eCLM
jjokella Jul 31, 2025
c07eede
bugfix: additional comments needed
jjokella Jul 31, 2025
41ea42e
bugfix: specific length for `varname`, then `trim` at usage
jjokella Jul 31, 2025
b0caaef
bugfix: missing `CLMSA` for `clmupdate_tws` usage
jjokella Jul 31, 2025
b6310b6
typo: fix comment
jjokella Aug 7, 2025
60ad293
bugfix: `domain_def_clm_tws` only for CLMFIVE
jjokella Aug 7, 2025
3ca42ab
bugfix: duplicate declaration of `c`
jjokella Aug 7, 2025
91ba7e5
bugfix: remove `dim_obs_f` in `init_dim_obs`
jjokella Aug 7, 2025
7d9dd4c
bugfix: TWS-DA code not called for ParFlow-obs
jjokella Aug 7, 2025
7698449
bugfix: `crns_flag` from `mod_tsmp`
jjokella Aug 7, 2025
1412768
bugfix: `inst_suffix` only for eCLM
jjokella Aug 7, 2025
a6b0f22
bugfix: `clmupdate_tws` undefined for OBS_ONLY_PARFLOW
jjokella Aug 7, 2025
abdd808
bugfix: `point_obs` and other vars in `init_obscovar_pdaf`
jjokella Aug 8, 2025
53e39f0
Merge branch 'tsmp-pdaf-patched' into tsmp-pdaf-patched-grace-da
jjokella Aug 8, 2025
487054b
bugfix: add `clmupdate_tws` in `init_dim_l_pdaf`
jjokella Aug 8, 2025
024fafb
bugfix: variables in `obs_op_f_pdaf`
jjokella Aug 8, 2025
072d7a4
Merge branch 'tsmp-pdaf-patched' into tsmp-pdaf-patched-grace-da
jjokella Aug 8, 2025
0dd75ae
Merge branch 'tsmp-pdaf-patched' into tsmp-pdaf-patched-grace-da
jjokella Aug 28, 2025
12c94ad
bugfix: remove unused `grc`
jjokella Aug 28, 2025
80b0ab2
Merge branch 'tsmp-pdaf-patched' into tsmp-pdaf-patched-grace-da
jjokella Aug 29, 2025
cbe2bad
bugfix: GRACE-DA printing routines only for eCLM
jjokella Aug 29, 2025
88360aa
bugfix: clmupdate_tws if-condition for CLMSA
jjokella Aug 29, 2025
ba6904a
Merge branch 'tsmp-pdaf-patched' into tsmp-pdaf-patched-grace-da
jjokella Oct 23, 2025
42bea2f
add Anne Springer as general contributor (GRACE-DA)
jjokella Oct 24, 2025
9fc7c76
compilation fixes
jjokella Oct 24, 2025
530d017
compilation fixes II
jjokella Oct 24, 2025
1a37bf9
compilation fixes III
jjokella Oct 24, 2025
37fc7cf
Default TWS off.
jjokella Oct 24, 2025
a4fc46c
fortitude changes
jjokella Oct 24, 2025
f043df5
compilation fix
jjokella Oct 24, 2025
4a9123c
compilation fix
jjokella Oct 24, 2025
11df625
compilation fix of if-condition naming scheme
jjokella Oct 25, 2025
922b4c4
compilation fix
jjokella Oct 25, 2025
1aa8a60
indentation for better diff
jjokella Oct 26, 2025
138710d
BUGFIX: l2g_state_pdaf, NOGRACE if-condition switched
jjokella Oct 26, 2025
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
1 change: 1 addition & 0 deletions docs/users_guide/introduction_to_tsmp_pdaf/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ In alphabetic order (to be extended):
* Stefan Poll
* Mukund Pondkule
* Prabhakar Shrestha
* Anne Springer
* Lukas Strebel

## About this documentation
Expand Down
25 changes: 25 additions & 0 deletions interface/framework/add_obs_error_pdaf.F90
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,11 @@ SUBROUTINE add_obs_error_pdaf(step, dim_obs, C_p)
! !USES:
USE mod_assimilation, &
ONLY: rms_obs, obs_pdaf2nc
USE mod_assimilation, ONLY: obscov

USE mod_read_obs, ONLY: multierr,clm_obserr, pressure_obserr
USE mod_read_obs, ONLY: vec_useObs_global
USE enkf_clm_mod, ONLY: clmupdate_tws
USE mod_parallel_pdaf, ONLY: mype_world
USE mod_parallel_pdaf, ONLY: abort_parallel
USE mod_tsmp, ONLY: point_obs
Expand All @@ -72,7 +75,9 @@ SUBROUTINE add_obs_error_pdaf(step, dim_obs, C_p)

! *** local variables ***
INTEGER :: i ! index of observation component
INTEGER :: j ! index of observation component
REAL :: variance_obs ! variance of observations
REAL :: clm_obserr_model(dim_obs) ! errors of observations in the model domain


! **********************
Expand All @@ -98,6 +103,8 @@ SUBROUTINE add_obs_error_pdaf(step, dim_obs, C_p)

if(multierr==1) then

NOGRACE: if (clmupdate_tws/=1) then

! Check that point observations are used
if (.not. point_obs == 1) then
print *, "TSMP-PDAF mype(w)=", mype_world, ": ERROR(3) `point_obs.eq.1` needed for using obs_pdaf2nc."
Expand All @@ -111,6 +118,24 @@ SUBROUTINE add_obs_error_pdaf(step, dim_obs, C_p)
C_p(i,i) = C_p(i,i) + pressure_obserr(obs_pdaf2nc(i))*pressure_obserr(obs_pdaf2nc(i))
#endif
enddo

else NOGRACE

clm_obserr_model = pack(clm_obserr,vec_useObs_global)
do i = 1,dim_obs
C_p(i,i) = C_p(i,i) + clm_obserr_model(i) ! we put already variances in GRACE observation files, so no square need
end do

end if NOGRACE

endif

if(multierr==2) then
do i = 1, size(obscov,1)
do j = 1, size(obscov,2)
C_p(i,j) = C_p(i,j)+obscov(i,j)
end do
end do
end if

END SUBROUTINE add_obs_error_pdaf
5 changes: 5 additions & 0 deletions interface/framework/g2l_obs_pdaf.F90
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ SUBROUTINE g2l_obs_pdaf(domain_p, step, dim_obs_f, dim_obs_l, mstate_f, &
! !USES:
USE mod_assimilation, &
ONLY: obs_index_l, obs_nc2pdaf
USE enkf_clm_mod, ONLY: clmupdate_tws

IMPLICIT NONE

Expand Down Expand Up @@ -89,8 +90,12 @@ SUBROUTINE g2l_obs_pdaf(domain_p, step, dim_obs_f, dim_obs_l, mstate_f, &
! Index array OBS_NC2PDAF set in subroutine INIT_DIM_OBS_F_PDAF
! Index array OBS_INDEX_L (returns nc-ordered index) set in subroutine INIT_DIM_OBS_L_PDAF
do i=1,dim_obs_l
GRACE: if (clmupdate_tws==1) then
mstate_l(i) = mstate_f(obs_index_l(i))
else GRACE
!mstate_l(i) = mstate_f(obs_index_l(i))
mstate_l(i) = mstate_f(obs_nc2pdaf(obs_index_l(i)))
end if GRACE
end do

END SUBROUTINE g2l_obs_pdaf
153 changes: 153 additions & 0 deletions interface/framework/g2l_state_pdaf.F90
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ SUBROUTINE g2l_state_pdaf(step, domain_p, dim_p, state_p, dim_l, state_l)
USE mod_tsmp, &
ONLY: nx_local, ny_local
#if defined CLMSA
use enkf_clm_mod, only: hactiveg_levels, num_layer, state_setup, num_hactiveg_patch, hactiveg_patch, clm_varsize_tws
USE enkf_clm_mod, ONLY: clmupdate_tws
USE enkf_clm_mod, ONLY: g2l_state_clm
#endif

Expand All @@ -68,6 +70,7 @@ SUBROUTINE g2l_state_pdaf(step, domain_p, dim_p, state_p, dim_l, state_l)
REAL, TARGET, INTENT(out) :: state_l(dim_l) ! State vector on local analysis domain

INTEGER :: i, n_domain, nshift_p
INTEGER :: sub, j, g
INTEGER :: begg, endg ! per-proc gridcell ending gridcell indices
! !CALLING SEQUENCE:
! Called by: PDAF_lseik_update (as U_g2l_state)
Expand All @@ -90,7 +93,157 @@ SUBROUTINE g2l_state_pdaf(step, domain_p, dim_p, state_p, dim_l, state_l)
end if
!call g2l_state(domain_p, c_loc(state_p), dim_l, c_loc(state_l))
#else
if (clmupdate_tws/=1) then
call g2l_state_clm(domain_p, dim_p, state_p, dim_l, state_l)
end if

if (clmupdate_tws==1) then


! first depth dependent variables --> liq and ice (together in statevector or not)
! dim_l is number of layers of gridcell + 3 (3 for other compartments that are added to the statevector)
! lets loop over known layers

! first do canopy water to check how many variables are for this gridcell available next to snow and surface water as well as the layers
! compartments to subtract from dim_l to get layers variables:

if (clm_varsize_tws(5)/=0) then
sub=3
else
sub=2
end if


select case (state_setup)
case(0) ! liq and ice seperated
g = hactiveg_levels(domain_p,1)
do i = 1, (dim_l-sub)/2 ! two entries for liq and ice seperated
do j = 1, num_layer(i) ! i is the layer that we are in right now
if (g==hactiveg_levels(j,i)) then ! if the counter is the gridcell of the local domain, we know the position in the statevector

if (i == 1) then ! if first layer
state_l(i) = state_p(j) ! first liquid water as it is first in the statevector
state_l(i+(dim_l-3)/2) = state_p(j+clm_varsize_tws(1))
else
state_l(i) = state_p(j + sum(num_layer(1:i-1)))
state_l(i+(dim_l-3)/2) = state_p(j + sum(num_layer(1:i-1)) + clm_varsize_tws(1))
end if

end if
end do
end do

do j = 1, num_layer(1)
if (g==hactiveg_levels(j,1)) then
if (sub==3) then
state_l(dim_l-2) = state_p(j + clm_varsize_tws(1) + clm_varsize_tws(2))
state_l(dim_l-1) = state_p(j + clm_varsize_tws(1) + clm_varsize_tws(2) + clm_varsize_tws(3))
state_l(dim_l) = state_p(j + clm_varsize_tws(1) + clm_varsize_tws(2) + clm_varsize_tws(3) + clm_varsize_tws(4))
else
state_l(dim_l-1) = state_p(j + clm_varsize_tws(1) + clm_varsize_tws(2))
state_l(dim_l) = state_p(j + clm_varsize_tws(1) + clm_varsize_tws(2) + clm_varsize_tws(3))
end if
end if
end do

case(1)

g = hactiveg_levels(domain_p,1)
do i = 1, dim_l-sub ! liq and ice added up
do j = 1, num_layer(i) ! i is the layer that we are in right now
if (g==hactiveg_levels(j,i)) then ! if the counter is the gridcell of the local domain, we know the position in the statevector

if (i == 1) then ! if first layer
state_l(i) = state_p(j) ! first liquid water as it is first in the statevector
else
state_l(i) = state_p(j + sum(num_layer(1:i-1)))
end if

end if
end do
end do

do j = 1, num_layer(1)
if (g==hactiveg_levels(j,1)) then
if (sub==3) then
state_l(dim_l-2) = state_p(j + clm_varsize_tws(1) + clm_varsize_tws(2))
state_l(dim_l-1) = state_p(j + clm_varsize_tws(1) + clm_varsize_tws(2) + clm_varsize_tws(3))
state_l(dim_l) = state_p(j + clm_varsize_tws(1) + clm_varsize_tws(2) + clm_varsize_tws(3) + clm_varsize_tws(4))
else
state_l(dim_l-1) = state_p(j + clm_varsize_tws(1) + clm_varsize_tws(2))
state_l(dim_l) = state_p(j + clm_varsize_tws(1) + clm_varsize_tws(2) + clm_varsize_tws(3))
end if
end if
end do

case(2) ! only tws in statevector
g = hactiveg_levels(domain_p,1)
do j = 1, num_layer(1)
if (g==hactiveg_levels(j,1)) then
state_l(1) = state_p(j)
end if
end do

case(3)

g = hactiveg_levels(domain_p,1)

do j = 1, num_layer(1)
if (g==hactiveg_levels(j,1)) then
state_l(1) = state_p(j)
state_l(2) = state_p(j + clm_varsize_tws(1) + clm_varsize_tws(2))
end if
end do

case(4)

g = hactiveg_levels(domain_p,1)

do j = 1, num_layer(1)
if (g==hactiveg_levels(j,1)) then
state_l(1) = state_p(j)
state_l(dim_l) = state_p(j + clm_varsize_tws(1) + clm_varsize_tws(2))
end if
end do

if (dim_l==3) then
do j = 1, num_layer(8)
if (g==hactiveg_levels(j,8)) then
state_l(2) = state_p(j + clm_varsize_tws(1))
end if
end do
end if

case(5)

g = hactiveg_levels(domain_p,1)

do j = 1, num_layer(1)
if (g==hactiveg_levels(j,1)) then
state_l(1) = state_p(j)
state_l(dim_l) = state_p(j + clm_varsize_tws(1) + clm_varsize_tws(2) + clm_varsize_tws(3))
end if
end do

if (dim_l>=3) then
do j = 1, num_layer(4)
if (g==hactiveg_levels(j,4)) then
state_l(2) = state_p(j + clm_varsize_tws(1))
end if
end do
end if

if (dim_l>=4) then
do j = 1, num_layer(13)
if (g==hactiveg_levels(j,13)) then
state_l(3) = state_p(j + clm_varsize_tws(1) + clm_varsize_tws(2))
end if
end do
end if

end select

end if
#endif

END SUBROUTINE g2l_state_pdaf
91 changes: 91 additions & 0 deletions interface/framework/init_dim_l_pdaf.F90
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ SUBROUTINE init_dim_l_pdaf(step, domain_p, dim_l)
tag_model_clm, model
USE mod_tsmp, &
ONLY: init_dim_l_pfl
use clm_varpar , only : nlevsoi
#ifdef CLMSA
USE enkf_clm_mod, &
ONLY: hactiveg_levels, num_layer, state_setup, num_hactiveg_patch, hactiveg_patch, clm_varsize_tws
USE enkf_clm_mod, ONLY: clmupdate_tws
USE enkf_clm_mod, ONLY: init_dim_l_clm
#endif
IMPLICIT NONE
Expand All @@ -59,6 +63,8 @@ SUBROUTINE init_dim_l_pdaf(step, domain_p, dim_l)
INTEGER, INTENT(in) :: domain_p ! Current local analysis domain
INTEGER, INTENT(out) :: dim_l ! Local state dimension

integer :: g, i, count

! !CALLING SEQUENCE:
! Called by: PDAF_lseik_update (as U_init_dim_l)
! Called by: PDAF_lestkf_update (as U_init_dim_l)
Expand All @@ -68,6 +74,7 @@ SUBROUTINE init_dim_l_pdaf(step, domain_p, dim_l)
! ****************************************
! *** Initialize local state dimension ***
! ****************************************

#if defined PARFLOW_STAND_ALONE
! Set the size of the local analysis domain
call init_dim_l_pfl(dim_l)
Expand All @@ -88,7 +95,91 @@ SUBROUTINE init_dim_l_pdaf(step, domain_p, dim_l)
! Set the size of the local analysis domain
! for clm stand alone mode only

if (clmupdate_tws/=1) then
call init_dim_l_clm(domain_p, dim_l)
end if

! Set the size of the local analysis domain
! for clm stand alone mode only
if (clmupdate_tws==1) then

! initialize local state dimension --> different for each domain as a domain is a gridcell, number of layers in statevector differs per gridcell
! --> check with begg and endg as well as domain_p and hactiveg_levels what is going on
! hactiveg_levels in level 1 at position domain_p gives gridcell index of domain_p --> go through rest of hactiveg_levels and check for number of layers
dim_l = 0
g = hactiveg_levels(domain_p,1)

select case(state_setup)
case(0)
do i = 1,nlevsoi
do count = 1, num_layer(i)
if (g==hactiveg_levels(count,i)) then
dim_l = dim_l+2
end if
end do
end do

! snow and surface water
dim_l = dim_l+2

! canopy water
if (clm_varsize_tws(5)/=0) then
dim_l = dim_l+1
end if

case(1)
do i = 1,nlevsoi
do count = 1, num_layer(i)
if (g==hactiveg_levels(count,i)) then
dim_l = dim_l+1
end if
end do
end do

! snow and surface water
dim_l = dim_l+2

if (clm_varsize_tws(5)/=0) then
dim_l = dim_l+1
end if

case(2) ! only TWS in statevector

dim_l=1

case(3) ! sum over all soil layers and snow in statevector

dim_l=2

case(4)

dim_l=2

do count = 1, num_layer(8)
if (g==hactiveg_levels(count,8)) then
dim_l = dim_l+1
end if
end do

case(5)

dim_l=2

do count = 1, num_layer(4)
if (g==hactiveg_levels(count,4)) then
dim_l = dim_l+1
end if
end do

do count = 1, num_layer(13)
if (g==hactiveg_levels(count,13)) then
dim_l = dim_l+1
end if
end do

end select

end if
#endif

END SUBROUTINE init_dim_l_pdaf
Loading