[[PageOutline]] Last edited [[Timestamp]] '''Author''' : Marcello Vichi '''[http://forge.ipsl.jussieu.fr/nemo/wiki/ticket ticket]''' : [http://forge.ipsl.jussieu.fr/nemo/ticket/665 #846] '''Branch''' : [https://forge.ipsl.jussieu.fr/nemo/browser/branches/2011/dev_r2784_CMCC1_topbfm dev_r2784_CMCC1_topbfm] ---- === Description === Branch to develop a common interface for other biogeochemical models not included in the TOP directory. The idea is to provide an as much as possible seamless interface for more complex biogeochemical models that do not fit into the TOP MY_TRC framework. This will consider the development done by CMCC, MetOffice (Karen Edwards) and NCOF-PML (Momme Butenschoen) integrating with the existing TOP interface. === Current state === Currently, BGC models are resolved within the SMS part (trcsms.F0) and that the transport (trc_trp) and output (trc_wri, trc_dia and trc_rst) is done identically for each model , assuming that all the memory layout is provided by NEMO through the tra and trn arrays and the number of passive tracers jptra. This is a good solution for models that are developed within NEMO but does not fit well with more complex biogeochemical models that are also used with other OGCMs. This is the case for the BFM, which has a wide growing community of users and therefore has an independent development with a specific coding structure. For models like the BFM (CMCC and INGV) and ERSEM (MetOffice and NERC) the common solution (independently developed) was to add an alternative set of routines for stepping and output This is an excerpt from a modified trcstp.F90 for the BFM case {{{ ... #if defined key_bfm !--------------------------------------------- ! Check the main BFM flag !--------------------------------------------- CALL trc_bfm( kt ) ! main call to BFM CALL trc_trp_bfm( kt ) ! transport of BFM tracers CALL trc_dia_bfm( kt ) ! diagnostic output for BFM #else ... tra(:,:,:,:) = 0.e0 ! IF( kt == nit000 .AND. lk_trdmld_trc ) & & CALL trd_mld_trc_init ! trends: Mixed-layer CALL trc_rst_opn( kt ) ! Open tracer restart file IF( lk_iomput ) THEN ; CALL trc_wri( kt ) ! output of passive tracers ELSE ; CALL trc_dia( kt ) ENDIF CALL trc_sms( kt ) ! tracers: sink and source CALL trc_trp( kt ) ! transport of passive tracers IF( kt == nit000 ) CALL iom_close( numrtr ) ! close input passive tracers restart file IF( lrst_trc ) CALL trc_rst_wri( kt ) ! write tracer restart file IF( lk_trdmld_trc ) CALL trd_mld_trc( kt ) ! trends: Mixed-layer }}} Actually MetOffice is currently using a hybrid approach mixing the standard SMS approach with a specific key. === Strategy === To accommodate this kind of models it is required to add flexibility to the code, like allowing the possibility to not use the output/restart facilities of NEMO and to have different combinations of transport schemes. The major issue here is the loop over the number of tracers, which is not possible within the my_trc framework and therefore requires another tracer stepping scheme. It is indeed possible to use trn(tra) with more complex models (Karen is doing this with ERSEM, while NERC/PML is not). However, this is not likely with the BFM as it allows to define the number of variables dynamically and it builds its own structure separately with specific input/output routines. Another issue is that it is important to keep the sedimentation rates separated from vertical advection as MPDATA schemes are not mass conserving. I think we can work out a common solution within the framework of my_trc, although I would propose to have an extended my_trc that allows more flexibility. Whether to achieve this through additional logical flags or by means of macros is a matter of discussion. I guess we all agree that it makes no sense to have a different key for each new model, though we also need to realize that we'll have to accommodate two different coupling strategies, one for SMS models and one for "ecosystem" models (which may also incorporate benthic systems like the ones we use now). One (very) simple solution is to have only an additional key (like key_obgcm, other biogeochemical model) to accommodate any BGC model that does not use at all the NEMO memory structure and facilities. This would only involve two changes in the NEMO code, during the initialization step and during the time stepping {{{ nemogcm.F90: ------------- #if defined key_top #if defined key_obgcm ! ! Other external biogeochemical model CALL trc_init_obgc #else ! ! Passive tracers CALL trc_init #endif #endif step.F90: --------- #if defined key_top #if defined key_obgcm !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! Passive Tracer Model !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< CALL trc_stp_obgc( kstp ) ! time-stepping #else !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! Other Biogeochemical Model !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< CALL trc_stp( kstp ) ! time-stepping #endif #endif }}} The routines trc_init_obgc and trc_stp_obgc are wrappers that have to be provided by the external model in its own directory structure and linked during compilation. We can also put an EXTERNAL statement in the code to clarify this. The strategy is open for discussion because it is not urgent matter in the 2011 work plan, but it is important that we find a common way forward that will maximize all development efforts and the research carried on by the community of ecosystem modelling. Alternatively to allow for switching between models at run-time without the need for recompilation, the follwoing approach can be taken: {{{ par_trc.F90: IMPLICIT NONE PUBLIC ! Passive tracers : Total size ! --------------- ! total number of passive tracers, of 2d and 3d output and trend arrays !=============================================== ! Modification to NEMO trunk for ERSEM coupling ! M.Butenschoen, PML - March 2009 ! \/ ! \/ # if defined key_PMLersem INTEGER, PUBLIC, PARAMETER :: jp_pmlersem = 56 INTEGER, PUBLIC, PARAMETER :: jptra = jp_pmlersem + jp_lobster + jp_pisces + jp_cfc + jp_c14b + jp_my_trc INTEGER, PUBLIC, PARAMETER :: jp_pmlersem0=1, jp_pmlersem1=jp_pmlersem # else ! /\ ! /\ !=============================================== INTEGER, PUBLIC, PARAMETER :: jptra = jp_lobster + jp_pisces + jp_cfc + jp_c14b + jp_my_trc !=============================================== ! Modification to NEMO trunk for ERSEM coupling ! M.Butenschoen, PML - March 2009 ! \/ ! \/ # endif ! /\ ! /\ !=============================================== INTEGER, PUBLIC, PARAMETER :: jpdia2d = jp_lobster_2d + jp_pisces_2d + jp_cfc_2d + jp_c14b_2d + jp_my_trc_2d trcini.F90: ENDIF !=============================================== ! Modification to NEMO trunk for ERSEM coupling ! M.Butenschoen, PML - March 2009 ! \/ ! \/ # if defined key_PMLersem CALL trc_ini_PMLersem ! MY_TRC tracers # else WRITE(numout,*) ' ERSEM not used' # endif ! /\ ! /\ !=============================================== IF( lk_my_trc ) THEN ; CALL trc_ini_my_trc ! MY_TRC tracer trc_oce.F90: #if defined key_top && defined key_pisces !!---------------------------------------------------------------------- !! 'key_top' & 'key_pisces' PISCES bio-model !!---------------------------------------------------------------------- LOGICAL, PUBLIC, PARAMETER :: lk_qsr_bio = .TRUE. !: bio-model light absorption flag !=============================================== ! Modification to NEMO trunk for ERSEM coupling ! M.Butenschoen, PML - March 2008 ! \/ ! \/ #elif defined key_top && defined key_PMLersem !! light for NEMO-ERSEM LOGICAL, PUBLIC, PARAMETER :: lk_qsr_bio = .TRUE. ! /\ ! /\ !=============================================== #else !!---------------------------------------------------------------------- !! Default option No bio-model light absorption trcrad.F90: IF( lk_my_trc ) CALL trc_rad_sms( kt, trb, trn, jp_myt0 , jp_myt1 ) ! MY_TRC model !=============================================== ! Modification to NEMO trunk for ERSEM coupling ! M.Butenschoen, PML - March 2009 ! \/ ! \/ # if defined key_PMLersem write(6,*) jp_pmlersem0,jp_pmlersem1 CALL trc_rad_sms( kt, trb, trn, jp_pmlersem0 , jp_pmlersem1) # endif ! /\ ! /\ !=============================================== trcsms.F90: IF( lk_my_trc ) CALL trc_sms_my_trc ( kt ) ! MY_TRC tracers !=============================================== ! Modification to NEMO trunk for ERSEM coupling ! M.Butenschoen, PML - March 2009 ! \/ ! \/ # if defined key_PMLersem CALL trc_PMLersem ( kt ) # endif ! /\ ! /\ !=============================================== trcstp.F90: CALL trc_sms( kt ) ! tracers: sink and source !=============================================== ! Modification to NEMO trunk for ERSEM coupling ! M.Butenschoen, PML - March 2009 ! \/ ! \/ #if defined key_PMLersem CALL trc_trp_PMLersem( kt ) #else ! /\ ! /\ !=============================================== CALL trc_trp( kt ) ! transport of passive tracers !=============================================== ! Modification to NEMO trunk for ERSEM coupling ! M.Butenschoen, PML - March 2009 ! \/ ! \/ #endif ! /\ ! /\ !=============================================== IF( kt == nittrc000 ) CALL iom_close( numrtr ) ! close input passive tracers restart file IF( lrst_trc ) CALL trc_rst_wri( kt ) ! write tracer restart file !=============================================== ! Modification to NEMO trunk for ERSEM coupling ! M.Butenschoen, PML - March 2009 ! \/ ! \/ # if defined key_PMLersem CALL trc_dia_PMLersem( kt ) ! diagnostics # else ! /\ ! /\ !=============================================== IF( lk_iomput ) THEN CALL trc_wri( kt ) ! output of passive tracers ELSE CALL trc_dia( kt ) ! diagnostics ENDIF !=============================================== ! Modification to NEMO trunk for ERSEM coupling ! M.Butenschoen, PML - March 2009 ! \/ ! \/ # endif ! /\ ! /\ !=============================================== IF( lk_trdmld_trc ) CALL trd_mld_trc( kt ) ! trends: Mixed-layer }}} ========= Christian's comments ========= The NEMO architecture ( with the use of FCM to build dependancies ), allow to rewrite a routine without needing to change anything. In that case, we can use the MY_TRC framework to manage every type of biogeochemical model. In fact, when compiling with makenemo ( for example : ./makenemo -n ORCA2_LIM_MY_TRC -r ORCA2_LIM_PISCES del_key "key_iomput key_pisces" add_key "key_my_trc"), a sub-directory where one can copy and modify all the routines we need is created : NEMOGCM/CONFIG/ORCA2_LIM_MY_TRC/MY_SRC. One can then copy the listed routines and modify them according to our convenience * TOP_SRC/trcini.F90 * TOP_SRC/trcstp.F90 * TOP_SRC/trcdia.F90 * TOP_SRC/TRP/trctrp.F90 * TOP_SRC/MY_TRC/* To go a little further - this is another proposition - we can add a new namelist parameter ln_nemo_io which is true if we want to use NEMO I/O manager and false if not. So we can modify the 2 modules trcini.F90 and trcstp.F90 as follow : trcini.F90 {{{ IF( lk_lobster ) THEN ; CALL trc_ini_lobster ! LOBSTER bio-model ELSE ; IF(lwp) WRITE(numout,*) ' LOBSTER not used' ENDIF IF( lk_pisces ) THEN ; CALL trc_ini_pisces ! PISCES bio-model ELSE ; IF(lwp) WRITE(numout,*) ' PISCES not used' ENDIF IF( lk_cfc ) THEN ; CALL trc_ini_cfc ! CFC tracers ELSE ; IF(lwp) WRITE(numout,*) ' CFC not used' ENDIF IF( lk_c14b ) THEN ; CALL trc_ini_c14b ! C14 bomb tracer ELSE ; IF(lwp) WRITE(numout,*) ' C14 not used' ENDIF IF( lk_my_trc ) THEN ; CALL trc_ini_my_trc ! MY_TRC tracers ELSE ; IF(lwp) WRITE(numout,*) ' MY_TRC not used' ENDIF IF( ln_nemo_io ) THEN ! Uses NEMO I/O and restart manager ! IF( ln_rsttr ) THEN ! IF( lk_offline ) neuler = 1 ! Set time-step indicator at nit000 (leap-frog) CALL trc_rst_read ! restart from a file ! ELSE IF( lk_offline ) THEN neuler = 0 ! Set time-step indicator at nit000 (euler) CALL day_init ! set calendar ENDIF #if defined key_dtatrc CALL trc_dta( nit000 ) ! Initialization of tracer from a file that may also be used for damping DO jn = 1, jptra IF( lutini(jn) ) trn(:,:,:,jn) = trdta(:,:,:,jn) * tmask(:,:,:) ! initialisation from file if required END DO #endif trb(:,:,:,:) = trn(:,:,:,:) ! ENDIF ! ENDIF tra(:,:,:,:) = 0._wp }}} trcstp.F90 {{{ IF( MOD( kt - 1 , nn_dttrc ) == 0 ) THEN ! only every nn_dttrc time step ! IF(ln_ctl) THEN WRITE(charout,FMT="('kt =', I4,' d/m/y =',I2,I2,I4)") kt, nday, nmonth, nyear CALL prt_ctl_trc_info(charout) ENDIF ! tra(:,:,:,:) = 0.e0 ! IF( ln_nemo_io ) THEN ! Uses NEMO I/O and restart manager ! IF( kt == nit000 .AND. lk_trdmld_trc ) & & CALL trd_mld_trc_init ! trends: Mixed-layer CALL trc_rst_opn( kt ) ! Open tracer restart file ENDIF IF( lk_iomput ) THEN ; CALL trc_wri( kt ) ! output of passive tracers ELSE ; CALL trc_dia( kt ) ENDIF CALL trc_sms( kt ) ! tracers: sink and source CALL trc_trp( kt ) ! transport of passive tracers IF( ln_nemo_io ) THEN ! Uses NEMO I/O and restart manager IF( kt == nit000 ) CALL iom_close( numrtr ) ! close input passive tracers restart file IF( lrst_trc ) CALL trc_rst_wri( kt ) ! write tracer restart file IF( lk_trdmld_trc ) CALL trd_mld_trc( kt ) ! trends: Mixed-layer ENDIF ! ENDIF }}} and then, just copy & modify in MY_SRC directory the 2 modules to manage transport and outputs * TOP_SRC/trcdia.F90 * TOP_SRC/TRP/trctrp.F90 === Status === On the dev branch we have now committed the method we currently use and that has to be modified. It is just a placeholder for the status quo at CMCC and very similar to NERC and MetOffice. ---- === Testing === Testing could consider (where appropriate) other configurations in addition to NVTK]. ||NVTK Tested||!'''YES/NO!'''|| ||Other model configurations||!'''YES/NO!'''|| ||Processor configurations tested||[ Enter processor configs tested here ]|| ||If adding new functionality please confirm that the [[BR]]New code doesn't change results when it is switched off [[BR]]and !''works!'' when switched on||!'''YES/NO/NA!'''|| (Answering UNSURE is likely to generate further questions from reviewers.) 'Please add further summary details here' * Processor configurations tested * etc---- === Bit Comparability === ||Does this change preserve answers in your tested standard configurations (to the last bit) ?||!'''YES/NO !'''|| ||Does this change bit compare across various processor configurations. (1xM, Nx1 and MxN are recommended)||!'''YES/NO!'''|| ||Is this change expected to preserve answers in all possible model configurations?||!'''YES/NO!'''|| ||Is this change expected to preserve all diagnostics? [[BR]]!,,!''Preserving answers in model runs does not necessarily imply preserved diagnostics. !''||!'''YES/NO!'''|| If you answered !'''NO!''' to any of the above, please provide further details: * Which routine(s) are causing the difference? * Why the changes are not protected by a logical switch or new section-version * What is needed to achieve regression with the previous model release (e.g. a regression branch, hand-edits etc). If this is not possible, explain why not. * What do you expect to see occur in the test harness jobs? * Which diagnostics have you altered and why have they changed?Please add details here........ ---- === System Changes === ||Does your change alter namelists?||!'''YES/NO !'''|| ||Does your change require a change in compiler options?||!'''YES/NO !'''|| If any of these apply, please document the changes required here....... ---- === Resources === !''Please !''summarize!'' any changes in runtime or memory use caused by this change......!'' ---- === IPR issues === ||Has the code been wholly (100%) produced by NEMO developers staff working exclusively on NEMO?||!''' NO !'''||