Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c49edbe
first implementation of LST-DA
jjokella Dec 5, 2024
0fb734a
bugfix: re-introduce default for general update
jjokella Dec 12, 2024
b186564
bugfix: lai is a patch-array
jjokella Dec 12, 2024
35c9c93
bugfix: typo
jjokella Dec 12, 2024
929471f
dev: skin temperature state vector, first implementation
jjokella Dec 12, 2024
0f3738b
dev: skin temperature state vector, first implementation II
jjokella Dec 12, 2024
53998fb
bugfix: t_skin declarations
jjokella Dec 13, 2024
75ac19f
bugfix: location of `newgridcell = .false`
jjokella Jan 23, 2025
34a47ca
LST-DA with TSKIN: use same obs_index_p setting as for TG/TV
jjokella Jan 23, 2025
43d1ba3
LST-DA: state-vector with TSKIN, plus TG and TV
jjokella Jan 23, 2025
3df6fd0
LST-DA: state-vector with TSKIN, plus TSOIL and TV
jjokella Jan 23, 2025
9e88c2a
LST-DA: add debug output for first layer `t_soisno`
jjokella Jan 24, 2025
ff0373a
LST-DA: all temperature layers updated
jjokella Jan 28, 2025
4bd276d
bugfix: LST-DA missing `end do`
jjokella Jan 29, 2025
75eb0ec
Merge branch 'tsmp-pdaf-patched' into tsmp-pdaf-patched-lstda
jjokella Mar 17, 2025
d41c6b2
Merge branch 'tsmp-pdaf-patched' into tsmp-pdaf-patched-lstda
jjokella Apr 25, 2025
0778801
introduce `clmupdate_T.eq.4`
jjokella Apr 25, 2025
6d8babe
Merge branch 'tsmp-pdaf-patched' into tsmp-pdaf-patched-lstda
jjokella Oct 9, 2025
fb67c10
fortitude fixes
jjokella Oct 9, 2025
75f2b8d
keep indentation of SM-case
jjokella Oct 9, 2025
2b7f957
syntax fix
jjokella Oct 9, 2025
6a6706a
line length fixes
jjokella Oct 9, 2025
90cefc6
Merge branch 'tsmp-pdaf-patched' into tsmp-pdaf-patched-lstda
jjokella Oct 17, 2025
9936414
CI-fix: handle clmswc_mask_snow as integer (#29)
jjokella Oct 29, 2025
9625bee
Merge branch 'tsmp-pdaf-patched' into tsmp-pdaf-patched-lstda
jjokella Nov 14, 2025
319bd8c
style changes
jjokella Nov 14, 2025
35b1dc0
set_clm_statevec_T: debug output to dedicated subroutine
jjokella Nov 14, 2025
58501ab
update_clm_T: all declarations to dedicated subroutine
jjokella Nov 14, 2025
3847db7
compilation fixes
jjokella Nov 14, 2025
ee6cc3e
compilation fixes for DEBUG
jjokella Nov 14, 2025
7174f1b
add LSTDA of TSKIN/TVEG (clmupdate_T==5)
jjokella Nov 20, 2025
95a0e5f
Merge branch 'tsmp-pdaf-patched' into tsmp-pdaf-patched-lstda
jjokella Dec 18, 2025
747dee9
correct condition for tsoisno_mype.update.* debug output
jjokella Dec 19, 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
102 changes: 101 additions & 1 deletion interface/framework/init_dim_obs_f_pdaf.F90
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ SUBROUTINE init_dim_obs_f_pdaf(step, dim_obs_f)
#ifdef CLMFIVE
use GridcellType, only: grc
use ColumnType, only : col
use PatchType, only : patch
! use GetGlobalValuesMod, only: GetGlobalWrite
! use clm_varcon, only: nameg
use enkf_clm_mod, only: state_clm2pdaf_p
Expand All @@ -145,6 +146,8 @@ SUBROUTINE init_dim_obs_f_pdaf(step, dim_obs_f)
USE enkf_clm_mod, only: domain_def_clm
USE enkf_clm_mod, only: get_interp_idx
use enkf_clm_mod, only: clmstatevec_allcol
use enkf_clm_mod, only: clmupdate_swc
use enkf_clm_mod, only: clmupdate_T
!hcp end
#endif
#endif
Expand All @@ -164,9 +167,12 @@ SUBROUTINE init_dim_obs_f_pdaf(step, dim_obs_f)
integer :: ierror
INTEGER :: max_var_id ! Multi-scale DA
INTEGER :: sum_dim_obs_p
INTEGER :: p ! CLM Patch index
INTEGER :: c ! CLM Column index
INTEGER :: g ! CLM Gridcell index
INTEGER :: cg
INTEGER :: pg
INTEGER :: pc
INTEGER :: i,j,k ! Counters
INTEGER :: cnt ! Counters
INTEGER :: cnt_interp ! Counter for interpolation grid cells
Expand Down Expand Up @@ -935,6 +941,8 @@ SUBROUTINE init_dim_obs_f_pdaf(step, dim_obs_f)
do i = 1, dim_obs
obs(i) = clm_obs(i)

if(clmupdate_swc==1) then

do g = begg,endg
newgridcell = .true.

Expand Down Expand Up @@ -1004,9 +1012,101 @@ SUBROUTINE init_dim_obs_f_pdaf(step, dim_obs_f)
end if

end if

end do
end do

else if(clmupdate_T==1 .or. clmupdate_T==2 .or. clmupdate_T==3 .or. clmupdate_T==4) then
#ifdef CLMFIVE
! patch loop
do g = begg,endg
newgridcell = .true.

do p = begp,endp

pg = patch%gridcell(p)
pc = patch%column(p)

if(pg == g) then
if(newgridcell) then
! Sets first patch/column in a gridcell. TODO: Make
! patch / column information part of the observation
! file

if(is_use_dr) then
deltax = abs(lon(g)-clmobs_lon(i))
deltay = abs(lat(g)-clmobs_lat(i))
end if

if(((is_use_dr).and.(deltax<=clmobs_dr(1)).and.(deltay<=clmobs_dr(2))).or. &
((.not. is_use_dr).and.(longxy_obs(i) == longxy(g-begg+1)) .and. (latixy_obs(i) == latixy(g-begg+1)))) then

! Set index in state vector, LST will be computed
! for first patch appearing here
obs_index_p(cnt) = state_clm2pdaf_p(p,1)

!write(*,*) 'obs_index_p(',cnt,') is',obs_index_p(cnt)
obs_p(cnt) = clm_obs(i)
if(multierr==1) clm_obserr_p(cnt) = clm_obserr(i)
cnt = cnt + 1

end if

newgridcell = .false.

end if
end if

end do
end do
#else
! gridcell loop
do g = begg,endg

if(is_use_dr) then
deltax = abs(lon(g)-clmobs_lon(i))
deltay = abs(lat(g)-clmobs_lat(i))
end if

if(((is_use_dr).and.(deltax<=clmobs_dr(1)).and.(deltay<=clmobs_dr(2))).or. &
((.not. is_use_dr).and.(longxy_obs(i) == longxy(g-begg+1)) .and. (latixy_obs(i) == latixy(g-begg+1)))) then
obs_index_p(cnt) = g-begg+1
end if

!write(*,*) 'obs_index_p(',cnt,') is',obs_index_p(cnt)
obs_p(cnt) = clm_obs(i)
if(multierr==1) clm_obserr_p(cnt) = clm_obserr(i)
cnt = cnt + 1

end do
#endif
else

print *, "TSMP-PDAF mype(w)=", mype_world, ": WARNING unsupported update in setting obs_index_p."
print *, "TSMP-PDAF mype(w)=", mype_world, ": WARNING using default gridcell loop."
! call abort_parallel()

! gridcell loop with layer information as default!
do g = begg,endg

if(is_use_dr) then
deltax = abs(lon(g)-clmobs_lon(i))
deltay = abs(lat(g)-clmobs_lat(i))
end if

if(((is_use_dr).and.(deltax<=clmobs_dr(1)).and.(deltay<=clmobs_dr(2))).or. &
((.not. is_use_dr).and.(longxy_obs(i) == longxy(g-begg+1)) .and. (latixy_obs(i) == latixy(g-begg+1)))) then
obs_index_p(cnt) = g-begg+1 + ((endg-begg+1) * (clmobs_layer(i)-1))
end if

!write(*,*) 'obs_index_p(',cnt,') is',obs_index_p(cnt)
obs_p(cnt) = clm_obs(i)
if(multierr==1) clm_obserr_p(cnt) = clm_obserr(i)
cnt = cnt + 1

end do

end if

end do

if(obs_interp_switch==1) then
Expand Down
102 changes: 101 additions & 1 deletion interface/framework/init_dim_obs_pdaf.F90
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ SUBROUTINE init_dim_obs_pdaf(step, dim_obs_p)
#ifdef CLMFIVE
use GridcellType, only: grc
use ColumnType, only : col
use PatchType, only : patch
! use GetGlobalValuesMod, only: GetGlobalWrite
! use clm_varcon, only: nameg
use enkf_clm_mod, only: state_clm2pdaf_p
Expand All @@ -141,6 +142,8 @@ SUBROUTINE init_dim_obs_pdaf(step, dim_obs_p)
USE enkf_clm_mod, only: domain_def_clm
USE enkf_clm_mod, only: get_interp_idx
use enkf_clm_mod, only: clmstatevec_allcol
use enkf_clm_mod, only: clmupdate_swc
use enkf_clm_mod, only: clmupdate_T
!hcp end
#endif
#endif
Expand All @@ -160,9 +163,12 @@ SUBROUTINE init_dim_obs_pdaf(step, dim_obs_p)
integer :: ierror
INTEGER :: max_var_id ! Multi-scale DA
INTEGER :: sum_dim_obs_p
INTEGER :: p ! CLM Patch index
INTEGER :: c ! CLM Column index
INTEGER :: g ! CLM Gridcell index
INTEGER :: cg
INTEGER :: pg
INTEGER :: pc
INTEGER :: i,j,k ! Counters
INTEGER :: cnt ! Counters
INTEGER :: cnt_interp ! Counter for interpolation grid cells
Expand Down Expand Up @@ -928,6 +934,8 @@ SUBROUTINE init_dim_obs_pdaf(step, dim_obs_p)
do i = 1, dim_obs
obs(i) = clm_obs(i)

if(clmupdate_swc==1) then

do g = begg,endg
newgridcell = .true.

Expand Down Expand Up @@ -997,9 +1005,101 @@ SUBROUTINE init_dim_obs_pdaf(step, dim_obs_p)
end if

end if

end do
end do

else if(clmupdate_T==1 .or. clmupdate_T==2 .or. clmupdate_T==3 .or. clmupdate_T==4 .or. clmupdate_T==5) then
#ifdef CLMFIVE
! patch loop
do g = begg,endg
newgridcell = .true.

do p = begp,endp

pg = patch%gridcell(p)
pc = patch%column(p)

if(pg == g) then
if(newgridcell) then
! Sets first patch/column in a gridcell. TODO: Make
! patch / column information part of the observation
! file

if(is_use_dr) then
deltax = abs(lon(g)-clmobs_lon(i))
deltay = abs(lat(g)-clmobs_lat(i))
end if

if(((is_use_dr).and.(deltax<=clmobs_dr(1)).and.(deltay<=clmobs_dr(2))).or. &
((.not. is_use_dr).and.(longxy_obs(i) == longxy(g-begg+1)) .and. (latixy_obs(i) == latixy(g-begg+1)))) then

! Set index in state vector, LST will be computed
! for first patch appearing here
obs_index_p(cnt) = state_clm2pdaf_p(p,1)

!write(*,*) 'obs_index_p(',cnt,') is',obs_index_p(cnt)
obs_p(cnt) = clm_obs(i)
if(multierr==1) clm_obserr_p(cnt) = clm_obserr(i)
cnt = cnt + 1

end if

newgridcell = .false.

end if
end if

end do
end do
#else
! gridcell loop
do g = begg,endg

if(is_use_dr) then
deltax = abs(lon(g)-clmobs_lon(i))
deltay = abs(lat(g)-clmobs_lat(i))
end if

if(((is_use_dr).and.(deltax<=clmobs_dr(1)).and.(deltay<=clmobs_dr(2))).or. &
((.not. is_use_dr).and.(longxy_obs(i) == longxy(g-begg+1)) .and. (latixy_obs(i) == latixy(g-begg+1)))) then
obs_index_p(cnt) = g-begg+1
end if

!write(*,*) 'obs_index_p(',cnt,') is',obs_index_p(cnt)
obs_p(cnt) = clm_obs(i)
if(multierr==1) clm_obserr_p(cnt) = clm_obserr(i)
cnt = cnt + 1

end do
#endif
else

print *, "TSMP-PDAF mype(w)=", mype_world, ": WARNING unsupported update in setting obs_index_p."
print *, "TSMP-PDAF mype(w)=", mype_world, ": WARNING using default gridcell loop."
! call abort_parallel()

! gridcell loop with layer information as default!
do g = begg,endg

if(is_use_dr) then
deltax = abs(lon(g)-clmobs_lon(i))
deltay = abs(lat(g)-clmobs_lat(i))
end if

if(((is_use_dr).and.(deltax<=clmobs_dr(1)).and.(deltay<=clmobs_dr(2))).or. &
((.not. is_use_dr).and.(longxy_obs(i) == longxy(g-begg+1)) .and. (latixy_obs(i) == latixy(g-begg+1)))) then
obs_index_p(cnt) = g-begg+1 + ((endg-begg+1) * (clmobs_layer(i)-1))
end if

!write(*,*) 'obs_index_p(',cnt,') is',obs_index_p(cnt)
obs_p(cnt) = clm_obs(i)
if(multierr==1) clm_obserr_p(cnt) = clm_obserr(i)
cnt = cnt + 1

end do

end if

end do

if(obs_interp_switch==1) then
Expand Down
25 changes: 19 additions & 6 deletions interface/framework/obs_op_pdaf.F90
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,14 @@ SUBROUTINE obs_op_pdaf(step, dim_p, dim_obs_p, state_p, m_state_p)

lpointobs = .false.

! Equation for LST computation from Kustas2009, Eq(7)
! http://dx.doi.org/10.1016/j.agrformet.2009.05.016
!
! Comment: Fractional vegetation cover (Eq(8) from Kustas2009)
! currently implemented with simplified settings: Vegetation
! clumping parameter `Omega=1`; radiometer view angle `phi=0`

DO i = 1, dim_obs_p
! Equation for LST computation from Kustas2009, Eq(7)
! http://dx.doi.org/10.1016/j.agrformet.2009.05.016
!
! Comment: Fractional vegetation cover (Eq(8) from Kustas2009)
! currently implemented with simplified settings: Vegetation
! clumping parameter `Omega=1`; radiometer view angle `phi=0`
m_state_p(i) &
= (exp(-0.5*clm_paramarr(obs_index_p(i))) &
*state_p(obs_index_p(i))**4 &
Expand All @@ -151,6 +152,18 @@ SUBROUTINE obs_op_pdaf(step, dim_p, dim_obs_p, state_p, m_state_p)
! write(*,*) 'model LST', m_state_p(:)
! write(*,*) 'TG', state_p(obs_index_p(:))
! write(*,*) 'TV', state_p(clm_varsize+obs_index_p(:))

endif

if (clmupdate_T==2 .OR. clmupdate_T==3 .OR. clmupdate_T==4 .OR. clmupdate_T==5) then

lpointobs = .false.

DO i = 1, dim_obs_p
! first implementation: simulated LST equals TSKIN
m_state_p(i) = state_p(obs_index_p(i))
END DO

endif
#endif

Expand Down
Loading