Commit 9cc189c0 authored by Jorn Bruggeman's avatar Jorn Bruggeman
Browse files

model clean-up

parent 50317b5f
module bb_model_library
use fabm_types, only: type_base_model_factory,type_base_model
use fabm_types, only: type_base_model_factory, type_base_model
implicit none
private
type,extends(type_base_model_factory) :: type_factory
contains
type, extends(type_base_model_factory) :: type_factory
contains
procedure :: create
end type
type (type_factory),save,target,public :: bb_model_factory
type (type_factory), save, target, public :: bb_model_factory
contains
subroutine create(self,name,model)
subroutine create(self, name, model)
use bb_filter_feeder
use bb_lorenz63
use bb_passive
! Add new BB models here
class (type_factory),intent(in) :: self
character(*), intent(in) :: name
class (type_base_model),pointer :: model
class (type_factory), intent(in) :: self
character(*), intent(in) :: name
class (type_base_model), pointer :: model
select case (name)
case ('passive'); allocate(type_bb_passive::model)
......
module examples_model_library
use fabm_types, only: type_base_model_factory,type_base_model
use fabm_types, only: type_base_model_factory, type_base_model
use examples_benthic_predator
use examples_duplicator
......@@ -14,13 +14,13 @@ module examples_model_library
private
type,extends(type_base_model_factory) :: type_factory
type, extends(type_base_model_factory) :: type_factory
contains
procedure :: initialize
procedure :: create
end type
type (type_factory),save,target,public :: examples_model_factory
type (type_factory), save, target, public :: examples_model_factory
contains
......@@ -34,10 +34,10 @@ contains
call self%type_base_model_factory%initialize()
end subroutine initialize
subroutine create(self,name,model)
class (type_factory),intent(in) :: self
character(*), intent(in) :: name
class (type_base_model),pointer :: model
subroutine create(self, name, model)
class (type_factory), intent(in) :: self
character(*), intent(in) :: name
class (type_base_model), pointer :: model
select case (name)
case ('benthic_predator'); allocate(type_examples_benthic_predator::model)
......@@ -48,7 +48,7 @@ contains
case ('light_cycle'); allocate(type_examples_light_cycle::model)
! Add individual example models here
case default
call self%type_base_model_factory%create(name,model)
call self%type_base_model_factory%create(name, model)
end select
end subroutine
......
......@@ -13,18 +13,18 @@ module examples_npzd_model_library
private
type,extends(type_base_model_factory) :: type_factory
contains
contains
procedure :: create
end type
type (type_factory),save,target,public :: examples_npzd_model_factory
type (type_factory), save, target, public :: examples_npzd_model_factory
contains
subroutine create(self,name,model)
class (type_factory),intent(in) :: self
character(*), intent(in) :: name
class (type_base_model),pointer :: model
subroutine create(self, name, model)
class (type_factory), intent(in) :: self
character(*), intent(in) :: name
class (type_base_model), pointer :: model
select case (name)
case ('nut'); allocate(type_examples_npzd_nut::model)
......
......@@ -10,15 +10,8 @@
! !
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!-----------------------------------------------------------------------
!BOP
!
! !MODULE: gotm\_ergom --- GOTM implementation of the biogeochemical model ERGOM
! GOTM implementation of the biogeochemical model ERGOM
!
! !INTERFACE:
module gotm_ergom
!
! !DESCRIPTION:
! The biogeochemical model by
! \cite{Neumannetal2002} consists of $I=10$
! state variables. The nutrient state variables are dissolved
......@@ -63,19 +56,16 @@
! }\label{fig_neumann}
! \end{center}
! \end{figure}
!
! !USES:
module gotm_ergom
use fabm_types
implicit none
private
!
! !PUBLIC MEMBER FUNCTIONS:
public type_gotm_ergom
!
! !PUBLIC_DERIVED_TYPES:
type, extends(type_base_model) :: type_gotm_ergom
type, extends(type_base_model), public :: type_gotm_ergom
! Variable identifiers
type (type_state_variable_id) :: id_p1,id_p2,id_p3,id_zo,id_de,id_am,id_ni,id_po,id_o2
type (type_bottom_state_variable_id) :: id_fl
......@@ -97,521 +87,403 @@
procedure :: do_surface
end type
!EOP
!-----------------------------------------------------------------------
contains
!-----------------------------------------------------------------------
!BOP
!
! !IROUTINE: Initialise the ergom model
!
! !INTERFACE:
subroutine initialize(self, configunit)
!
! !DESCRIPTION:
! Here, parameter values are read and the variables exported by the model are registered with FABM
!
! !INPUT PARAMETERS:
class (type_gotm_ergom), intent(inout), target :: self
integer, intent(in) :: configunit
!
! !LOCAL VARIABLES:
real(rk) :: w_p1
real(rk) :: w_p2
real(rk) :: w_p3
real(rk) :: w_de
real(rk), parameter :: secs_pr_day=86400.0_rk
!EOP
!-----------------------------------------------------------------------
!BOC
! Store parameter values in our own derived type
! NB! All rates must be provided in values per day,
! and are converted here to values per second
call self%get_parameter(self%sfl_po, 'sfl_po', 'mmol P/m2/d', 'surface phosphate flux', default=0.0015_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%sfl_ni, 'sfl_ni', 'mmol N/m2/d', 'surface nitrate flux', default=0.09_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%sfl_am, 'sfl_am', 'mmol N/m2/d', 'surface ammonium flux', default=0.07_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%fluff, 'fluff', '', 'use fluff', default=.false.)
call self%get_parameter(self%p10, 'p10', 'mmol N/m3', 'background concentration of diatoms', default=0.0225_rk)
call self%get_parameter(self%p20, 'p20', 'mmol N/m3', 'background concentration of flagellates', default=0.0225_rk)
call self%get_parameter(self%p30, 'p30', 'mmol N/m3', 'background concentration of cyanobacteria', default=0.0225_rk)
call self%get_parameter(self%zo0, 'zo0', 'mmol N/m3', 'background concentration of zooplankton', default=0.0225_rk)
call self%get_parameter(self%kc, 'kc', 'm2/mmol N', 'specific light attenuation of phytoplankton and detritus', default=0.03_rk)
call self%get_parameter(self%i_min, 'i_min', 'W/m2', 'minimum optimal photosynthetically active radiation', default=25.0_rk)
call self%get_parameter(self%r1max, 'r1max', '1/d', 'maximum growth rate of diatoms', default=2.0_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%r2max, 'r2max', '1/d', 'maximum growth rate of flagellates', default=0.7_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%r3max, 'r3max', '1/d', 'maximum growth rate of cyanobacteria', default=0.5_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%alpha1, 'alpha1', 'mmol N/m3', 'half-saturation nutrient concentration for diatoms', default=1.35_rk)
call self%get_parameter(self%alpha2, 'alpha2', 'mmol N/m3', 'half-saturation nutrient concentration for flagellates', default=0.675_rk)
call self%get_parameter(self%alpha3, 'alpha3', 'mmol N/m3', 'half-saturation nutrient concentration for cyanobacteria', default=0.5_rk)
call self%get_parameter(self%lpa, 'lpa', '1/d', 'phytoplankton exudation', default=0.01_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%lpd, 'lpd', '1/d', 'phytoplankton mortality', default=0.02_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%tf, 'tf', 'deg C', 'half-saturation temperature for flagellates', default=10.0_rk)
call self%get_parameter(self%tbg, 'tbg', 'deg C', 'reference temperature for cyanobacteria', default=14.0_rk)
call self%get_parameter(self%beta_bg, 'beta_bg', '1/deg C', 'temperature sensitivity for cyanobacteria', default=1.0_rk)
call self%get_parameter(self%g1max, 'g1max', '1/d', 'maximum grazing rate on diatoms', default=0.5_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%g2max, 'g2max', '1/d', 'maximum grazing rate on flagellates', default=0.5_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%g3max, 'g3max', '1/d', 'maximum grazing rate on cyanobacteria', default=0.25_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%lza, 'lza', 'm3/mmol N/d', 'quadratic zooplankton loss to dissolved matter', default=0.0666666666_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%lzd, 'lzd', 'm3/mmol N/d', 'quadratic zooplankton loss to detritus', default=0.1333333333_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%iv, 'iv', 'm3/mmol N', 'Ivlev constant for grazing', default=0.24444444_rk)
call self%get_parameter(self%topt, 'topt', 'deg C', 'optimum temperature for grazing', default=20.0_rk)
call self%get_parameter(self%lan, 'lan', '1/d', 'maximum nitrification rate', default=0.1_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%oan, 'oan', 'mmol o2/m3', 'half-saturation oxygen concentration for nitrification', default=0.01_rk)
call self%get_parameter(self%beta_an, 'beta_an', '1/deg C', 'temperature sensitivity of nitrification', default=0.11_rk)
call self%get_parameter(self%lda, 'lda', '1/d', 'remineralisation rate', default=0.003_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%tda, 'tda', 'deg C', 'half-saturation temperature for remineralisation', default=13.0_rk)
call self%get_parameter(self%beta_da, 'beta_da', '-', 'temperature sensitivity of remineralisation', default=20.0_rk)
call self%get_parameter(self%pvel, 'pvel', 'm/d', 'piston velocity', default=5.0_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%sr, 'sr', 'mol P/mol N', 'phosphorus to nitrogen ratio', default=0.0625_rk)
call self%get_parameter(self%s1, 's1', '-', 'reduced nitrate : oxidized detritus for denitrification', default=5.3_rk)
call self%get_parameter(self%s2, 's2', 'mol O2/mol N', 'oxygen : nitrogen ratio for ammonium-based biomass synthesis and remineralisation', default=6.625_rk)
call self%get_parameter(self%s3, 's3', 'mol O2/mol N', 'oxygen : nitrogen ratio for nitrate-based biomass synthesis', default=8.625_rk)
call self%get_parameter(self%s4, 's4', 'mol O2/mol N', 'oxygen : nitrogen ratio for nitrification', default=2.0_rk)
call self%get_parameter(self%a0, 'a0', 'mmol O2/g', 'mmol O2 per gram', default=31.25_rk)
call self%get_parameter(self%a1, 'a1', 'g/m3', 'saturation mass concentration of oxygen at 0 deg C', default=14.603_rk)
call self%get_parameter(self%a2, 'a2', 'g/m3/deg C', 'decrease in saturation mass concentration of oxygen per deg C', default=0.4025_rk)
if (self%fluff) then
call self%get_parameter(self%lds, 'lds', 'm/d', 'sedimentation rate of detritus', default=3.5_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%lsd, 'lsd', '1/d', 'resuspension rate of fluff', default=25.0_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%tau_crit, 'tau_crit', 'critical bottom stress', 'N/m2', default=0.07_rk)
call self%get_parameter(self%lsa, 'lsa', '1/d', 'fluff mineralisation rate', default=0.001_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%bsa, 'bsa', '1/deg C', 'temperature sensitivity of fluff mineralisation', default=0.15_rk)
call self%get_parameter(self%ph1, 'ph1', '-', 'inhibition of phosphate release during fluff mineralisation', default=0.15_rk)
call self%get_parameter(self%ph2, 'ph2', 'mmol O2/m3', 'half-saturation oxygen concentration for inhibition of phosphate release', default=0.1_rk)
end if
call self%get_parameter(w_p1, 'w_p1', 'vertical velocity of diatoms (< for sinking)', 'm/d', default=-1.0_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(w_p2, 'w_p2', 'vertical velocity of flagellates (< for sinking)', 'm/d', default=-5.0_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(w_p3, 'w_p3', 'vertical velocity of cyanobacteria (< for sinking)', 'm/d', default=-5.0_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(w_de, 'w_de', 'vertical velocity of detritus (< for sinking)', 'm/d', default=-3.0_rk, scale_factor=1.0_rk/secs_pr_day)
! Register state variables
call self%register_state_variable(self%id_p1, 'dia', 'mmol N/m3', 'diatoms', &
4.5_rk, minimum=0.0_rk, vertical_movement=w_p1)
call self%register_state_variable(self%id_p2, 'fla', 'mmol N/m3', 'flagellates', &
4.5_rk, minimum=0.0_rk, vertical_movement=w_p2)
call self%register_state_variable(self%id_p3, 'cya', 'mmol N/m3', 'cyanobacteria',&
4.5_rk, minimum=0.0_rk, vertical_movement=w_p3)
call self%register_state_variable(self%id_zo, 'zoo', 'mmol N/m3', 'zooplankton', &
4.5_rk, minimum=0.0_rk)
call self%register_state_variable(self%id_de, 'det', 'mmol N/m3', 'detritus', &
4.5_rk, minimum=0.0_rk, vertical_movement=w_de)
call self%register_state_variable(self%id_am, 'amm', 'mmol N/m3', 'ammonium', &
4.5_rk, minimum=0.0_rk, no_river_dilution=.true.)
call self%register_state_variable(self%id_ni, 'nit', 'mmol N/m3', 'nitrate', &
4.5_rk, minimum=0.0_rk, no_river_dilution=.true.)
call self%register_state_variable(self%id_po, 'pho', 'mmol P/m3', 'phosphate', &
4.5_rk, minimum=0.0_rk, no_river_dilution=.true.)
call self%register_state_variable(self%id_o2, 'oxy', 'mmol O2/m3', 'oxygen', 4.5_rk)
if (self%fluff) call self%register_state_variable(self%id_fl, 'flf', 'mmol N/m2', 'fluff', &
0.0_rk, minimum=0.0_rk)
! Register diagnostic variables
call self%register_diagnostic_variable(self%id_dPAR, 'PAR', 'W/m2', 'photosynthetically active radiation')
call self%register_diagnostic_variable(self%id_GPP, 'GPP', 'mmol/m3', 'gross primary production')
call self%register_diagnostic_variable(self%id_NCP, 'NCP', 'mmol/m3', 'net community production')
call self%register_diagnostic_variable(self%id_PPR, 'PPR', 'mmol/m3/d', 'gross primary production rate')
call self%register_diagnostic_variable(self%id_NPR, 'NPR', 'mmol/m3/d', 'net community production rate')
! Register environmental dependencies
call self%register_dependency(self%id_par, standard_variables%downwelling_photosynthetic_radiative_flux)
call self%register_dependency(self%id_temp, standard_variables%temperature)
call self%register_dependency(self%id_salt, standard_variables%practical_salinity)
call self%register_dependency(self%id_I_0, standard_variables%surface_downwelling_photosynthetic_radiative_flux)
call self%register_dependency(self%id_wind, standard_variables%wind_speed)
if (self%fluff) call self%register_dependency(self%id_taub, standard_variables%bottom_stress)
! Let phytoplankton (including background concentration) and detritus contribute to light attentuation
call self%add_to_aggregate_variable(standard_variables%attenuation_coefficient_of_photosynthetic_radiative_flux, self%id_p1, scale_factor=self%kc)
call self%add_to_aggregate_variable(standard_variables%attenuation_coefficient_of_photosynthetic_radiative_flux, self%id_p2, scale_factor=self%kc)
call self%add_to_aggregate_variable(standard_variables%attenuation_coefficient_of_photosynthetic_radiative_flux, self%id_p3, scale_factor=self%kc)
call self%add_to_aggregate_variable(standard_variables%attenuation_coefficient_of_photosynthetic_radiative_flux, self%id_de, scale_factor=self%kc)
call self%add_to_aggregate_variable(standard_variables%attenuation_coefficient_of_photosynthetic_radiative_flux, (self%p10 + self%p20 + self%p30) * self%kc)
class (type_gotm_ergom), intent(inout), target :: self
integer, intent(in) :: configunit
real(rk) :: w_p1
real(rk) :: w_p2
real(rk) :: w_p3
real(rk) :: w_de
real(rk), parameter :: secs_pr_day=86400.0_rk
! Store parameter values in our own derived type
! NB! All rates must be provided in values per day in the configuration file,
! and are converted here to values per second by specifying scale_factor=1.0_rk/secs_pr_day
call self%get_parameter(self%sfl_po, 'sfl_po', 'mmol P/m2/d', 'surface phosphate flux', default=0.0015_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%sfl_ni, 'sfl_ni', 'mmol N/m2/d', 'surface nitrate flux', default=0.09_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%sfl_am, 'sfl_am', 'mmol N/m2/d', 'surface ammonium flux', default=0.07_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%fluff, 'fluff', '', 'use fluff', default=.false.)
call self%get_parameter(self%p10, 'p10', 'mmol N/m3', 'background concentration of diatoms', default=0.0225_rk)
call self%get_parameter(self%p20, 'p20', 'mmol N/m3', 'background concentration of flagellates', default=0.0225_rk)
call self%get_parameter(self%p30, 'p30', 'mmol N/m3', 'background concentration of cyanobacteria', default=0.0225_rk)
call self%get_parameter(self%zo0, 'zo0', 'mmol N/m3', 'background concentration of zooplankton', default=0.0225_rk)
call self%get_parameter(self%kc, 'kc', 'm2/mmol N', 'specific light attenuation of phytoplankton and detritus', default=0.03_rk)
call self%get_parameter(self%i_min, 'i_min', 'W/m2', 'minimum optimal photosynthetically active radiation', default=25.0_rk)
call self%get_parameter(self%r1max, 'r1max', '1/d', 'maximum growth rate of diatoms', default=2.0_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%r2max, 'r2max', '1/d', 'maximum growth rate of flagellates', default=0.7_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%r3max, 'r3max', '1/d', 'maximum growth rate of cyanobacteria', default=0.5_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%alpha1, 'alpha1', 'mmol N/m3', 'half-saturation nutrient concentration for diatoms', default=1.35_rk)
call self%get_parameter(self%alpha2, 'alpha2', 'mmol N/m3', 'half-saturation nutrient concentration for flagellates', default=0.675_rk)
call self%get_parameter(self%alpha3, 'alpha3', 'mmol N/m3', 'half-saturation nutrient concentration for cyanobacteria', default=0.5_rk)
call self%get_parameter(self%lpa, 'lpa', '1/d', 'phytoplankton exudation', default=0.01_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%lpd, 'lpd', '1/d', 'phytoplankton mortality', default=0.02_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%tf, 'tf', 'deg C', 'half-saturation temperature for flagellates', default=10.0_rk)
call self%get_parameter(self%tbg, 'tbg', 'deg C', 'reference temperature for cyanobacteria', default=14.0_rk)
call self%get_parameter(self%beta_bg, 'beta_bg', '1/deg C', 'temperature sensitivity for cyanobacteria', default=1.0_rk)
call self%get_parameter(self%g1max, 'g1max', '1/d', 'maximum grazing rate on diatoms', default=0.5_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%g2max, 'g2max', '1/d', 'maximum grazing rate on flagellates', default=0.5_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%g3max, 'g3max', '1/d', 'maximum grazing rate on cyanobacteria', default=0.25_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%lza, 'lza', 'm3/mmol N/d', 'quadratic zooplankton loss to dissolved matter', default=0.0666666666_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%lzd, 'lzd', 'm3/mmol N/d', 'quadratic zooplankton loss to detritus', default=0.1333333333_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%iv, 'iv', 'm3/mmol N', 'Ivlev constant for grazing', default=0.24444444_rk)
call self%get_parameter(self%topt, 'topt', 'deg C', 'optimum temperature for grazing', default=20.0_rk)
call self%get_parameter(self%lan, 'lan', '1/d', 'maximum nitrification rate', default=0.1_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%oan, 'oan', 'mmol o2/m3', 'half-saturation oxygen concentration for nitrification', default=0.01_rk)
call self%get_parameter(self%beta_an, 'beta_an', '1/deg C', 'temperature sensitivity of nitrification', default=0.11_rk)
call self%get_parameter(self%lda, 'lda', '1/d', 'remineralisation rate', default=0.003_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%tda, 'tda', 'deg C', 'half-saturation temperature for remineralisation', default=13.0_rk)
call self%get_parameter(self%beta_da, 'beta_da', '-', 'temperature sensitivity of remineralisation', default=20.0_rk)
call self%get_parameter(self%pvel, 'pvel', 'm/d', 'piston velocity', default=5.0_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%sr, 'sr', 'mol P/mol N', 'phosphorus to nitrogen ratio', default=0.0625_rk)
call self%get_parameter(self%s1, 's1', '-', 'reduced nitrate : oxidized detritus for denitrification', default=5.3_rk)
call self%get_parameter(self%s2, 's2', 'mol O2/mol N', 'oxygen : nitrogen ratio for ammonium-based biomass synthesis and remineralisation', default=6.625_rk)
call self%get_parameter(self%s3, 's3', 'mol O2/mol N', 'oxygen : nitrogen ratio for nitrate-based biomass synthesis', default=8.625_rk)
call self%get_parameter(self%s4, 's4', 'mol O2/mol N', 'oxygen : nitrogen ratio for nitrification', default=2.0_rk)
call self%get_parameter(self%a0, 'a0', 'mmol O2/g', 'mmol O2 per gram', default=31.25_rk)
call self%get_parameter(self%a1, 'a1', 'g/m3', 'saturation mass concentration of oxygen at 0 deg C', default=14.603_rk)
call self%get_parameter(self%a2, 'a2', 'g/m3/deg C', 'decrease in saturation mass concentration of oxygen per deg C', default=0.4025_rk)
if (self%fluff) then
call self%get_parameter(self%lds, 'lds', 'm/d', 'sedimentation rate of detritus', default=3.5_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%lsd, 'lsd', '1/d', 'resuspension rate of fluff', default=25.0_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%tau_crit, 'tau_crit', 'critical bottom stress', 'N/m2', default=0.07_rk)
call self%get_parameter(self%lsa, 'lsa', '1/d', 'fluff mineralisation rate', default=0.001_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(self%bsa, 'bsa', '1/deg C', 'temperature sensitivity of fluff mineralisation', default=0.15_rk)
call self%get_parameter(self%ph1, 'ph1', '-', 'inhibition of phosphate release during fluff mineralisation', default=0.15_rk)
call self%get_parameter(self%ph2, 'ph2', 'mmol O2/m3', 'half-saturation oxygen concentration for inhibition of phosphate release', default=0.1_rk)
end if
call self%get_parameter(w_p1, 'w_p1', 'vertical velocity of diatoms (< for sinking)', 'm/d', default=-1.0_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(w_p2, 'w_p2', 'vertical velocity of flagellates (< for sinking)', 'm/d', default=-5.0_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(w_p3, 'w_p3', 'vertical velocity of cyanobacteria (< for sinking)', 'm/d', default=-5.0_rk, scale_factor=1.0_rk/secs_pr_day)
call self%get_parameter(w_de, 'w_de', 'vertical velocity of detritus (< for sinking)', 'm/d', default=-3.0_rk, scale_factor=1.0_rk/secs_pr_day)
! Register state variables
call self%register_state_variable(self%id_p1, 'dia', 'mmol N/m3', 'diatoms', &
4.5_rk, minimum=0.0_rk, vertical_movement=w_p1)
call self%register_state_variable(self%id_p2, 'fla', 'mmol N/m3', 'flagellates', &
4.5_rk, minimum=0.0_rk, vertical_movement=w_p2)
call self%register_state_variable(self%id_p3, 'cya', 'mmol N/m3', 'cyanobacteria',&
4.5_rk, minimum=0.0_rk, vertical_movement=w_p3)
call self%register_state_variable(self%id_zo, 'zoo', 'mmol N/m3', 'zooplankton', &
4.5_rk, minimum=0.0_rk)
call self%register_state_variable(self%id_de, 'det', 'mmol N/m3', 'detritus', &
4.5_rk, minimum=0.0_rk, vertical_movement=w_de)
call self%register_state_variable(self%id_am, 'amm', 'mmol N/m3', 'ammonium', &
4.5_rk, minimum=0.0_rk, no_river_dilution=.true.)
call self%register_state_variable(self%id_ni, 'nit', 'mmol N/m3', 'nitrate', &
4.5_rk, minimum=0.0_rk, no_river_dilution=.true.)
call self%register_state_variable(self%id_po, 'pho', 'mmol P/m3', 'phosphate', &
4.5_rk, minimum=0.0_rk, no_river_dilution=.true.)
call self%register_state_variable(self%id_o2, 'oxy', 'mmol O2/m3', 'oxygen', 4.5_rk)
if (self%fluff) call self%register_state_variable(self%id_fl, 'flf', 'mmol N/m2', 'fluff', &
0.0_rk, minimum=0.0_rk)
! Register diagnostic variables
call self%register_diagnostic_variable(self%id_dPAR, 'PAR', 'W/m2', 'photosynthetically active radiation')
call self%register_diagnostic_variable(self%id_GPP, 'GPP', 'mmol/m3', 'gross primary production')
call self%register_diagnostic_variable(self%id_NCP, 'NCP', 'mmol/m3', 'net community production')
call self%register_diagnostic_variable(self%id_PPR, 'PPR', 'mmol/m3/d', 'gross primary production rate')
call self%register_diagnostic_variable(self%id_NPR, 'NPR', 'mmol/m3/d', 'net community production rate')
! Register environmental dependencies
call self%register_dependency(self%id_par, standard_variables%downwelling_photosynthetic_radiative_flux)
call self%register_dependency(self%id_temp, standard_variables%temperature)
call self%register_dependency(self%id_salt, standard_variables%practical_salinity)
call self%register_dependency(self%id_I_0, standard_variables%surface_downwelling_photosynthetic_radiative_flux)
call self%register_dependency(self%id_wind, standard_variables%wind_speed)
if (self%fluff) call self%register_dependency(self%id_taub, standard_variables%bottom_stress)
! Let phytoplankton (including background concentration) and detritus contribute to light attentuation
call self%add_to_aggregate_variable(standard_variables%attenuation_coefficient_of_photosynthetic_radiative_flux, self%id_p1, scale_factor=self%kc)
call self%add_to_aggregate_variable(standard_variables%attenuation_coefficient_of_photosynthetic_radiative_flux, self%id_p2, scale_factor=self%kc)
call self%add_to_aggregate_variable(standard_variables%attenuation_coefficient_of_photosynthetic_radiative_flux, self%id_p3, scale_factor=self%kc)
call self%add_to_aggregate_variable(standard_variables%attenuation_coefficient_of_photosynthetic_radiative_flux, self%id_de, scale_factor=self%kc)
call self%add_to_aggregate_variable(standard_variables%attenuation_coefficient_of_photosynthetic_radiative_flux, (self%p10 + self%p20 + self%p30) * self%kc)
end subroutine initialize
!EOC
!-----------------------------------------------------------------------
!BOP
!
! !IROUTINE: Right hand sides of ergom model
!
! !INTERFACE:
subroutine do(self, _ARGUMENTS_DO_)
!
! !INPUT PARAMETERS:
class (type_gotm_ergom), intent(in) :: self
_DECLARE_ARGUMENTS_DO_
!
! !LOCAL VARIABLES:
real(rk) :: p1,p2,p3,zo,am,ni,po,de,o2,par,I_0
real(rk) :: iopt,ppi,temp,psum,llda,llan,lp,r1,r2,r3
real(rk) :: wo=30.0_rk,wn=0.1_rk
real(rk) :: thopnp,thomnp,thomnm,thsum
real(rk) :: secs_pr_day=86400.0_rk
!EOP
!-----------------------------------------------------------------------
!BOC
! Enter spatial_loops (if any)
_LOOP_BEGIN_
! Retrieve current (local) state variable values
_GET_(self%id_p1,p1) !diatoms
_GET_(self%id_p2,p2) !flagellates
_GET_(self%id_p3,p3) !cyanobacteria
_GET_(self%id_zo,zo) !zooplankton
_GET_(self%id_de,de) !detritus
_GET_(self%id_am,am) !ammonium
_GET_(self%id_ni,ni) !nitrate
_GET_(self%id_po,po) !phosphate
_GET_(self%id_o2,o2) !oxygen
! Retrieve current environmental conditions
_GET_(self%id_par,par) ! local photosynthetically active radiation
_GET_SURFACE_(self%id_I_0,I_0) ! surface photosynthetically active radiation
_GET_(self%id_temp,temp) ! local water temperature
! Light acclimation formulation based on surface light intensity
iopt = max(0.25*I_0,self%i_min)
ppi = par/iopt*exp(1.0_rk-par/iopt)
thopnp=th( o2,wo,0.0_rk,1.0_rk)*yy(wn,ni)
thomnp=th(-o2,wo,0.0_rk,1.0_rk)*yy(wn,ni)
thomnm=th(-o2,wo,0.0_rk,1.0_rk)*(1.0_rk-yy(wn,ni))
thsum=thopnp+thomnp+thomnm
thopnp=thopnp/thsum
thomnp=thomnp/thsum
thomnm=thomnm/thsum
psum=p1+p2+p3+self%p10+self%p20+self%p30
llda=self%lda*(1.0_rk+self%beta_da*yy(self%tda,temp))
llan=th(o2,0.0_rk,0.0_rk,1.0_rk)*o2/(self%oan+o2)*self%lan*exp(self%beta_an*temp)
lp=self%lpa+self%lpd
r1=self%r1max*min(yy(self%alpha1,am+ni),yy(self%sr*self%alpha1,po),ppi)*(p1+self%p10)
r2=self%r2max*(1.0_rk+yy(self%tf,temp))*min(yy(self%alpha2,am+ni), &
yy(self%sr*self%alpha2,po),ppi)*(p2+self%p20)
r3=self%r3max*1.0_rk/(1.0_rk+exp(self%beta_bg*(self%tbg-temp))) &
*min(yy(self%sr*self%alpha3,po),ppi)*(p3+self%p30)
_SET_ODE_(self%id_p1,r1-fpz(self,self%g1max,temp,self%topt,psum)*p1/psum*(zo+self%zo0)-lp*p1)
_SET_ODE_(self%id_p2,r2-fpz(self,self%g2max,temp,self%topt,psum)*p2/psum*(zo+self%zo0)-lp*p2)
_SET_ODE_(self%id_p3,r3-fpz(self,self%g3max,temp,self%topt,psum)*p3/psum*(zo+self%zo0)-lp*p3)
_SET_ODE_(self%id_zo,(fpz(self,self%g1max,temp,self%topt,psum)*p1+fpz(self,self%g2max,temp,self%topt,psum)*p2+fpz(self,self%g3max,temp,self%topt,psum)*p3)*(zo+self%zo0)/psum-self%lza*zo*(zo+self%zo0)-self%lzd*zo*(zo+self%zo0))
_SET_ODE_(self%id_de,self%lpd*p1+self%lpd*p2+self%lpd*p3+self%lzd*zo*(zo+self%zo0)-llda*de)
_SET_ODE_(self%id_am,llda*de-llan*am-am/(am+ni)*r1-am/(am+ni)*r2+self%lpa*(p1+p2+p3)+self%lza*zo*(zo+self%zo0))
_SET_ODE_(self%id_ni,llan*am-ni/(am+ni)*r1-ni/(am+ni)*r2-self%s1*llda*de*thomnp)
_SET_ODE_(self%id_po,self%sr*(-r1-r2-r3+llda*de+self%lpa*(p1+p2+p3)+self%lza*zo*(zo+self%zo0)))
_SET_ODE_(self%id_o2,self%s2*(am/(am+ni)*(r1+r2)+r3)-self%s4*(llan*am)+self%s3*(ni/(am+ni)*(r1+r2))-self%s2*(thopnp+thomnm)*llda*de-self%s2*(self%lpa*(p1+p2+p3)+self%lza*zo*(zo+self%zo0)))
! Set diagnostic variables
_SET_DIAGNOSTIC_(self%id_dPAR,par)
_SET_DIAGNOSTIC_(self%id_GPP ,r1+r2+r3)
_SET_DIAGNOSTIC_(self%id_NCP ,r1+r2+r3 - self%lpa*(p1+p2+p3))
_SET_DIAGNOSTIC_(self%id_PPR ,(r1+r2+r3)*secs_pr_day)
_SET_DIAGNOSTIC_(self%id_NPR ,(r1+r2+r3 - self%lpa*(p1+p2+p3))*secs_pr_day)
! Leave spatial loops (if any)
_LOOP_END_
class (type_gotm_ergom), intent(in) :: self
_DECLARE_ARGUMENTS_DO_
real(rk) :: p1,p2,p3,zo,am,ni,po,de,o2,par,I_0
real(rk) :: iopt,ppi,temp,psum,llda,llan,lp,r1,r2,r3
real(rk) :: wo=30.0_rk,wn=0.1_rk
real(rk) :: thopnp,thomnp,thomnm,thsum
real(rk) :: secs_pr_day=86400.0_rk
! Enter spatial_loops (if any)
_LOOP_BEGIN_
! Retrieve current (local) state variable values
_GET_(self%id_p1,p1) ! diatoms
_GET_(self%id_p2,p2) ! flagellates
_GET_(self%id_p3,p3) ! cyanobacteria
_GET_(self%id_zo,zo) ! zooplankton
_GET_(self%id_de,de) ! detritus
_GET_(self%id_am,am) ! ammonium
_GET_(self%id_ni,ni) ! nitrate
_GET_(self%id_po,po) ! phosphate
_GET_(self%id_o2,o2) ! oxygen
! Retrieve current environmental conditions
_GET_(self%id_par,par) ! local photosynthetically active radiation
_GET_SURFACE_(self%id_I_0,I_0) ! surface photosynthetically active radiation
_GET_(self%id_temp,temp) ! local water temperature
! Light acclimation formulation based on surface light intensity
iopt = max(0.25*I_0,self%i_min)
ppi = par/iopt*exp(1.0_rk-par/iopt)
thopnp=th( o2,wo,0.0_rk,1.0_rk)*yy(wn,ni)
thomnp=th(-o2,wo,0.0_rk,1.0_rk)*yy(wn,ni)
thomnm=th(-o2,wo,0.0_rk,1.0_rk)*(1.0_rk-yy(wn,ni))
thsum=thopnp+thomnp+thomnm
thopnp=thopnp/thsum
thomnp=thomnp/thsum
thomnm=thomnm/thsum