Skip to content

Commit 6102496

Browse files
authored
Add princeton met forcing (#524)
# CABLE Thank you for submitting a pull request to the CABLE Project. ## Description Add the Princeton forcing as part of the changes brought by the groundwater work. The implementation follows the way it was initially done for the groundwater with the following differences: - adaptation to the refactoring of the driver - bug fixed in renameFiles_Princeton() (added the "BACK" keyword to INDEX() call) and modification in cable_input since Princeton does not provide a file for snowfall. Fixes #477 ## Type of change Please delete options that are not relevant. - [X] New ## Checklist - [X] The new content is accessible and located in the appropriate section. - [X] I have checked that links are valid and point to the intended content. - [X] I have checked my code/text and corrected any misspellings ## Testing When running with the Princeton forcing on for the year 1948, I have tested that the forcings output by CABLE are identical to the values in the input files. This is true except for the pressure and precipitation variables: - pressure shows a small noise with a maximum difference of 0.008 Pa that is negligible. This is linked to the unit conversions between hPa and Pa. - precipitation shows a few grid cells with differences up to -4e-10 mm/s. This is negligible and likely due to the split between rain and snow precipitation. benchcab fluxsite tests return bitwise-comparable results with main, highlighting no side effects: ``` 2025-03-13 18:25:58,919 - INFO - benchcab.benchcab.py:381 - 0 failed, 168 passed ``` Please add a reviewer when ready for review. <!-- readthedocs-preview cable start --> ---- 📚 Documentation preview 📚: https://cable--524.org.readthedocs.build/en/524/ <!-- readthedocs-preview cable end -->
2 parents 4799d35 + 48052c1 commit 6102496

File tree

6 files changed

+106
-31
lines changed

6 files changed

+106
-31
lines changed

documentation/docs/user_guide/inputs/cable_nml.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ The cable.nml file includes some settings that are common across all CABLE appli
9898
| cable_user%soil_thermal_fix | logical | .TRUE. .FALSE. | .FALSE. | Use alternative soil conductivity implementation. |
9999
| cable_user%phenology_switch | character(len=20) | 'MODIS' 'climate' | 'MODIS' | Use prescribed MODIS phenology or climate dependant phenology. |
100100
| cable_user%RunIden | character(len=10) | any string of max. 10 characters | 'STANDARD' | Run identifier string for input/output files. |
101-
| cable_user%MetType | character(len=6) | '' 'gswp' 'gswp3' 'plum' 'cru' 'site' 'bios' | ' ' | Type of input meteorological data. |
101+
| cable_user%MetType | character(len=6) | '' 'gswp' 'gswp3' 'plum' 'cru' 'site' 'bios' 'prin' | ' ' | Type of input meteorological data. |
102102
| cable_user%soil_struc | character(len=20) | 'default' 'sli' | 'default' | Use default or soil-litter-iso soil model. |
103103
| cable_user%POP_out | character(len=3) | 'epi' 'rst' 'ini' | 'rst' | POP restart file type. `'epi'` is end of year state `'rst'` is a standard restart file, `'ini'` is an initialisation restart file. |
104104
| cable_user%POP_rst | character(len=50) | any string of max. 50 characters | ' ' | POP restart file directory. |

src/offline/cable_driver_common.F90

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ MODULE cable_driver_common_mod
108108
PUBLIC :: cable_driver_init_default
109109
PUBLIC :: prepareFiles
110110
PUBLIC :: renameFiles
111+
PUBLIC :: prepareFiles_princeton
111112
PUBLIC :: LUCdriver
112113
PUBLIC :: compare_consistency_check_values
113114

@@ -325,10 +326,9 @@ SUBROUTINE cable_driver_init_cru(dels, koffset, CRU)
325326
END SUBROUTINE cable_driver_init_cru
326327

327328
SUBROUTINE prepareFiles(ncciy)
328-
!* Select the correct files given the year for filenames following the gswp format
329+
!* Select the correct files given the year for filenames following
330+
! the gswp format
329331

330-
USE cable_IO_vars_module, ONLY: logn,gswpfile
331-
IMPLICIT NONE
332332
INTEGER, INTENT(IN) :: ncciy !! Year to select met. forcing data.
333333

334334
WRITE(logn,*) 'CABLE offline global run using gswp forcing for ', ncciy
@@ -346,7 +346,8 @@ SUBROUTINE prepareFiles(ncciy)
346346
END SUBROUTINE prepareFiles
347347

348348
SUBROUTINE renameFiles(logn,inFile,ncciy,inName)
349-
!! Replace the year in the filename with the value of ncciy.
349+
!* Replace the year in the filename with the value of ncciy
350+
! for the gswp file format.
350351

351352
IMPLICIT NONE
352353
INTEGER, INTENT(IN) :: logn !! Log file unit number
@@ -363,6 +364,45 @@ SUBROUTINE renameFiles(logn,inFile,ncciy,inName)
363364

364365
END SUBROUTINE renameFiles
365366

367+
SUBROUTINE prepareFiles_princeton(ncciy)
368+
!* Select the correct files given the year for filenames following the
369+
! princeton format
370+
INTEGER, INTENT(IN) :: ncciy
371+
372+
WRITE(logn,*) 'CABLE offline global run using princeton forcing for ', ncciy
373+
PRINT *, 'CABLE offline global run using princeton forcing for ', ncciy
374+
375+
CALL renameFiles_princeton(logn,gswpfile%rainf,ncciy,'rainf')
376+
CALL renameFiles_princeton(logn,gswpfile%LWdown,ncciy,'LWdown')
377+
CALL renameFiles_princeton(logn,gswpfile%SWdown,ncciy,'SWdown')
378+
CALL renameFiles_princeton(logn,gswpfile%PSurf,ncciy,'PSurf')
379+
CALL renameFiles_princeton(logn,gswpfile%Qair,ncciy,'Qair')
380+
CALL renameFiles_princeton(logn,gswpfile%Tair,ncciy,'Tair')
381+
CALL renameFiles_princeton(logn,gswpfile%wind,ncciy,'wind')
382+
383+
END SUBROUTINE prepareFiles_princeton
384+
385+
SUBROUTINE renameFiles_princeton(logn,inFile,ncciy,inName)
386+
!* Replace the year in the filename with the value of ncciy for
387+
! the princeton format
388+
INTEGER, INTENT(IN) :: logn,ncciy
389+
INTEGER:: nn
390+
CHARACTER(LEN=200), INTENT(INOUT) :: inFile
391+
CHARACTER(LEN=*), INTENT(IN) :: inName
392+
INTEGER :: idummy
393+
394+
nn = INDEX(inFile,'19')
395+
READ(inFile(nn:nn+3),'(i4)') idummy
396+
WRITE(inFile(nn:nn+3),'(i4.4)') ncciy
397+
nn = INDEX(inFile,'19', BACK=.TRUE.)
398+
READ(inFile(nn:nn+3),'(i4)') idummy
399+
WRITE(inFile(nn:nn+3),'(i4.4)') ncciy
400+
READ(inFile(nn-5:nn-2),'(i4)') idummy
401+
WRITE(inFile(nn-5:nn-2),'(i4.4)') ncciy
402+
WRITE(logn,*) TRIM(inName), ' global data from ', TRIM(inFile)
403+
404+
END SUBROUTINE renameFiles_princeton
405+
366406
!==============================================================================
367407
! subroutine for
368408
SUBROUTINE LUCdriver( casabiome,casapool, &

src/offline/cable_input.F90

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ SUBROUTINE open_met_file(dels,koffset,kend,spinup, TFRZ)
400400
PRINT*,'rainf'
401401
CALL handle_err( ok )
402402
ENDIF
403-
IF(.NOT. globalMetfile%l_gpcc) THEN
403+
IF(.NOT. globalMetfile%l_gpcc .AND. cable_user%MetType .NE. "prin") THEN
404404
ok = NF90_OPEN(gswpfile%snowf,0,ncid_snow)
405405
IF (ok /= NF90_NOERR) THEN
406406
PRINT*,'snow'
@@ -497,9 +497,12 @@ SUBROUTINE open_met_file(dels,koffset,kend,spinup, TFRZ)
497497
IF(ok/=NF90_NOERR) THEN ! if failed
498498
! Try 'lon' instead of x
499499
ok = NF90_INQ_DIMID(ncid_met,'lon', xdimID)
500-
IF(ok/=NF90_NOERR) CALL nc_abort &
501-
(ok,'Error finding x dimension in '&
502-
//TRIM(filename%met)//' (SUBROUTINE open_met_file)')
500+
IF(ok/=NF90_NOERR) THEN ! MMY
501+
ok = NF90_INQ_DIMID(ncid_met,'longitude', xdimID) ! MMY ! For princeton
502+
IF(ok/=NF90_NOERR) CALL nc_abort & ! MMY
503+
(ok,'Error finding x dimension in '& ! MMY
504+
//TRIM(filename%met)//' (SUBROUTINE open_met_file)') ! MMY
505+
END IF ! MMY
503506
END IF
504507
ok = NF90_INQUIRE_DIMENSION(ncid_met,xdimID,len=xdimsize)
505508
IF(ok/=NF90_NOERR) CALL nc_abort &
@@ -510,9 +513,12 @@ SUBROUTINE open_met_file(dels,koffset,kend,spinup, TFRZ)
510513
IF(ok/=NF90_NOERR) THEN ! if failed
511514
! Try 'lat' instead of y
512515
ok = NF90_INQ_DIMID(ncid_met,'lat', ydimID)
513-
IF(ok/=NF90_NOERR) CALL nc_abort &
514-
(ok,'Error finding y dimension in ' &
515-
//TRIM(filename%met)//' (SUBROUTINE open_met_file)')
516+
IF(ok/=NF90_NOERR) THEN ! MMY
517+
ok = NF90_INQ_DIMID(ncid_met,'latitude', ydimID) ! MMY ! For princeton
518+
IF(ok/=NF90_NOERR) CALL nc_abort & ! MMY
519+
(ok,'Error finding y dimension in ' & ! MMY
520+
//TRIM(filename%met)//' (SUBROUTINE open_met_file)') ! MMY
521+
END IF ! MMY
516522
END IF
517523
ok = NF90_INQUIRE_DIMENSION(ncid_met,ydimID,len=ydimsize)
518524
IF(ok/=NF90_NOERR) CALL nc_abort &
@@ -821,7 +827,10 @@ SUBROUTINE open_met_file(dels,koffset,kend,spinup, TFRZ)
821827
!===== done bug fixing for timevar in PALS met file ===============
822828

823829
!===== gswp input file has bug in timeunits ===========
824-
IF (ncciy > 0) WRITE(timeunits(26:27),'(i2.2)') 0
830+
IF (TRIM(cable_user%MetType) .NE. "prin") THEN ! MMY
831+
IF (ncciy > 0) WRITE(timeunits(26:27),'(i2.2)') 0
832+
END IF ! MMY
833+
825834
!===== done bug fixing for timeunits in gwsp file ========
826835
WRITE(logn,*) 'Time variable units: ', timeunits
827836
! Get coordinate field:
@@ -848,17 +857,25 @@ SUBROUTINE open_met_file(dels,koffset,kend,spinup, TFRZ)
848857
! start time) from character to integer; calculate starting hour-of-day,
849858
! day-of-year, year:
850859
IF (.NOT.cable_user%GSWP3) THEN
851-
READ(timeunits(15:18),*) syear
852-
READ(timeunits(20:21),*) smoy ! integer month
853-
READ(timeunits(23:24),*) sdoytmp ! integer day of that month
854-
READ(timeunits(26:27),*) shod ! starting hour of day
860+
IF (cable_user%MetType .eq. "prin") THEN ! MMY
861+
READ(timeunits(13:16),*) syear ! MMY
862+
READ(timeunits(18:19),*) smoy ! integer month ! MMY
863+
READ(timeunits(21:22),*) sdoytmp ! integer day of that month ! MMY
864+
READ(timeunits(24:25),*) shod ! starting hour of day ! MMY
865+
ELSE ! MMY
866+
READ(timeunits(15:18),*) syear
867+
READ(timeunits(20:21),*) smoy ! integer month
868+
READ(timeunits(23:24),*) sdoytmp ! integer day of that month
869+
READ(timeunits(26:27),*) shod ! starting hour of day
870+
END IF
855871
ELSE
856872
syear=ncciy
857873
smoy=1
858874
sdoytmp=1
859875
shod=0
860876
END IF
861877

878+
862879
! if site data, shift start time to middle of timestep
863880
! only do this if not already at middle of timestep
864881
! vh_js !
@@ -1055,14 +1072,18 @@ SUBROUTINE open_met_file(dels,koffset,kend,spinup, TFRZ)
10551072
IF(ok /= NF90_NOERR) CALL nc_abort &
10561073
(ok,'Error finding Rainf units in met data file ' &
10571074
//TRIM(filename%met)//' (SUBROUTINE open_met_file)')
1058-
IF(metunits%Rainf(1:8)=='kg/m^2/s'.OR.metunits%Rainf(1:6)=='kg/m2s'.OR.metunits%Rainf(1:10)== &
1059-
'kgm^-2s^-1'.OR.metunits%Rainf(1:4)=='mm/s'.OR. &
1060-
metunits%Rainf(1:6)=='mms^-1'.OR. &
1061-
metunits%Rainf(1:7)=='kg/m^2s'.OR.metunits%Rainf(1:10)=='kg m-2 s-1'.OR.metunits%Wind(1:5)/='m s-1') THEN
1075+
IF(metunits%Rainf(1:8)=='kg/m^2/s' .OR. &
1076+
metunits%Rainf(1:7)=='kg/m2/s' .OR. &
1077+
metunits%Rainf(1:6)=='kg/m2s' .OR. &
1078+
metunits%Rainf(1:10)=='kgm^-2s^-1' .OR. &
1079+
metunits%Rainf(1:4)=='mm/s' .OR. &
1080+
metunits%Rainf(1:6)=='mms^-1' .OR. &
1081+
metunits%Rainf(1:7)=='kg/m^2s' .OR. &
1082+
metunits%Rainf(1:10)=='kg m-2 s-1' ) THEN
10621083
! Change from mm/s to mm/time step:
10631084
convert%Rainf = dels
1064-
ELSE IF(metunits%Rainf(1:4)=='mm/h'.OR.metunits%Rainf(1:6)== &
1065-
'mmh^-1') THEN
1085+
ELSE IF(metunits%Rainf(1:4)=='mm/h' .OR. &
1086+
metunits%Rainf(1:6)== 'mmh^-1' ) THEN
10661087
! Change from mm/h to mm/time step:
10671088
convert%Rainf = dels/3600.0
10681089
ELSE

src/offline/cable_mpimaster.F90

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ MODULE cable_mpimaster
8686
delgwM, &
8787
LALLOC, &
8888
prepareFiles, &
89-
renameFiles, &
89+
prepareFiles_princeton, &
9090
LUCdriver, &
9191
compare_consistency_check_values
9292
USE cable_mpicommon
@@ -352,11 +352,17 @@ SUBROUTINE mpidrv_master (comm, dels, koffset, kend, PLUME, CRU)
352352
ENDIF
353353

354354
SELECT CASE (TRIM(cable_user%MetType))
355-
CASE ('gswp')
355+
CASE ('gswp', 'prin')
356356
ncciy = CurYear
357357

358358
WRITE(*,*) 'Looking for global offline run info.'
359-
CALL prepareFiles(ncciy)
359+
360+
IF ( TRIM(cable_user%MetType) == 'gswp' ) THEN
361+
CALL prepareFiles(ncciy)
362+
ELSE ! cable_user%MetType == 'prin'
363+
CALL prepareFiles_princeton(ncciy)
364+
END IF
365+
360366
CALL open_met_file( dels, koffset, kend, spinup, CTFRZ )
361367

362368
CASE ('plum')
@@ -739,7 +745,8 @@ SUBROUTINE mpidrv_master (comm, dels, koffset, kend, PLUME, CRU)
739745

740746
END SELECT
741747
IF ( (TRIM(cable_user%MetType) .NE. 'gswp') .AND. &
742-
(TRIM(cable_user%MetType) .NE. 'gswp3') ) CurYear = met%year(1)
748+
(TRIM(cable_user%MetType) .NE. 'gswp3') .AND. &
749+
(TRIM(cable_user%MetType) .NE. 'prin' )) CurYear = met%year(1)
743750

744751
!$ IF ( CASAONLY .AND. IS_CASA_TIME("dread", yyyy, iktau, kstart, koffset, &
745752
!$ kend, ktauday, logn) ) THEN
@@ -846,7 +853,7 @@ SUBROUTINE mpidrv_master (comm, dels, koffset, kend, PLUME, CRU)
846853
IF ( (.NOT. CASAONLY).AND. spinConv ) THEN
847854

848855
SELECT CASE (TRIM(cable_user%MetType))
849-
CASE ('plum', 'cru', 'gswp', 'gswp3')
856+
CASE ('plum', 'cru', 'gswp', 'gswp3', 'prin')
850857
CALL write_output( dels, ktau_tot, met, canopy, casaflux, casapool, &
851858
casamet,ssnow, &
852859
rad, bal, air, soil, veg, CSBOLTZ, &

src/offline/cable_offline_driver.F90

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ PROGRAM cable_offline_driver
4242
CALL cable_driver_init_gswp(mpi_grp, GSWP_MID, NRRRR)
4343
CASE('gswp3')
4444
CALL cable_driver_init_gswp(mpi_grp)
45+
CASE('prin')
46+
CALL cable_driver_init_gswp(mpi_grp, GSWP_MID, NRRRR)
4547
CASE('plum')
4648
CALL cable_driver_init_plume(dels, koffset, PLUME)
4749
CASE('cru')

src/offline/cable_serial.F90

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ MODULE cable_serial
7575
delgwM, &
7676
LALLOC, &
7777
prepareFiles, &
78-
renameFiles, &
78+
prepareFiles_princeton, &
7979
LUCdriver, &
8080
compare_consistency_check_values
8181
USE cable_def_types_mod
@@ -296,10 +296,15 @@ SUBROUTINE serialdrv(NRRRR, dels, koffset, kend, GSWP_MID, PLUME, CRU, site)
296296

297297
! Check for gswp run
298298
SELECT CASE (TRIM(cable_user%MetType))
299-
CASE ('gswp')
299+
CASE ('gswp', 'prin')
300300
ncciy = CurYear
301301

302-
CALL prepareFiles(ncciy)
302+
IF (cable_user%MetType == 'gswp') THEN
303+
CALL prepareFiles(ncciy)
304+
ELSE ! cable_user%MetType == 'prin'
305+
CALL prepareFiles_princeton(ncciy) ! MMY
306+
END IF
307+
303308
IF ( RRRR .EQ. 1 ) THEN
304309
CALL open_met_file( dels, koffset, kend, spinup, CTFRZ )
305310
IF (leaps.AND.is_leapyear(YYYY).AND.kend.EQ.2920) THEN

0 commit comments

Comments
 (0)