MODULE biology_mod ! !git $Id$ !svn $Id: ecosim.h 1151 2023-02-09 03:08:53Z arango $ !================================================== Hernan G. Arango === ! Copyright (c) 2002-2023 The ROMS/TOMS Group ! ! Licensed under a MIT/X style license ! ! See License_ROMS.md ! !=================================================== W. Paul Bissett === ! Copyright (c) 1997 W. Paul Bissett, FERI ! !======================================================================= ! ! ! The EcoSim code has been developed for research purposes only. It ! ! consists of unpublished, proprietary formulations protected under ! ! U.S. copyright law. It is freely available on request from the ! ! Florida Environmental Research Institute (FERI). Commercial usage ! ! of these formulations is forbidden without express written ! ! permission from FERI. All rights reserved. ! ! ! !*********************************************************************** ! ! ! This routine computes the EcoSim sources and sinks and adds them ! ! to the global biological fields. ! ! ! ! Reference: ! ! ! ! Bissett, W.P., J.J. Walsh, D.A. Dieterle, K.L. Carder, 1999: ! ! Carbon cycling in the upper waters of the Sargasso Sea: I. ! ! Numerical simulation of differential carbon and nitrogen ! ! fluxes, Deep-Sea Res., 46, 205-269. ! ! ! ! Bissett, W.P., K.L. Carder, J.J. Walsh, D.A. Dieterle, 1999: ! ! Carbon cycling in the upper waters of the Sargasso Sea: II. ! ! Numerical simulation of apparent and inherent optical ! ! properties, Deep-Sea Res., 46, 271-317 ! ! ! ! NOTES to EcoSim: ! ! ! ! * This version uses a descending index for depth that is different ! ! than the original coding. ! ! ! ! * This version of the code has been modified by Bronwyn Cahill and ! ! includes a semi-Lagrangian vertical sinking flux algorithm for ! ! fecal material and bio_sediment subroutine which remineralizes ! ! particulate nitrogen and returns it into dissolved nitrate pool. ! ! ! !======================================================================= ! implicit none ! PRIVATE PUBLIC :: biology ! CONTAINS ! !*********************************************************************** SUBROUTINE biology (ng, tile) !*********************************************************************** ! USE mod_param #ifdef DIAGNOSTICS_BIO USE mod_diags #endif USE mod_forces USE mod_grid USE mod_ncparam USE mod_ocean USE mod_stepping ! ! Imported variable declarations. ! integer, intent(in) :: ng, tile ! ! Local variable declarations. ! character (len=*), parameter :: MyFile = & & __FILE__ ! #include "tile.h" ! ! Set header file name. ! #ifdef DISTRIBUTE IF (Lbiofile(iNLM)) THEN #else IF (Lbiofile(iNLM).and.(tile.eq.0)) THEN #endif Lbiofile(iNLM)=.FALSE. BIONAME(iNLM)=MyFile END IF ! #ifdef PROFILE CALL wclock_on (ng, iNLM, 15, __LINE__, MyFile) #endif CALL ecosim_tile (ng, tile, & & LBi, UBi, LBj, UBj, N(ng), NT(ng), & & IminS, ImaxS, JminS, JmaxS, & & nstp(ng), nnew(ng), & #ifdef MASKING & GRID(ng) % rmask, & # if defined WET_DRY && defined DIAGNOSTICS_BIO & GRID(ng) % rmask_full, & # endif #endif & GRID(ng) % Hz, & & GRID(ng) % z_r, & & GRID(ng) % z_w, & & FORCES(ng) % SpecIr, & & FORCES(ng) % avcos, & #ifdef DIAGNOSTICS_BIO & DIAGS(ng) % DiaBio3d, & & DIAGS(ng) % DiaBio4d, & #endif & OCEAN(ng) % t) #ifdef PROFILE CALL wclock_off (ng, iNLM, 15, __LINE__, MyFile) #endif ! RETURN END SUBROUTINE biology ! !*********************************************************************** SUBROUTINE ecosim_tile (ng, tile, & & LBi, UBi, LBj, UBj, UBk, UBt, & & IminS, ImaxS, JminS, JmaxS, & & nstp, nnew, & #ifdef MASKING & rmask, & # if defined WET_DRY && defined DIAGNOSTICS_BIO & rmask_full, & # endif #endif & Hz, z_r, z_w, & & SpecIr, avcos, & #ifdef DIAGNOSTICS_BIO & DiaBio3d, & & DiaBio4d, & #endif & t) !*********************************************************************** ! USE mod_param USE mod_biology USE mod_eclight USE mod_scalars USE mod_iounits ! ! Imported variable declarations. ! integer, intent(in) :: ng, tile integer, intent(in) :: LBi, UBi, LBj, UBj, UBk, UBt integer, intent(in) :: IminS, ImaxS, JminS, JmaxS integer, intent(in) :: nstp, nnew #ifdef ASSUMED_SHAPE # ifdef MASKING real(r8), intent(in) :: rmask(LBi:,LBj:) # if defined WET_DRY && defined DIAGNOSTICS_BIO real(r8), intent(in) :: rmask_full(LBi:,LBj:) # endif # endif real(r8), intent(in) :: Hz(LBi:,LBj:,:) real(r8), intent(in) :: z_r(LBi:,LBj:,:) real(r8), intent(in) :: z_w(LBi:,LBj:,0:) real(r8), intent(in) :: SpecIr(LBi:,LBj:,:) real(r8), intent(in) :: avcos(LBi:,LBj:,:) # ifdef DIAGNOSTICS_BIO real(r8), intent(inout) :: DiaBio3d(LBi:,LBj:,:,:) real(r8), intent(inout) :: DiaBio4d(LBi:,LBj:,:,:,:) # endif real(r8), intent(inout) :: t(LBi:,LBj:,:,:,:) #else # ifdef MASKING real(r8), intent(in) :: rmask(LBi:UBi,LBj:UBj) # if defined WET_DRY && defined DIAGNOSTICS_BIO real(r8), intent(in) :: rmask_full(LBi:UBi,LBj:UBj) # endif # endif real(r8), intent(in) :: Hz(LBi:UBi,LBj:UBj,UBk) real(r8), intent(in) :: z_r(LBi:UBi,LBj:UBj,UBk) real(r8), intent(in) :: z_w(LBi:UBi,LBj:UBj,0:UBk) real(r8), intent(in) :: SpecIr(LBi:UBi,LBj:UBj,NBands) real(r8), intent(in) :: avcos(LBi:UBi,LBj:UBj,NBands) # ifdef DIAGNOSTICS_BIO real(r8), intent(inout) :: DiaBio3d(LBi:UBi,LBj:UBj, & & NDbands,NDbio3d) real(r8), intent(inout) :: DiaBio4d(LBi:UBi,LBj:UBj,N(ng), & & NDbands,NDbio4d) # endif real(r8), intent(inout) :: t(LBi:UBi,LBj:UBj,UBk,3,UBt) #endif ! ! Local variable declarations. ! integer, parameter :: Msink = 30 integer :: i, j, k, ks integer :: Iter, Tindex, ic, isink, ibio, id, itrc, ivar integer :: ibac, iband, idom, ifec, iphy, ipig integer :: Nsink integer, dimension(Msink) :: idsink integer, dimension(IminS:ImaxS,N(ng)) :: ksource real(r8), parameter :: MinVal = 0.0_r8 real(r8) :: FV1, FV2, FV3, FV4, FV5, FV6, FV7, dtbio real(r8) :: DOC_lab, Ed_tot, Nup_max, aph442, aPHYN_wa real(r8) :: avgcos_min, par_b, par_s, photo_DIC, photo_DOC real(r8) :: photo_decay, slope_AC, tChl, theta_m, total_photo real(r8) :: WLE, factint real(r8) :: Het_BAC real(r8) :: N_quota, RelDOC1, RelDON1, RelDOP1, RelFe real(r8) :: cff, cff1, cff2, cffL, cffR, cu, dltL, dltR #ifdef DIAGNOSTICS_BIO real(r8) :: fiter #endif real(r8), dimension(Msink) :: Wbio real(r8), dimension(4) :: Bac_G real(r8), dimension(NBands) :: dATT_sum real(r8), dimension(N(ng),NBands) :: avgcos, dATT real(r8), dimension(N(ng),NBands) :: specir_d real(r8), dimension(N(ng),NBands) :: tot_ab, tot_b, tot_s #ifdef BIO_OPTIC real(r8), dimension(0:N(ng),NBands) :: specir_w #endif real(r8), dimension(N(ng),Nphy) :: C2CHL, C2CHL_w real(r8), dimension(N(ng),Nphy) :: Gt_fl, Gt_ll, Gt_nl real(r8), dimension(N(ng),Nphy) :: Gt_sl, Gt_pl real(r8), dimension(N(ng),Nphy) :: alfa real(r8), dimension(N(ng),Nphy) :: pac_eff real(r8), dimension(N(ng),Nphy,Npig) :: Pigs_w integer, dimension(IminS:ImaxS) :: Keuphotic real(r8), dimension(IminS:ImaxS,N(ng)) :: E0_nz real(r8), dimension(IminS:ImaxS,N(ng)) :: Ed_nz real(r8), dimension(IminS:ImaxS,N(ng)) :: DOC_frac real(r8), dimension(IminS:ImaxS,N(ng)) :: NitrBAC real(r8), dimension(IminS:ImaxS,N(ng)) :: NH4toNO3 real(r8), dimension(IminS:ImaxS,N(ng)) :: NtoNBAC real(r8), dimension(IminS:ImaxS,N(ng)) :: NtoPBAC real(r8), dimension(IminS:ImaxS,N(ng)) :: NtoFeBAC real(r8), dimension(IminS:ImaxS,N(ng)) :: totDOC_d real(r8), dimension(IminS:ImaxS,N(ng)) :: totDON_d real(r8), dimension(IminS:ImaxS,N(ng)) :: totDOP_d real(r8), dimension(IminS:ImaxS,N(ng)) :: totFe_d real(r8), dimension(IminS:ImaxS,N(ng)) :: totNH4_d real(r8), dimension(IminS:ImaxS,N(ng)) :: totNO3_d real(r8), dimension(IminS:ImaxS,N(ng)) :: totPO4_d real(r8), dimension(IminS:ImaxS,N(ng)) :: totSiO_d real(r8), dimension(IminS:ImaxS,N(ng),Nbac) :: GtBAC real(r8), dimension(IminS:ImaxS,N(ng),Nbac) :: NupDOC_ba real(r8), dimension(IminS:ImaxS,N(ng),Nbac) :: NupDON_ba real(r8), dimension(IminS:ImaxS,N(ng),Nbac) :: NupDOP_ba real(r8), dimension(IminS:ImaxS,N(ng),Nbac) :: NupFe_ba real(r8), dimension(IminS:ImaxS,N(ng),Nbac) :: NupNH4_ba real(r8), dimension(IminS:ImaxS,N(ng),Nbac) :: NupPO4_ba real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: C2fALG real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: C2nALG real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: C2pALG real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: C2sALG real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: GtALG real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: GtALG_r real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: NupDOP real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: NupDON real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: NupFe real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: NupNH4 real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: NupNO3 real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: NupPO4 real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: NupSiO real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: graz_act real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: mu_bar_f real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: mu_bar_n real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: mu_bar_p real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: mu_bar_s real(r8), dimension(IminS:ImaxS,N(ng),Nphy) :: refuge real(r8), dimension(IminS:ImaxS,N(ng),Nfec) :: Regen_C real(r8), dimension(IminS:ImaxS,N(ng),Nfec) :: Regen_F real(r8), dimension(IminS:ImaxS,N(ng),Nfec) :: Regen_N real(r8), dimension(IminS:ImaxS,N(ng),Nfec) :: Regen_P real(r8), dimension(IminS:ImaxS,N(ng),Nfec) :: Regen_S real(r8), dimension(IminS:ImaxS,N(ng),NBands) :: specir_scal real(r8), dimension(IminS:ImaxS,N(ng),Nphy,NBands) :: aPHYN_al real(r8), dimension(IminS:ImaxS,N(ng),Nphy,NBands) :: aPHYN_at real(r8), dimension(IminS:ImaxS,N(ng),NBands) :: aDET real(r8), dimension(IminS:ImaxS,N(ng),NBands) :: aCDC real(r8), dimension(IminS:ImaxS,N(ng),NBands) :: b_phy real(r8), dimension(IminS:ImaxS,N(ng),NBands) :: s_phy real(r8), dimension(IminS:ImaxS,N(ng),NBands) :: b_tot real(r8), dimension(IminS:ImaxS,N(ng),NBands) :: s_tot real(r8), dimension(IminS:ImaxS,N(ng),NT(ng)) :: Bio real(r8), dimension(IminS:ImaxS,N(ng),NT(ng)) :: Bio_old real(r8), dimension(IminS:ImaxS,N(ng),NT(ng)) :: Bio_new real(r8), dimension(IminS:ImaxS,0:N(ng)) :: FC real(r8), dimension(IminS:ImaxS,N(ng)) :: Hz_inv real(r8), dimension(IminS:ImaxS,N(ng)) :: Hz_inv2 real(r8), dimension(IminS:ImaxS,N(ng)) :: Hz_inv3 real(r8), dimension(IminS:ImaxS,N(ng)) :: WL real(r8), dimension(IminS:ImaxS,N(ng)) :: WR real(r8), dimension(IminS:ImaxS,N(ng)) :: bL real(r8), dimension(IminS:ImaxS,N(ng)) :: bR real(r8), dimension(IminS:ImaxS,N(ng)) :: qc #include "set_bounds.h" #ifdef DIAGNOSTICS_BIO ! !----------------------------------------------------------------------- ! If appropriate, initialize time-averaged diagnostic arrays. !----------------------------------------------------------------------- ! IF (((iic(ng).gt.ntsDIA(ng)).and. & & (MOD(iic(ng),nDIA(ng)).eq.1)).or. & & ((iic(ng).ge.ntsDIA(ng)).and.(nDIA(ng).eq.1)).or. & & ((nrrec(ng).gt.0).and.(iic(ng).eq.ntstart(ng)))) THEN DO ivar=1,NDbio3d DO k=1,NDbands DO j=Jstr,Jend DO i=Istr,Iend DiaBio3d(i,j,k,ivar)=0.0_r8 END DO END DO END DO END DO DO ivar=1,NDbio4d DO iband=1,NDbands DO k=1,N(ng) DO j=Jstr,Jend DO i=Istr,Iend DiaBio4d(i,j,k,iband,ivar)=0.0_r8 END DO END DO END DO END DO END DO END IF #endif ! !======================================================================= ! Add EcoSim Source/Sink terms. !======================================================================= ! ! Set internal time-stepping. ! dtbio=dt(ng)/REAL(BioIter(ng),r8) #ifdef DIAGNOSTICS_BIO ! ! A factor to account for the number of iterations in accumulating ! diagnostic rate variables. ! fiter=1.0_r8/REAL(BioIter(ng),r8) #endif ! ! Set vertical sinking identification and associated sinking velocity ! arrays. ! ic=1 DO ifec=1,Nfec idsink(ic)=iFecN(ifec) Wbio(ic)=WF(ifec,ng) ic=ic+1 idsink(ic)=iFecC(ifec) Wbio(ic)=WF(ifec,ng) ic=ic+1 idsink(ic)=iFecP(ifec) Wbio(ic)=WF(ifec,ng) ic=ic+1 idsink(ic)=iFecS(ifec) Wbio(ic)=WF(ifec,ng) ic=ic+1 idsink(ic)=iFecF(ifec) Wbio(ic)=WF(ifec,ng) ic=ic+1 END DO DO iphy=1,Nphy idsink(ic)=iPhyN(iphy) Wbio(ic)=WS(iphy,ng) ic=ic+1 idsink(ic)=iPhyC(iphy) Wbio(ic)=WS(iphy,ng) ic=ic+1 idsink(ic)=iPhyP(iphy) Wbio(ic)=WS(iphy,ng) IF (iPhyS(iphy).ne.0) THEN ic=ic+1 idsink(ic)=iPhyS(iphy) Wbio(ic)=WS(iphy,ng) END IF ic=ic+1 idsink(ic)=iPhyF(iphy) Wbio(ic)=WS(iphy,ng) ic=ic+1 END DO Nsink=ic-1 ! !----------------------------------------------------------------------- ! Compute inverse thickness to avoid repeated divisions. !----------------------------------------------------------------------- ! J_LOOP : DO j=Jstr,Jend DO k=1,N(ng) DO i=Istr,Iend Hz_inv(i,k)=1.0_r8/Hz(i,j,k) END DO END DO DO k=1,N(ng)-1 DO i=Istr,Iend Hz_inv2(i,k)=1.0_r8/(Hz(i,j,k)+Hz(i,j,k+1)) END DO END DO DO k=2,N(ng)-1 DO i=Istr,Iend Hz_inv3(i,k)=1.0_r8/(Hz(i,j,k-1)+Hz(i,j,k)+Hz(i,j,k+1)) END DO END DO ! !----------------------------------------------------------------------- ! Extract biological variables from tracer arrays, place them into ! scratch arrays, and restrict their values to be positive definite. !----------------------------------------------------------------------- ! ! At input, all tracers (index nnew) from predictor step have ! transport units (m Tunits) since we do not have yet the new ! values for zeta and Hz. These are known after the 2D barotropic ! time-stepping. ! DO ibio=1,NBT itrc=idbio(ibio) DO k=1,N(ng) DO i=Istr,Iend Bio(i,k,itrc)=MAX(MinVal,t(i,j,k,nstp,itrc)) Bio_old(i,k,itrc)=Bio(i,k,itrc) !! !! HGA - The new tendency terms were not initialized. This gives !! unexpected behavior on different computers since a variable !! was used before it was assigned. This may explain earlier !! problems with the algorithm. Perhaps, this time-stepping can !! be modified latter to avoid unnecessary storage between !! Bio, Bio_old, and Bio_new. !! Bio_new(i,k,itrc)=0.0_r8 END DO END DO END DO ! ! Extract potential temperature and salinity. ! DO k=1,N(ng) DO i=Istr,Iend Bio(i,k,itemp)=t(i,j,k,nstp,itemp) Bio(i,k,isalt)=t(i,j,k,nstp,isalt) END DO END DO ! !----------------------------------------------------------------------- ! Compute temperature and salinity dependent variables. !----------------------------------------------------------------------- ! ! Refuge depth calculation. ! DO iphy=1,Nphy DO k=1,N(ng) DO i=Istr,Iend refuge(i,k,iphy)=MinRefuge(iphy,ng) END DO END DO END DO ! ! Initialize fecal regeneration arrays (N, P, and Fe from Moore et al., ! DSRII 2001; silica is given by values from Bidle and Azam, Nature, ! 1999). ! IF (Regen_flag(ng)) THEN DO ifec=1,Nfec DO k=1,N(ng) DO i=Istr,Iend FV1=EXP(RegTfac(ifec,ng)*(Bio(i,k,itemp)- & & RegTbase(ifec,ng))) Regen_C(i,k,ifec)=RegCR(ifec,ng)*FV1 Regen_N(i,k,ifec)=RegNR(ifec,ng)*FV1 Regen_P(i,k,ifec)=RegPR(ifec,ng)*FV1 Regen_F(i,k,ifec)=RegFR(ifec,ng)*FV1 Regen_S(i,k,ifec)=RegSR(ifec,ng)*FV1 END DO END DO END DO END IF ! ! Calculate temperature dependent growth rate. ! DO iphy=1,Nphy DO k=1,N(ng) DO i=Istr,Iend GtALG(i,k,iphy)=GtALG_max(iphy,ng)* & & EXP(PhyTfac(iphy,ng)* & & (Bio(i,k,itemp)-PhyTbase(iphy,ng))) ! ! Calculate mu_bar for droop equation. ! FV1=maxC2nALG(iphy,ng)*(1.0_r8+GtALG(i,k,iphy)) mu_bar_n(i,k,iphy)=GtALG(i,k,iphy)* & & FV1/(FV1-minC2nALG(iphy,ng)) IF (HsSiO(iphy,ng).lt.LARGER) THEN FV1=maxC2SiALG(iphy,ng)*(1.0_r8+GtALG(i,k,iphy)) mu_bar_s(i,k,iphy)=GtALG(i,k,iphy)* & & FV1/(FV1-minC2SiALG(iphy,ng)) ELSE mu_bar_s(i,k,iphy)=LARGER END IF IF (HsPO4(iphy,ng).lt.LARGER) THEN FV1=maxC2pALG(iphy,ng)*(1.0_r8+GtALG(i,k,iphy)) mu_bar_p(i,k,iphy)=GtALG(i,k,iphy)* & & FV1/(FV1-minC2pALG(iphy,ng)) ELSE mu_bar_p(i,k,iphy)=LARGER END IF IF (HsFe(iphy,ng).lt.LARGER) THEN FV1=maxC2FeALG(iphy,ng)*(1.0_r8+GtALG(i,k,iphy)) mu_bar_f(i,k,iphy)=GtALG(i,k,iphy)* & & FV1/(FV1-minC2FeALG(iphy,ng)) ELSE mu_bar_f(i,k,iphy)=LARGER END IF END DO END DO END DO ! ! Bacterial growth rate from Fasham et al., 1990. ! DO ibac=1,Nbac DO k=1,N(ng) DO i=Istr,Iend GtBAC(i,k,ibac)=GtBAC_max(ibac,ng)* & & EXP(BacTfac(ibac,ng)* & & (Bio(i,k,itemp)-BacTbase(ibac,ng))) END DO END DO END DO ! ! Grazing rate calculation. ! NOTE: ES1 included separation calculations for grazing beneath the ! zone of refuge (250 m). This has been removed and may ! result in differences in deeper waters. !! Revisions, WPB 10/20/02. New grazing formulation that is better !! representation of basal loss rates and biomass accumulations. ! DO iphy=1,Nphy DO k=1,N(ng) DO i=Istr,Iend FV1=MAX(1.0_r8,(Bio(i,k,iPhyC(iphy))/refuge(i,k,iphy))) graz_act(i,k,iphy)=HsGRZ(iphy,ng)*LOG(FV1) END DO END DO END DO ! !----------------------------------------------------------------------- ! Iterate biology source and sink terms. !----------------------------------------------------------------------- ! ITER_LOOP : DO Iter=1,BioIter(ng) DO k=1,N(ng) DO i=Istr,Iend totNH4_d(i,k)=0.0_r8 totNO3_d(i,k)=0.0_r8 totPO4_d(i,k)=0.0_r8 totSiO_d(i,k)=0.0_r8 totFe_d (i,k)=0.0_r8 totDOC_d(i,k)=0.0_r8 totDON_d(i,k)=0.0_r8 totDOP_d(i,k)=0.0_r8 END DO END DO DO iphy=1,Nphy DO k=1,N(ng) DO i=Istr,Iend NupNH4(i,k,iphy)=0.0_r8 NupNO3(i,k,iphy)=0.0_r8 NupPO4(i,k,iphy)=0.0_r8 NupSiO(i,k,iphy)=0.0_r8 NupFe (i,k,iphy)=0.0_r8 NupDON(i,k,iphy)=0.0_r8 NupDOP(i,k,iphy)=0.0_r8 END DO END DO END DO ! ! Compute Ratio Arrays. ! (Calculating only those that are accessed more than once.) ! DO iphy=1,Nphy DO k=1,N(ng) DO i=Istr,Iend C2nALG(i,k,iphy)=0.0_r8 IF (Bio(i,k,iPhyN(iphy)).gt.0.0_r8) THEN C2nALG(i,k,iphy)=Bio(i,k,iPhyC(iphy))/ & & Bio(i,k,iPhyN(iphy)) END IF C2pALG(i,k,iphy)=0.0_r8 IF (Bio(i,k,iPhyP(iphy)).gt.0.0_r8) THEN C2pALG(i,k,iphy)=Bio(i,k,iPhyC(iphy))/ & & Bio(i,k,iPhyP(iphy)) END IF C2sALG(i,k,iphy)=0.0_r8 IF (iPhyS(iphy).gt.0) THEN IF (Bio(i,k,iPhyS(iphy)).gt.0.0_r8) THEN C2sALG(i,k,iphy)=Bio(i,k,iPhyC(iphy))/ & & Bio(i,k,iPhyS(iphy)) END IF END IF C2fALG(i,k,iphy)=0.0_r8 IF (Bio(i,k,iPhyF(iphy)).gt.0.0_r8) THEN C2fALG(i,k,iphy)=Bio(i,k,iPhyC(iphy))/ & & Bio(i,k,iPhyF(iphy)) END IF END DO END DO END DO ! !----------------------------------------------------------------------- ! Daylight Computations. !----------------------------------------------------------------------- ! ! Initialize. ! DO i=Istr,Iend Ed_nz(i,N(ng))=0.0_r8 E0_nz(i,N(ng))=0.0_r8 Keuphotic(i)=N(ng)+1 IF (SpecIr(i,j,21).gt.VSMALL) THEN DO k=1,N(ng)-1 Ed_nz(i,k)=0.0_r8 E0_nz(i,k)=0.0_r8 END DO DO iband=1,NBands dATT_sum(iband)=0.0_r8 DO k=1,N(ng) avgcos(k,iband)=0.0_r8 dATT(k,iband)=0.0_r8 #ifdef DIAGNOSTICS_BIO aDET(i,k,iband)=0.0_r8 aCDC(i,k,iband)=0.0_r8 b_phy(i,k,iband)=0.0_r8 s_phy(i,k,iband)=0.0_r8 b_tot(i,k,iband)=0.0_r8 s_tot(i,k,iband)=0.0_r8 #endif END DO DO iphy=1,Nphy DO k=1,N(ng) aPHYN_at(i,k,iphy,iband)=0.0_r8 aPHYN_al(i,k,iphy,iband)=0.0_r8 END DO END DO END DO ! ! Calculate average cosine zenith angle at surface. ! (See equation 14 Morel, 1991 Prog. Ocean.) ! Ed_tot=0.0_r8 DO iband=1,NBands Ed_tot=Ed_tot+SpecIr(i,j,iband)*DLAM avgcos(N(ng),iband)=avcos(i,j,iband) END DO ! ! Total aph(442). adp(442) is set to 50% of aph(442). ! NOTE: choosing sbands=9 which is band 442 using v8r16 ! sbands formulation. If spectral resolution changes, this ! value must change! ! DO k=N(ng),1,-1 IF (Ed_tot.ge.1.0_r8) THEN aph442=0.0_r8 tChl=0.0_r8 DO iphy=1,Nphy IF (Bio(i,k,iPhyC(iphy)).gt.0.0_r8) THEN tChl=tChl+Bio(i,k,iPigs(iphy,ichl)) pac_eff(k,iphy)=1.0_r8 IF (b_PacEff(iphy,ng).gt.SMALL) THEN FV2=Bio(i,k,iPigs(iphy,ichl))/ & & (Bio(i,k,iPhyC(iphy))*12.0_r8) pac_eff(k,iphy)=MAX(0.5_r8, & & (MIN(1.0_r8, & & b_PacEff(iphy,ng)+ & & mxPacEff(iphy,ng)* & & (FV2- & & b_C2Cl(iphy,ng))))) END IF iband=9 DO ipig=1,Npig IF (iPigs(iphy,ipig).gt.0) THEN aph442=aph442+ & & Bio(i,k,iPigs(iphy,ipig))* & & apigs(ipig,iband)*pac_eff(k,iphy) END IF END DO END IF END DO ! ! Calculate absorption. ! Calculating phytoplankton absorption for attenuation calculation. ! NOTE: 12 factor to convert to ugrams (mg m-3) ! aph442=0.5_r8*aph442 DO iband=1,NBands tot_ab=0.0_r8 DO iphy=1,Nphy DO ipig=1,Npig IF (iPigs(iphy,ipig).gt.0) THEN aPHYN_at(i,k,iphy,iband)= & & aPHYN_at(i,k,iphy,iband)+ & & Bio(i,k,iPigs(iphy,ipig))* & & apigs(ipig,iband)* & & pac_eff(k,iphy) END IF END DO tot_ab(k,iband)=tot_ab(k,iband)+ & & aPHYN_at(i,k,iphy,iband) #ifdef DIAGNOSTICS_BIO DiaBio4d(i,j,k,iband,idaPHY)=DiaBio4d(i,j,k,iband,& & idaPHY)+ & & aPHYN_at(i,k,iphy, & & iband) #endif ! ! Removing absorption due to PPC for "alfa" calculation. ! ipig=5 IF (iPigs(iphy,ipig).gt.0) THEN aPHYN_al(i,k,iphy,iband)= & & aPHYN_at(i,k,iphy,iband)- & & Bio(i,k,iPigs(iphy,ipig))* & & apigs(ipig,iband)* & & pac_eff(k,iphy) END IF END DO ! ! Adding detrital absorption. ! cff=aph442*EXP(0.011_r8* & & (442.0_r8- & & (397.0_r8+REAL(iband,r8)*DLAM))) tot_ab(k,iband)=tot_ab(k,iband)+cff #ifdef DIAGNOSTICS_BIO aDET(i,k,iband)=aDET(i,k,iband)+cff DiaBio4d(i,j,k,iband,idaDET)=DiaBio4d(i,j,k,iband, & & idaDET)+ & & aDET(i,k,iband) #endif ! ! Calculate CDOC absorption. ! NOTE: 12 factor is to convert ugrams per liter, and 0.001 converts ! to mg/liter. Specific absorption ! coefficients were calculated as m-1 / (mg DOC/liters sw). ! net factor = (12*0.001) = 0.012 ! cff=0.012_r8*(Bio(i,k,iCDMC(ilab))* & & aDOC(ilab,iband)+ & & Bio(i,k,iCDMC(irct))* & & aDOC(irct,iband)) tot_ab(k,iband)=tot_ab(k,iband)+cff+awater(iband) #ifdef DIAGNOSTICS_BIO aCDC(i,k,iband)=aCDC(i,k,iband)+cff DiaBio4d(i,j,k,iband,idaCDC)=DiaBio4d(i,j,k,iband, & & idaCDC)+ & & aCDC(i,k,iband) #endif ! ! Calculate scattering and backscattering (see equation 19 Morel, 1991, ! Prog. Ocean). Morel, 1988 puts spectral dependency in backscattering. ! Since Morel (1991) does not have a backscattering equation, use 1988 ! paper. Morel 2001 has slight adjustment 0.01, rather than 0.02. ! This was altered, but never tested in ROMS 1.8 on 03/08/03. ! par_s=0.3_r8*(tChl**0.62_r8) ! scattering par_b=0.0_r8 ! backscattering IF (tChl.gt.0.0_r8) THEN par_b=par_s*(0.002_r8+ & & 0.01_r8* & & (0.5_r8-0.25_r8*LOG10(tChl))* & & wavedp(iband)) END IF par_b=MAX(par_b,0.0_r8) #ifdef DIAGNOSTICS_BIO s_phy(i,k,iband)=s_phy(i,k,iband)+par_s b_phy(i,k,iband)=b_phy(i,k,iband)+par_b DiaBio4d(i,j,k,iband,idsPHY)=DiaBio4d(i,j,k,iband, & & idsPHY)+ & & s_phy(i,k,iband) DiaBio4d(i,j,k,iband,idbPHY)=DiaBio4d(i,j,k,iband, & & idbPHY)+ & & b_phy(i,k,iband) #endif ! ! However, for omega0 calculation, "par_s" must be spectral, so use ! dependency from Sathy and Platt 1988. ! tot_s(k,iband)=bwater(iband)+par_s*wavedp(iband) #ifdef DIAGNOSTICS_BIO s_tot(i,k,iband)=s_tot(i,k,iband)+tot_s(k,iband) #endif ! ! Morel, 1988 instead of 1991. See methods. ! tot_b(k,iband)=0.5_r8*bwater(iband)+par_b #ifdef DIAGNOSTICS_BIO b_tot(i,k,iband)=b_tot(i,k,iband)+tot_b(k,iband) DiaBio4d(i,j,k,iband,idsTOT)=DiaBio4d(i,j,k,iband, & & idsTOT)+ & & s_tot(i,k,iband) DiaBio4d(i,j,k,iband,idbTOT)=DiaBio4d(i,j,k,iband, & & idbTOT)+ & & b_tot(i,k,iband) #endif #ifdef BIO_OPTIC ! ! Next statement is Eq. 11 of Lee et al. (2005) from Gallegos ! equal to SPECKD in Gallegos. Notice that the in-water solar ! angle in "cff1" is in degrees. ! cff1=1.0_r8+ & & 0.005_r8*ACOS(avgcos(k,iband))*rad2deg cff2=4.18_r8*(1.0_r8-0.52_r8* & & EXP(-10.8_r8*tot_ab(k,iband))) dATT(k,iband)=cff1*tot_ab(k,iband)+ & & cff2*tot_b (k,iband) #else ! ! Sathy and Platt JGR 1988. This is set with the average cosine of ! the box above, and used to calculate a new avgcos for this level. ! This new average cosine is then used to recalculate the attenuation ! coefficient. ! dATT(k,iband)=(tot_ab(k,iband)+ & & tot_b (k,iband))/avgcos(k,iband) #endif ! ! See Mobley, 1995 for graphical depiction of this equation. ! avgcos_min=avgcos(k,iband)+ & & (0.5_r8-avgcos(k,iband))* & & (tot_s(k,iband)/ & & (tot_ab(k,iband)+tot_s(k,iband))) ! ! Calculate average cosine. Linear fit to average cosine versus optical ! depth relationship. The FV1 calculation keeps the denominator of the ! slope calculation from going negative and above 1. ! FV1=MAX(1.0_r8, & & 7.0_r8-dATT(k,iband)*ABS(z_r(i,j,k))) slope_AC =MIN(0.0_r8, & & (avgcos_min-avgcos(k,iband))/FV1) avgcos(k,iband)=avgcos(k,iband)+ & & slope_AC*dATT(k,iband)*Hz(i,j,k) #ifdef BIO_OPTIC ! ! Next statement is Eq. 11 of Lee et al. (2005). Notice that "cff1" is ! recomputed because "avgcos" changed and "cff2" is the same as above. ! cff1=1.0_r8+ & & 0.005_r8*ACOS(avgcos(k,iband))*rad2deg dATT(k,iband)=cff1*tot_ab(k,iband)+ & & cff2*tot_b (k,iband) #else dATT(k,iband)=(tot_ab(k,iband)+ & & tot_b (k,iband))/avgcos(k,iband) #endif ! ! Set avgcos for next level. ! IF (k.ne.1) THEN avgcos(k-1,iband)=avgcos(k,iband) END IF ! ! Calculate spectral irradiance with depth. ! FV1=dATT(k,iband)*Hz(i,j,k) FV2=dATT_sum(iband)+0.5_r8*FV1 dATT_sum(iband)=dATT_sum(iband)+FV1 specir_d(k,iband)=SpecIr(i,j,iband)* & & EXP(-FV2)*DLAM ! ! Calculate spectral scalar irradiance. Morel, 1991 Prog. Ocean. ! specir_scal(i,k,iband)=specir_d(k,iband)* & & (dATT(k,iband)/ & & tot_ab(k,iband)) E0_nz(i,k)=E0_nz(i,k)+specir_scal(i,k,iband) ! ! Calculate Ed_nz. ! Ed_nz(i,k)=Ed_nz(i,k)+specir_d(k,iband) #ifdef DIAGNOSTICS_BIO DiaBio3d(i,j,iband,idSpIr)=DiaBio3d(i,j,iband, & & idSpIr)+ & & SpecIr(i,j,iband) DiaBio4d(i,j,k,iband,iddIrr)=DiaBio4d(i,j,k,iband, & & iddIrr)+ & & specir_d(k,iband) DiaBio4d(i,j,k,iband,idsIrr)=DiaBio4d(i,j,k,iband, & & idsIrr)+ & & specir_scal(i,k,iband) DiaBio4d(i,j,k,iband,idLatt)=DiaBio4d(i,j,k,iband, & & idLatt)+ & & dATT(k,iband) DiaBio4d(i,j,k,iband,idAcos)=DiaBio4d(i,j,k,iband, & & idAcos)+ & & avgcos(k,iband) #endif END DO Ed_tot=E0_nz(i,k) ! ! Set bottom of the euphotic zone. ! Keuphotic(i)=k END IF END DO END IF END DO ! !----------------------------------------------------------------------- ! Bacterial nutrient uptake. !----------------------------------------------------------------------- ! DO ibac=1,Nbac DO k=1,N(ng) DO i=Istr,Iend ! ! DOM uptake. ! IF ((Bio(i,k,iDOMC(ilab)).gt.0.0_r8).and. & & (Bio(i,k,iDOMN(ilab)).gt.0.0_r8).and. & & (Bio(i,k,iDOMP(ilab)).gt.0.0_r8)) THEN NupDOC_ba(i,k,ibac)=GtBAC(i,k,ibac)* & & Bio(i,k,iBacC(ibac))* & & I_Bac_Ceff(ng)* & & (Bio(i,k,iDOMC(ilab))/ & & (HsDOC_ba(ibac,ng)+ & & Bio(i,k,iDOMC(ilab)))) NupDON_ba(i,k,ibac)=NupDOC_ba(i,k,ibac)* & & Bio(i,k,iDOMN(ilab))/ & & Bio(i,k,iDOMC(ilab)) NupDOP_ba(i,k,ibac)=NupDOC_ba(i,k,ibac)* & & Bio(i,k,iDOMP(ilab))/ & & Bio(i,k,iDOMC(ilab)) ELSE NupDOC_ba(i,k,ibac)=0.0_r8 NupDON_ba(i,k,ibac)=0.0_r8 NupDOP_ba(i,k,ibac)=0.0_r8 END IF totDOC_d(i,k)=totDOC_d(i,k)+NupDOC_ba(i,k,ibac) totDON_d(i,k)=totDON_d(i,k)+NupDON_ba(i,k,ibac) totDOP_d(i,k)=totDOP_d(i,k)+NupDOP_ba(i,k,ibac) ! ! NH4 uptake. ! NupNH4_ba(i,k,ibac)=GtBAC(i,k,ibac)* & & Bio(i,k,iBacN(ibac))* & & Bio(i,k,iNH4_)/ & & (HsNH4_ba(ibac,ng)+Bio(i,k,iNH4_)) totNH4_d(i,k)=totNH4_d(i,k)+NupNH4_ba(i,k,ibac) ! ! PO4 uptake. ! NupPO4_ba(i,k,ibac)=GtBAC(i,k,ibac)* & & Bio(i,k,iBacP(ibac))* & & Bio(i,k,iPO4_)/ & & (HsPO4_ba(ibac,ng)+Bio(i,k,iPO4_)) totPO4_d(i,k)=totPO4_d(i,k)+NupPO4_ba(i,k,ibac) ! ! Fe uptake. ! NupFe_ba(i,k,ibac)=GtBAC(i,k,ibac)* & & Bio(i,k,iBacF(ibac))* & & Bio(i,k,iFeO_)/ & & (HsFe_ba(ibac,ng)+Bio(i,k,iFeO_)) totFe_d(i,k)=totFe_d(i,k)+NupFe_ba(i,k,ibac) END DO END DO END DO ! !----------------------------------------------------------------------- ! Phytoplankton dark nutrient uptake. !----------------------------------------------------------------------- ! DO iphy=1,Nphy DO k=1,N(ng) DO i=Istr,Iend IF (C2nALG(i,k,iphy).gt.C2nALGminABS(iphy,ng)) THEN ! ! NOTE: these are being saved to test for total nutrient uptake. ! If nutrient uptake is greater than maximum nutrient, then ! each of the uptakes are reduced by their fractional contri- ! bution to the total. ! Nup_max=GtALG(i,k,iphy) NupNO3(i,k,iphy)=(Bio(i,k,iNO3_)/ & & (HsNO3(iphy,ng)+Bio(i,k,iNO3_))* & & EXP(-BET_(iphy,ng)*Bio(i,k,iNH4_))) NupNH4(i,k,iphy)=Bio(i,k,iNH4_)/ & & (HsNH4(iphy,ng)+Bio(i,k,iNH4_)) ! ! Test that Wroblewski equation does not exceed 1.0. ! FV1=NupNO3(i,k,iphy)+NupNH4(i,k,iphy) IF (FV1.gt.1.0_r8) THEN FV1=1.0_r8/FV1 NupNO3(i,k,iphy)=NupNO3(i,k,iphy)*FV1 NupNH4(i,k,iphy)=NupNH4(i,k,iphy)*FV1 END IF ! ! Change from percentage of maximum to mass per second. ! FV1=Nup_max*Bio(i,k,iPhyN(iphy)) NupNO3(i,k,iphy)=NupNO3(i,k,iphy)*FV1 NupNH4(i,k,iphy)=NupNH4(i,k,iphy)*FV1 ! ! Test for DON uptake. ! IF (C2nALG(i,k,iphy).gt.C2nNupDON(iphy,ng)) THEN NupDON(i,k,iphy)=FV1* & & Bio(i,k,iDOMN(ilab))/ & & (HsDON(iphy,ng)+ & & Bio(i,k,iDOMN(ilab))) END IF ! ! Accumulate total demand for nutrients. ! totNO3_d(i,k)=totNO3_d(i,k)+NupNO3(i,k,iphy) totNH4_d(i,k)=totNH4_d(i,k)+NupNH4(i,k,iphy) totDON_d(i,k)=totDON_d(i,k)+NupDON(i,k,iphy) END IF ! ! Dark silica uptake, min C2Si test. ! The LARGER test can be removed after testing phase. ! IF (HsSiO(iphy,ng).lt.LARGER) THEN IF (C2sALG(i,k,iphy).gt.C2SiALGminABS(iphy,ng)) THEN Nup_max=GtALG(i,k,iphy) NupSiO(i,k,iphy)=Bio(i,k,iSiO_)/ & & (HsSiO(iphy,ng)+Bio(i,k,iSiO_)) ! ! Change from percentage of maximum to mass per second. ! IF (iPhyS(iphy).gt.0) THEN FV1=Nup_max*Bio(i,k,iPhyS(iphy)) NupSiO(i,k,iphy)=NupSiO(i,k,iphy)*FV1 ELSE NupSiO(i,k,iphy)=0.0_r8 END IF ! ! Accumulate total demand for nutrients. ! totSiO_d(i,k)=totSiO_d(i,k)+NupSiO(i,k,iphy) END IF END IF ! ! Dark phophorus uptake, min C2P test. ! The LARGER test can be removed after testing phase. ! IF (HsPO4(iphy,ng).lt.LARGER) THEN IF (C2pALG(i,k,iphy).gt.C2pALGminABS(iphy,ng)) THEN Nup_max=GtALG(i,k,iphy) NupPO4(i,k,iphy)=Bio(i,k,iPO4_)/ & & (HsPO4(iphy,ng)+Bio(i,k,iPO4_)) ! ! Change from percentage of maximum to mass per second. ! FV1=Nup_max*Bio(i,k,iPhyP(iphy)) NupPO4(i,k,iphy)=NupPO4(i,k,iphy)*FV1 ! ! Test for alk. phosphatase ! IF (C2pALG(i,k,iphy).gt.C2pALKPHOS(iphy,ng)) THEN NupDOP(i,k,iphy)=FV1* & Bio(i,k,iDOMP(ilab))/ & & (HsDOP(iphy,ng)+ & & Bio(i,k,iDOMP(ilab))) END IF ! ! Accumulate total demand for nutrients. ! totPO4_d(i,k)=totPO4_d(i,k)+NupPO4(i,k,iphy) totDOP_d(i,k)=totDOP_d(i,k)+NupDOP(i,k,iphy) END IF END IF ! ! Dark iron uptake, min C2Fe test. ! The LARGER test can be removed after testing phase. ! IF (HsFe(iphy,ng).lt.LARGER) THEN IF (C2fALG(i,k,iphy).gt.C2FeALGminABS(iphy,ng)) THEN Nup_max=GtALG(i,k,iphy) NupFe(i,k,iphy)=Bio(i,k,iFeO_)/ & & (HsFe(iphy,ng)+Bio(i,k,iFeO_)) ! ! Change from percentage of maximum to mass per second. ! FV1=Nup_max*Bio(i,k,iPhyF(iphy)) NupFe(i,k,iphy)=NupFe(i,k,iphy)*FV1 ! ! Accumulate total demand for nutrients. ! totFe_d(i,k)=totFe_d(i,k)+NupFe(i,k,iphy) END IF END IF END DO END DO END DO ! ! Calculate bacterial nitrification as a Michaelis-Menton function ! of ambient NH4 concentration, beneath the euphotic zone (light ! inhibits nitrification). ! DO k=1,N(ng) DO i=Istr,Iend NitrBAC(i,k)=0.0_r8 NH4toNO3(i,k)=0.0_r8 NtoNBAC(i,k)=0.0_r8 NtoPBAC(i,k)=0.0_r8 NtoFeBAC(i,k)=0.0_r8 IF (k.lt.Keuphotic(i)) THEN NH4toNO3(i,k)=RtNIT(ng)* & & Bio(i,k,iNH4_)/(HsNIT(ng)+Bio(i,k,iNH4_)) ! ! Nitrification fixes DIC into POC. ! Conversion factor of 7.0 from Kaplan 1983 "Nitrogen in the Sea" ! factor equals (1.0 / (7.0 * C2nBAC)). Adds NH4 uptake as biomass. ! NitrBAC(i,k)=NH4toNO3(i,k)/7.0_r8 NtoNBAC(i,k)=NitrBAC(i,k)*N2cBAC(ng) NtoPBAC(i,k)=NitrBAC(i,k)*P2cBAC(ng) NtoFeBAC(i,k)=NitrBAC(i,k)*Fe2cBAC(ng) totNH4_d(i,k)=totNH4_d(i,k)+NH4toNO3(i,k)+NtoNBAC(i,k) totPO4_d(i,k)=totPO4_d(i,k)+NtoPBAC(i,k) totFe_d (i,k)=totFe_d (i,k)+NtoFeBAC(i,k) END IF END DO END DO ! !----------------------------------------------------------------------- ! Test that total nutrient demand does not exceed supply. If it does ! total demand is normalized to the total supply. Each species demand ! is reduced to its weighted average percentage of the supply. !----------------------------------------------------------------------- ! DO k=1,N(ng) DO i=Istr,Iend FV2=totNO3_d(i,k)*dtbio IF (FV2.gt.Bio(i,k,iNO3_)) THEN FV1=(Bio(i,k,iNO3_)-VSMALL)/FV2 DO iphy=1,Nphy NupNO3(i,k,iphy)=NupNO3(i,k,iphy)*FV1 END DO END IF ! FV2=totNH4_d(i,k)*dtbio IF (FV2.gt.Bio(i,k,iNH4_)) THEN FV1=(Bio(i,k,iNH4_)-VSMALL)/FV2 DO iphy=1,Nphy NupNH4(i,k,iphy)=NupNH4(i,k,iphy)*FV1 END DO DO ibac=1,Nbac NupNH4_ba(i,k,ibac)=NupNH4_ba(i,k,ibac)*FV1 END DO NH4toNO3(i,k)=NH4toNO3(i,k)*FV1 NtoNBAC(i,k)=NtoNBAC(i,k)*FV1 END IF ! FV2=totSiO_d(i,k)*dtbio IF (FV2.gt.Bio(i,k,iSiO_)) THEN FV1=(Bio(i,k,iSiO_)-VSMALL)/FV2 DO iphy=1,Nphy NupSiO(i,k,iphy)=NupSiO(i,k,iphy)*FV1 END DO END IF ! FV2=totPO4_d(i,k)*dtbio IF (FV2.gt.Bio(i,k,iPO4_)) THEN FV1=(Bio(i,k,iPO4_)-VSMALL)/FV2 DO iphy=1,Nphy NupPO4(i,k,iphy)=NupPO4(i,k,iphy)*FV1 END DO DO ibac=1,Nbac NupPO4_ba(i,k,ibac)=NupPO4_ba(i,k,ibac)*FV1 END DO NtoPBAC(i,k)=NtoPBAC(i,k)*FV1 END IF ! FV2=totFe_d(i,k)*dtbio IF (FV2.gt.Bio(i,k,iFeO_)) THEN FV1=(Bio(i,k,iFeO_)-VSMALL)/FV2 DO iphy=1,Nphy NupFe(i,k,iphy)=NupFe(i,k,iphy)*FV1 END DO DO ibac=1,Nbac NupFe_ba(i,k,ibac)=NupFe_ba(i,k,ibac)*FV1 END DO NtoFeBAC(i,k)=NtoFeBAC(i,k)*FV1 END IF ! ! Bacteria are the only group to take up DOC. Remove BAC DON and ! BAC DOP uptake from total uptake; adjust uptake and add back. ! FV2=totDOC_d(i,k)*dtbio IF (FV2.gt.Bio(i,k,iDOMC(ilab))) THEN FV1=(Bio(i,k,iDOMC(ilab))-VSMALL)/FV2 totDOC_d(i,k)=totDOC_d(i,k)*FV1 DO ibac=1,Nbac NupDOC_ba(i,k,ibac)=NupDOC_ba(i,k,ibac)*FV1 totDON_d(i,k)=totDON_d(i,k)-NupDON_ba(i,k,ibac) NupDON_ba(i,k,ibac)=NupDON_ba(i,k,ibac)*FV1 totDON_d(i,k)=totDON_d(i,k)+NupDON_ba(i,k,ibac) totDOP_d(i,k)=totDOP_d(i,k)-NupDOP_ba(i,k,ibac) NupDOP_ba(i,k,ibac)=NupDOP_ba(i,k,ibac)*FV1 totDOP_d(i,k)=totDOP_d(i,k)+NupDOP_ba(i,k,ibac) END DO END IF ! ! Remove BAC DON uptake from total uptake; adjust uptake and add back. ! FV2=totDON_d(i,k)*dtbio IF (FV2.gt.Bio(i,k,iDOMN(ilab))) THEN FV1=(Bio(i,k,iDOMN(ilab))-VSMALL)/FV2 totDON_d(i,k)=totDON_d(i,k)*FV1 totDOC_d(i,k)=totDOC_d(i,k)*FV1 DO iphy=1,Nphy NupDON(i,k,iphy)=NupDON(i,k,iphy)*FV1 END DO DO ibac=1,Nbac NupDON_ba(i,k,ibac)=NupDON_ba(i,k,ibac)*FV1 NupDOC_ba(i,k,ibac)=NupDOC_ba(i,k,ibac)*FV1 totDOP_d(i,k)=totDOP_d(i,k)-NupDOP_ba(i,k,ibac) NupDOP_ba(i,k,ibac)=NupDOP_ba(i,k,ibac)*FV1 totDOP_d(i,k)=totDOP_d(i,k)+NupDOP_ba(i,k,ibac) END DO END IF ! ! Remove BAC DOP uptake from total uptake; adjust uptake and add back. ! FV2=totDOP_d(i,k)*dtbio IF (FV2.gt.Bio(i,k,iDOMP(ilab))) THEN FV1=(Bio(i,k,iDOMP(ilab))-VSMALL)/FV2 totDOP_d(i,k)=totDOP_d(i,k)*FV1 totDOC_d(i,k)=totDOC_d(i,k)*FV1 DO iphy=1,Nphy NupDOP(i,k,iphy)=NupDOP(i,k,iphy)*FV1 END DO DO ibac=1,Nbac NupDOP_ba(i,k,ibac)=NupDOP_ba(i,k,ibac)*FV1 totDON_d(i,k)=totDON_d(i,k)-NupDON_ba(i,k,ibac) NupDON_ba(i,k,ibac)=NupDON_ba(i,k,ibac)*FV1 totDON_d(i,k)=totDON_d(i,k)+NupDON_ba(i,k,ibac) NupDOC_ba(i,k,ibac)=NupDOC_ba(i,k,ibac)*FV1 END DO END IF END DO END DO ! ! Increase particulate nutrients by the amount of the uptake. ! DO iphy=1,Nphy DO k=1,N(ng) DO i=Istr,Iend Bio_new(i,k,iPhyN(iphy))=Bio_new(i,k,iPhyN(iphy))+ & & NupNO3(i,k,iphy)+ & & NupNH4(i,k,iphy)+ & & NupDON(i,k,iphy) Bio_new(i,k,iPhyP(iphy))=Bio_new(i,k,iPhyP(iphy))+ & & NupPO4(i,k,iphy)+ & & NupDOP(i,k,iphy) Bio_new(i,k,iPhyF(iphy))=Bio_new(i,k,iPhyF(iphy))+ & & NupFe(i,k,iphy) IF (iPhyS(iphy).gt.0) THEN Bio_new(i,k,iPhyS(iphy))=Bio_new(i,k,iPhyS(iphy))+ & & NupSiO(i,k,iphy) END IF ! ! Update nutrient arrays for growth and budgets. Bacterial uptake ! included below. ! Bio_new(i,k,iNO3_)=Bio_new(i,k,iNO3_)- & & NupNO3(i,k,iphy) Bio_new(i,k,iNH4_)=Bio_new(i,k,iNH4_)- & & NupNH4(i,k,iphy) Bio_new(i,k,iSiO_)=Bio_new(i,k,iSiO_)- & & NupSiO(i,k,iphy) Bio_new(i,k,iPO4_)=Bio_new(i,k,iPO4_)- & & NupPO4(i,k,iphy) Bio_new(i,k,iFeO_)=Bio_new(i,k,iFeO_)- & & NupFe (i,k,iphy) Bio_new(i,k,iDOMN(ilab))=Bio_new(i,k,iDOMN(ilab))- & & NupDON(i,k,iphy) Bio_new(i,k,iDOMP(ilab))=Bio_new(i,k,iDOMP(ilab))- & & NupDOP(i,k,iphy) END DO END DO END DO ! ! Nitrification fixes DIC into DOC. ! DO k=1,N(ng) DO i=Istr,Iend Bio_new(i,k,iDIC_)=Bio_new(i,k,iDIC_)- & & NitrBAC(i,k) END DO END DO ! ! Add nitrifying bacteria biomass to heterotrophic bacteria biomass. ! Adding PON, POP, POFe to BacC arrays at current C2_BAC ratios. ! DO ibac=1,Nbac DO k=1,N(ng) DO i=Istr,Iend Bio_new(i,k,iBacC(ibac))=Bio_new(i,k,iBacC(ibac))+ & & NitrBAC(i,k) Bio_new(i,k,iBacN(ibac))=Bio_new(i,k,iBacN(ibac))+ & & NtoNBAC(i,k) Bio_new(i,k,iBacP(ibac))=Bio_new(i,k,iBacP(ibac))+ & & NtoPBAC(i,k) Bio_new(i,k,iBacF(ibac))=Bio_new(i,k,iBacF(ibac))+ & & NtoFeBAC(i,k) END DO END DO END DO ! ! Update nutrient arrays for nitrification. ! DO k=1,N(ng) DO i=Istr,Iend Bio_new(i,k,iNO3_)=Bio_new(i,k,iNO3_)+ & & NH4toNO3(i,k) Bio_new(i,k,iNH4_)=Bio_new(i,k,iNH4_)- & & (NH4toNO3(i,k)+NtoNBAC(i,k)) Bio_new(i,k,iPO4_)=Bio_new(i,k,iPO4_)- & & NtoPBAC(i,k) Bio_new(i,k,iFeO_)=Bio_new(i,k,iFeO_)- & & NtoFeBAC(i,k) END DO END DO ! !----------------------------------------------------------------------- ! Light mediated carbon growth. !----------------------------------------------------------------------- ! DO i=Istr,Iend DO k=N(ng),Keuphotic(i),-1 DO iphy=1,Nphy IF (Bio(i,k,iPhyC(iphy)).gt.0.0_r8) THEN ! ! Calculate weighted average spectral absorption. ! aPHYN_wa=0.0_r8 DO iband=1,NBands aPHYN_wa=aPHYN_wa+(aPHYN_al(i,k,iphy,iband)* & & specir_scal(i,k,iband)) END DO ! ! If Keuphotic(i) < N+1, and E0_nz(i,k)=0, this will cause pigments to ! blow up. This should never happen, unless Keuphotic is not calcuated ! properly. WPB ! aPHYN_wa=aPHYN_wa/E0_nz(i,k) ! ! Calculate "alfa" for HTAN function of P vs. I. ! (conversion: Ein/microEin * 10e3) ! alfa(k,iphy)=(aPHYN_wa/Bio(i,k,iPhyC(iphy)))* & & qu_yld(iphy,ng)*0.001_r8 ! ! Light limited growth rate. ! FV1=MAX(0.0_r8,E0_nz(i,k)-E0_comp(iphy,ng)) FV2=E0_nz(i,k)-E0_inhib(iphy,ng) IF (FV2.gt.0.0_r8) THEN Gt_ll(k,iphy)=GtALG(i,k,iphy)* & & TANH(alfa(k,iphy)*FV1/ & & GtALG(i,k,iphy))* & & EXP(-inhib_fac(iphy,ng)*FV2) ELSE Gt_ll(k,iphy)=GtALG(i,k,iphy)* & & TANH(alfa(k,iphy)*FV1/ & & GtALG(i,k,iphy)) END IF ! ! Nutrient limited growth rates. ! ! REMEMBER that sinking speed to be set by gradient of limiting ! nutrient, allowing for negative sinking. Try storing growth ! rate terms in an array and using MAXLOC for if test. ! ! Nitrogen limited growth rate. ! IF (Bio(i,k,iPhyN(iphy)).gt.0.0_r8) THEN FV1=Bio(i,k,iPhyC(iphy))/ & & (Bio(i,k,iPhyN(iphy))+Bio_new(i,k,iPhyN(iphy))) Gt_nl(k,iphy)=mu_bar_n(i,k,iphy)* & & (1.0_r8-ImaxC2nALG(iphy,ng)*FV1) Gt_nl(k,iphy)=MAX(0.0_r8, & & MIN(Gt_nl(k,iphy), & & GtALG(i,k,iphy))) END IF ! ! Silica limited growth rate. ! Testing for silica incorporation. ! IF (iPhyS(iphy).gt.0) THEN IF ((HsSiO(iphy,ng).lt.LARGER).and. & & (Bio(i,k,iPhyS(iphy)).gt.0.0_r8)) THEN FV1=Bio(i,k,iPhyC(iphy))/ & & (Bio(i,k,iPhyS(iphy))+ & & Bio_new(i,k,iPhyS(iphy))) Gt_sl(k,iphy)=mu_bar_s(i,k,iphy)* & & (1.0_r8-ImaxC2SiALG(iphy,ng)*FV1) Gt_sl(k,iphy)=MAX(0.0_r8, & & MIN(Gt_sl(k,iphy), & & GtALG(i,k,iphy))) ELSE Gt_sl(k,iphy)=LARGER END IF ELSE Gt_sl(k,iphy)=LARGER END IF ! ! Phosphorus limited growth rate. ! IF ((HsPO4(iphy,ng).lt.LARGER).and. & & (Bio(i,k,iPhyP(iphy)).gt.0.0_r8)) THEN FV1=Bio(i,k,iPhyC(iphy))/ & & (Bio(i,k,iPhyP(iphy))+Bio_new(i,k,iPhyP(iphy))) Gt_pl(k,iphy)=mu_bar_p(i,k,iphy)* & & (1.0_r8-ImaxC2pALG(iphy,ng)*FV1) Gt_pl(k,iphy)=MAX(0.0_r8, & & MIN(Gt_pl(k,iphy), & & GtALG(i,k,iphy))) ELSE Gt_pl(k,iphy)=LARGER END IF ! ! Iron limited growth rate ! IF ((HsFe(iphy,ng).lt.LARGER).and. & & (Bio(i,k,iPhyF(iphy)).gt.0.0_r8)) THEN FV1=Bio(i,k,iPhyC(iphy))/ & & (Bio(i,k,iPhyF(iphy))+Bio_new(i,k,iPhyF(iphy))) Gt_fl(k,iphy)=mu_bar_f(i,k,iphy)* & & (1.0_r8-ImaxC2FeALG(iphy,ng)*FV1) Gt_fl(k,iphy)=MAX(0.0_r8, & & MIN(Gt_fl(k,iphy), & & GtALG(i,k,iphy))) ELSE Gt_fl(k,iphy)=LARGER END IF ! ! Realized growth rate is minimum of light or nutrient limited rate. ! GtALG_r(i,k,iphy)=MIN(Gt_ll(k,iphy),Gt_nl(k,iphy), & & Gt_sl(k,iphy),Gt_pl(k,iphy), & & Gt_fl(k,iphy)) IF (GtALG_r(i,k,iphy).ge.LARGER) THEN GtALG_r(i,k,iphy)=0.0_r8 END IF ! ! Carbon growth calculations. ! FV1=Bio(i,k,iPhyC(iphy))*GtALG_r(i,k,iphy) Bio_new(i,k,iPhyC(iphy))=Bio_new(i,k,iPhyC(iphy))+ & & FV1 Bio_new(i,k,iDIC_)=Bio_new(i,k,iDIC_)- & & FV1 ! ! Pigment growth calculations. ! DO ipig=1,Npig IF (iPigs(iphy,ipig).gt.0) THEN itrc=iPigs(iphy,ipig) IF (Bio(i,k,iPhyC(iphy)).gt.0.0_r8) THEN FV1=Bio(i,k,itrc)*GtALG_r(i,k,iphy) Bio_new(i,k,itrc)=Bio_new(i,k,itrc)+FV1 END IF END IF END DO END IF END DO END DO END DO ! !----------------------------------------------------------------------- ! Bacterioplankton carbon growth terms. !----------------------------------------------------------------------- ! DO k=1,N(ng) DO i=Istr,Iend Het_BAC=0.0_r8 RelDOC1=0.0_r8 RelDON1=0.0_r8 RelDOP1=0.0_r8 RelFe=0.0_r8 ! ! NOTE: Only DOC2/DON2 formation is in this section. ! Take colored excretion off the top. 03/18/00 ! also, not excreting any DOP or Fe ! REMEMBER, if excreting DOP and Fe, must address changes in growth if ! tests. (see DON equations). 03/21/00. ! DO ibac=1,Nbac FV1=NupDOC_ba(i,k,ibac)*ExBAC_c(ng)* & & (1.0_r8-cDOCfrac_c(irct,ng)) FV2=NupDOC_ba(i,k,ibac)*ExBAC_c(ng)* & & cDOCfrac_c(irct,ng) FV3=NupDON_ba(i,k,ibac)*ExBAC_n(ng) ! Bio_new(i,k,iDOMC(irct))=Bio_new(i,k,iDOMC(irct))+ & & FV1 Bio_new(i,k,iCDMC(irct))=Bio_new(i,k,iCDMC(irct))+ & & FV2 Bio_new(i,k,iDOMN(irct))=Bio_new(i,k,iDOMN(irct))+ & & FV3 ! ! As we are taking it off the top, must remove from DOMN1 now. No other ! organisms use DOMC1, so net term (totDOC_d) can be used in budgeting ! below. This saves cycles, but makes code difficult to read. WPB ! Bio_new(i,k,iDOMN(ilab))=Bio_new(i,k,iDOMN(ilab))- & & FV3 ! ! Remove from uptake. ! NupDOC_ba(i,k,ibac)=NupDOC_ba(i,k,ibac)- & & (FV1+FV2) NupDON_ba(i,k,ibac)=NupDON_ba(i,k,ibac)- & & FV3 ! ! Determine growth limitation. Assuming 100% efficiency for N, P, Fe. ! If DOMC=0, or DOMN=0, or DOMP=0, then NupDOC_ba = NupDON_ba = ! NupDOP_ba = 0 and none of the divisions below are accessed. WPB ! Bac_G(1)=NupDOC_ba(i,k,ibac)*Bac_Ceff(ng) Bac_G(2)=(NupDON_ba(i,k,ibac)+ & & NupNH4_ba(i,k,ibac))* & & C2nBAC(ng) Bac_G(3)=(NupDOP_ba(i,k,ibac)+ & & NupPO4_ba(i,k,ibac))* & & C2pBAC(ng) Bac_G(4)=NupFe_ba(i,k,ibac)*C2FeBAC(ng) ! ! Energy limited case. All excess nutrients returned in inorganic form. ! IF ((Bac_G(1).le.Bac_G(2)).and. & & (Bac_G(1).le.Bac_G(3)).and. & & (Bac_G(1).le.Bac_G(4))) THEN Het_BAC=Bac_G(1) FV1=Bac_G(1)*N2cBAC(ng) FV2=Bac_G(1)*P2cBAC(ng) FV3=Bac_G(1)*Fe2cBAC(ng) Bio_new(i,k,iBacN(ibac))=Bio_new(i,k,iBacN(ibac))+ & & FV1 Bio_new(i,k,iBacP(ibac))=Bio_new(i,k,iBacP(ibac))+ & & FV2 Bio_new(i,k,iBacF(ibac))=Bio_new(i,k,iBacF(ibac))+ & & FV3 ! ! Uptake arrays should probably now be negative. If NH4 or PO4 is ! positive, then there is some uptake of inorganic forms, but this ! value will be less than the original Nup value because of IF test. ! NupNH4_ba(i,k,ibac)=FV1-NupDON_ba(i,k,ibac) NupPO4_ba(i,k,ibac)=FV2-NupDOP_ba(i,k,ibac) ! ! Because Fe is considered to be all inorganic, only net uptake of Fe ! is needed. ! RelFe=NupFe_ba(i,k,ibac)-FV3 NupFe_ba(i,k,ibac)=FV3 ! ! Nitrogen limited case. Excess nutrients returned in organic form ! first, inorganic second. ! ELSE IF ((Bac_G(2).le.Bac_G(3)).and. & & (Bac_G(2).le.Bac_G(4))) THEN Het_BAC=Bac_G(2) FV2=Bac_G(2)*P2cBAC(ng) FV3=Bac_G(2)*Fe2cBAC(ng) Bio_new(i,k,iBacN(ibac))=Bio_new(i,k,iBacN(ibac))+ & & (NupDON_ba(i,k,ibac)+ & & NupNH4_ba(i,k,ibac)) Bio_new(i,k,iBacP(ibac))=Bio_new(i,k,iBacP(ibac))+ & & FV2 Bio_new(i,k,iBacF(ibac))=Bio_new(i,k,iBacF(ibac))+ & & FV3 ! ! Uptake arrays will now reflect release of inorganic and organic ! revision of uptake. ! FV1=(Bac_G(1)-Bac_G(2))*I_Bac_Ceff(ng) NupDOC_ba(i,k,ibac)=NupDOC_ba(i,k,ibac)-FV1 RelDOC1=FV1 ! ! To get accurate DOP from C2pDOC, must add back excreted DOC. ! FV4=FV1*R_ExBAC_c(ng)* & !! & DOC_frac(i,k)* & & Bio(i,k,iDOMP(ilab))/ & & Bio(i,k,iDOMC(ilab)) FV5=FV2-(NupDOP_ba(i,k,ibac)+ & NupPO4_ba(i,k,ibac)-FV4) ! ! If FV5 is positive then released DOP is required for bacteria growth. ! IF (FV5.lt.0.0_r8) THEN RelDOP1=FV4 NupPO4_ba(i,k,ibac)=NupPO4_ba(i,k,ibac)+FV5 ELSE RelDOP1=FV4-FV5 END IF NupDOP_ba(i,k,ibac)=NupDOP_ba(i,k,ibac)-RelDOP1 ! ! Release Fe. ! RelFe=NupFe_ba(i,k,ibac)-FV3 NupFe_ba(i,k,ibac)=FV3 ! ! Phosphorous limited case. Excess nutrients returned in organic form ! first, inorganic second. ! ELSE IF (Bac_G(3).le.Bac_G(4)) THEN Het_BAC=Bac_G(3) FV2=Bac_G(3)*N2cBAC(ng) FV3=Bac_G(3)*Fe2cBAC(ng) Bio_new(i,k,iBacN(ibac))=Bio_new(i,k,iBacN(ibac))+ & & FV2 Bio_new(i,k,iBacP(ibac))=Bio_new(i,k,iBacP(ibac))+ & & (NupDOP_ba(i,k,ibac)+ & & NupPO4_ba(i,k,ibac)) Bio_new(i,k,iBacF(ibac))=Bio_new(i,k,iBacF(ibac))+ & & FV3 ! ! Uptake arrays will now reflect release of inorganic and organic ! revision of uptake. ! FV1=(Bac_G(1)-Bac_G(3))*I_Bac_Ceff(ng) NupDOC_ba(i,k,ibac)=NupDOC_ba(i,k,ibac)-FV1 RelDOC1=FV1 ! ! To get accurate DON from C2nDOC, must add back excreted DOC. ! FV4=FV1*R_ExBAC_c(ng)* & !! & DOC_frac(i,k)* & & (Bio(i,k,iDOMN(ilab))/ & & Bio(i,k,iDOMC(ilab)))*Frac_ExBAC_n(ng) FV5=FV2-(NupDON_ba(i,k,ibac)+ & & NupNH4_ba(i,k,ibac)-FV4) ! ! If FV5 is positive then released DON is required for bacteria growth. ! IF (FV5.lt.0.0_r8) THEN RelDON1=FV4 NupNH4_ba(i,k,ibac)=NupNH4_ba(i,k,ibac)+FV5 ELSE RelDON1=FV4-FV5 END IF NupDON_ba(i,k,ibac)=NupDON_ba(i,k,ibac)-RelDON1 ! ! Release Fe. ! RelFe=NupFe_ba(i,k,ibac)-FV3 NupFe_ba(i,k,ibac)=FV3 ! ! Fe limited case. Excess nutrients returned in organic form ! first, inorganic second. ! ELSE Het_BAC=Bac_G(4) FV2=Bac_G(4)*N2cBAC(ng) FV3=Bac_G(4)*P2cBAC(ng) Bio_new(i,k,iBacN(ibac))=Bio_new(i,k,iBacN(ibac))+ & & FV2 Bio_new(i,k,iBacP(ibac))=Bio_new(i,k,iBacP(ibac))+ & & FV3 Bio_new(i,k,iBacF(ibac))=Bio_new(i,k,iBacF(ibac))+ & & NupFe_ba(i,k,ibac) ! ! Uptake arrays will now reflect release of inorganic and organic ! revision of uptake. ! FV1=(Bac_G(1)-Bac_G(4))*I_Bac_Ceff(ng) NupDOC_ba(i,k,ibac)=NupDOC_ba(i,k,ibac)-FV1 RelDOC1=FV1 ! ! To get accurate DON from C2nDOC, must add back excreted DOC. ! FV4=FV1*R_ExBAC_c(ng)* & !! & DOC_frac(i,k)* & & Bio(i,k,iDOMN(ilab))/ & & Bio(i,k,iDOMC(ilab))*Frac_ExBAC_n(ng) FV5=FV2-(NupDON_ba(i,k,ibac)+ & & NupNH4_ba(i,k,ibac)-FV4) ! ! If FV5 is positive then released DON is required for bacteria growth. ! IF (FV5.lt.0.0_r8) THEN RelDON1=FV4 NupNH4_ba(i,k,ibac)=NupNH4_ba(i,k,ibac)+FV5 ELSE RelDON1=FV4-FV5 END IF NupDON_ba(i,k,ibac)=NupDON_ba(i,k,ibac)-RelDON1 ! ! To get accurate DOP from C2pDOC, must add back excreted DOC. ! FV4=FV1*R_ExBAC_c(ng)* & !! & DOC_frac(i,k)* & & Bio(i,k,iDOMP(ilab))/ & & Bio(i,k,iDOMC(ilab)) FV5=FV2-(NupDOP_ba(i,k,ibac)+ & & NupPO4_ba(i,k,ibac)-FV4) ! ! If FV5 is positive then released DOP is required for bacteria growth. ! IF (FV5.lt.0.0_r8) THEN RelDOP1=FV4 NupPO4_ba(i,k,ibac)=NupPO4_ba(i,k,ibac)+FV5 ELSE RelDOP1=FV4-FV5 END IF NupDOP_ba(i,k,ibac)=NupDOP_ba(i,k,ibac)-RelDOP1 END IF ! ! Increment nutrient arrays. ! Bio_new(i,k,iBacC(ibac))=Bio_new(i,k,iBacC(ibac))+ & & Het_BAC FV1=NupDOC_ba(i,k,ibac)-Het_BAC Bio_new(i,k,iDIC_)=Bio_new(i,k,iDIC_)+ & & FV1 ! ! NOTE: to be strictly accurate we should remove RelDOC1 from DOCNP1, ! and then add it back, since NupDOC_ba is a net term. This should ! wash out in the budgeting. ! Bio_new(i,k,iDOMC(ilab))=Bio_new(i,k,iDOMC(ilab))- & & (totDOC_d(i,k)-RelDOC1) !! & (totDOC_d(i,k)-RelDOC1)* & !! & DOC_frac(i,k) !! Bio_new(i,k,iCDMC(ilab))=Bio_new(i,k,iCDMC(ilab))- & !! & (totDOC_d(i,k)-RelDOC1)* & !! & (1.0_r8-DOC_frac(i,k)) !! ! This is inclusive of RelDOX1, excretion of DON1 removed above. ! Bio_new(i,k,iDOMN(ilab))=Bio_new(i,k,iDOMN(ilab))- & & NupDON_ba(i,k,ibac) Bio_new(i,k,iDOMP(ilab))=Bio_new(i,k,iDOMP(ilab))- & & NupDOP_ba(i,k,ibac) Bio_new(i,k,iNH4_)=Bio_new(i,k,iNH4_)- & & NupNH4_ba(i,k,ibac) Bio_new(i,k,iPO4_)=Bio_new(i,k,iPO4_)- & & NupPO4_ba(i,k,ibac) Bio_new(i,k,iFeO_)=Bio_new(i,k,iFeO_)- & & NupFe_ba(i,k,ibac) END DO END DO END DO ! !----------------------------------------------------------------------- ! Phytoplankton Losses. !----------------------------------------------------------------------- ! DO iphy=1,Nphy DO k=1,N(ng) DO i=Istr,Iend ! ! Excretion. ! IF ((C2nALG(i,k,iphy).ge. & & C2nALGminABS(iphy,ng)).and. & & (C2pALG(i,k,iphy).ge. & & C2pALGminABS(iphy,ng)).and. & & (HsSiO(iphy,ng).gt.LARGER)) THEN FV1=Bio(i,k,iPhyC(iphy))*ExALG(iphy,ng) Bio_new(i,k,iPhyC(iphy))=Bio_new(i,k,iPhyC(iphy))- & & FV1 ! ! No excretion of CDOC. ! Bio_new(i,k,iDOMC(ilab))=Bio_new(i,k,iDOMC(ilab))+ & & FV1 ELSE IF ((C2nALG(i,k,iphy).ge. & & C2nALGminABS(iphy,ng)).and. & & (C2pALG(i,k,iphy).ge. & & C2pALGminABS(iphy,ng)).and. & & (C2sALG(i,k,iphy).ge. & & C2SiALGminABS(iphy,ng))) THEN FV1=Bio(i,k,iPhyC(iphy))*ExALG(iphy,ng) Bio_new(i,k,iPhyC(iphy))=Bio_new(i,k,iPhyC(iphy))- & & FV1 ! ! No excretion of CDOC. ! Bio_new(i,k,iDOMC(ilab))=Bio_new(i,k,iDOMC(ilab))+ & & FV1 END IF ! ! Grazing. ! IF (Bio(i,k,iPhyC(iphy)).gt.refuge(i,k,iphy)) THEN ! ! Carbon calculations. ! FV1=graz_act(i,k,iphy)*Bio(i,k,iPhyC(iphy)) Bio_new(i,k,iPhyC(iphy))=Bio_new(i,k,iPhyC(iphy))- & & FV1 Bio_new(i,k,iFecC(isfc))=Bio_new(i,k,iFecC(isfc))+ & & FecPEL(iphy,isfc,ng)*FV1 Bio_new(i,k,iFecC(iffc))=Bio_new(i,k,iFecC(iffc))+ & & FecPEL(iphy,iffc,ng)*FV1 FV3=FecDOC(iphy,ng)*FV1 Bio_new(i,k,iDOMC(ilab))=Bio_new(i,k,iDOMC(ilab))+ & & (1.0_r8-cDOCfrac_c(ilab,ng))*& & FV3 Bio_new(i,k,iCDMC(ilab))=Bio_new(i,k,iCDMC(ilab))+ & & cDOCfrac_c(ilab,ng)*FV3 Bio_new(i,k,iDIC_)=Bio_new(i,k,iDIC_)+ & & FecCYC(iphy,ng)*FV1 ! ! Nitrogen calculations. ! FV2=graz_act(i,k,iphy)*Bio(i,k,iPhyN(iphy)) Bio_new(i,k,iPhyN(iphy))=Bio_new(i,k,iPhyN(iphy))- & & FV2 Bio_new(i,k,iFecN(isfc))=Bio_new(i,k,iFecN(isfc))+ & & FecPEL(iphy,isfc,ng)*FV2 Bio_new(i,k,iFecN(iffc))=Bio_new(i,k,iFecN(iffc))+ & & FecPEL(iphy,iffc,ng)*FV2 Bio_new(i,k,iDOMN(ilab))=Bio_new(i,k,iDOMN(ilab))+ & & FecDOC(iphy,ng)*FV2 Bio_new(i,k,iNH4_)=Bio_new(i,k,iNH4_)+ & & FecCYC(iphy,ng)*FV2 ! ! Silica calculations. ! IF (iPhyS(iphy).gt.0) THEN FV2=graz_act(i,k,iphy)*Bio(i,k,iPhyS(iphy)) Bio_new(i,k,iPhyS(iphy))=Bio_new(i,k,iPhyS(iphy))- & & FV2 ! ! Assuming that the fraction of material lost via sloppy feeding/cell ! lysis also results in silica tests being put into FecS pool. ! Bio_new(i,k,iFecS(isfc))=Bio_new(i,k,iFecS(isfc))+ & & FecDOC(iphy,ng)*FV2 Bio_new(i,k,iFecS(iffc))=Bio_new(i,k,iFecS(iffc))+ & & (1.0_r8-FecDOC(iphy,ng))* & & FV2 END IF ! ! Phosphorus calculations. ! FV2=graz_act(i,k,iphy)*Bio(i,k,iPhyP(iphy)) Bio_new(i,k,iPhyP(iphy))=Bio_new(i,k,iPhyP(iphy))- & & FV2 Bio_new(i,k,iFecP(isfc))=Bio_new(i,k,iFecP(isfc))+ & & FecPEL(iphy,isfc,ng)*FV2 Bio_new(i,k,iFecP(iffc))=Bio_new(i,k,iFecP(iffc))+ & & FecPEL(iphy,iffc,ng)*FV2 Bio_new(i,k,iDOMP(ilab))=Bio_new(i,k,iDOMP(ilab))+ & & FecDOC(iphy,ng)*FV2 Bio_new(i,k,iPO4_)=Bio_new(i,k,iPO4_)+ & & FecCYC(iphy,ng)*FV2 ! ! Iron calculations. Assuming no DOMF. ! FV2=graz_act(i,k,iphy)*Bio(i,k,iPhyF(iphy)) Bio_new(i,k,iPhyF(iphy))=Bio_new(i,k,iPhyF(iphy))- & & FV2 Bio_new(i,k,iFecF(isfc))=Bio_new(i,k,iFecF(isfc))+ & & FecPEL(iphy,isfc,ng)*FV2 Bio_new(i,k,iFecF(iffc))=Bio_new(i,k,iFecF(iffc))+ & & FecPEL(iphy,iffc,ng)*FV2 Bio_new(i,k,iFeO_)=Bio_new(i,k,iFeO_)+ & & (FecCYC(iphy,ng)+ & & FecDOC(iphy,ng))*FV2 END IF END DO END DO END DO ! ! Pigment Grazing. No fecal or dissolved terms for pigments. ! DO ipig=1,Npig DO iphy=1,Nphy IF (iPigs(iphy,ipig).gt.0) THEN itrc=iPigs(iphy,ipig) DO k=1,N(ng) DO i=Istr,Iend IF (Bio(i,k,iPhyC(iphy)).gt.refuge(i,k,iphy)) THEN FV1=graz_act(i,k,iphy)*Bio(i,k,itrc) Bio_new(i,k,itrc)=Bio_new(i,k,itrc) - FV1 END IF END DO END DO END IF END DO END DO ! !----------------------------------------------------------------------- ! Bacterial losses. !----------------------------------------------------------------------- ! ! NOTE: Bacterial growth is completely reminerialized. ! DO ibac=1,Nbac DO k=1,N(ng) DO i=Istr,Iend ! ! Grazing calculation. (All fecal material to slow sinking pool.) ! !! WPB - There appears to be some rounding errors that cause bacteria !! populations to drop just below initialization values. Once !! they do, they never recover and the new lower values propagate !! through the model. Only evident in Bac_P1 at the moment. !! !! FV1=BacCYC(ng)*Bio_new(i,k,iBacC(ibac)) !! FV2=BacPEL(ng)*Bio_new(i,k,iBacC(ibac)) !! FV3=BacDOC(ng)*Bio_new(i,k,iBacC(ibac)) !! FV4=FV1+FV2+FV3 ! ! Carbon calculations. ! Bio_new(i,k,iBacC(ibac))=Bio_new(i,k,iBacC(ibac))- & !! & FV4 & Bio_new(i,k,iBacC(ibac)) Bio_new(i,k,iFecC(isfc))=Bio_new(i,k,iFecC(isfc))+ & !! & FV2 & Bio_new(i,k,iBacC(ibac))* & & BacPEL(ng) Bio_new(i,k,iDOMC(ilab))=Bio_new(i,k,iDOMC(ilab))+ & & (1.0_r8-cDOCfrac_c(ilab,ng))* & !! & FV3 & Bio_new(i,k,iBacC(ibac))* & & BacDOC(ng) Bio_new(i,k,iCDMC(ilab))=Bio_new(i,k,iCDMC(ilab))+ & & cDOCfrac_c(ilab,ng)* & !! & FV3 & Bio_new(i,k,iBacC(ibac))* & & BacDOC(ng) Bio_new(i,k,iDIC_)=Bio_new(i,k,iDIC_)+ & !! & FV1 & Bio_new(i,k,iBacC(ibac))* & & BacCYC(ng) ! ! Nitrogen calculations. ! Bio_new(i,k,iBacN(ibac))=Bio_new(i,k,iBacN(ibac))- & !! & N2cBAC(ng)*FV4 & Bio_new(i,k,iBacN(ibac)) Bio_new(i,k,iFecN(isfc))=Bio_new(i,k,iFecN(isfc))+ & !! & N2cBAC(ng)*FV2 & Bio_new(i,k,iBacN(ibac))* & & BacPEL(ng) Bio_new(i,k,iDOMN(ilab))=Bio_new(i,k,iDOMN(ilab))+ & !! & N2cBAC(ng)*FV3 & Bio_new(i,k,iBacN(ibac))* & & BacDOC(ng) Bio_new(i,k,iNH4_)=Bio_new(i,k,iNH4_)+ & !! & N2cBAC(ng)*FV1 & Bio_new(i,k,iBacN(ibac))* & & BacCYC(ng) ! ! Phosphorous calculations. ! Bio_new(i,k,iBacP(ibac))=Bio_new(i,k,iBacP(ibac))- & !! & P2cBAC(ng)*FV4 & Bio_new(i,k,iBacP(ibac)) Bio_new(i,k,iFecP(isfc))=Bio_new(i,k,iFecP(isfc))+ & !! & P2cBAC(ng)*FV2 & Bio_new(i,k,iBacP(ibac))* & & BacPEL(ng) Bio_new(i,k,iDOMP(ilab))=Bio_new(i,k,iDOMP(ilab))+ & !! & P2cBAC(ng)*FV3 & Bio_new(i,k,iBacP(ibac))* & & BacDOC(ng) Bio_new(i,k,iPO4_)=Bio_new(i,k,iPO4_)+ & !! & P2cBAC(ng)*FV1 & Bio_new(i,k,iBacP(ibac))* & & BacCYC(ng) ! ! Iron calculations. ! Bio_new(i,k,iBacF(ibac))=Bio_new(i,k,iBacF(ibac))- & !! & Fe2cBAC(ng)*FV4 & Bio_new(i,k,iBacF(ibac)) Bio_new(i,k,iFecF(isfc))=Bio_new(i,k,iFecF(isfc))+ & !! & Fe2cBAC(ng)*FV2 & Bio_new(i,k,iBacF(ibac))* & & BacPEL(ng) Bio_new(i,k,iFeO_)=Bio_new(i,k,iFeO_)+ & !! & Fe2cBAC(ng)*(FV1+FV3) & Bio_new(i,k,iBacF(ibac))* & & (BacDOC(ng)+BacCYC(ng)) END DO END DO END DO ! !----------------------------------------------------------------------- ! Fecal pellet remineralization. !----------------------------------------------------------------------- ! DO ifec=1,Nfec DO k=1,N(ng) DO i=Istr,Iend ! ! Carbon calculations. All carbon goes to CO2. ! FV3=Regen_C(i,k,ifec)*Bio(i,k,iFecC(ifec)) Bio_new(i,k,iFecC(ifec))=Bio_new(i,k,iFecC(ifec))- & & FV3 Bio_new(i,k,iDIC_)=Bio_new(i,k,iDIC_)+ & & FV3 ! ! Nitrogen calculations. Nitrogen goes to NH4. ! FV2=Regen_N(i,k,ifec)*Bio(i,k,iFecN(ifec)) Bio_new(i,k,iFecN(ifec))=Bio_new(i,k,iFecN(ifec))- & & FV2 Bio_new(i,k,iNH4_)=Bio_new(i,k,iNH4_)+ & & FV2 ! ! Silica calculations. ! FV2=Regen_S(i,k,ifec)*Bio(i,k,iFecS(ifec)) Bio_new(i,k,iFecS(ifec))=Bio_new(i,k,iFecS(ifec))- & & FV2 Bio_new(i,k,iSiO_)=Bio_new(i,k,iSiO_)+ & & FV2 ! ! Phosphorous calculations. ! FV2=Regen_P(i,k,ifec)*Bio(i,k,iFecP(ifec)) Bio_new(i,k,iFecP(ifec))=Bio_new(i,k,iFecP(ifec))- & & FV2 Bio_new(i,k,iPO4_)=Bio_new(i,k,iPO4_)+ & & FV2 ! ! Iron calculations. ! FV2=Regen_F(i,k,ifec)*Bio(i,k,iFecF(ifec)) Bio_new(i,k,iFecF(ifec))=Bio_new(i,k,iFecF(ifec))- & & FV2 Bio_new(i,k,iFeO_)=Bio_new(i,k,iFeO_)+ & & FV2 END DO END DO END DO ! !----------------------------------------------------------------------- ! CDMC photolysis calculations. !----------------------------------------------------------------------- ! IF (RtUVR_flag(ng)) THEN DO i=Istr,Iend ! ! If Ed_nz(i,N(ng)) > zero, then there is sunlight. Standardizing rate ! to 1500 umol quanta m-2 s-1. ! IF (Ed_nz(i,N(ng)).ge.0.01) THEN ! FV1=RtUVR_DIC(ng)*Ed_nz(i,N(ng))/1500.0_r8 FV2=RtUVR_DOC(ng)*Ed_nz(i,N(ng))/1500.0_r8 ! ! FV4 equals the CDMC1 absorption at 410 nm. 0.012 converts to g m-3. ! FV5 equals the CDMC2 absorption at 410 nm. ! Weighted average attenuation of UVB of water at 300 nm = 0.2 m-1. ! FV4=Bio(i,N(ng),iCDMC(ilab))*0.012_r8*aDOC410(ilab) FV5=Bio(i,N(ng),iCDMC(irct))*0.012_r8*aDOC410(irct) photo_decay=0.5_r8*Hz(i,j,N(ng))* & & (0.2_r8+(FV4+FV5)*aDOC300(ilab)) FV3=EXP(-photo_decay) photo_decay=2.0_r8*photo_decay ! ! Do not photolyze below the euphotic zone. ! DO k=N(ng),Keuphotic(i),-1 IF (FV3.gt.0.01_r8) THEN FV6=FV5+FV4 IF (FV6.gt.0.0_r8) THEN FV7=FV4/FV6 photo_DIC=FV3*FV1*FV6 photo_DOC=FV3*FV2*FV6 total_photo=photo_DIC+photo_DOC ! ! NOTE: not testing for excess photolysis (CDOC going negative). ! FV4=(1.0_r8-FV7)*total_photo Bio_new(i,k,iCDMC(irct))=Bio_new(i,k,iCDMC(irct))-& & FV4 Bio_new(i,k,iDOMC(ilab))=Bio_new(i,k,iDOMC(ilab))+& & photo_DOC Bio_new(i,k,iCDMC(ilab))=Bio_new(i,k,iCDMC(ilab))-& & FV7*total_photo Bio_new(i,k,iDIC_)=Bio_new(i,k,iDIC_)+ & & photo_DIC END IF ! ! FV4 equals the CDMC1 absorption at 410 nm. 0.012 converts to g m-3. ! FV5 equals the CDMC2 absorption at 410 nm. ! Weighted average attenuation of UVB of water at 300 nm = 0.2 m-1. ! FV4=Bio(i,k,iCDMC(ilab))*0.012_r8*aDOC410(ilab) FV5=Bio(i,k,iCDMC(irct))*0.012_r8*aDOC410(irct) FV7=photo_decay+ & & 0.5_r8*Hz(i,j,k)*(0.2_r8+(FV4+FV5)*aDOC300(ilab)) ! ! If k is greater than the bottom of the euphotic zone (and by ! by extension the bottom boundary) or the decay constant is ! greater than 4.61 (or < 1% photolysis zone) then exit do loop. ! FV3=EXP(-FV7) ! ! Store value for passage through entire Hz(i,j,k). ! photo_decay=photo_decay+2.0_r8*FV7 END IF END DO END IF END DO END IF ! !----------------------------------------------------------------------- ! Create optimal pigment ratios. !----------------------------------------------------------------------- ! DO i=Istr,Iend IF (Keuphotic(i).le.N(ng)) THEN DO iphy=1,Nphy ! ! Carbon to chlorophyll a ratio ! This statement says that nutrient limitation of C2CHL ratio overides ! light adaptation. Minimum of two functions may be more ecologically ! accurate? ! DO k=N(ng),Keuphotic(i),-1 IF (b_C2Cn(iphy,ng).lt.0.0_r8+SMALL) THEN C2CHL_w(k,iphy)=MIN((b_C2Cl(iphy,ng)+ & & mxC2Cl(iphy,ng)*E0_nz(i,k)), & & C2CHL_max(iphy,ng)) ELSE IF (C2nALG(i,k,iphy).gt. & & minC2nALG(iphy,ng)+SMALL) THEN C2CHL_w(k,iphy)=b_C2Cn(iphy,ng)+ & & mxC2Cn(iphy,ng)* & & (C2nALG(i,k,iphy)- & & minC2nALG(iphy,ng)) ELSE C2CHL_w(k,iphy)=MIN((b_C2Cl(iphy,ng)+ & & mxC2Cl(iphy,ng)*E0_nz(i,k)), & & C2CHL_max(iphy,ng)) END IF END DO ! ! Chlorophyll a concentation per species. form g CHL a / g C ! DO k=N(ng),Keuphotic(i),-1 Pigs_w(k,iphy,ichl)=1.0_r8/C2CHL_w(k,iphy) END DO ! ! Chlorophyll b concentration per species. form g CHL b / g C ! IF (iPigs(iphy,2).gt.0) THEN DO k=N(ng),Keuphotic(i),-1 Pigs_w(k,iphy,2)=b_ChlB(iphy,ng)+ & & mxChlB(iphy,ng)* & & (C2CHL_w(k,iphy)- & & b_C2Cl(iphy,ng)) Pigs_w(k,iphy,2)=Pigs_w(k,iphy,2)* & & Pigs_w(k,iphy,ichl) END DO END IF ! ! Chlorophyll c concentration per species. form g CHL c / g C ! IF (iPigs(iphy,3).gt.0) THEN DO k=N(ng),Keuphotic(i),-1 Pigs_w(k,iphy,3)=b_ChlC(iphy,ng)+ & & mxChlC(iphy,ng)* & & (C2CHL_w(k,iphy)- & & b_C2Cl(iphy,ng)) Pigs_w(k,iphy,3)=Pigs_w(k,iphy,3)* & & Pigs_w(k,iphy,ichl) END DO END IF ! ! Photosynthetic caroteniods per species. form g PSC / g C ! IF (iPigs(iphy,4).gt.0) THEN DO k=N(ng),Keuphotic(i),-1 Pigs_w(k,iphy,4)=b_PSC(iphy,ng)+ & & mxPSC(iphy,ng)* & & (C2CHL_w(k,iphy)- & & b_C2Cl(iphy,ng)) Pigs_w(k,iphy,4)=Pigs_w(k,iphy,4)* & & Pigs_w(k,iphy,ichl) END DO END IF ! ! Photoprotective caroteniods per species. form g PPC / g C ! IF (iPigs(iphy,5).gt.0) THEN DO k=N(ng),Keuphotic(i),-1 Pigs_w(k,iphy,5)=b_PPC(iphy,ng)+ & & mxPPC(iphy,ng)* & & (C2CHL_w(k,iphy)- & & b_C2Cl(iphy,ng)) Pigs_w(k,iphy,5)=Pigs_w(k,iphy,5)* & & Pigs_w(k,iphy,ichl) END DO END IF ! ! Low Urobilin Phycoeurythin concentration per species. g LPUB / g C ! IF (iPigs(iphy,6).gt.0) THEN DO k=N(ng),Keuphotic(i),-1 Pigs_w(k,iphy,6)=b_LPUb(iphy,ng)+ & & mxLPUb(iphy,ng)* & & (C2CHL_w(k,iphy)- & & b_C2Cl(iphy,ng)) Pigs_w(k,iphy,6)=Pigs_w(k,iphy,6)* & & Pigs_w(k,iphy,ichl) END DO END IF ! ! High Urobilin Phycoeurythin concentration per species (g HPUB / g C). ! IF (iPigs(iphy,7).gt.0) THEN DO k=N(ng),Keuphotic(i),-1 Pigs_w(k,iphy,7)=b_HPUb(iphy,ng)+ & & mxHPUb(iphy,ng)* & & (C2CHL_w(k,iphy)- & & b_C2Cl(iphy,ng)) Pigs_w(k,iphy,7)=Pigs_w(k,iphy,7)* & & Pigs_w(k,iphy,ichl) END DO END IF END DO ! ! Calculate pigment ratio changes. ! NOTE: 12 factor to convert to ugrams (mg m-3) ! DO ipig=1,Npig DO iphy=1,Nphy IF (iPigs(iphy,ipig).gt.0) THEN itrc=iPigs(iphy,ipig) DO k=N(ng),Keuphotic(i),-1 IF ((Bio(i,k,iPhyC(iphy)).gt.0.0_r8).and. & & (Bio(i,k,itrc).gt.0.0_r8)) THEN FV1=Bio(i,k,iPhyC(iphy))*12.0_r8 FV2=GtALG_r(i,k,iphy) FV3=FV1/ & & (FV2/Pigs_w(k,iphy,ipig)+ & & FV1*(1.0_r8-FV2)/ & & Bio(i,k,itrc)) Bio_new(i,k,itrc)=Bio_new(i,k,itrc)+ & & (FV3-Bio(i,k,itrc)) END IF END DO END IF END DO END DO END IF END DO ! !----------------------------------------------------------------------- ! Vertical sinking terms. !----------------------------------------------------------------------- ! ! Reconstruct vertical profile of selected biological constituents ! "Bio(:,:,isink)" in terms of a set of parabolic segments within each ! grid box. Then, compute semi-Lagrangian flux due to sinking. ! SINK_LOOP: DO isink=1,Nsink itrc=idsink(isink) ! ! Copy concentration of biological particulates into scratch array ! "qc" (q-central, restrict it to be positive) which is hereafter ! interpreted as a set of grid-box averaged values for biogeochemical ! constituent concentration. ! DO k=1,N(ng) DO i=Istr,Iend qc(i,k)=Bio(i,k,itrc) END DO END DO ! DO k=N(ng)-1,1,-1 DO i=Istr,Iend FC(i,k)=(qc(i,k+1)-qc(i,k))*Hz_inv2(i,k) END DO END DO DO k=2,N(ng)-1 DO i=Istr,Iend dltR=Hz(i,j,k)*FC(i,k) dltL=Hz(i,j,k)*FC(i,k-1) cff=Hz(i,j,k-1)+2.0_r8*Hz(i,j,k)+Hz(i,j,k+1) cffR=cff*FC(i,k) cffL=cff*FC(i,k-1) ! ! Apply PPM monotonicity constraint to prevent oscillations within the ! grid box. ! IF ((dltR*dltL).le.0.0_r8) THEN dltR=0.0_r8 dltL=0.0_r8 ELSE IF (ABS(dltR).gt.ABS(cffL)) THEN dltR=cffL ELSE IF (ABS(dltL).gt.ABS(cffR)) THEN dltL=cffR END IF ! ! Compute right and left side values (bR,bL) of parabolic segments ! within grid box Hz(k); (WR,WL) are measures of quadratic variations. ! ! NOTE: Although each parabolic segment is monotonic within its grid ! box, monotonicity of the whole profile is not guaranteed, ! because bL(k+1)-bR(k) may still have different sign than ! qc(i,k+1)-qc(i,k). This possibility is excluded, ! after bL and bR are reconciled using WENO procedure. ! cff=(dltR-dltL)*Hz_inv3(i,k) dltR=dltR-cff*Hz(i,j,k+1) dltL=dltL+cff*Hz(i,j,k-1) bR(i,k)=qc(i,k)+dltR bL(i,k)=qc(i,k)-dltL WR(i,k)=(2.0_r8*dltR-dltL)**2 WL(i,k)=(dltR-2.0_r8*dltL)**2 END DO END DO cff=1.0E-14_r8 DO k=2,N(ng)-2 DO i=Istr,Iend dltL=MAX(cff,WL(i,k )) dltR=MAX(cff,WR(i,k+1)) bR(i,k)=(dltR*bR(i,k)+dltL*bL(i,k+1))/(dltR+dltL) bL(i,k+1)=bR(i,k) END DO END DO DO i=Istr,Iend FC(i,N(ng))=0.0_r8 ! NO-flux boundary condition #if defined LINEAR_CONTINUATION bL(i,N(ng))=bR(i,N(ng)-1) bR(i,N(ng))=2.0_r8*qc(i,N(ng))-bL(i,N(ng)) #elif defined NEUMANN bL(i,N(ng))=bR(i,N(ng)-1) bR(i,N(ng))=1.5_r8*qc(i,N(ng))-0.5_r8*bL(i,N(ng)) #else bR(i,N(ng))=qc(i,N(ng)) ! default strictly monotonic bL(i,N(ng))=qc(i,N(ng)) ! conditions bR(i,N(ng)-1)=qc(i,N(ng)) #endif #if defined LINEAR_CONTINUATION bR(i,1)=bL(i,2) bL(i,1)=2.0_r8*qc(i,1)-bR(i,1) #elif defined NEUMANN bR(i,1)=bL(i,2) bL(i,1)=1.5_r8*qc(i,1)-0.5_r8*bR(i,1) #else bL(i,2)=qc(i,1) ! bottom grid boxes are bR(i,1)=qc(i,1) ! re-assumed to be bL(i,1)=qc(i,1) ! piecewise constant. #endif END DO ! ! Apply monotonicity constraint again, since the reconciled interfacial ! values may cause a non-monotonic behavior of the parabolic segments ! inside the grid box. ! DO k=1,N(ng) DO i=Istr,Iend dltR=bR(i,k)-qc(i,k) dltL=qc(i,k)-bL(i,k) cffR=2.0_r8*dltR cffL=2.0_r8*dltL IF ((dltR*dltL).lt.0.0_r8) THEN dltR=0.0_r8 dltL=0.0_r8 ELSE IF (ABS(dltR).gt.ABS(cffL)) THEN dltR=cffL ELSE IF (ABS(dltL).gt.ABS(cffR)) THEN dltL=cffR END IF bR(i,k)=qc(i,k)+dltR bL(i,k)=qc(i,k)-dltL END DO END DO ! ! After this moment reconstruction is considered complete. The next ! stage is to compute vertical advective fluxes, FC. It is expected ! that sinking may occurs relatively fast, the algorithm is designed ! to be free of CFL criterion, which is achieved by allowing ! integration bounds for semi-Lagrangian advective flux to use as ! many grid boxes in upstream direction as necessary. ! ! In the two code segments below, WL is the z-coordinate of the ! departure point for grid box interface z_w with the same indices; ! FC is the finite volume flux; ksource(:,k) is index of vertical ! grid box which contains the departure point (restricted by N(ng)). ! During the search: also add in content of whole grid boxes ! participating in FC. ! cff=dtbio*ABS(Wbio(isink)) DO k=1,N(ng) DO i=Istr,Iend FC(i,k-1)=0.0_r8 WL(i,k)=z_w(i,j,k-1)+cff WR(i,k)=Hz(i,j,k)*qc(i,k) ksource(i,k)=k END DO END DO DO k=1,N(ng) DO ks=k,N(ng)-1 DO i=Istr,Iend IF (WL(i,k).gt.z_w(i,j,ks)) THEN ksource(i,k)=ks+1 FC(i,k-1)=FC(i,k-1)+WR(i,ks) END IF END DO END DO END DO ! ! Finalize computation of flux: add fractional part. ! DO k=1,N(ng) DO i=Istr,Iend ks=ksource(i,k) cu=MIN(1.0_r8,(WL(i,k)-z_w(i,j,ks-1))*Hz_inv(i,ks)) FC(i,k-1)=FC(i,k-1)+ & & Hz(i,j,ks)*cu* & & (bL(i,ks)+ & & cu*(0.5_r8*(bR(i,ks)-bL(i,ks))- & & (1.5_r8-cu)* & & (bR(i,ks)+bL(i,ks)- & & 2.0_r8*qc(i,ks)))) END DO END DO DO k=1,N(ng) DO i=Istr,Iend Bio(i,k,itrc)=qc(i,k)+(FC(i,k)-FC(i,k-1))*Hz_inv(i,k) END DO END DO #ifdef BIO_SEDIMENT ! ! Particulate flux reaching the seafloor is remineralized and returned ! to the dissolved nitrate pool. Without this conversion, particulate ! material falls out of the system. This is a temporary fix to restore ! total nitrogen conservation. It will be replaced later by a ! parameterization that includes the time delay of remineralization ! and dissolved oxygen. ! DO ifec=1,Nfec IF (itrc.eq.iFecN(ifec)) THEN DO i=Istr,Iend cff1=FC(i,0)*Hz_inv(i,1) Bio(i,1,iNO3_)=Bio(i,1,iNO3_)+cff1 END DO ELSE IF (itrc.eq.iFecC(ifec)) THEN DO i=Istr,Iend cff1=FC(i,0)*Hz_inv(i,1) Bio(i,1,iDIC_)=Bio(i,1,iDIC_)+cff1 END DO ELSE IF (itrc.eq.iFecP(ifec)) THEN DO i=Istr,Iend cff1=FC(i,0)*Hz_inv(i,1) Bio(i,1,iPO4_)=Bio(i,1,iPO4_)+cff1 END DO ELSE IF (itrc.eq.iFecS(ifec)) THEN DO i=Istr,Iend cff1=FC(i,0)*Hz_inv(i,1) Bio(i,1,iSiO_)=Bio(i,1,iSiO_)+cff1 END DO ELSE IF (itrc.eq.iFecF(ifec)) THEN DO i=Istr,Iend cff1=FC(i,0)*Hz_inv(i,1) Bio(i,1,iFeO_)=Bio(i,1,iFeO_)+cff1 END DO END IF END DO DO iphy=1,Nphy IF (itrc.eq.iPhyN(iphy)) THEN DO i=Istr,Iend cff1=FC(i,0)*Hz_inv(i,1) Bio(i,1,iNO3_)=Bio(i,1,iNO3_)+cff1 END DO ELSE IF (itrc.eq.iPhyC(iphy)) THEN DO i=Istr,Iend cff1=FC(i,0)*Hz_inv(i,1) Bio(i,1,iDIC_)=Bio(i,1,iDIC_)+cff1 END DO ELSE IF (itrc.eq.iPhyP(iphy)) THEN DO i=Istr,Iend cff1=FC(i,0)*Hz_inv(i,1) Bio(i,1,iPO4_)=Bio(i,1,iPO4_)+cff1 END DO ELSE IF (itrc.eq.iPhyS(iphy)) THEN DO i=Istr,Iend cff1=FC(i,0)*Hz_inv(i,1) Bio(i,1,iSiO_)=Bio(i,1,iSiO_)+cff1 END DO ELSE IF (itrc.eq.iPhyF(iphy)) THEN DO i=Istr,Iend cff1=FC(i,0)*Hz_inv(i,1) Bio(i,1,iFeO_)=Bio(i,1,iFeO_)+cff1 END DO END IF END DO #endif END DO SINK_LOOP ! !----------------------------------------------------------------------- ! Update the tendency arrays !----------------------------------------------------------------------- ! DO ibio=1,NBT itrc=idbio(ibio) DO k=1,N(ng) DO i=Istr,Iend Bio(i,k,itrc)=Bio(i,k,itrc)+dtbio*Bio_new(i,k,itrc) END DO END DO END DO END DO ITER_LOOP ! !----------------------------------------------------------------------- ! Update global tracer variables: Add increment due to BGC processes ! to tracer array in time index "nnew". Index "nnew" is solution after ! advection and mixing and has transport units (m Tunits) hence the ! increment is multiplied by Hz. Notice that we need to subtract ! original values "Bio_old" at the top of the routine to just account ! for the concentractions affected by BGC processes. This also takes ! into account any constraints (non-negative concentrations, carbon ! concentration range) specified before entering BGC kernel. If "Bio" ! were unchanged by BGC processes, the increment would be exactly ! zero. Notice that final tracer values, t(:,:,:,nnew,:) are not ! bounded >=0 so that we can preserve total inventory of nutrients ! when advection causes tracer concentration to go negative. !----------------------------------------------------------------------- ! DO ibio=1,NBT itrc=idbio(ibio) DO k=1,N(ng) DO i=Istr,Iend cff=Bio(i,k,itrc)-Bio_old(i,k,itrc) t(i,j,k,nnew,itrc)=t(i,j,k,nnew,itrc)+cff*Hz(i,j,k) END DO END DO END DO END DO J_LOOP ! RETURN END SUBROUTINE ecosim_tile END MODULE biology_mod