-
Notifications
You must be signed in to change notification settings - Fork 1
TOP
To understand the changes in the TOP code to call FABM, it is helpful to examine the flow structure. TOP is called from two locations in the main OCE code; one at the beginning to initialise the tracers, followed by a call every time step to update the values.
From there TOP will call a variety of processes, which are represented schematically below. On the left is the flow at the initialisation stage whilst the right is the flow at each time step. In red are the calls made to FABM specific functions outlined in TOP/FABM Directory.
Here we will detail all the changes necessary to add FABM into TOP. Most of the changes are simply calls to the corresponding FABM function, and there are also significant changes to allow multiple boundaries for tracers in line with the main OCE module. For readability all indents have been removed on this wiki.
This script defines the parameters used in TOP, so the fabm specific parameters also need to be included through a call to par_fabm. Additionally the parameters that declare the number of diagnostic variables have been set to zero by default.
diff par_trc.F90
@@ Line 17 @@
+ USE par_fabm
@@ Line 33 @@
+ INTEGER, PUBLIC :: jp_dia3d = 0
+ INTEGER, PUBLIC :: jp_dia2d = 0
+ INTEGER, PUBLIC :: jp_diabio = 0
- INTEGER, PUBLIC :: jp_dia3d
- INTEGER, PUBLIC :: jp_dia2d
All general fields and variables used within the TOP module are declared in this script, as well as a function to allocate arrays. Changes include:
- Setting default values for file read flags
- Allowing the size boundary related fields to be allocatable
- Increase the size of ice related fields when allocated
- Allocating all boundary fields at run time with correct parameter
diff trc.F90
@@ Line 92 @@
92,103c93,96
+ LOGICAL :: llinit=.FALSE.
+ LOGICAL :: llsbc=.FALSE.
+ LOGICAL :: llcbc=.FALSE.
+ LOGICAL :: llobc=.FALSE.
+ LOGICAL :: llsave=.FALSE.
- LOGICAL :: llinit
- LOGICAL :: llsbc
- LOGICAL :: llcbc
- LOGICAL :: llobc
@@ Line 128 @@
+ CHARACTER(len=20), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) :: cn_trc_dflt
+ CHARACTER(len=20), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) :: cn_trc
+ INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) :: nn_trcdmp_bdy
+ INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) :: nb_trc_jpk_bdy
- CHARACTER(len=20), PUBLIC, DIMENSION(jp_bdy) :: cn_trc_dflt
- CHARACTER(len=20), PUBLIC, DIMENSION(jp_bdy) :: cn_trc
- INTEGER, PUBLIC, DIMENSION(jp_bdy) :: nn_trcdmp_bdy
@@ Line 161 @@
+ & trc_ice_ratio(jpmaxtrc) , trc_ice_prescr(jpmaxtrc) , cn_trc_o(jpmaxtrc) , &
- & trc_ice_ratio(jptra) , trc_ice_prescr(jptra) , cn_trc_o(jptra) , &
@@ Line 170 @@
+ IF ( ln_bdy ) THEN
+ ALLOCATE( cn_trc_dflt(nb_bdy) , cn_trc(nb_bdy) , nn_trcdmp_bdy(nb_bdy) , &
+ & nb_trc_jpk_bdy(nb_bdy) , trcdta_bdy(jptra,nb_bdy) , &
+ & STAT = ierr(2) )
+ ENDIF
- IF( ln_bdy ) ALLOCATE( trcdta_bdy(jptra, jp_bdy) , STAT = ierr(2) )
Set of functions to manage tracer boundary conditions. No changes are necessary to this script to use FABM, however there are several changes to allow for multiple boundaries in line with the main OCE code and for use with domains such as the Atlantic Margin Model (AMM). These changes include:
- Making relevant arrays multidimensional
- Read OBC information from namelist into temporary array
- Allow namelist variable that defines the number of levels in the OBC data
- Add loop over the number of boundaries around namelist read statements
- Add loop over the number of boundaries around output log write statements
- Allocate multidimensional arrays
- Read initial OBC data into relavant part of arrays
- Set necessary pointers for boundary variables
- Read OBC data for all boundaries during time loop
diff trcbc.F90
@@ Line 40 @@
40c40
+ REAL(wp) , SAVE, PUBLIC, ALLOCATABLE, DIMENSION(:,:) :: rf_trofac
+ TYPE(FLD), SAVE, PUBLIC, ALLOCATABLE, DIMENSION(:,:) :: sf_trcobc
+ TYPE(FLD), SAVE, PUBLIC, ALLOCATABLE, DIMENSION(:,:), TARGET :: sf_trcobc
- REAL(wp) , SAVE, PUBLIC, ALLOCATABLE, DIMENSION(:) :: rf_trofac
- TYPE(FLD), SAVE, PUBLIC, ALLOCATABLE, DIMENSION(:) :: sf_trcobc
- TYPE(FLD), SAVE, PUBLIC, ALLOCATABLE, DIMENSION(:), TARGET :: sf_trcobc
SUBROUTINE trc_bc_ini
@@ Line 75 @@
+ TYPE(FLD_N), DIMENSION(jpmaxtrc,nb_bdy) :: sn_trcobc
+ TYPE(FLD_N), DIMENSION(jpmaxtrc) :: sn_trcobc_dta
- TYPE(FLD_N), DIMENSION(jpmaxtrc) :: sn_trcobc
@@ Line 83 @@
+ NAMELIST/namtrc_bc/ cn_dir_obc, sn_trcobc_dta, rn_trofac, cn_dir_sbc, sn_trcsbc, rn_trsfac, &
- NAMELIST/namtrc_bc/ cn_dir_obc, sn_trcobc, rn_trofac, cn_dir_sbc, sn_trcsbc, rn_trsfac, &
& cn_dir_cbc, sn_trccbc, rn_trcfac, ln_rnf_ctl, rn_bc_time
+ NAMELIST/namtrc_bdy/ cn_trc_dflt, cn_trc, nn_trcdmp_bdy, nb_trc_jpk_bdy
- NAMELIST/namtrc_bdy/ cn_trc_dflt, cn_trc, nn_trcdmp_bdy
@@ Line 126 @@
126,135c124,129
+ DO ib = 1, nb_bdy
READ ( numnat_cfg, namtrc_bc, IOSTAT = ios, ERR = 902 )
902 IF( ios > 0 ) CALL ctl_nam ( ios , 'namtrc_bdy in configuration namelist' )
IF(lwm) WRITE ( numont, namtrc_bc )
+ sn_trcobc(:,ib)=sn_trcobc_dta(:)
+ ENDDO
@@ Line 140 @@
- cn_trc (2:jp_bdy) = cn_trc (1)
- cn_trc_dflt(2:jp_bdy) = cn_trc_dflt(1)
@@ Line 209 @@
+ DO ib = 1, nb_bdy
+ WRITE(numout,*) ' ------ Open boundary data set ', ib, '------'
WRITE(numout,*) ' #trc NAME Boundary Mult.Fact. OBC Settings'
DO jn = 1, ntrc
+ IF ( ln_trc_obc(jn) ) THEN
+ WRITE(numout, 9001) jn, TRIM( sn_trcobc(jn,ib)%clvar ), 'OBC', rn_trofac(jn), &
+ & (trcdta_bdy(jn,ib)%cn_obc)
- IF ( ln_trc_obc(jn) ) WRITE(numout, 9001) jn, TRIM( sn_trcobc(jn)%clvar ), 'OBC', rn_trofac(jn), &
- & (trcdta_bdy(jn,ib)%cn_obc,ib=1,nb_bdy)
+ ELSE
+ WRITE(numout, 9002) jn, 'Set data to IC and use default condition' , &
+ & (trcdta_bdy(jn,ib)%cn_obc)
+ ENDIF
- IF ( .NOT. ln_trc_obc(jn) ) WRITE(numout, 9002) jn, 'Set data to IC and use default condition' , &
- & (trcdta_bdy(jn,ib)%cn_obc,ib=1,nb_bdy)
+ END DO
@@ Line 247 @@
+ ALLOCATE ( sf_trcobc(nb_trcobc,nb_bdy), rf_trofac(nb_trcobc,nb_bdy), STAT=ierr1 )
- ALLOCATE ( sf_trcobc(nb_trcobc), rf_trofac(nb_trcobc), STAT=ierr1 )
@@ Line 261 @@
+ slf_i(jl) = sn_trcobc(jn,ib)
+ rf_trofac(jl,ib) = rn_trofac(jn)
+ ALLOCATE( sf_trcobc(jl,ib)%fnow(nblen,1,jpk) , STAT=ierr2 )
+ IF( sn_trcobc(jn,ib)%ln_tint ) ALLOCATE( sf_trcobc(jl,ib)%fdta(nblen,1,jpk,2) , STAT=ierr3 )
- slf_i(jl) = sn_trcobc(jn)
- rf_trofac(jl) = rn_trofac(jn)
- ALLOCATE( sf_trcobc(jl)%fnow(nblen,1,jpk) , STAT=ierr2 )
- IF( sn_trcobc(jn)%ln_tint ) ALLOCATE( sf_trcobc(jl)%fdta(nblen,1,jpk,2) , STAT=ierr3 )
@@ Line 268 @@
+ trcdta_bdy(jn,ib)%trc => sf_trcobc(jl,ib)%fnow(:,1,:)
+ trcdta_bdy(jn,ib)%rn_fac = rf_trofac(jl,ib)
- trcdta_bdy(jn,ib)%trc => sf_trcobc(jl)%fnow(:,1,:)
- trcdta_bdy(jn,ib)%rn_fac = rf_trofac(jl)
@@ Line 283 @@
+ CALL fld_fill( sf_trcobc(:,ib), slf_i, cn_dir_obc, 'trc_bc_ini', 'Passive tracer OBC data', 'namtrc_bc' )
- CALL fld_fill( sf_trcobc, slf_i, cn_dir_obc, 'trc_bc_ini', 'Passive tracer OBC data', 'namtrc_bc' )
@@ Line 290 @@
+ sf_trcobc(jl,ib)%imap => idx_bdy(ib)%nbmap(1:idx_bdy(ib)%nblen(igrd),igrd)
- sf_trcobc(jl)%imap => idx_bdy(ib)%nbmap(1:idx_bdy(ib)%nblen(igrd),igrd)
SUBROUTINE trc_bc
@@ Line 366 @@
+ INTEGER :: ji, jj, jk, jn, jl, ib ! Loop index
- INTEGER :: ji, jj, jk, jn, jl ! Loop index
@@ Line 384 @@
+ DO ib = 1, nb_bdy
+ IF (lwp) WRITE(numout,*) ' ------ Open boundary data set ', ib, '------'
+ CALL fld_read( kt=kt, kn_fsbc=1, sd=sf_trcobc(:,ib), kit=jit, kt_offset=+1)
+ END DO
- CALL fld_read( kt=kt, kn_fsbc=1, sd=sf_trcobc, kit=jit, kt_offset=+1)
@@ Line 414 @@
+ DO ib = 1, nb_bdy
+ IF (lwp) WRITE(numout,*) ' ------ Open boundary data set ', ib, '------'
+ CALL fld_read( kt=kt, kn_fsbc=1, sd=sf_trcobc(:,ib), kt_offset=+1)
+ END DO
- CALL fld_read( kt=kt, kn_fsbc=1, sd=sf_trcobc, kt_offset=+1)
Called by OCE code to initialize tracers. Changes include:
- Include necessary FABM scripts
- Call FABM configuration to create fabm model from fabm.yaml
- Call function to override tracer descriptions/units read from namelist_top with those in fabm.yaml
- Initialize FABM model
- Initialize FABM diagnostic variables and tracer boundary conditions.
diff trcini.F90
@@ Line 29 @@
+ USE trcsms_fabm
+ USE trcini_fabm
+ USE trcnam_fabm
@@ Line 67 @@
+ IF( ln_fabm ) CALL nemo_fabm_configure
@@ Line 176 @@
+ IF( ln_fabm ) THEN
+ CALL trc_nam_fabm_override(sn_tracer)
+ CALL trc_ini_fabm
+ END IF
@@ Line 236 @@
+ IF( ln_my_trc ) CALL trc_bc_ini ( jptra )
- CALL trc_bc_ini ( jptra )
@@ Line 269 @@
+ IF( ln_fabm ) THEN
+ wndm=0._wp
+ qsr=0._wp
+ CALL trc_bc_ini(jptra)
+ ENDIF
Contains routines that read/write restart files. Changes involve calling FABM restart read/write functions.
diff trcrst.F90
@@ Line 26 @@
+ USE trcrst_fabm
@@ Line 126 @@
+ IF (ln_fabm) CALL trc_rst_read_fabm
@@ Line 154 @@
+ IF (ln_fabm) CALL trc_rst_wri_fabm(kt)
Called by main OCE code to control tracer time-stepping. Added in a line to call the FABM time-stepping routine.
diff trcsms.F90
@@ Line 23 @@
+ USE trcsms_fabm
@@ Line 60 @@
+ IF( ln_fabm ) CALL trc_sms_fabm ( kt ) ! FABM tracers
Script to control writing tracer output. Changes include
- Added an extra input parameter when NEMO is compiled with key_tracer_budget
- Check for presence of extra parameter then call relevant FABM write function
diff trcwri.F90
@@ Line 25 @@
+ USE trcwri_fabm
@@ Line 36 @@
+ #if defined key_tracer_budget
+ SUBROUTINE trc_wri( kt , fl)
+ #else
SUBROUTINE trc_wri( kt )
+ #endif
@@ Line 47 @@
+ #if defined key_tracer_budget
+ INTEGER, INTENT( in ), OPTIONAL :: fl
+ #endif
@@ Line 84 @@
+ #if defined key_tracer_budget
+ IF( PRESENT(fl) ) THEN
+ IF( ln_fabm ) CALL trc_wri_fabm (kt, fl)
+ ELSE
+ IF( ln_fabm ) CALL trc_wri_fabm (kt)
+ ENDIF
+ #else
+ IF( ln_fabm ) CALL trc_wri_fabm (kt)
+ #endif
- IF ( ln_my_trc ) CALL trc_wri_my_trc
This script contains a routine to artificially correct negative tracer concentrations to avoid numerical issues. Added in the call to the routine for all tracers using the FABM parameters.
diff TRP/trcrad.F90
@@ Line 58 @@
+ INTEGER :: jn
@@ Line 71 @@
69,78d65
+ IF( ln_fabm ) THEN
+ DO jn=1,jp_fabm
+ IF (lk_rad_fabm(jn)) THEN
+ CALL trc_rad_sms( kt, trb, trn, jn+jp_fabm_m1 , jn+jp_fabm_m1 )
+ ENDIF
+ END DO
+ END IF