Skip to content
Open
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
26 changes: 26 additions & 0 deletions bld/namelist_files/namelist_definition.xml
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,32 @@
Default: FALSE
</entry>

<entry id="Nudge_SpectralFilter" type="logical" category="nudging"
group="nudging_nl" valid_values="" >
Toggle Spectral Filtering of Nudging Tendencies ON/OFF.

Nudge_SpectralFilter - LOGICAL Option to apply spherical harminic filtering to
the model state and target data so that nudging
tendencies are only applied to scales larger than
the specified truncation.
Default: FALSE
</entry>

<entry id="Nudge_SpectralNtrunc" type="integer" category="nudging"
group="nudging_nl" valid_values="" >
Set Horizonal Scale for Spectral Filtering

Nudge_SpectralNtrunc - INT The number of meridional spherical harmonic modes used
for spectral filtering. The nominal horizontal scale of
the filtering can be estimated as:

Hscale = PI*6350/Nudge_SpectralNtrunc

i.e. Nudge_SpectralNtrunc=40 corresponds to a horizontal
nudging scale Hscale~500km.
Default: -1
</entry>

<entry id="Nudge_Path" type="char*256" input_pathname="abs" category="nudging"
group="nudging_nl" valid_values="" >
Full pathname of analyses data to use for nudging.
Expand Down
2 changes: 2 additions & 0 deletions cime_config/testdefs/testmods_dirs/cam/nudging/user_nl_cam
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
Nudge_TimeScale_Opt = 0
Nudge_Times_Per_Day=4
Model_Times_Per_Day=48
Nudge_SpectralFilter=.false.
Nudge_SpectralNtrunc=-1
Nudge_Uprof =1
Nudge_Ucoef =1.00
Nudge_Vprof =1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
Nudge_TimeScale_Opt = 0
Nudge_Times_Per_Day=4
Model_Times_Per_Day=48
Nudge_SpectralFilter=.false.
Nudge_SpectralNtrunc=-1
Nudge_Uprof =1
Nudge_Ucoef =1.00
Nudge_Vprof =1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
Nudge_TimeScale_Opt = 0
Nudge_Times_Per_Day=4
Model_Times_Per_Day=48
Nudge_SpectralFilter=.false.
Nudge_SpectralNtrunc=-1
Nudge_Uprof =1
Nudge_Ucoef =1.00
Nudge_Vprof =1
Expand Down
105 changes: 96 additions & 9 deletions src/physics/cam/nudging.F90
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ module nudging
! Some analyses products can have gaps in the available data, where values
! are missing for some interval of time. When files are missing, the nudging
! force is switched off for that interval of time, so we effectively 'coast'
! thru the gap.
! thru the gap. The default behavior is now for the model to error exit if there
! is a gap. Users with known gaps in their nuding data can manually change the
! gap behavior to accomodate their needs.
!
! Currently, the nudging module is set up to accomodate nudging of PS
! values, however that functionality requires forcing that is applied in
Expand Down Expand Up @@ -149,6 +151,20 @@ module nudging
! 0 --> TimeScale = 1/Tdlt_Anal [DEFAULT]
! 1 --> TimeScale = 1/(t'_next - t_curr )
!
! Nudge_SpectralFilter - LOGICAL Option to apply spherical harminic filtering to
! the model state and target data so that nudging
! tendencies are only applied to scales larger than
! the specified truncation.
!
! Nudge_SpectralNtrunc - INT The number of meridional spherical harmonic modes used
! for spectral filtering. The nominal horizontal scale of
! the filtering can be estimated as:
!
! Hscale = PI*6350/Nudge_SpectralNtrunc
!
! i.e. Nudge_SpectralNtrunc=40 corresponds to a horizontal
! nudging scale Hscale~500km.
!
! Nudge_Uprof - INT index of profile structure to use for U. [0,1,2]
! Nudge_Vprof - INT index of profile structure to use for V. [0,1,2]
! Nudge_Tprof - INT index of profile structure to use for T. [0,1,2]
Expand Down Expand Up @@ -202,6 +218,7 @@ module nudging
use spmd_utils, only: mpi_integer, mpi_real8, mpi_logical, mpi_character
use cam_logfile, only: iulog
use zonal_mean_mod, only: ZonalMean_t
use spherical_harmonic_mod, only: SphericalHarmonic_t

! Set all Global values and routines to private by default
! and then explicitly set their exposure.
Expand Down Expand Up @@ -273,14 +290,21 @@ module nudging
real(r8) :: Nudge_Hwin_max
real(r8) :: Nudge_Hwin_min

! Nudging Zonal Filter variables
!---------------------------------
! Nudging Zonal/Spectral Filter variables
!-----------------------------------------
logical :: Nudge_ZonalFilter =.false.
integer :: Nudge_ZonalNbasis = -1
type(ZonalMean_t) :: ZM
real(r8),allocatable:: Zonal_Bamp2d(:)
real(r8),allocatable:: Zonal_Bamp3d(:,:)

logical :: Nudge_SpectralFilter =.false.
integer :: Nudge_SpectralNtrunc = -1
integer :: Nudge_SpectralNbasis = -1
Copy link

Choose a reason for hiding this comment

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

I am not seeing where Nudge_SpectralNbasis gets sets. Is it always -1?

type(SphericalHarmonic_t):: SH
real(r8),allocatable:: Spectral_Bamp2d(:)
real(r8),allocatable:: Spectral_Bamp3d(:,:)

! Nudging State Arrays
!-----------------------
integer :: Nudge_nlon,Nudge_nlat,Nudge_ncol,Nudge_nlev
Expand Down Expand Up @@ -343,6 +367,7 @@ subroutine nudging_readnl(nlfile)
Nudge_File_Template, Nudge_Force_Opt, &
Nudge_TimeScale_Opt, &
Nudge_Times_Per_Day, Model_Times_Per_Day, &
Nudge_SpectralFilter, Nudge_SpectralNtrunc, &
Nudge_Ucoef , Nudge_Uprof, &
Nudge_Vcoef , Nudge_Vprof, &
Nudge_Qcoef , Nudge_Qprof, &
Expand Down Expand Up @@ -583,6 +608,10 @@ subroutine nudging_readnl(nlfile)
if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_ZonalFilter')
call MPI_bcast(Nudge_ZonalNbasis, 1, mpi_integer, mstrid, mpicom, ierr)
if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_ZonalNbasis')
call MPI_bcast(Nudge_SpectralFilter, 1, mpi_logical, mstrid, mpicom, ierr)
if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_SpectralFilter')
call MPI_bcast(Nudge_SpectralNtrunc, 1, mpi_integer, mstrid, mpicom, ierr)
if (ierr /= mpi_success) call endrun(prefix//'FATAL: mpi_bcast: Nudge_SpectralNtrunc')

! End Routine
!------------
Expand Down Expand Up @@ -848,6 +877,8 @@ subroutine nudging_init
write(iulog,*) 'NUDGING: Model_Step=',Model_Step
write(iulog,*) 'NUDGING: Nudge_ZonalFilter=',Nudge_ZonalFilter
write(iulog,*) 'NUDGING: Nudge_ZonalNbasis=',Nudge_ZonalNbasis
write(iulog,*) 'NUDGING: Nudge_SpectralFilter=',Nudge_SpectralFilter
write(iulog,*) 'NUDGING: Nudge_SpectralNtrunc=',Nudge_SpectralNtrunc
write(iulog,*) 'NUDGING: Nudge_Ucoef =',Nudge_Ucoef
write(iulog,*) 'NUDGING: Nudge_Vcoef =',Nudge_Vcoef
write(iulog,*) 'NUDGING: Nudge_Qcoef =',Nudge_Qcoef
Expand Down Expand Up @@ -985,8 +1016,8 @@ subroutine nudging_init
endif
!!DIAG

! Initialize the Zonal Mean type if needed
!------------------------------------------
! Initialize the Zonal Mean Spectral type if needed
!--------------------------------------------------
if(Nudge_ZonalFilter) then
call ZM%init(Nudge_ZonalNbasis)
allocate(Zonal_Bamp2d(Nudge_ZonalNbasis),stat=istat)
Expand All @@ -995,6 +1026,17 @@ subroutine nudging_init
call alloc_err(istat,'nudging_init','Zonal_Bamp3d',Nudge_ZonalNbasis*pver)
endif

if(Nudge_SpectralFilter) then
write(iulog,*) 'NUDGING: calling SH%init() Nudge_SpectralNtrunc =',Nudge_SpectralNtrunc
call SH%init(Nudge_SpectralNtrunc,Nudge_SpectralNbasis)
write(iulog,*) 'NUDGING: done SH%init() Nudge_SpectralNbasis =',Nudge_SpectralNbasis
allocate(Spectral_Bamp2d(Nudge_SpectralNbasis),stat=istat)
call alloc_err(istat,'nudging_init','Spectral_Bamp2d',Nudge_SpectralNbasis)
allocate(Spectral_Bamp3d(Nudge_SpectralNbasis,pver),stat=istat)
call alloc_err(istat,'nudging_init','Spectral_Bamp3d',Nudge_SpectralNbasis*pver)
write(iulog,*) 'NUDGING: SH% Arrays allocated'
endif

! Initialize the analysis filename at the NEXT time for startup.
!---------------------------------------------------------------
Nudge_File=interpret_filename_spec(Nudge_File_Template , &
Expand Down Expand Up @@ -1199,8 +1241,8 @@ subroutine nudging_timestep_init(phys_state)
end do
endif

! Optionally: Apply Zonal Filtering to Model state data
!-------------------------------------------------------
! Optionally: Apply Zonal/Spectral Filtering to Model state data
!----------------------------------------------------------------
if(Nudge_ZonalFilter) then
call ZM%calc_amps(Model_U,Zonal_Bamp3d)
call ZM%eval_grid(Zonal_Bamp3d,Model_U)
Expand All @@ -1220,6 +1262,26 @@ subroutine nudging_timestep_init(phys_state)
call ZM%calc_amps(Model_PS,Zonal_Bamp2d)
call ZM%eval_grid(Zonal_Bamp2d,Model_PS)
endif

if(Nudge_SpectralFilter) then
call SH%calc_amps(Model_U,Spectral_Bamp3d)
call SH%eval_grid(Spectral_Bamp3d,Model_U)

call SH%calc_amps(Model_V,Spectral_Bamp3d)
call SH%eval_grid(Spectral_Bamp3d,Model_V)

call SH%calc_amps(Model_T,Spectral_Bamp3d)
call SH%eval_grid(Spectral_Bamp3d,Model_T)

call SH%calc_amps(Model_S,Spectral_Bamp3d)
call SH%eval_grid(Spectral_Bamp3d,Model_S)

call SH%calc_amps(Model_Q,Spectral_Bamp3d)
call SH%eval_grid(Spectral_Bamp3d,Model_Q)

call SH%calc_amps(Model_PS,Spectral_Bamp2d)
call SH%eval_grid(Spectral_Bamp2d,Model_PS)
endif
endif ! ((Before_End) .and. (Update_Model)) then

!----------------------------------------------------------------
Expand Down Expand Up @@ -1286,9 +1348,11 @@ subroutine nudging_timestep_init(phys_state)
endif
if(.not.Nudge_ON) then
if(masterproc) then
write(iulog,*) 'NUDGING: WARNING - analyses file NOT FOUND. Switching '
write(iulog,*) 'NUDGING: nudging OFF to coast thru the gap. '
write(iulog,*) 'NUDGING: WARNING - analyses file NOT FOUND. You can switch nudging '
write(iulog,*) 'NUDGING: OFF to coast thru a known gap in your files '
write(iulog,*) 'NUDGING: by commenting out the following endrun command.'
endif
call endrun('nudging_timestep_init:: ERROR Missing Nudging File')
Comment on lines +1351 to +1355
Copy link

Choose a reason for hiding this comment

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

Should a namelist switch to turn on / off the abort behavior? I agree that aborting the run should be the default behavior.

endif
else
Nudge_ON=.false.
Expand Down Expand Up @@ -1556,6 +1620,10 @@ subroutine nudging_update_analyses(anal_file)
call ZM%calc_amps(Tmp3D,Zonal_Bamp3d)
call ZM%eval_grid(Zonal_Bamp3d,Tmp3D)
endif
if(Nudge_SpectralFilter) then
call SH%calc_amps(Tmp3D,Spectral_Bamp3d)
call SH%eval_grid(Spectral_Bamp3d,Tmp3D)
endif
Nobs_U(:,:,begchunk:endchunk,Nudge_ObsInd(1)) = Tmp3D(:,:,begchunk:endchunk)
else
call endrun('Variable "U" is missing in '//trim(anal_file))
Expand All @@ -1569,6 +1637,10 @@ subroutine nudging_update_analyses(anal_file)
call ZM%calc_amps(Tmp3D,Zonal_Bamp3d)
call ZM%eval_grid(Zonal_Bamp3d,Tmp3D)
endif
if(Nudge_SpectralFilter) then
call SH%calc_amps(Tmp3D,Spectral_Bamp3d)
call SH%eval_grid(Spectral_Bamp3d,Tmp3D)
endif
Nobs_V(:,:,begchunk:endchunk,Nudge_ObsInd(1)) = Tmp3D(:,:,begchunk:endchunk)
else
call endrun('Variable "V" is missing in '//trim(anal_file))
Expand All @@ -1582,6 +1654,10 @@ subroutine nudging_update_analyses(anal_file)
call ZM%calc_amps(Tmp3D,Zonal_Bamp3d)
call ZM%eval_grid(Zonal_Bamp3d,Tmp3D)
endif
if(Nudge_SpectralFilter) then
call SH%calc_amps(Tmp3D,Spectral_Bamp3d)
call SH%eval_grid(Spectral_Bamp3d,Tmp3D)
endif
Nobs_T(:,:,begchunk:endchunk,Nudge_ObsInd(1)) = Tmp3D(:,:,begchunk:endchunk)
else
call endrun('Variable "T" is missing in '//trim(anal_file))
Expand All @@ -1595,6 +1671,10 @@ subroutine nudging_update_analyses(anal_file)
call ZM%calc_amps(Tmp3D,Zonal_Bamp3d)
call ZM%eval_grid(Zonal_Bamp3d,Tmp3D)
endif
if(Nudge_SpectralFilter) then
call SH%calc_amps(Tmp3D,Spectral_Bamp3d)
call SH%eval_grid(Spectral_Bamp3d,Tmp3D)
endif
Nobs_Q(:,:,begchunk:endchunk,Nudge_ObsInd(1)) = Tmp3D(:,:,begchunk:endchunk)
else
call endrun('Variable "Q" is missing in '//trim(anal_file))
Expand All @@ -1608,6 +1688,10 @@ subroutine nudging_update_analyses(anal_file)
call ZM%calc_amps(Tmp2D,Zonal_Bamp2d)
call ZM%eval_grid(Zonal_Bamp2d,Tmp2D)
endif
if(Nudge_SpectralFilter) then
call SH%calc_amps(Tmp2D,Spectral_Bamp2d)
call SH%eval_grid(Spectral_Bamp2d,Tmp2D)
endif
Nobs_PS(:,begchunk:endchunk,Nudge_ObsInd(1)) = Tmp2D(:,begchunk:endchunk)
else
call endrun('Variable "PS" is missing in '//trim(anal_file))
Expand Down Expand Up @@ -1768,8 +1852,11 @@ subroutine nudging_final
if (allocated(Nobs_PS)) deallocate(Nobs_PS)
if (allocated(Zonal_Bamp2d)) deallocate(Zonal_Bamp2d)
if (allocated(Zonal_Bamp3d)) deallocate(Zonal_Bamp3d)
if (allocated(Spectral_Bamp2d)) deallocate(Spectral_Bamp2d)
if (allocated(Spectral_Bamp3d)) deallocate(Spectral_Bamp3d)

call ZM%final()
call SH%final()

end subroutine nudging_final
!================================================================
Expand Down
Loading