diff --git a/.gitignore b/.gitignore
index f869d2cbc..820a4f247 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,4 @@ Makefile.in
mesh_part/build
test/output_pi
src/cvmix_driver/CVMix-*
+finished_config.yaml
diff --git a/config/bin_2p1z1d/job_albedo b/config/bin_2p1z1d/job_albedo
index bac3e2b3a..23caf2e11 100755
--- a/config/bin_2p1z1d/job_albedo
+++ b/config/bin_2p1z1d/job_albedo
@@ -1,16 +1,15 @@
#!/bin/bash
-#SBATCH --account=nwg_hauck.maresys # edit your account
+#SBATCH --account=biogeo_model.biogeo_model # edit your account
#SBATCH --job-name=recom
#SBATCH --partition=mpp
#SBATCH --time=01:30:00
-####SBATCH --constraint="[rack1|rack3]"
#SBATCH --qos=12h
#SBATCH --nodes=9 # Number of tasks (MPI) tasks to be launched
#SBATCH --tasks-per-node 96 #8 #4 # using all 128CPus we exceed the maxload limit (>130) of many used nodes when us parallel I/O
#SBATCH --cpus-per-task 1
-#SBATCH -o fesom2o.out
-#SBATCH -e fesom2e.out
+#SBATCH -o slurm-out.out
+#SBATCH -e slurm-err.out
# disable hyperthreading
#SBATCH --hint=nomultithread
@@ -35,23 +34,22 @@ cp -n ../config/namelist.icepack .
#___DETERMINE SLURM JOBID+OUTPUTFILE____________________________________________
jobid=$(echo $SLURM_JOB_ID | cut -d"." -f1)
-fname="fesom2_${SLURM_JOB_NAME}_${jobid}.out"
+fname="fesom2.0.out"
#___PUT JOB IN QUEUE____________________________________________________________
date
-####srun --mpi=pmi2 ./fesom.x >> ${fname}
srun --mpi=pmi2 ./fesom.x > fesom2.0.out
date
#qstat -f $PBS_JOBID
#export EXITSTATUS=$?
#if [ ${EXITSTATUS} -eq 0 ] || [ ${EXITSTATUS} -eq 127 ] ; then
-#sbatch job_ollie
+#sbatch job_albedo
#fi
-#Resultpath='/albedo/scratch/user/ogurses/ocean_only/'
-Resultpath='/albedo/scratch/user/ogurses/fesom2.5_recom_st1_vsink_vben_diags/'
-test -d $Resultpath/fesom.2019.oce.restart && exit
+
+Resultpath='/albedo/scratch/user/XXXX/'
+test -e $Resultpath/fesom.XXXX.oce.restart && exit
IsInFile=$( tail -3 fesom2.0.out | grep -c timesteps)
if (( IsInFile > 0 )); then
diff --git a/config/bin_2p1z1d/namelist.config b/config/bin_2p1z1d/namelist.config
index eb9a4375d..27c3d140a 100644
--- a/config/bin_2p1z1d/namelist.config
+++ b/config/bin_2p1z1d/namelist.config
@@ -1,67 +1,133 @@
-! This is the namelist file for model general configuration
+! ============================================================================
+! ============ Namelist file for FESOM2 general configuration ================
+! ============================================================================
+! This file contains the main configuration parameters for FESOM2, including:
+! - Model identification and run settings
+! - Time stepping and simulation duration
+! - Initial time/date settings
+! - File paths for mesh, forcing, and output
+! - Restart and logging configuration
+! - Vertical coordinate system (ALE)
+! - Grid geometry and rotation
+! - Calendar settings
+! - Model components (ice, cavities, etc.)
+! - Parallel decomposition
+! - Iceberg settings
+! ============================================================================
+! ============================================================================
+! RUN IDENTIFICATION
+! ============================================================================
&modelname
-runid='fesom'
+runid = 'fesom' ! run identifier (used in output filenames)
/
+! ============================================================================
+! TIME STEPPING AND RUN LENGTH
+! ============================================================================
×tep
-step_per_day=32 !96 !96 !72 !72 !45 !72 !96
-run_length=1 !62 !62 !62 !28
-run_length_unit='y' ! y, m, d, s
+step_per_day = 36 ! number of time steps per day (determines dt = 86400/step_per_day seconds)
+ ! common values: 32 (45min), 48 (30min), 72 (20min), 96 (15min), 192 (7min 30sec),
+ ! 216 (6min 40sec), 240 (6min), 288 (5min), 360 (4min), 720 (2min), 1440 (1min), 2880 (30sec)
+run_length = 1 ! total length of simulation run
+run_length_unit = 'y' ! unit for run_length: 'y' (years), 'm' (months), 'd' (days), 's' (steps)
/
-&clockinit ! the model starts at
-timenew=0.0
-daynew=1
-yearnew=1958
+! ============================================================================
+! INITIAL TIME/DATE SETTINGS
+! ============================================================================
+&clockinit
+timenew = 0.0 ! initial time within the day [seconds] (0.0 = midnight)
+daynew = 1 ! initial day of the month (1-31)
+yearnew = 1958 ! initial year
/
+! ============================================================================
+! MESH, INITIALIZATION & OUTPUT PATHS
+! ============================================================================
&paths
-MeshPath='/albedo/work/projects/p_recompdaf/frbunsen/FESOM2/meshes/core2/'
-ClimateDataPath='/albedo/work/projects/MarESys/ogurses/input/corrected_input/'
-ResultPath='/albedo/scratch/user/ogurses/fesom2.5_recom_st1_vsink_vben_diags/'
+MeshPath = '/albedo/work/projects/p_recompdaf/frbunsen/FESOM2/meshes/core2/' ! path to mesh files (nod2d.out, elem2d.out, etc.)
+ClimateDataPath = '/albedo/work/projects/MarESys/ogurses/input/corrected_input/' ! path to initial conditions (temperature, salinity)
+ResultPath = '/albedo/scratch/user/XXXX'
/
+! ============================================================================
+! RESTART AND LOGGING CONFIGURATION
+! ============================================================================
&restart_log
-restart_length=1 ! --> do netcdf restart ( only required for d,h,s cases, y, m take 1)
-restart_length_unit='y' !output period: y, d, h, s, off
-raw_restart_length=1 ! --> do core dump restart
-raw_restart_length_unit='off' ! e.g. y, d, h, s, off
-bin_restart_length=1 ! --> do derived type binary restart
-bin_restart_length_unit='off' ! e.g. y, d, h, s, off
-logfile_outfreq=960 !in logfile info. output frequency, # steps
+restart_length = 1 ! frequency for netCDF restart files (required for d,h,s; y,m use 1)
+restart_length_unit = 'y' ! unit: 'y' (years), 'm' (months), 'd' (days), 'h' (hours), 's' (steps), 'off' (disabled)
+raw_restart_length = 1 ! frequency for raw core dump restart files
+raw_restart_length_unit = 'off' ! unit: 'y', 'm', 'd', 'h', 's', 'off'
+bin_restart_length = 1 ! frequency for binary derived type restart files
+bin_restart_length_unit = 'off' ! unit: 'y', 'm', 'd', 'h', 's', 'off'
+logfile_outfreq = 960 ! log file output frequency [number of time steps]
/
+! ============================================================================
+! VERTICAL COORDINATE SYSTEM (ALE - Arbitrary Lagrangian-Eulerian)
+! ============================================================================
&ale_def
-which_ALE='zstar' ! 'linfs','zlevel', 'zstar'
-use_partial_cell=.true.
+which_ALE = 'zstar' ! vertical coordinate type:
+ ! 'linfs' = linear free surface
+ ! 'zlevel' = z-level (fixed depth levels)
+ ! 'zstar' = z-star (terrain-following with SSH scaling)
+use_partial_cell = .false. ! use partial bottom cells for better topography representation (not recommended)
/
+! ============================================================================
+! GRID GEOMETRY AND ROTATION
+! ============================================================================
&geometry
-cartesian=.false.
-fplane=.false.
-cyclic_length=360 ![degree]
-rotated_grid=.true. !option only valid for coupled model case now
-force_rotation=.true.
-alphaEuler=50. ![degree] Euler angles, convention:
-betaEuler=15. ![degree] first around z, then around new x,
-gammaEuler=-90. ![degree] then around new z.
+cartesian = .false. ! use Cartesian coordinates (false = spherical Earth)
+fplane = .false. ! use f-plane approximation (constant Coriolis parameter)
+cyclic_length = 360 ! length of cyclic domain [degrees] (360 = global)
+rotated_grid = .true. ! use rotated grid (typically for coupled models to avoid pole singularity)
+force_rotation = .true. ! force grid rotation even if not coupled
+alphaEuler = 50. ! first Euler angle (rotation around z-axis) [degrees]
+betaEuler = 15. ! second Euler angle (rotation around new x-axis) [degrees]
+gammaEuler = -90. ! third Euler angle (rotation around new z-axis) [degrees]
+ ! Euler angle convention: rotate first around z, then around new x, then around new z
/
+! ============================================================================
+! CALENDAR SETTINGS
+! ============================================================================
&calendar
-include_fleapyear=.false.
+include_fleapyear = .false. ! include leap years in calendar (false = 365-day year, true = 365/366-day year)
/
+! ============================================================================
+! MODEL COMPONENTS AND FEATURES
+! ============================================================================
&run_config
-use_ice=.true. ! ocean+ice
-use_cavity=.false. !
-use_cavity_partial_cell=.false.
-use_floatice = .false.
-use_sw_pene=.true.
-flag_debug=.false.
+use_ice = .true. ! enable sea ice model
+use_cavity = .false. ! enable ice shelf cavities
+use_cavity_partial_cell = .false. ! use partial cells in ice shelf cavities (not recommended)
+use_floatice = .false. ! enable floating ice (icebergs)
+use_sw_pene = .true. ! enable shortwave radiation penetration into ocean
+flag_debug = .false. ! enable debug output (verbose logging)
+use_transit = .false. ! enable transient tracer module (CFCs, SF6, etc.)
/
+! ============================================================================
+! PARALLEL DECOMPOSITION (DOMAIN PARTITIONING)
+! ============================================================================
&machine
-n_levels=2
-n_part= 12, 36 ! 432 number of partitions on each hierarchy level
+n_levels = 2 ! number of hierarchy levels for domain decomposition
+n_part = 2, 128 ! number of partitions at each level (total CPUs = product of n_part)
+ ! example: 2 x 128 = 256 MPI tasks
+ ! adjust based on mesh size and available compute resources
+ ! maximum scaling reached at ~300 FESOM2 2D nodes per CPU (see first line in nod2d.out for number of 2D nodes)
+/
+
+! ============================================================================
+! ICEBERG SETTINGS
+! ============================================================================
+&icebergs
+use_icesheet_coupling = .false. ! enable ice sheet model
+ib_num = 1 ! number of iceberg classes
+use_icebergs = .false. ! enable iceberg module
+steps_per_ib_step = 8 ! ocean time steps per iceberg time step (iceberg subcycling)
+ib_async_mode = 0 ! iceberg asynchronous mode (0=synchronous, 1=asynchronous)
/
diff --git a/config/bin_2p1z1d/namelist.forcing b/config/bin_2p1z1d/namelist.forcing
index a17799393..d890c69ec 100644
--- a/config/bin_2p1z1d/namelist.forcing
+++ b/config/bin_2p1z1d/namelist.forcing
@@ -23,11 +23,23 @@ ncar_bulk_z_shum=10.0 ! height at which humi forcing is located (CORE, JRA-do: 1
use_landice_water=.false.
landice_start_mon=5
landice_end_mon=10
+fwf_path='./mesh/'
+
+/
+
+&age_tracer
+use_age_tracer=.false.
+use_age_mask=.false.
+age_tracer_path='./mesh/'
+age_start_year=2000
+
/
&nam_sbc
nm_xwind_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/uas.clim61' ! name of file with winds, if nm_sbc=2
nm_ywind_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/vas.clim61' ! name of file with winds, if nm_sbc=2
+ nm_xstre_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/uas.clim61' ! name of file with winds, if nm_sbc=2
+ nm_ystre_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/vas.clim61' ! name of file with winds, if nm_sbc=2
nm_humi_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/huss.clim61' ! name of file with humidity
nm_qsr_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/rsds.clim61' ! name of file with solar heat
nm_qlw_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/rlds.clim61' ! name of file with Long wave
@@ -37,24 +49,32 @@ landice_end_mon=10
nm_mslp_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/psl.clim61' ! air_pressure_at_sea_level
nm_xwind_var = 'uas' ! name of variable in file with wind
nm_ywind_var = 'vas' ! name of variable in file with wind
- nm_humi_var = 'huss' ! name of variable in file with humidity
- nm_qsr_var = 'rsds' ! name of variable in file with solar heat
- nm_qlw_var = 'rlds' ! name of variable in file with Long wave
+ nm_xstre_var = 'uas' ! name of variable in file with wind
+ nm_ystre_var = 'vas' ! name of variable in file with wind
+ nm_humi_var = 'huss' ! name of variable in file with humidity
+ nm_qsr_var = 'rsds' ! name of variable in file with solar heat
+ nm_qlw_var = 'rlds' ! name of variable in file with Long wave
nm_tair_var = 'tas' ! name of variable in file with 2m air temperature
- nm_prec_var = 'prra' ! name of variable in file with total precipitation
- nm_snow_var = 'prsn' ! name of variable in file with total precipitation
- nm_mslp_var = 'psl' ! name of variable in file with air_pressure_at_sea_level
+ nm_prec_var = 'prra' ! name of variable in file with total precipitation
+ nm_snow_var = 'prsn' ! name of variable in file with total precipitation
+ nm_mslp_var = 'psl' ! name of variable in file with air_pressure_at_sea_level
nm_nc_iyear = 1900
nm_nc_imm = 1 ! initial month of time axis in netCDF
nm_nc_idd = 1 ! initial day of time axis in netCDF
nm_nc_freq = 1 ! data points per day (i.e. 86400 if the time axis is in seconds)
nm_nc_tmid = 0 ! 1 if the time stamps are given at the mid points of the netcdf file, 0 otherwise (i.e. 1 in CORE1, CORE2; 0 in JRA55)
y_perpetual=.true.
- l_xwind=.true. l_ywind=.true. l_humi=.true. l_qsr=.true. l_qlw=.true. l_tair=.true. l_prec=.true. l_mslp=.true. l_cloud=.false. l_snow=.true.
+ l_xwind=.true. l_ywind=.true. l_xstre=.false. l_ystre=.false. l_humi=.true. l_qsr=.true. l_qlw=.true. l_tair=.true. l_prec=.true. l_mslp=.true. l_cloud=.false. l_snow=.true.
nm_runoff_file ='/albedo/pool/FESOM/forcing/CORE2/runoff.nc'
runoff_data_source ='CORE2' !Dai09, CORE2
!runoff_data_source ='Dai09' !Dai09, CORE2, JRA55
!runoff_climatology =.true.
- nm_sss_data_file ='/albedo/pool/FESOM/forcing/CORE2/PHC2_salx.nc'
sss_data_source ='CORE2'
+ nm_sss_data_file ='/albedo/pool/FESOM/forcing/CORE2/PHC2_salx.nc'
+ chl_data_source ='None' !'Sweeney' monthly chlorophyll climatology or 'NONE' for constant chl_const (below). Make use_sw_pene=.TRUE. in namelist.config!
+ nm_chl_data_file ='/pool/data/AWICM/FESOM2/FORCING/JRA55-do-v1.4.0/Sweeney/Sweeney_2005.nc'
+ chl_const = 0.1
+ use_runoff_mapper = .FALSE.
+ runoff_basins_file = 'runoff_maps_regular.nc'
+ runoff_radius = 500000.
/
diff --git a/config/bin_2p1z1d/namelist.io b/config/bin_2p1z1d/namelist.io
index 7a6fe3cff..1cff5280d 100644
--- a/config/bin_2p1z1d/namelist.io
+++ b/config/bin_2p1z1d/namelist.io
@@ -55,7 +55,6 @@ io_list = 'sst ',1, 'm', 4,
'Hp ',1, 'm', 4,
'aFe ',1, 'm', 4,
'aN ',1, 'm', 4,
- 'denb ',1, 'm', 4,
'benN ',1, 'm', 4,
'benC ',1, 'm', 4,
'benSi ',1, 'm', 4,
diff --git a/config/bin_2p1z1d/namelist.recom b/config/bin_2p1z1d/namelist.recom
index dd53c8538..afde32d97 100644
--- a/config/bin_2p1z1d/namelist.recom
+++ b/config/bin_2p1z1d/namelist.recom
@@ -1,353 +1,514 @@
-! This is the namelist file for recom
-
+! ============================================================================
+! ============ Namelist file for REcoM Biogeochemical Model =================
+! ============================================================================
+! Regional Ecosystem Model (REcoM) configuration
+! This file controls biogeochemical processes including:
+! - Carbon, nitrogen, silicon, iron cycling
+! - Phytoplankton (small phyto, diatoms, coccolithophores)
+! - Zooplankton (micro, meso, krill)
+! - Organic matter remineralization and sinking
+! - Carbonate chemistry and air-sea CO2 fluxes
+! - External nutrient inputs (dust, rivers, erosion)
+! ============================================================================
+
+! ============================================================================
+! DATA SOURCES AND INPUT FILES
+! ============================================================================
&nam_rsbc
fe_data_source ='Albani'
nm_fe_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/DustClimMonthlyAlbani.nc'
nm_aen_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/AeolianNitrogenDep.nc'
nm_river_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/RiverineInput.nc'
nm_erosion_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/ErosionInput.nc'
-nm_co2_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/MonthlyAtmCO2_gcb2023.nc'
+nm_co2_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/MonthlyAtmCO2_gcb2024.nc'
/
-&pavariables
-use_REcoM =.true.
-REcoM_restart =.true.
-
-bgc_num = 22 !33 !24 !38
-diags3d_num = 28 ! Number of diagnostic 3d tracers to be saved
-bgc_base_num = 22 ! standard tracers
-VDet = 20.d0 ! Sinking velocity, constant through the water column and positive downwards
-VDet_zoo2 = 200.d0 ! Sinking velocity, constant through the water column
-VPhy = 0.d0 !!! If the number of sinking velocities are different from 3, code needs to be changed !!!
-VDia = 0.d0
-VCocco = 0.d0
-allow_var_sinking = .true.
-biostep = 1 ! Number of times biology should be stepped forward for each time step
-REcoM_Geider_limiter = .false. ! Decides what routine should be used to calculate limiters in sms
-REcoM_Grazing_Variable_Preference = .true. ! Decides if grazing should have preference for phyN or DiaN
-Grazing_detritus = .true.
-het_resp_noredfield = .true. ! Decides respiratation of copepod group
-diatom_mucus = .true. ! Decides nutrient limitation effect on aggregation
-O2dep_remin = .false. ! O2remin Add option for O2 dependency of organic matter remineralization
-use_ballasting = .false. ! BALL
-use_density_scaling = .false. ! BALL
-use_viscosity_scaling = .false. ! BALL
-OmegaC_diss = .false. ! DISS Use OmegaC from Mocsy to compute calcite dissolution (after Aumont et al. 2015 and Gehlen et al. 2007)
-CO2lim = .false. ! CO2 dependence of growth and calcification
-Diags = .true.
-constant_CO2 = .true.
-UseFeDust = .true. ! Turns dust input of iron off when set to.false.
-UseDustClim = .true.
-UseDustClimAlbani = .true. ! Use Albani dustclim field (If it is false Mahowald will be used)
-use_photodamage = .true. ! use Alvarez et al (2018) for chlorophyll degradation
-HetRespFlux_plus = .true. !MB More stable computation of zooplankton respiration fluxes adding a small number to HetN
-REcoMDataPath = '/albedo/work/projects/MarESys/ogurses/input/mesh_CORE2_finaltopo_mean/'
-restore_alkalinity = .true.
-useRivers = .false.
-useRivFe = .false. ! When set to true, riverine Fe source is activated
-useErosion = .false.
-NitrogenSS = .false. ! When set to true, external sources and sinks of nitrogen are activated (Riverine, aeolian and denitrification)
-useAeolianN = .false. ! When set to true, aeolian nitrogen deposition is activated
-firstyearoffesomcycle = 1958 ! The first year of the actual physical forcing (e.g. JRA-55) used
-lastyearoffesomcycle = 2022 ! Last year of the actual physical forcing used
-numofCO2cycles = 1 ! Number of cycles of the forcing planned
-currentCO2cycle = 1 ! Which CO2 cycle we are currently running
-DIC_PI = .true.
-Nmocsy = 1 ! Length of the vector that is passed to mocsy (always one for recom)
-recom_debug =.false.
-ciso =.false. ! Main switch to enable/disable carbon isotopes (13|14C)
-benthos_num = 4 ! number of benthic BGC tracers -> 8 if (ciso == .true.) otherwise -> 4
-use_MEDUSA = .false. ! Main switch for the sediment model MEDUSA
-sedflx_num = 0 ! if 0: no file from MEDUSA is read but default sediment
-bottflx_num = 4 ! if ciso&ciso_14: =8; if .not.ciso_14: =6; no ciso: =4
-use_atbox = .false.
-add_loopback = .false. ! add loopback fluxes through rivers to the surface
-lb_tscale = 1.0 ! /year: fraction of loopback fluxes yearly added to the surface
+! ============================================================================
+! GENERAL MODEL CONFIGURATION
+! ============================================================================
+&parecomsetup
+enable_3zoo2det = .false. ! Enable 3 zooplankton + 2 detritus configuration (currently disabled)
+enable_coccos = .false. ! Enable coccolithophores (currently disabled)
/
+! ============================================================================
+! MAIN MODEL SWITCHES AND SETTINGS
+! ============================================================================
+! --- Core Model Settings ---
+&pavariables
+use_REcoM = .true.
+REcoM_restart = .true.
+recom_debug = .false.
+
+! --- Tracer Configuration ---
+bgc_num = 22 ! Total number of BGC tracers
+diags3d_num = 28 ! Number of diagnostic 3D tracers
+bgc_base_num = 22 ! Number of standard tracers
+benthos_num = 4 ! Number of benthic BGC tracers (8 if ciso=.true., else 4)
+sedflx_num = 0 ! Sediment fluxes from MEDUSA (0 = use defaults)
+bottflx_num = 4 ! Bottom fluxes (8 if ciso & ciso_14, 6 if not ciso_14, 4 otherwise)
+
+! --- Sinking Velocities [m/day] ---
+VDet = 20.0 ! Small detritus sinking velocity (constant, positive down)
+VDet_zoo2 = 200.0 ! Large detritus sinking velocity
+VPhy = 0.0 ! Small phytoplankton (non-sinking)
+VDia = 0.0 ! Diatoms (variable sinking if allow_var_sinking=.true.)
+VCocco = 0.0 ! Coccolithophores
+allow_var_sinking = .true. ! Enable variable sinking velocity
+
+! --- Time Stepping ---
+biostep = 1 ! Number of biology sub-steps per physical time step
+
+! --- Process Switches ---
+REcoM_Geider_limiter = .false. ! Use Geider limiter for nutrient limitation
+REcoM_Grazing_Variable_Preference = .true. ! Variable grazing preference (PhyN vs DiaN)
+Grazing_detritus = .true. ! Enable zooplankton grazing on detritus
+het_resp_noredfield = .true. ! Non-Redfield respiration for copepods
+diatom_mucus = .true. ! Nutrient-limited diatom aggregation
+O2dep_remin = .false. ! O2-dependent organic matter remineralization
+use_ballasting = .false. ! Ballast effect on sinking
+use_density_scaling = .false. ! Density-dependent sinking
+use_viscosity_scaling = .false. ! Viscosity-dependent sinking
+OmegaC_diss = .false. ! OmegaC-dependent calcite dissolution (set calc_diss_guts=0 if false)
+CO2lim = .false. ! CO2 effects on growth and calcification
+use_photodamage = .true. ! Chlorophyll photodamage (Alvarez et al. 2018)
+HetRespFlux_plus = .true. ! Stabilized zooplankton respiration computation
+Diags = .true. ! Enable diagnostics output
+
+! --- External Inputs ---
+constant_CO2 = .true.
+UseFeDust = .true. ! Enable iron input from dust
+UseDustClim = .true. ! Use dust climatology
+UseDustClimAlbani = .true. ! Use Albani dust fields (false = Mahowald)
+useRivers = .false. ! Enable riverine inputs
+useRivFe = .false. ! Enable riverine iron source
+useErosion = .false. ! Enable erosion inputs
+NitrogenSS = .false. ! Enable nitrogen sources/sinks (rivers, aeolian, denitrification)
+useAeolianN = .false. ! Enable aeolian nitrogen deposition
+
+! --- Time Period Configuration ---
+firstyearoffesomcycle = 1958 ! First year of physical forcing (e.g., JRA-55)
+lastyearoffesomcycle = 2024 ! Last year of physical forcing
+numofCO2cycles = 1 ! Number of forcing cycles
+currentCO2cycle = 1 ! Current forcing cycle number
+
+! --- Alkalinity and Carbon ---
+DIC_PI = .true. ! Use pre-industrial DIC
+restore_alkalinity = .true. ! Restore surface alkalinity
+Nmocsy = 1 ! Vector length for mocsy (always 1 for REcoM)
+
+! --- Data Path ---
+REcoMDataPath = '/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/'
+
+! --- Carbon Isotopes ---
+ciso = .false. ! Enable carbon isotopes (13C, 14C)
+
+! --- Sediment Model ---
+use_MEDUSA = .false. ! Enable MEDUSA sediment model
+add_loopback = .false. ! Add loopback fluxes through rivers
+lb_tscale = 1.0 ! Loopback timescale [1/year]
+
+! --- Miscellaneous ---
+use_atbox = .false. ! Use atmospheric box model
+/
+
+! ============================================================================
+! SINKING VELOCITY PARAMETERS
+! ============================================================================
&pasinking
-Vdet_a = 0.0288 ! [1/day]
-Vcalc = 0.0144 ! [1/day]
+Vdet_a = 0.0288 ! Slope of the linearly increasing sinking velocity [1/day]
+Vcalc = 0.0144 ! Depth dependence of calcite dissolution (when use_coccos disabled) [1/day]
/
+! ============================================================================
+! INITIAL CONDITIONS
+! ============================================================================
&painitialization_N
-cPhyN = 0.2d0
-cHetN = 0.2d0
-cZoo2N = 0.2d0
+cPhyN = 0.2 ! Initial small phytoplankton nitrogen [mmol N/m³]
+cHetN = 0.2 ! Initial microzooplankton nitrogen [mmol N/m³]
+cZoo2N = 0.2 ! Initial mesozooplankton nitrogen [mmol N/m³]
/
+! ============================================================================
+! TEMPERATURE DEPENDENCE (ARRHENIUS)
+! ============================================================================
&paArrhenius
-recom_Tref = 288.15d0 ! [K]
-C2K = 273.15d0 ! Conversion from degrees C to K
-Ae = 4500.d0 ! [K] Slope of the linear part of the Arrhenius function
-reminSi = 0.02d0
-k_o2_remin = 15.d0 ! NEW O2remin mmol m-3; Table 1 in Cram 2018 cites DeVries & Weber 2017 for a range of 0-30 mmol m-3
+recom_Tref = 288.15 ! Reference temperature [K]
+C2K = 273.15 ! Celsius to Kelvin conversion
+Ae = 4500.0 ! Arrhenius slope [K]
+reminSi = 0.02 ! Silicate remineralization base rate [1/day]
+k_o2_remin = 15.0 ! Half-saturation for O2 remineralization [mmol O2/m³]
/
&palimiter_function
-NMinSlope = 50.d0
-SiMinSlope = 1000.d0
-NCmin = 0.04d0 !0.05d0
-NCmin_d = 0.04d0 !0.05d0
-NCmin_c = 0.04d0 ! NEW
-SiCmin = 0.04d0
-k_Fe = 0.04d0
-k_Fe_d = 0.12d0
-k_Fe_c = 0.09d0 ! NEW
-k_si = 4.d0
-P_cm = 3.0d0 ! [1/day] Rate of C-specific photosynthesis
-P_cm_d = 3.5d0
-P_cm_c = 2.8d0 ! NEW
-/
-
+! --- Limitation Function Slopes ---
+NMinSlope = 50.0 ! Nitrogen minimum slope
+SiMinSlope = 1000.0 ! Silicon minimum slope
+
+! --- Minimum Quotas [mmol/mmol C] ---
+NCmin = 0.04 ! Small phytoplankton N:C minimum
+NCmin_d = 0.04 ! Diatom N:C minimum
+NCmin_c = 0.04 ! Coccolithophore N:C minimum
+SiCmin = 0.04 ! Diatom Si:C minimum
+
+! --- Half-Saturation Constants ---
+k_Fe = 0.04 ! Small phyto iron half-sat [µmol Fe/m³]
+k_Fe_d = 0.12 ! Diatom iron half-sat [µmol Fe/m³]
+k_Fe_c = 0.09 ! Coccolith iron half-sat [µmol Fe/m³]
+k_si = 4.0 ! Silicon half-sat [mmol Si/m³]
+
+! --- Maximum Photosynthesis Rates [1/day] ---
+P_cm = 3.0 ! Small phytoplankton max C-specific photosynthesis
+P_cm_d = 3.5 ! Diatom max C-specific photosynthesis
+P_cm_c = 2.8 ! Coccolithophore max C-specific photosynthesis
+/
+
+! ============================================================================
+! LIGHT ATTENUATION
+! ============================================================================
&palight_calculations
-k_w = 0.04d0 ! [1/m] Light attenuation coefficient
-a_chl = 0.03d0 ! [1/m * 1/(mg Chl)] Chlorophyll specific attenuation coefficients
+k_w = 0.04 ! Water attenuation coefficient [1/m]
+a_chl = 0.03 ! Chlorophyll-specific attenuation [1/m per mg Chl/m³]
/
+! ============================================================================
+! PHOTOSYNTHESIS (P-I CURVE)
+! ============================================================================
&paphotosynthesis
-alfa = 0.14d0 ! [(mmol C*m2)/(mg Chl*W*day)]
-alfa_d = 0.19d0 ! An initial slope of the P-I curve
-alfa_c = 0.10d0 ! NEW
-parFrac = 0.43d0
+alfa = 0.14 ! Small phyto initial P-I slope [(mmol C·m²)/(mg Chl·W·day)]
+alfa_d = 0.19 ! Diatom initial P-I slope
+alfa_c = 0.10 ! Coccolithophore initial P-I slope
+parFrac = 0.43 ! Fraction of shortwave that is PAR
/
+! ============================================================================
+! NUTRIENT ASSIMILATION
+! ============================================================================
&paassimilation
-V_cm_fact = 0.7d0 ! scaling factor for temperature dependent maximum of C-specific N-uptake
-V_cm_fact_d = 0.7d0
-V_cm_fact_c = 0.7d0 ! NEW
-NMaxSlope = 1000.d0 ! Max slope for limiting function
-SiMaxSlope = 1000.d0
-NCmax = 0.2d0 ! [mmol N/mmol C] Maximum cell quota of nitrogen (N:C)
-NCmax_d = 0.2d0
-NCmax_c = 0.15d0 ! NEW
-SiCmax = 0.8d0
-NCuptakeRatio = 0.2d0 ! [mmol N/mmol C] Maximum uptake ratio of N:C
-NCUptakeRatio_d = 0.2d0
-NCUptakeRatio_c = 0.2d0 ! NEW
-SiCUptakeRatio = 0.2d0
-k_din = 0.55d0 ! [mmol N/m3] Half-saturation constant for nitrate uptake
-k_din_d = 1.0d0
-k_din_c = 0.9d0 ! NEW
-Chl2N_max = 3.15d0 ! [mg CHL/mmol N] Maximum CHL a : N ratio = 0.3 gCHL gN^-1
-Chl2N_max_d = 4.2d0
-Chl2N_max_c = 3.5d0 ! NEW
-res_phy = 0.01d0 ! [1/day] Maintenance respiration rate constant
-res_phy_d = 0.01d0
-res_phy_c = 0.01d0 ! NEW
-biosynth = 2.33d0 ! [mmol C/mmol N] Cost of biosynthesis
-biosynthSi = 0.d0
-/
-
+! --- Maximum Uptake Scaling ---
+V_cm_fact = 0.7 ! Small phyto N-uptake scaling factor
+V_cm_fact_d = 0.7 ! Diatom N-uptake scaling factor
+V_cm_fact_c = 0.7 ! Coccolithophore N-uptake scaling factor
+
+! --- Limitation Function Slopes ---
+NMaxSlope = 1000.0 ! Nitrogen maximum slope
+SiMaxSlope = 1000.0 ! Silicon maximum slope
+
+! --- Maximum Cell Quotas [mmol/mmol C] ---
+NCmax = 0.2 ! Small phyto maximum N:C
+NCmax_d = 0.2 ! Diatom maximum N:C
+NCmax_c = 0.15 ! Coccolithophore maximum N:C
+SiCmax = 0.8 ! Diatom maximum Si:C
+
+! --- Maximum Uptake Ratios [mmol/mmol C] ---
+NCuptakeRatio = 0.2 ! Small phyto N:C uptake ratio
+NCUptakeRatio_d = 0.2 ! Diatom N:C uptake ratio
+NCUptakeRatio_c = 0.2 ! Coccolithophore N:C uptake ratio
+SiCUptakeRatio = 0.2 ! Diatom Si:C uptake ratio
+
+! --- Chlorophyll Parameters ---
+Chl2N_max = 3.15 ! Small phyto max Chl:N [mg Chl/mmol N]
+Chl2N_max_d = 4.2 ! Diatom max Chl:N [mg Chl/mmol N]
+Chl2N_max_c = 3.5 ! Coccolithophore max Chl:N [mg Chl/mmol N]
+
+! --- Half-Saturation Constants ---
+k_din = 0.55 ! Small phyto nitrate half-sat [mmol N/m³]
+k_din_d = 1.0 ! Diatom nitrate half-sat [mmol N/m³]
+k_din_c = 0.9 ! Coccolith nitrate half-sat [mmol N/m³]
+
+! --- Respiration and Biosynthesis ---
+res_phy = 0.01 ! Small phyto maintenance respiration [1/day]
+res_phy_d = 0.01 ! Diatom maintenance respiration [1/day]
+res_phy_c = 0.01 ! Coccolithophore maintenance respiration [1/day]
+biosynth = 2.33 ! Cost of biosynthesis [mmol C/mmol N]
+biosynthSi = 0.0 ! Silicon biosynthesis cost [mmol C/mmol Si]
+/
+
+! ============================================================================
+! IRON CHEMISTRY
+! ============================================================================
&pairon_chem
-totalligand = 1.d0 ! [mumol/m3] order 1. Total free ligand
-ligandStabConst = 100.d0 ! [m3/mumol] order 100. Ligand-free iron stability constant
+totalligand = 1.0 ! Total free ligand concentration [µmol/m³]
+ligandStabConst = 100.0 ! Ligand-Fe stability constant [m³/µmol]
/
+! ============================================================================
+! MICROZOOPLANKTON (FIRST ZOOPLANKTON)
+! ============================================================================
&pazooplankton
-graz_max = 0.31d0 ! [mmol N/(m3 * day)] Maximum grazing loss parameter
-epsilonr = 0.09d0 ! [(mmol N)2 /m6] Half saturation constant for grazing loss
-res_het = 0.028d0 ! [1/day] Respiration by heterotrophs and mortality (loss to detritus)
-Redfield = 6.625 ! [mmol C/mmol N] Redfield ratio of C:N = 106:16
-loss_het = 0.04d0 ! [1/day] Temperature dependent N degradation of extracellular organic N (EON)
-pzDia = 1.0d0 !0.5d0 ! Maximum diatom preference
-sDiaNsq = 0.d0
-pzPhy = 0.5d0 !0.25d0 !1.0d0 ! Maximum nano-phytoplankton preference (NEW: 3/12)
-sPhyNsq = 0.d0
-pzCocco = 0.666d0 ! NEW (8/12)
-sCoccoNsq = 0.d0 ! NEW
-pzMicZoo = 1.0d0 ! NEW 3Zoo Maximum nano-phytoplankton preference
-sMicZooNsq = 0.d0 ! NEW 3Zoo
-tiny_het = 1.d-5 ! for more stable computation of HetRespFlux (_plus). Value can be > tiny because HetRespFlux ~ hetC**2.
-/
-
+graz_max = 0.31 ! Maximum grazing rate [1/day]
+epsilonr = 0.09 ! Half-saturation constant [(mmol N)²/m⁶]
+res_het = 0.028 ! Respiration + mortality [1/day]
+Redfield = 6.625 ! C:N Redfield ratio [mmol C/mmol N]
+loss_het = 0.04 ! Extracellular N degradation [1/day]
+tiny_het = 1.d-5 ! Small number for stable computation
+
+! --- Grazing Preferences ---
+pzDia = 1.0 ! Diatom preference (maximum)
+sDiaNsq = 0.0 ! Diatom preference slope
+pzPhy = 0.5 ! Small phyto preference
+sPhyNsq = 0.0 ! Small phyto preference slope
+pzCocco = 0.666 ! Coccolithophore preference
+sCoccoNsq = 0.0 ! Coccolithophore preference slope
+pzMicZoo = 1.0 ! Microzooplankton preference (self-grazing)
+sMicZooNsq = 0.0 ! Microzooplankton preference slope
+/
+
+! ============================================================================
+! MESOZOOPLANKTON (SECOND ZOOPLANKTON)
+! ============================================================================
&pasecondzooplankton
-graz_max2 = 0.1d0 ! [mmol N/(m3 * day)] Maximum grazing loss parameter
-epsilon2 = 0.0144d0 ! [(mmol N)2 /m6] Half saturation constant for grazing loss
-res_zoo2 = 0.0107d0 ! [1/day] Respiration by heterotrophs and mortality (loss to detritus)
-loss_zoo2 = 0.003d0 ! [1/day] Temperature dependent N degradation of extracellular organic N (EON)
-fecal_rate_n = 0.104d0 ! [1/day] Temperature dependent N degradation of \
-fecal_rate_c = 0.236d0
-fecal_rate_n_mes = 0.25d0 ! NEW 3Zoo
-fecal_rate_c_mes = 0.32d0 ! NEW 3Zoo
-pzDia2 = 1.5d0 !1.d0 ! Maximum diatom preference
-sDiaNsq2 = 0.d0
-pzPhy2 = 0.5d0 ! Maximum diatom preference
-sPhyNsq2 = 0.d0
-pzCocco2 = 0.5d0 ! NEW
-sCoccoNsq2 = 0.d0 ! NEW
-pzHet = 1.5d0 !0.8d0 ! Maximum diatom preference
-sHetNsq = 0.d0
-t1_zoo2 = 28145.d0 ! Krill temp. function constant1
-t2_zoo2 = 272.5d0 ! Krill temp. function constant2
-t3_zoo2 = 105234.d0 ! Krill temp. function constant3
-t4_zoo2 = 274.15d0 ! Krill temp. function constant3
-/
-
+graz_max2 = 0.1 ! Maximum grazing rate [1/day]
+epsilon2 = 0.0144 ! Half-saturation constant [(mmol N)²/m⁶]
+res_zoo2 = 0.0107 ! Respiration + mortality [1/day]
+loss_zoo2 = 0.003 ! Extracellular N degradation [1/day]
+
+! --- Fecal Pellet Production ---
+fecal_rate_n = 0.104 ! Nitrogen fecal rate [1/day]
+fecal_rate_c = 0.236 ! Carbon fecal rate [1/day]
+fecal_rate_n_mes = 0.25 ! Mesozooplankton N fecal rate [1/day]
+fecal_rate_c_mes = 0.32 ! Mesozooplankton C fecal rate [1/day]
+
+! --- Grazing Preferences ---
+pzDia2 = 1.5 ! Diatom preference
+sDiaNsq2 = 0.0 ! Diatom preference slope
+pzPhy2 = 0.5 ! Small phyto preference
+sPhyNsq2 = 0.0 ! Small phyto preference slope
+pzCocco2 = 0.5 ! Coccolithophore preference (unused)
+sCoccoNsq2 = 0.0 ! Coccolithophore preference slope
+pzHet = 1.5 ! Microzooplankton preference
+sHetNsq = 0.0 ! Microzooplankton preference slope
+
+! --- Temperature Function (Krill-specific) ---
+t1_zoo2 = 28145.0 ! Temperature function constant 1
+t2_zoo2 = 272.5 ! Temperature function constant 2 [K]
+t3_zoo2 = 105234.0 ! Temperature function constant 3
+t4_zoo2 = 274.15 ! Temperature function constant 4 [K]
+/
+
+! ============================================================================
+! MICROZOOPLANKTON (THIRD ZOOPLANKTON)
+! ============================================================================
&pathirdzooplankton
-graz_max3 = 0.46d0 ! NEW 3Zoo [mmol N/(m3 * day)] Maximum grazing loss parameter
-epsilon3 = 0.64d0 ! NEW 3Zoo [(mmol N)2 /m6] Half saturation constant for grazing loss
-loss_miczoo = 0.01d0 ! NEW 3Zoo [1/day] Temperature dependent N degradation of extracellular organic N (EON)
-res_miczoo = 0.01d0 ! NEW 3Zoo [1/day] Respiration by heterotrophs and mortality (loss to detritus)
-pzDia3 = 0.5d0 ! NEW 3Zoo Maximum diatom preference
-sDiaNsq3 = 0.d0 ! NEW 3Zoo
-pzPhy3 = 1.0d0 ! NEW 3Zoo Maximum nano-phytoplankton preference
-sPhyNsq3 = 0.d0 ! NEW 3Zoo
-pzCocco3 = 0.d0 ! NEW 3Zoo Maximum coccolithophore preference ! ATTENTION: This value needs to be tuned; I start with zero preference!
-sCoccoNsq3 = 0.d0 ! NEW 3Zoo
-/
-
+graz_max3 = 0.46 ! Maximum grazing rate [1/day]
+epsilon3 = 0.64 ! Half-saturation constant [(mmol N)²/m⁶]
+loss_miczoo = 0.01 ! Extracellular N degradation [1/day]
+res_miczoo = 0.01 ! Respiration + mortality [1/day]
+
+! --- Grazing Preferences ---
+pzDia3 = 0.5 ! Diatom preference
+sDiaNsq3 = 0.0 ! Diatom preference slope
+pzPhy3 = 1.0 ! Small phyto preference
+sPhyNsq3 = 0.0 ! Small phyto preference slope
+pzCocco3 = 0.0 ! Coccolithophore preference (unused)
+sCoccoNsq3 = 0.0 ! Coccolithophore preference slope
+/
+
+! ============================================================================
+! GRAZING ON DETRITUS
+! ============================================================================
&pagrazingdetritus
-pzDet = 0.5d0 ! Maximum small detritus prefence by first zooplankton
-sDetNsq = 0.d0
-pzDetZ2 = 0.5d0 ! Maximum large detritus preference by first zooplankton
-sDetZ2Nsq = 0.d0
-pzDet2 = 0.5d0 ! Maximum small detritus prefence by second zooplankton
-sDetNsq2 = 0.d0
-pzDetZ22 = 0.5d0 ! Maximum large detritus preference by second zooplankton
-sDetZ2Nsq2 = 0.d0
-/
-
+! --- First Zooplankton (Microzooplankton) ---
+pzDet = 0.5 ! Small detritus preference
+sDetNsq = 0.0 ! Small detritus preference slope
+pzDetZ2 = 0.5 ! Large detritus preference
+sDetZ2Nsq = 0.0 ! Large detritus preference slope
+
+! --- Second Zooplankton (Mesozooplankton) ---
+pzDet2 = 0.5 ! Small detritus preference
+sDetNsq2 = 0.0 ! Small detritus preference slope
+pzDetZ22 = 0.5 ! Large detritus preference
+sDetZ2Nsq2 = 0.0 ! Large detritus preference slope
+/
+
+! ============================================================================
+! AGGREGATION
+! ============================================================================
&paaggregation
-agg_PD = 0.165d0 ! [m3/(mmol N * day)] Maximum aggregation loss parameter for DetN
-agg_PP = 0.015d0 ! [m3/(mmol N * day)] Maximum aggregation loss parameter for PhyN and DiaN (plankton)
+agg_PD = 0.165 ! Detritus aggregation rate [m³/(mmol N·day)]
+agg_PP = 0.015 ! Plankton aggregation rate [m³/(mmol N·day)]
/
+! ============================================================================
+! DISSOLVED ORGANIC MATTER REMINERALIZATION
+! ============================================================================
&padin_rho_N
-rho_N = 0.11d0 ! [1/day] Temperature dependent N degradation of extracellular organic N (EON) (Remineralization of DON)
+rho_N = 0.11 ! DON remineralization rate [1/day]
+rho_Nt = 0.67d0 ! [1/day] terrestrial N degradation of extracellular organic N (DONt) (Remineralization of terrestrial DON) ~ scale of 1.5 years ! R2OMIP
/
&padic_rho_C1
-rho_C1 = 0.1d0 ! [1/day] Temperature dependent C degradation of extracellular organic C (EOC)
+rho_C1 = 0.1 ! DOC remineralization rate [1/day]
/
+! ============================================================================
+! PHYTOPLANKTON LOSSES
+! ============================================================================
&paphytoplankton_N
-lossN = 0.05d0 ! [1/day] Phytoplankton loss of organic N compounds
-lossN_d = 0.05d0
-lossN_c = 0.05d0 ! NEW
+lossN = 0.05 ! Small phyto N loss rate [1/day]
+lossN_d = 0.05 ! Diatom N loss rate [1/day]
+lossN_c = 0.05 ! Coccolithophore N loss rate [1/day]
/
&paphytoplankton_C
-lossC = 0.10d0 ! [1/day] Phytoplankton loss of carbon
-lossC_d = 0.10d0
-lossC_c = 0.10d0 ! NEW
+lossC = 0.10 ! Small phyto C loss rate [1/day]
+lossC_d = 0.10 ! Diatom C loss rate [1/day]
+lossC_c = 0.10 ! Coccolithophore C loss rate [1/day]
/
&paphytoplankton_ChlA
-deg_Chl = 0.25d0 !0.2d0 !0.25d0 ! [1/day]
-deg_Chl_d = 0.15d0 !0.2d0 !0.15d0
-deg_Chl_c = 0.2d0 ! NEW (has been 0.5)
+deg_Chl = 0.25 !0.2 !0.25 ! Small phyto Chl degradation [1/day]
+deg_Chl_d = 0.15 !0.2 !0.15 ! Diatom Chl degradation [1/day]
+deg_Chl_c = 0.2 ! Coccolithophore Chl degradation [1/day]
/
+! ============================================================================
+! DETRITUS REMINERALIZATION
+! ============================================================================
&padetritus_N
-gfin = 0.3d0 ! NEW 3Zoo [] Grazing efficiency (fraction of grazing flux into zooplankton pool)
-grazEff2 = 0.8d0 ! [] Grazing efficiency (fraction of grazing flux into second zooplankton pool)
-grazEff3 = 0.8d0 ! NEW 3Zoo [] Grazing efficiency (fraction of grazing flux into microzooplankton pool)
-reminN = 0.165d0 ! [1/day] Temperature dependent remineralisation rate of detritus
+gfin = 0.3 ! First zooplankton grazing efficiency
+grazEff2 = 0.8 ! Second zooplankton grazing efficiency
+grazEff3 = 0.8 ! Third zooplankton grazing efficiency
+reminN = 0.165 ! Detritus N remineralization rate [1/day]
/
&padetritus_C
-reminC = 0.15d0 ! [1/day] Temperature dependent remineralisation rate of detritus
-rho_c2 = 0.1d0 ! [1/day] Temperature dependent C degradation of TEP-C
+reminC = 0.15 ! Detritus C remineralization rate [1/day]
+rho_c2 = 0.1 ! TEP-C degradation rate [1/day]
/
+! ============================================================================
+! ZOOPLANKTON LOSSES
+! ============================================================================
&paheterotrophs
-lossN_z = 0.1d0
-lossC_z = 0.1d0
+lossN_z = 0.1 ! First zooplankton N loss [1/day]
+lossC_z = 0.1 ! First zooplankton C loss [1/day]
/
&paseczooloss
-lossN_z2 = 0.02d0
-lossC_z2 = 0.02d0
+lossN_z2 = 0.02 ! Second zooplankton N loss [1/day]
+lossC_z2 = 0.02 ! Second zooplankton C loss [1/day]
/
&pathirdzooloss
-lossN_z3 = 0.05d0 ! NEW 3Zoo
-lossC_z3 = 0.05d0 ! NEW 3Zoo
-/
-
-&paco2lim ! NEW
-Cunits = 976.5625 ! Conversion factor between [mol/m3] (model) and [umol/kg] (function): (1000 * 1000) / 1024
-a_co2_phy = 1.162e+00 ! [dimensionless]
-a_co2_dia = 1.040e+00 ! [dimensionless]
-a_co2_cocco = 1.109e+00 ! [dimensionless]
-a_co2_calc = 1.102e+00 ! [dimensionless]
-b_co2_phy = 4.888e+01 ! [mol/kg]
-b_co2_dia = 2.890e+01 ! [mol/kg]
-b_co2_cocco = 3.767e+01 ! [mol/kg]
-b_co2_calc = 4.238e+01 ! [mol/kg]
-c_co2_phy = 2.255e-01 ! [kg/mol]
-c_co2_dia = 8.778e-01 ! [kg/mol]
-c_co2_cocco = 3.912e-01 ! [kg/mol]
-c_co2_calc = 7.079e-01 ! [kg/mol]
-d_co2_phy = 1.023e+07 ! [kg/mol]
-d_co2_dia = 2.640e+06 ! [kg/mol]
-d_co2_cocco = 9.450e+06 ! [kg/mol]
-d_co2_calc = 1.343e+07 ! [kg/mol]
+lossN_z3 = 0.05 ! Third zooplankton N loss [1/day]
+lossC_z3 = 0.05 ! Third zooplankton C loss [1/day]
+/
+
+! ============================================================================
+! CO2 LIMITATION PARAMETERS
+! ============================================================================
+&paco2lim
+Cunits = 976.5625 ! Unit conversion factor: mol/m³ → µmol/kg
+
+! --- Small Phytoplankton ---
+a_co2_phy = 1.162e+00 ! Dimensionless
+b_co2_phy = 4.888e+01 ! [mol/kg]
+c_co2_phy = 2.255e-01 ! [kg/mol]
+d_co2_phy = 1.023e+07 ! [kg/mol]
+
+! --- Diatoms ---
+a_co2_dia = 1.040e+00 ! Dimensionless
+b_co2_dia = 2.890e+01 ! [mol/kg]
+c_co2_dia = 8.778e-01 ! [kg/mol]
+d_co2_dia = 2.640e+06 ! [kg/mol]
+
+! --- Coccolithophores ---
+a_co2_cocco = 1.109e+00 ! Dimensionless (growth)
+b_co2_cocco = 3.767e+01 ! [mol/kg] (growth)
+c_co2_cocco = 3.912e-01 ! [kg/mol] (growth)
+d_co2_cocco = 9.450e+06 ! [kg/mol] (growth)
+
+a_co2_calc = 1.102e+00 ! Dimensionless (calcification)
+b_co2_calc = 4.238e+01 ! [mol/kg] (calcification)
+c_co2_calc = 7.079e-01 ! [kg/mol] (calcification)
+d_co2_calc = 1.343e+07 ! [kg/mol] (calcification)
/
&pairon
-Fe2N = 0.033d0 ! Fe2C * 6.625
-Fe2N_benthos = 0.15d0 ! test, default was 0.14 Fe2C_benthos * 6.625 - will have to be tuned. [umol/m2/day]
-kScavFe = 0.07d0
-dust_sol = 0.02d0 ! Dissolution of Dust for bioavaliable
-RiverFeConc = 100
+Fe2N = 0.033 ! Iron to nitrogen ratio (= Fe2C × 6.625)
+Fe2N_benthos = 0.15 ! Benthic flux ratio [micromol Fe : mmol N,]
+kScavFe = 0.07 ! Iron scavenging rate [1/day]
+dust_sol = 0.02 ! Dust iron solubility fraction
+RiverFeConc = 100 ! Riverine iron concentration [µmol/m³]
/
+! ============================================================================
+! CALCITE PRODUCTION AND DISSOLUTION
+! ============================================================================
&pacalc
-calc_prod_ratio = 0.02
-calc_diss_guts = 0.0d0
-calc_diss_rate = 0.005714 ! 20.d0/3500.d0
-calc_diss_rate2 = 0.005714d0
-calc_diss_omegac = 0.197d0 ! NEW DISS Value from Aumont et al. 2015, will be used with OmegaC_diss flag
-calc_diss_exp = 1.d0 ! NEW DISS Exponent in the dissolution rate of calcite, will be used with OmegaC_diss flag
+calc_prod_ratio = 0.02 ! Calcite production ratio (CaCO₃:POC)
+calc_diss_guts = 0.0 ! Gut dissolution fraction (set to 0 if OmegaC_diss=.false.)
+calc_diss_rate = 0.005714 ! Standard dissolution rate [1/day] = 20/3500
+calc_diss_rate2 = 0.005714 ! Standard dissolution rate [1/day]
+calc_diss_omegac = 0.197 ! Critical Ω_calcite (Aumont et al. 2015)
+calc_diss_exp = 1.0 ! Dissolution rate exponent
/
+! ============================================================================
+! BENTHIC PROCESSES
+! ============================================================================
&pabenthos_decay_rate
-decayRateBenN = 0.005d0
-decayRateBenC = 0.005d0
-decayRateBenSi = 0.005d0
-q_NC_Denit = 0.86d0 ! N:C quota of the denitrification process
+decayRateBenN = 0.005 ! Benthic N decay rate [1/day]
+decayRateBenC = 0.005 ! Benthic C decay rate [1/day]
+decayRateBenSi = 0.005 ! Benthic Si decay rate [1/day]
+q_NC_Denit = 0.86 ! N:C quota for denitrification
/
+! ============================================================================
+! AIR-SEA CO2 FLUX
+! ============================================================================
&paco2_flux_param
-permil = 0.000000976 ! 1.e-3/1024.5d0 ! Converting DIC from [mmol/m3] to [mol/kg]
-permeg = 1.e-6 ! [atm/uatm] Changes units from uatm to atm
-!X1 = exp(-5.d0*log(10.d0)) ! Lowest ph-value = 7.7 (phlo)
-!X2 = exp(-9.d0*log(10.d0)) ! Highest ph-value = 9.5 (phhi)
-Xacc = 1.e-12 ! Accuracy for ph-iteration (phacc)
-CO2_for_spinup = 278.d0 ! [uatm] Atmospheric partial pressure of CO2
+permil = 0.000000976 ! DIC conversion: mmol/m³ → mol/kg (1e-3/1024.5)
+permeg = 1.e-6 ! Pressure conversion: µatm → atm
+!X1 = exp(-5.0*log(10.0)) ! Lowest ph-value = 7.7 (phlo)
+!X2 = exp(-9.0*log(10.0)) ! Highest ph-value = 9.5 (phhi)
+Xacc = 1.e-12 ! pH iteration accuracy
+CO2_for_spinup = 278.0 ! Pre-industrial atmospheric pCO₂ [µatm]
/
+! ============================================================================
+! ALKALINITY RESTORING
+! ============================================================================
&paalkalinity_restoring
-surf_relax_Alk = 3.2e-07 !10.d0/31536000.d0
+surf_relax_Alk = 3.2e-07 ! Surface alkalinity relaxation [1/s] = 10 days⁻¹
/
+! ============================================================================
+! BALLASTING AND DENSITY-DEPENDENT SINKING
+! ============================================================================
&paballasting
-rho_POC = 1033.d0 ! kg m-3; density of POC (see Table 1 in Cram et al., 2018)
-rho_PON = 1033.d0 ! kg m-3; density of PON (see Table 1 in Cram et al., 2018)
-rho_CaCO3 = 2830.d0 ! kg m-3; density of CaCO3 (see Table 1 in Cram et al., 2018)
-rho_opal = 2090.d0 ! kg m-3; density of Opal (see Table 1 in Cram et al., 2018)
-rho_ref_part = 1230.d0 ! kg m-3; reference particle density (see Cram et al., 2018)
-rho_ref_water = 1027.d0 ! kg m-3; reference seawater density (see Cram et al., 2018)
-visc_ref_water = 0.00158d0 ! kg m-1 s-1; reference seawater viscosity, at Temp=4 degC (see Cram et al., 2018)
-w_ref1 = 10.d0 ! m s-1; reference sinking velocity of small detritus
-w_ref2 = 200.d0 ! m s-1; reference sinking velocity of large detritus
-depth_scaling1 = 0.015d0 ! s-1; factor to increase sinking speed of det1 with depth, set to 0 if not wanted
-depth_scaling2 = 0.d0 ! s-1; factor to increase sinking speed of det2 with depth, set to 0 if not wanted
-max_sinking_velocity = 250.d0 ! d-1; for numerical stability, set a maximum possible sinking velocity here (applies to both detritus classes)
-/
-
+! --- Particle Densities [kg/m³] ---
+rho_POC = 1033.0 ! POC density
+rho_PON = 1033.0 ! PON density
+rho_CaCO3 = 2830.0 ! Calcite density
+rho_opal = 2090.0 ! Biogenic opal density
+rho_ref_part = 1230.0 ! Reference particle density
+rho_ref_water = 1027.0 ! Reference seawater density
+
+! --- Viscosity and Sinking ---
+visc_ref_water = 0.00158 ! Reference seawater viscosity [kg·m⁻¹·s⁻¹] at 4°C
+w_ref1 = 10.0 ! Reference sinking velocity, small detritus [m/day]
+w_ref2 = 200.0 ! Reference sinking velocity, large detritus [m/day]
+depth_scaling1 = 0.015 ! Depth-dependent increase sinking speed of det1 [1/day]
+depth_scaling2 = 0.0 ! Depth-dependent increase sinking speed of det2 [1/day]
+max_sinking_velocity = 250.0 ! Maximum sinking velocity [m/day] (numerical stability)
+/
+
+! ============================================================================
+! CARBON ISOTOPES (¹³C AND ¹⁴C)
+! ============================================================================
&paciso
-ciso_init = .false. ! initial fractionation of bulk organic matter
-ciso_14 = .false. ! include inorganic radiocarbon
-ciso_organic_14 = .false. ! include organic radiocarbon
-lambda_14 = 3.8561e-12 ! corresponding to 1 year = 365.00 days
-delta_CO2_13 = -6.61 ! atmospheric d13C (permil), global-mean value
+ciso_init = .false. ! Initialize with fractionated organic matter
+ciso_14 = .false. ! Include inorganic radiocarbon (¹⁴C-DIC)
+ciso_organic_14 = .false. ! Include organic radiocarbon (¹⁴C-POC/DOC)
+lambda_14 = 3.8561e-12 ! ¹⁴C decay constant [s⁻¹] (5730 yr half-life)
+delta_CO2_13 = -6.61 ! Atmospheric δ¹³C [‰] (global mean)
+
+! --- Atmospheric Δ¹⁴C
big_delta_CO2_14(1) = 0. ! atmospheric D14C (permil), northern hemisphere polewards of 30°N
big_delta_CO2_14(2) = 0. ! atmospheric D14C (permil), (sub) tropical zone 30°N - 30°S
big_delta_CO2_14(3) = 0. ! atmospheric D14C (permil), southern hemisphere polewards of 30°S
-atbox_spinup = .false.
-cosmic_14_init = 2.0
+atbox_spinup = .false.
+cosmic_14_init = 2.0
/
-
diff --git a/config/bin_2p3z2d/job_albedo b/config/bin_2p3z2d/job_albedo
index 5f3c516e7..23caf2e11 100755
--- a/config/bin_2p3z2d/job_albedo
+++ b/config/bin_2p3z2d/job_albedo
@@ -1,16 +1,15 @@
#!/bin/bash
-#SBATCH --account=nwg_hauck.maresys # edit your account
+#SBATCH --account=biogeo_model.biogeo_model # edit your account
#SBATCH --job-name=recom
#SBATCH --partition=mpp
#SBATCH --time=01:30:00
-####SBATCH --constraint="[rack1|rack3]"
#SBATCH --qos=12h
#SBATCH --nodes=9 # Number of tasks (MPI) tasks to be launched
#SBATCH --tasks-per-node 96 #8 #4 # using all 128CPus we exceed the maxload limit (>130) of many used nodes when us parallel I/O
#SBATCH --cpus-per-task 1
-#SBATCH -o fesom2o.out
-#SBATCH -e fesom2e.out
+#SBATCH -o slurm-out.out
+#SBATCH -e slurm-err.out
# disable hyperthreading
#SBATCH --hint=nomultithread
@@ -35,23 +34,22 @@ cp -n ../config/namelist.icepack .
#___DETERMINE SLURM JOBID+OUTPUTFILE____________________________________________
jobid=$(echo $SLURM_JOB_ID | cut -d"." -f1)
-fname="fesom2_${SLURM_JOB_NAME}_${jobid}.out"
+fname="fesom2.0.out"
#___PUT JOB IN QUEUE____________________________________________________________
date
-####srun --mpi=pmi2 ./fesom.x >> ${fname}
srun --mpi=pmi2 ./fesom.x > fesom2.0.out
date
#qstat -f $PBS_JOBID
#export EXITSTATUS=$?
#if [ ${EXITSTATUS} -eq 0 ] || [ ${EXITSTATUS} -eq 127 ] ; then
-#sbatch job_ollie
+#sbatch job_albedo
#fi
-#Resultpath='/albedo/scratch/user/ogurses/ocean_only/'
-Resultpath='/albedo/scratch/user/ogurses/fesom2.5_recom_st1_vsink_vben_diags_3Zoo2Det_v3/'
-test -d $Resultpath/fesom.2019.oce.restart && exit
+
+Resultpath='/albedo/scratch/user/XXXX/'
+test -e $Resultpath/fesom.XXXX.oce.restart && exit
IsInFile=$( tail -3 fesom2.0.out | grep -c timesteps)
if (( IsInFile > 0 )); then
diff --git a/config/bin_2p3z2d/namelist.config b/config/bin_2p3z2d/namelist.config
index 25c5e4a31..27c3d140a 100644
--- a/config/bin_2p3z2d/namelist.config
+++ b/config/bin_2p3z2d/namelist.config
@@ -1,67 +1,133 @@
-! This is the namelist file for model general configuration
+! ============================================================================
+! ============ Namelist file for FESOM2 general configuration ================
+! ============================================================================
+! This file contains the main configuration parameters for FESOM2, including:
+! - Model identification and run settings
+! - Time stepping and simulation duration
+! - Initial time/date settings
+! - File paths for mesh, forcing, and output
+! - Restart and logging configuration
+! - Vertical coordinate system (ALE)
+! - Grid geometry and rotation
+! - Calendar settings
+! - Model components (ice, cavities, etc.)
+! - Parallel decomposition
+! - Iceberg settings
+! ============================================================================
+! ============================================================================
+! RUN IDENTIFICATION
+! ============================================================================
&modelname
-runid='fesom'
+runid = 'fesom' ! run identifier (used in output filenames)
/
+! ============================================================================
+! TIME STEPPING AND RUN LENGTH
+! ============================================================================
×tep
-step_per_day=32 !96 !96 !72 !72 !45 !72 !96
-run_length=1 !62 !62 !62 !28
-run_length_unit='y' ! y, m, d, s
+step_per_day = 36 ! number of time steps per day (determines dt = 86400/step_per_day seconds)
+ ! common values: 32 (45min), 48 (30min), 72 (20min), 96 (15min), 192 (7min 30sec),
+ ! 216 (6min 40sec), 240 (6min), 288 (5min), 360 (4min), 720 (2min), 1440 (1min), 2880 (30sec)
+run_length = 1 ! total length of simulation run
+run_length_unit = 'y' ! unit for run_length: 'y' (years), 'm' (months), 'd' (days), 's' (steps)
/
-&clockinit ! the model starts at
-timenew=0.0
-daynew=1
-yearnew=1958
+! ============================================================================
+! INITIAL TIME/DATE SETTINGS
+! ============================================================================
+&clockinit
+timenew = 0.0 ! initial time within the day [seconds] (0.0 = midnight)
+daynew = 1 ! initial day of the month (1-31)
+yearnew = 1958 ! initial year
/
+! ============================================================================
+! MESH, INITIALIZATION & OUTPUT PATHS
+! ============================================================================
&paths
-MeshPath='/albedo/work/projects/p_recompdaf/frbunsen/FESOM2/meshes/core2/'
-ClimateDataPath='/albedo/work/projects/MarESys/ogurses/input/corrected_input/'
-ResultPath='/albedo/scratch/user/ogurses/fesom2.5_recom_st1_vsink_vben_diags_3Zoo2Det_v3/'
+MeshPath = '/albedo/work/projects/p_recompdaf/frbunsen/FESOM2/meshes/core2/' ! path to mesh files (nod2d.out, elem2d.out, etc.)
+ClimateDataPath = '/albedo/work/projects/MarESys/ogurses/input/corrected_input/' ! path to initial conditions (temperature, salinity)
+ResultPath = '/albedo/scratch/user/XXXX'
/
+! ============================================================================
+! RESTART AND LOGGING CONFIGURATION
+! ============================================================================
&restart_log
-restart_length=1 ! --> do netcdf restart ( only required for d,h,s cases, y, m take 1)
-restart_length_unit='y' !output period: y, d, h, s, off
-raw_restart_length=1 ! --> do core dump restart
-raw_restart_length_unit='off' ! e.g. y, d, h, s, off
-bin_restart_length=1 ! --> do derived type binary restart
-bin_restart_length_unit='off' ! e.g. y, d, h, s, off
-logfile_outfreq=960 !in logfile info. output frequency, # steps
+restart_length = 1 ! frequency for netCDF restart files (required for d,h,s; y,m use 1)
+restart_length_unit = 'y' ! unit: 'y' (years), 'm' (months), 'd' (days), 'h' (hours), 's' (steps), 'off' (disabled)
+raw_restart_length = 1 ! frequency for raw core dump restart files
+raw_restart_length_unit = 'off' ! unit: 'y', 'm', 'd', 'h', 's', 'off'
+bin_restart_length = 1 ! frequency for binary derived type restart files
+bin_restart_length_unit = 'off' ! unit: 'y', 'm', 'd', 'h', 's', 'off'
+logfile_outfreq = 960 ! log file output frequency [number of time steps]
/
+! ============================================================================
+! VERTICAL COORDINATE SYSTEM (ALE - Arbitrary Lagrangian-Eulerian)
+! ============================================================================
&ale_def
-which_ALE='zstar' ! 'linfs','zlevel', 'zstar'
-use_partial_cell=.true.
+which_ALE = 'zstar' ! vertical coordinate type:
+ ! 'linfs' = linear free surface
+ ! 'zlevel' = z-level (fixed depth levels)
+ ! 'zstar' = z-star (terrain-following with SSH scaling)
+use_partial_cell = .false. ! use partial bottom cells for better topography representation (not recommended)
/
+! ============================================================================
+! GRID GEOMETRY AND ROTATION
+! ============================================================================
&geometry
-cartesian=.false.
-fplane=.false.
-cyclic_length=360 ![degree]
-rotated_grid=.true. !option only valid for coupled model case now
-force_rotation=.true.
-alphaEuler=50. ![degree] Euler angles, convention:
-betaEuler=15. ![degree] first around z, then around new x,
-gammaEuler=-90. ![degree] then around new z.
+cartesian = .false. ! use Cartesian coordinates (false = spherical Earth)
+fplane = .false. ! use f-plane approximation (constant Coriolis parameter)
+cyclic_length = 360 ! length of cyclic domain [degrees] (360 = global)
+rotated_grid = .true. ! use rotated grid (typically for coupled models to avoid pole singularity)
+force_rotation = .true. ! force grid rotation even if not coupled
+alphaEuler = 50. ! first Euler angle (rotation around z-axis) [degrees]
+betaEuler = 15. ! second Euler angle (rotation around new x-axis) [degrees]
+gammaEuler = -90. ! third Euler angle (rotation around new z-axis) [degrees]
+ ! Euler angle convention: rotate first around z, then around new x, then around new z
/
+! ============================================================================
+! CALENDAR SETTINGS
+! ============================================================================
&calendar
-include_fleapyear=.false.
+include_fleapyear = .false. ! include leap years in calendar (false = 365-day year, true = 365/366-day year)
/
+! ============================================================================
+! MODEL COMPONENTS AND FEATURES
+! ============================================================================
&run_config
-use_ice=.true. ! ocean+ice
-use_cavity=.false. !
-use_cavity_partial_cell=.false.
-use_floatice = .false.
-use_sw_pene=.true.
-flag_debug=.false.
+use_ice = .true. ! enable sea ice model
+use_cavity = .false. ! enable ice shelf cavities
+use_cavity_partial_cell = .false. ! use partial cells in ice shelf cavities (not recommended)
+use_floatice = .false. ! enable floating ice (icebergs)
+use_sw_pene = .true. ! enable shortwave radiation penetration into ocean
+flag_debug = .false. ! enable debug output (verbose logging)
+use_transit = .false. ! enable transient tracer module (CFCs, SF6, etc.)
/
+! ============================================================================
+! PARALLEL DECOMPOSITION (DOMAIN PARTITIONING)
+! ============================================================================
&machine
-n_levels=2
-n_part= 12, 36 ! 432 number of partitions on each hierarchy level
+n_levels = 2 ! number of hierarchy levels for domain decomposition
+n_part = 2, 128 ! number of partitions at each level (total CPUs = product of n_part)
+ ! example: 2 x 128 = 256 MPI tasks
+ ! adjust based on mesh size and available compute resources
+ ! maximum scaling reached at ~300 FESOM2 2D nodes per CPU (see first line in nod2d.out for number of 2D nodes)
+/
+
+! ============================================================================
+! ICEBERG SETTINGS
+! ============================================================================
+&icebergs
+use_icesheet_coupling = .false. ! enable ice sheet model
+ib_num = 1 ! number of iceberg classes
+use_icebergs = .false. ! enable iceberg module
+steps_per_ib_step = 8 ! ocean time steps per iceberg time step (iceberg subcycling)
+ib_async_mode = 0 ! iceberg asynchronous mode (0=synchronous, 1=asynchronous)
/
diff --git a/config/bin_2p3z2d/namelist.forcing b/config/bin_2p3z2d/namelist.forcing
index a17799393..d890c69ec 100644
--- a/config/bin_2p3z2d/namelist.forcing
+++ b/config/bin_2p3z2d/namelist.forcing
@@ -23,11 +23,23 @@ ncar_bulk_z_shum=10.0 ! height at which humi forcing is located (CORE, JRA-do: 1
use_landice_water=.false.
landice_start_mon=5
landice_end_mon=10
+fwf_path='./mesh/'
+
+/
+
+&age_tracer
+use_age_tracer=.false.
+use_age_mask=.false.
+age_tracer_path='./mesh/'
+age_start_year=2000
+
/
&nam_sbc
nm_xwind_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/uas.clim61' ! name of file with winds, if nm_sbc=2
nm_ywind_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/vas.clim61' ! name of file with winds, if nm_sbc=2
+ nm_xstre_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/uas.clim61' ! name of file with winds, if nm_sbc=2
+ nm_ystre_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/vas.clim61' ! name of file with winds, if nm_sbc=2
nm_humi_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/huss.clim61' ! name of file with humidity
nm_qsr_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/rsds.clim61' ! name of file with solar heat
nm_qlw_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/rlds.clim61' ! name of file with Long wave
@@ -37,24 +49,32 @@ landice_end_mon=10
nm_mslp_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/psl.clim61' ! air_pressure_at_sea_level
nm_xwind_var = 'uas' ! name of variable in file with wind
nm_ywind_var = 'vas' ! name of variable in file with wind
- nm_humi_var = 'huss' ! name of variable in file with humidity
- nm_qsr_var = 'rsds' ! name of variable in file with solar heat
- nm_qlw_var = 'rlds' ! name of variable in file with Long wave
+ nm_xstre_var = 'uas' ! name of variable in file with wind
+ nm_ystre_var = 'vas' ! name of variable in file with wind
+ nm_humi_var = 'huss' ! name of variable in file with humidity
+ nm_qsr_var = 'rsds' ! name of variable in file with solar heat
+ nm_qlw_var = 'rlds' ! name of variable in file with Long wave
nm_tair_var = 'tas' ! name of variable in file with 2m air temperature
- nm_prec_var = 'prra' ! name of variable in file with total precipitation
- nm_snow_var = 'prsn' ! name of variable in file with total precipitation
- nm_mslp_var = 'psl' ! name of variable in file with air_pressure_at_sea_level
+ nm_prec_var = 'prra' ! name of variable in file with total precipitation
+ nm_snow_var = 'prsn' ! name of variable in file with total precipitation
+ nm_mslp_var = 'psl' ! name of variable in file with air_pressure_at_sea_level
nm_nc_iyear = 1900
nm_nc_imm = 1 ! initial month of time axis in netCDF
nm_nc_idd = 1 ! initial day of time axis in netCDF
nm_nc_freq = 1 ! data points per day (i.e. 86400 if the time axis is in seconds)
nm_nc_tmid = 0 ! 1 if the time stamps are given at the mid points of the netcdf file, 0 otherwise (i.e. 1 in CORE1, CORE2; 0 in JRA55)
y_perpetual=.true.
- l_xwind=.true. l_ywind=.true. l_humi=.true. l_qsr=.true. l_qlw=.true. l_tair=.true. l_prec=.true. l_mslp=.true. l_cloud=.false. l_snow=.true.
+ l_xwind=.true. l_ywind=.true. l_xstre=.false. l_ystre=.false. l_humi=.true. l_qsr=.true. l_qlw=.true. l_tair=.true. l_prec=.true. l_mslp=.true. l_cloud=.false. l_snow=.true.
nm_runoff_file ='/albedo/pool/FESOM/forcing/CORE2/runoff.nc'
runoff_data_source ='CORE2' !Dai09, CORE2
!runoff_data_source ='Dai09' !Dai09, CORE2, JRA55
!runoff_climatology =.true.
- nm_sss_data_file ='/albedo/pool/FESOM/forcing/CORE2/PHC2_salx.nc'
sss_data_source ='CORE2'
+ nm_sss_data_file ='/albedo/pool/FESOM/forcing/CORE2/PHC2_salx.nc'
+ chl_data_source ='None' !'Sweeney' monthly chlorophyll climatology or 'NONE' for constant chl_const (below). Make use_sw_pene=.TRUE. in namelist.config!
+ nm_chl_data_file ='/pool/data/AWICM/FESOM2/FORCING/JRA55-do-v1.4.0/Sweeney/Sweeney_2005.nc'
+ chl_const = 0.1
+ use_runoff_mapper = .FALSE.
+ runoff_basins_file = 'runoff_maps_regular.nc'
+ runoff_radius = 500000.
/
diff --git a/config/bin_2p3z2d/namelist.recom b/config/bin_2p3z2d/namelist.recom
index 24145b956..f04a4a97e 100644
--- a/config/bin_2p3z2d/namelist.recom
+++ b/config/bin_2p3z2d/namelist.recom
@@ -1,355 +1,516 @@
-! This is the namelist file for recom
-
+! ============================================================================
+! ============ Namelist file for REcoM Biogeochemical Model =================
+! ============================================================================
+! Regional Ecosystem Model (REcoM) configuration
+! This file controls biogeochemical processes including:
+! - Carbon, nitrogen, silicon, iron cycling
+! - Phytoplankton (small phyto, diatoms, coccolithophores)
+! - Zooplankton (micro, meso, krill)
+! - Organic matter remineralization and sinking
+! - Carbonate chemistry and air-sea CO2 fluxes
+! - External nutrient inputs (dust, rivers, erosion)
+! ============================================================================
+
+! ============================================================================
+! DATA SOURCES AND INPUT FILES
+! ============================================================================
&nam_rsbc
fe_data_source ='Albani'
nm_fe_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/DustClimMonthlyAlbani.nc'
nm_aen_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/AeolianNitrogenDep.nc'
nm_river_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/RiverineInput.nc'
nm_erosion_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/ErosionInput.nc'
-nm_co2_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/MonthlyAtmCO2_gcb2023.nc'
+nm_co2_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/MonthlyAtmCO2_gcb2024.nc'
/
-&pavariables
-use_REcoM =.true.
-REcoM_restart =.true.
-
-bgc_num = 30 !22 !33 !24 !38
-diags3d_num = 28 ! Number of diagnostic 3d tracers to be saved
-bgc_base_num = 22 ! standard tracers
-VDet = 20.d0 ! Sinking velocity, constant through the water column and positive downwards
-VDet_zoo2 = 200.d0 ! Sinking velocity, constant through the water column
-VPhy = 0.d0 !!! If the number of sinking velocities are different from 3, code needs to be changed !!!
-VDia = 0.d0
-VCocco = 0.d0
-allow_var_sinking = .true.
-biostep = 1 ! Number of times biology should be stepped forward for each time step
-REcoM_Geider_limiter = .false. ! Decides what routine should be used to calculate limiters in sms
-REcoM_Grazing_Variable_Preference = .true. ! Decides if grazing should have preference for phyN or DiaN
-Grazing_detritus = .true.
-het_resp_noredfield = .true. ! Decides respiratation of copepod group
-diatom_mucus = .true. ! Decides nutrient limitation effect on aggregation
-O2dep_remin = .false. ! O2remin Add option for O2 dependency of organic matter remineralization
-use_ballasting = .false. ! BALL
-use_density_scaling = .false. ! BALL
-use_viscosity_scaling = .false. ! BALL
-OmegaC_diss = .false. ! DISS Use OmegaC from Mocsy to compute calcite dissolution (after Aumont et al. 2015 and Gehlen et al. 2007)
-CO2lim = .false. ! CO2 dependence of growth and calcification
-Diags = .true.
-constant_CO2 = .true.
-UseFeDust = .true. ! Turns dust input of iron off when set to.false.
-UseDustClim = .true.
-UseDustClimAlbani = .true. ! Use Albani dustclim field (If it is false Mahowald will be used)
-use_photodamage = .true. ! use Alvarez et al (2018) for chlorophyll degradation
-HetRespFlux_plus = .true. !MB More stable computation of zooplankton respiration fluxes adding a small number to HetN
-REcoMDataPath = '/albedo/work/projects/MarESys/ogurses/input/mesh_CORE2_finaltopo_mean/'
-restore_alkalinity = .true.
-useRivers = .false.
-useRivFe = .false. ! When set to true, riverine Fe source is activated
-useErosion = .false.
-NitrogenSS = .false. ! When set to true, external sources and sinks of nitrogen are activated (Riverine, aeolian and denitrification)
-useAeolianN = .false. ! When set to true, aeolian nitrogen deposition is activated
-firstyearoffesomcycle = 1958 ! The first year of the actual physical forcing (e.g. JRA-55) used
-lastyearoffesomcycle = 2022 ! Last year of the actual physical forcing used
-numofCO2cycles = 1 ! Number of cycles of the forcing planned
-currentCO2cycle = 1 ! Which CO2 cycle we are currently running
-DIC_PI = .true.
-Nmocsy = 1 ! Length of the vector that is passed to mocsy (always one for recom)
-recom_debug =.false.
-ciso =.false. ! Main switch to enable/disable carbon isotopes (13|14C)
-benthos_num = 4 ! number of benthic BGC tracers -> 8 if (ciso == .true.) otherwise -> 4
-use_MEDUSA = .false. ! Main switch for the sediment model MEDUSA
-sedflx_num = 0 ! if 0: no file from MEDUSA is read but default sediment
-bottflx_num = 4 ! if ciso&ciso_14: =8; if .not.ciso_14: =6; no ciso: =4
-use_atbox = .false.
-add_loopback = .false. ! add loopback fluxes through rivers to the surface
-lb_tscale = 1.0 ! /year: fraction of loopback fluxes yearly added to the surface
+! ============================================================================
+! GENERAL MODEL CONFIGURATION
+! ============================================================================
+&parecomsetup
+enable_3zoo2det = .true. ! Enable 3 zooplankton + 2 detritus configuration
+enable_coccos = .false. ! Enable coccolithophores (currently disabled)
/
+! ============================================================================
+! MAIN MODEL SWITCHES AND SETTINGS
+! ============================================================================
+! --- Core Model Settings ---
+&pavariables
+use_REcoM = .true.
+REcoM_restart = .true.
+recom_debug = .false.
+
+! --- Tracer Configuration ---
+bgc_num = 30 ! Total number of BGC tracers
+diags3d_num = 28 ! Number of diagnostic 3D tracers
+bgc_base_num = 22 ! Number of standard tracers
+benthos_num = 4 ! Number of benthic BGC tracers (8 if ciso=.true., else 4)
+sedflx_num = 0 ! Sediment fluxes from MEDUSA (0 = use defaults)
+bottflx_num = 4 ! Bottom fluxes (8 if ciso & ciso_14, 6 if not ciso_14, 4 otherwise)
+
+! --- Sinking Velocities [m/day] ---
+VDet = 20.0 ! Small detritus sinking velocity (constant, positive down)
+VDet_zoo2 = 200.0 ! Large detritus sinking velocity
+VPhy = 0.0 ! Small phytoplankton (non-sinking)
+VDia = 0.0 ! Diatoms (variable sinking if allow_var_sinking=.true.)
+VCocco = 0.0 ! Coccolithophores
+allow_var_sinking = .true. ! Enable variable sinking velocity
+
+! --- Time Stepping ---
+biostep = 1 ! Number of biology sub-steps per physical time step
+
+! --- Process Switches ---
+REcoM_Geider_limiter = .false. ! Use Geider limiter for nutrient limitation
+REcoM_Grazing_Variable_Preference = .true. ! Variable grazing preference (PhyN vs DiaN)
+Grazing_detritus = .true. ! Enable zooplankton grazing on detritus
+het_resp_noredfield = .true. ! Non-Redfield respiration for copepods
+diatom_mucus = .true. ! Nutrient-limited diatom aggregation
+O2dep_remin = .true. ! O2-dependent organic matter remineralization
+use_ballasting = .true. ! Ballast effect on sinking
+use_density_scaling = .true. ! Density-dependent sinking
+use_viscosity_scaling = .true. ! Viscosity-dependent sinking
+OmegaC_diss = .false. ! OmegaC-dependent calcite dissolution (set calc_diss_guts=0 if false)
+CO2lim = .true. ! CO2 effects on growth and calcification
+use_photodamage = .true. ! Chlorophyll photodamage (Alvarez et al. 2018)
+HetRespFlux_plus = .true. ! Stabilized zooplankton respiration computation
+Diags = .true. ! Enable diagnostics output
+
+! --- External Inputs ---
+constant_CO2 = .true.
+UseFeDust = .true. ! Enable iron input from dust
+UseDustClim = .true. ! Use dust climatology
+UseDustClimAlbani = .true. ! Use Albani dust fields (false = Mahowald)
+useRivers = .false. ! Enable riverine inputs
+useRivFe = .false. ! Enable riverine iron source
+useErosion = .false. ! Enable erosion inputs
+NitrogenSS = .false. ! Enable nitrogen sources/sinks (rivers, aeolian, denitrification)
+useAeolianN = .false. ! Enable aeolian nitrogen deposition
+
+! --- Time Period Configuration ---
+firstyearoffesomcycle = 1958 ! First year of physical forcing (e.g., JRA-55)
+lastyearoffesomcycle = 2024 ! Last year of physical forcing
+numofCO2cycles = 1 ! Number of forcing cycles
+currentCO2cycle = 1 ! Current forcing cycle number
+
+! --- Alkalinity and Carbon ---
+DIC_PI = .true. ! Use pre-industrial DIC
+restore_alkalinity = .true. ! Restore surface alkalinity
+Nmocsy = 1 ! Vector length for mocsy (always 1 for REcoM)
+
+! --- Data Path ---
+REcoMDataPath = '/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/'
+
+! --- Carbon Isotopes ---
+ciso = .false. ! Enable carbon isotopes (13C, 14C)
+
+! --- Sediment Model ---
+use_MEDUSA = .false. ! Enable MEDUSA sediment model
+add_loopback = .false. ! Add loopback fluxes through rivers
+lb_tscale = 1.0 ! Loopback timescale [1/year]
+
+! --- Miscellaneous ---
+use_atbox = .false. ! Use atmospheric box model
+/
+
+! ============================================================================
+! SINKING VELOCITY PARAMETERS
+! ============================================================================
&pasinking
-Vdet_a = 0.0288 ! [1/day]
-Vcalc = 0.0144 ! [1/day]
+Vdet_a = 0.0288 ! Slope of the linearly increasing sinking velocity [1/day]
+Vcalc = 0.0144 ! Depth dependence of calcite dissolution (when use_coccos disabled) [1/day]
/
+! ============================================================================
+! INITIAL CONDITIONS
+! ============================================================================
&painitialization_N
-cPhyN = 0.2d0
-cHetN = 0.2d0
-cZoo2N = 0.2d0
+cPhyN = 0.2 ! Initial small phytoplankton nitrogen [mmol N/m³]
+cHetN = 0.2 ! Initial microzooplankton nitrogen [mmol N/m³]
+cZoo2N = 0.2 ! Initial mesozooplankton nitrogen [mmol N/m³]
/
+! ============================================================================
+! TEMPERATURE DEPENDENCE (ARRHENIUS)
+! ============================================================================
&paArrhenius
-recom_Tref = 288.15d0 ! [K]
-C2K = 273.15d0 ! Conversion from degrees C to K
-Ae = 4500.d0 ! [K] Slope of the linear part of the Arrhenius function
-reminSi = 0.02d0
-k_o2_remin = 15.d0 ! NEW O2remin mmol m-3; Table 1 in Cram 2018 cites DeVries & Weber 2017 for a range of 0-30 mmol m-3
+recom_Tref = 288.15 ! Reference temperature [K]
+C2K = 273.15 ! Celsius to Kelvin conversion
+Ae = 4500.0 ! Arrhenius slope [K]
+reminSi = 0.02 ! Silicate remineralization base rate [1/day]
+k_o2_remin = 15.0 ! Half-saturation for O2 remineralization [mmol O2/m³]
/
&palimiter_function
-NMinSlope = 50.d0
-SiMinSlope = 1000.d0
-NCmin = 0.04d0 !0.05d0
-NCmin_d = 0.04d0 !0.05d0
-NCmin_c = 0.04d0 ! NEW
-SiCmin = 0.04d0
-k_Fe = 0.04d0
-k_Fe_d = 0.12d0
-k_Fe_c = 0.09d0 ! NEW
-k_si = 4.d0
-P_cm = 3.0d0 ! [1/day] Rate of C-specific photosynthesis
-P_cm_d = 3.5d0
-P_cm_c = 2.8d0 ! NEW
-/
-
+! --- Limitation Function Slopes ---
+NMinSlope = 50.0 ! Nitrogen minimum slope
+SiMinSlope = 1000.0 ! Silicon minimum slope
+
+! --- Minimum Quotas [mmol/mmol C] ---
+NCmin = 0.04 ! Small phytoplankton N:C minimum
+NCmin_d = 0.04 ! Diatom N:C minimum
+NCmin_c = 0.04 ! Coccolithophore N:C minimum
+SiCmin = 0.04 ! Diatom Si:C minimum
+
+! --- Half-Saturation Constants ---
+k_Fe = 0.04 ! Small phyto iron half-sat [µmol Fe/m³]
+k_Fe_d = 0.12 ! Diatom iron half-sat [µmol Fe/m³]
+k_Fe_c = 0.09 ! Coccolith iron half-sat [µmol Fe/m³]
+k_si = 4.0 ! Silicon half-sat [mmol Si/m³]
+
+! --- Maximum Photosynthesis Rates [1/day] ---
+P_cm = 3.0 ! Small phytoplankton max C-specific photosynthesis
+P_cm_d = 3.5 ! Diatom max C-specific photosynthesis
+P_cm_c = 2.8 ! Coccolithophore max C-specific photosynthesis
+/
+
+! ============================================================================
+! LIGHT ATTENUATION
+! ============================================================================
&palight_calculations
-k_w = 0.04d0 ! [1/m] Light attenuation coefficient
-a_chl = 0.03d0 ! [1/m * 1/(mg Chl)] Chlorophyll specific attenuation coefficients
+k_w = 0.04 ! Water attenuation coefficient [1/m]
+a_chl = 0.03 ! Chlorophyll-specific attenuation [1/m per mg Chl/m³]
/
+! ============================================================================
+! PHOTOSYNTHESIS (P-I CURVE)
+! ============================================================================
&paphotosynthesis
-alfa = 0.14d0 ! [(mmol C*m2)/(mg Chl*W*day)]
-alfa_d = 0.19d0 ! An initial slope of the P-I curve
-alfa_c = 0.10d0 ! NEW
-parFrac = 0.43d0
+alfa = 0.14 ! Small phyto initial P-I slope [(mmol C·m²)/(mg Chl·W·day)]
+alfa_d = 0.19 ! Diatom initial P-I slope
+alfa_c = 0.10 ! Coccolithophore initial P-I slope
+parFrac = 0.43 ! Fraction of shortwave that is PAR
/
+! ============================================================================
+! NUTRIENT ASSIMILATION
+! ============================================================================
&paassimilation
-V_cm_fact = 0.7d0 ! scaling factor for temperature dependent maximum of C-specific N-uptake
-V_cm_fact_d = 0.7d0
-V_cm_fact_c = 0.7d0 ! NEW
-NMaxSlope = 1000.d0 ! Max slope for limiting function
-SiMaxSlope = 1000.d0
-NCmax = 0.2d0 ! [mmol N/mmol C] Maximum cell quota of nitrogen (N:C)
-NCmax_d = 0.2d0
-NCmax_c = 0.15d0 ! NEW
-SiCmax = 0.8d0
-NCuptakeRatio = 0.2d0 ! [mmol N/mmol C] Maximum uptake ratio of N:C
-NCUptakeRatio_d = 0.2d0
-NCUptakeRatio_c = 0.2d0 ! NEW
-SiCUptakeRatio = 0.2d0
-k_din = 0.55d0 ! [mmol N/m3] Half-saturation constant for nitrate uptake
-k_din_d = 1.0d0
-k_din_c = 0.9d0 ! NEW
-Chl2N_max = 3.15d0 ! [mg CHL/mmol N] Maximum CHL a : N ratio = 0.3 gCHL gN^-1
-Chl2N_max_d = 4.2d0
-Chl2N_max_c = 3.5d0 ! NEW
-res_phy = 0.01d0 ! [1/day] Maintenance respiration rate constant
-res_phy_d = 0.01d0
-res_phy_c = 0.01d0 ! NEW
-biosynth = 2.33d0 ! [mmol C/mmol N] Cost of biosynthesis
-biosynthSi = 0.d0
-/
-
+! --- Maximum Uptake Scaling ---
+V_cm_fact = 0.7 ! Small phyto N-uptake scaling factor
+V_cm_fact_d = 0.7 ! Diatom N-uptake scaling factor
+V_cm_fact_c = 0.7 ! Coccolithophore N-uptake scaling factor
+
+! --- Limitation Function Slopes ---
+NMaxSlope = 1000.0 ! Nitrogen maximum slope
+SiMaxSlope = 1000.0 ! Silicon maximum slope
+
+! --- Maximum Cell Quotas [mmol/mmol C] ---
+NCmax = 0.2 ! Small phyto maximum N:C
+NCmax_d = 0.2 ! Diatom maximum N:C
+NCmax_c = 0.15 ! Coccolithophore maximum N:C
+SiCmax = 0.8 ! Diatom maximum Si:C
+
+! --- Maximum Uptake Ratios [mmol/mmol C] ---
+NCuptakeRatio = 0.2 ! Small phyto N:C uptake ratio
+NCUptakeRatio_d = 0.2 ! Diatom N:C uptake ratio
+NCUptakeRatio_c = 0.2 ! Coccolithophore N:C uptake ratio
+SiCUptakeRatio = 0.2 ! Diatom Si:C uptake ratio
+
+! --- Chlorophyll Parameters ---
+Chl2N_max = 3.15 ! Small phyto max Chl:N [mg Chl/mmol N]
+Chl2N_max_d = 4.2 ! Diatom max Chl:N [mg Chl/mmol N]
+Chl2N_max_c = 3.5 ! Coccolithophore max Chl:N [mg Chl/mmol N]
+
+! --- Half-Saturation Constants ---
+k_din = 0.55 ! Small phyto nitrate half-sat [mmol N/m³]
+k_din_d = 1.0 ! Diatom nitrate half-sat [mmol N/m³]
+k_din_c = 0.9 ! Coccolith nitrate half-sat [mmol N/m³]
+
+! --- Respiration and Biosynthesis ---
+res_phy = 0.01 ! Small phyto maintenance respiration [1/day]
+res_phy_d = 0.01 ! Diatom maintenance respiration [1/day]
+res_phy_c = 0.01 ! Coccolithophore maintenance respiration [1/day]
+biosynth = 2.33 ! Cost of biosynthesis [mmol C/mmol N]
+biosynthSi = 0.0 ! Silicon biosynthesis cost [mmol C/mmol Si]
+/
+
+! ============================================================================
+! IRON CHEMISTRY
+! ============================================================================
&pairon_chem
-totalligand = 1.d0 ! [mumol/m3] order 1. Total free ligand
-ligandStabConst = 100.d0 ! [m3/mumol] order 100. Ligand-free iron stability constant
+totalligand = 1.0 ! Total free ligand concentration [µmol/m³]
+ligandStabConst = 100.0 ! Ligand-Fe stability constant [m³/µmol]
/
+! ============================================================================
+! MICROZOOPLANKTON (FIRST ZOOPLANKTON)
+! ============================================================================
&pazooplankton
-graz_max = 0.31d0 ! [mmol N/(m3 * day)] Maximum grazing loss parameter
-epsilonr = 0.09d0 ! [(mmol N)2 /m6] Half saturation constant for grazing loss
-res_het = 0.028d0 ! [1/day] Respiration by heterotrophs and mortality (loss to detritus)
-Redfield = 6.625 ! [mmol C/mmol N] Redfield ratio of C:N = 106:16
-loss_het = 0.04d0 ! [1/day] Temperature dependent N degradation of extracellular organic N (EON)
-pzDia = 1.0d0 !0.5d0 ! Maximum diatom preference
-sDiaNsq = 0.d0
-pzPhy = 0.5d0 !0.25d0 !1.0d0 ! Maximum nano-phytoplankton preference (NEW: 3/12)
-sPhyNsq = 0.d0
-pzCocco = 0.666d0 ! NEW (8/12)
-sCoccoNsq = 0.d0 ! NEW
-pzMicZoo = 1.0d0 ! NEW 3Zoo Maximum nano-phytoplankton preference
-sMicZooNsq = 0.d0 ! NEW 3Zoo
-tiny_het = 1.d-5 ! for more stable computation of HetRespFlux (_plus). Value can be > tiny because HetRespFlux ~ hetC**2.
-/
-
+graz_max = 0.31 ! Maximum grazing rate [1/day]
+epsilonr = 0.09 ! Half-saturation constant [(mmol N)²/m⁶]
+res_het = 0.028 ! Respiration + mortality [1/day]
+Redfield = 6.625 ! C:N Redfield ratio [mmol C/mmol N]
+loss_het = 0.04 ! Extracellular N degradation [1/day]
+tiny_het = 1.d-5 ! Small number for stable computation
+
+! --- Grazing Preferences ---
+pzDia = 0.5 ! Diatom preference (maximum)
+sDiaNsq = 0.0 ! Diatom preference slope
+pzPhy = 0.04 ! Small phyto preference
+sPhyNsq = 0.0 ! Small phyto preference slope
+pzCocco = 0.4 ! Coccolithophore preference (unused in 2p3z3d)
+sCoccoNsq = 0.0 ! Coccolithophore preference slope
+pzMicZoo = 1.0 ! Microzooplankton preference (self-grazing)
+sMicZooNsq = 0.0 ! Microzooplankton preference slope
+/
+
+! ============================================================================
+! MESOZOOPLANKTON (SECOND ZOOPLANKTON)
+! ============================================================================
&pasecondzooplankton
-graz_max2 = 0.1d0 ! [mmol N/(m3 * day)] Maximum grazing loss parameter
-epsilon2 = 0.0144d0 ! [(mmol N)2 /m6] Half saturation constant for grazing loss
-res_zoo2 = 0.0107d0 ! [1/day] Respiration by heterotrophs and mortality (loss to detritus)
-loss_zoo2 = 0.003d0 ! [1/day] Temperature dependent N degradation of extracellular organic N (EON)
-fecal_rate_n = 0.104d0 ! [1/day] Temperature dependent N degradation of \
-fecal_rate_c = 0.236d0
-fecal_rate_n_mes = 0.25d0 ! NEW 3Zoo
-fecal_rate_c_mes = 0.32d0 ! NEW 3Zoo
-pzDia2 = 1.5d0 !1.d0 ! Maximum diatom preference
-sDiaNsq2 = 0.d0
-pzPhy2 = 0.5d0 ! Maximum diatom preference
-sPhyNsq2 = 0.d0
-pzCocco2 = 0.5d0 ! NEW
-sCoccoNsq2 = 0.d0 ! NEW
-pzHet = 1.5d0 !0.8d0 ! Maximum diatom preference
-sHetNsq = 0.d0
-pzMicZoo2 = 1.0d0 ! NEW 3Zoo Maximum nano-phytoplankton preference
-sMicZooNsq2 = 0.d0
-t1_zoo2 = 28145.d0 ! Krill temp. function constant1
-t2_zoo2 = 272.5d0 ! Krill temp. function constant2
-t3_zoo2 = 105234.d0 ! Krill temp. function constant3
-t4_zoo2 = 274.15d0 ! Krill temp. function constant3
-/
-
+graz_max2 = 0.1 ! Maximum grazing rate [1/day]
+epsilon2 = 0.0144 ! Half-saturation constant [(mmol N)²/m⁶]
+res_zoo2 = 0.0107 ! Respiration + mortality [1/day]
+loss_zoo2 = 0.003 ! Extracellular N degradation [1/day]
+
+! --- Fecal Pellet Production ---
+fecal_rate_n = 0.104 ! Nitrogen fecal rate [1/day]
+fecal_rate_c = 0.236 ! Carbon fecal rate [1/day]
+fecal_rate_n_mes = 0.25 ! Mesozooplankton N fecal rate [1/day]
+fecal_rate_c_mes = 0.32 ! Mesozooplankton C fecal rate [1/day]
+
+! --- Grazing Preferences ---
+pzDia2 = 1.0 ! Diatom preference
+sDiaNsq2 = 0.0 ! Diatom preference slope
+pzPhy2 = 0.07 ! Small phyto preference
+sPhyNsq2 = 0.0 ! Small phyto preference slope
+pzCocco2 = 0.7 ! Coccolithophore preference (unused)
+sCoccoNsq2 = 0.0 ! Coccolithophore preference slope
+pzHet = 1.5 ! Microzooplankton preference
+sHetNsq = 0.0 ! Microzooplankton preference slope
+pzMicZoo2 = 1.0 ! Mesozooplankton preference
+sMicZooNsq2 = 0.0 ! Mesozooplankton preference slope
+
+! --- Temperature Function (Krill-specific) ---
+t1_zoo2 = 28145.0 ! Temperature function constant 1
+t2_zoo2 = 272.5 ! Temperature function constant 2 [K]
+t3_zoo2 = 105234.0 ! Temperature function constant 3
+t4_zoo2 = 274.15 ! Temperature function constant 4 [K]
+/
+
+! ============================================================================
+! MICROZOOPLANKTON (THIRD ZOOPLANKTON)
+! ============================================================================
&pathirdzooplankton
-graz_max3 = 0.46d0 ! NEW 3Zoo [mmol N/(m3 * day)] Maximum grazing loss parameter
-epsilon3 = 0.64d0 ! NEW 3Zoo [(mmol N)2 /m6] Half saturation constant for grazing loss
-loss_miczoo = 0.01d0 ! NEW 3Zoo [1/day] Temperature dependent N degradation of extracellular organic N (EON)
-res_miczoo = 0.01d0 ! NEW 3Zoo [1/day] Respiration by heterotrophs and mortality (loss to detritus)
-pzDia3 = 0.5d0 ! NEW 3Zoo Maximum diatom preference
-sDiaNsq3 = 0.d0 ! NEW 3Zoo
-pzPhy3 = 1.0d0 ! NEW 3Zoo Maximum nano-phytoplankton preference
-sPhyNsq3 = 0.d0 ! NEW 3Zoo
-pzCocco3 = 0.d0 ! NEW 3Zoo Maximum coccolithophore preference ! ATTENTION: This value needs to be tuned; I start with zero preference!
-sCoccoNsq3 = 0.d0 ! NEW 3Zoo
-/
-
+graz_max3 = 0.46 ! Maximum grazing rate [1/day]
+epsilon3 = 0.64 ! Half-saturation constant [(mmol N)²/m⁶]
+loss_miczoo = 0.01 ! Extracellular N degradation [1/day]
+res_miczoo = 0.02 ! Respiration + mortality [1/day]
+
+! --- Grazing Preferences ---
+pzDia3 = 0.04 ! Diatom preference
+sDiaNsq3 = 0.0 ! Diatom preference slope
+pzPhy3 = 0.07 ! Small phyto preference
+sPhyNsq3 = 0.0 ! Small phyto preference slope
+pzCocco3 = 0.7 ! Coccolithophore preference (unused)
+sCoccoNsq3 = 0.0 ! Coccolithophore preference slope
+/
+
+! ============================================================================
+! GRAZING ON DETRITUS
+! ============================================================================
&pagrazingdetritus
-pzDet = 0.5d0 ! Maximum small detritus prefence by first zooplankton
-sDetNsq = 0.d0
-pzDetZ2 = 0.5d0 ! Maximum large detritus preference by first zooplankton
-sDetZ2Nsq = 0.d0
-pzDet2 = 0.5d0 ! Maximum small detritus prefence by second zooplankton
-sDetNsq2 = 0.d0
-pzDetZ22 = 0.5d0 ! Maximum large detritus preference by second zooplankton
-sDetZ2Nsq2 = 0.d0
-/
-
+! --- First Zooplankton (Microzooplankton) ---
+pzDet = 0.5 ! Small detritus preference
+sDetNsq = 0.0 ! Small detritus preference slope
+pzDetZ2 = 0.5 ! Large detritus preference
+sDetZ2Nsq = 0.0 ! Large detritus preference slope
+
+! --- Second Zooplankton (Mesozooplankton) ---
+pzDet2 = 0.5 ! Small detritus preference
+sDetNsq2 = 0.0 ! Small detritus preference slope
+pzDetZ22 = 0.5 ! Large detritus preference
+sDetZ2Nsq2 = 0.0 ! Large detritus preference slope
+/
+
+! ============================================================================
+! AGGREGATION
+! ============================================================================
&paaggregation
-agg_PD = 0.165d0 ! [m3/(mmol N * day)] Maximum aggregation loss parameter for DetN
-agg_PP = 0.015d0 ! [m3/(mmol N * day)] Maximum aggregation loss parameter for PhyN and DiaN (plankton)
+agg_PD = 0.165 ! Detritus aggregation rate [m³/(mmol N·day)]
+agg_PP = 0.015 ! Plankton aggregation rate [m³/(mmol N·day)]
/
+! ============================================================================
+! DISSOLVED ORGANIC MATTER REMINERALIZATION
+! ============================================================================
&padin_rho_N
-rho_N = 0.11d0 ! [1/day] Temperature dependent N degradation of extracellular organic N (EON) (Remineralization of DON)
+rho_N = 0.11 ! DON remineralization rate [1/day]
+rho_Nt = 0.67d0 ! [1/day] terrestrial N degradation of extracellular organic N (DONt) (Remineralization of terrestrial DON) ~ scale of 1.5 years ! R2OMIP
/
&padic_rho_C1
-rho_C1 = 0.1d0 ! [1/day] Temperature dependent C degradation of extracellular organic C (EOC)
+rho_C1 = 0.1 ! DOC remineralization rate [1/day]
/
+! ============================================================================
+! PHYTOPLANKTON LOSSES
+! ============================================================================
&paphytoplankton_N
-lossN = 0.05d0 ! [1/day] Phytoplankton loss of organic N compounds
-lossN_d = 0.05d0
-lossN_c = 0.05d0 ! NEW
+lossN = 0.05 ! Small phyto N loss rate [1/day]
+lossN_d = 0.05 ! Diatom N loss rate [1/day]
+lossN_c = 0.05 ! Coccolithophore N loss rate [1/day]
/
&paphytoplankton_C
-lossC = 0.10d0 ! [1/day] Phytoplankton loss of carbon
-lossC_d = 0.10d0
-lossC_c = 0.10d0 ! NEW
+lossC = 0.10 ! Small phyto C loss rate [1/day]
+lossC_d = 0.10 ! Diatom C loss rate [1/day]
+lossC_c = 0.10 ! Coccolithophore C loss rate [1/day]
/
&paphytoplankton_ChlA
-deg_Chl = 0.25d0 !0.2d0 !0.25d0 ! [1/day]
-deg_Chl_d = 0.15d0 !0.2d0 !0.15d0
-deg_Chl_c = 0.2d0 ! NEW (has been 0.5)
+deg_Chl = 0.25 !0.2 !0.25 ! Small phyto Chl degradation [1/day]
+deg_Chl_d = 0.15 !0.2 !0.15 ! Diatom Chl degradation [1/day]
+deg_Chl_c = 0.2 ! Coccolithophore Chl degradation [1/day]
/
+! ============================================================================
+! DETRITUS REMINERALIZATION
+! ============================================================================
&padetritus_N
-gfin = 0.3d0 ! NEW 3Zoo [] Grazing efficiency (fraction of grazing flux into zooplankton pool)
-grazEff2 = 0.8d0 ! [] Grazing efficiency (fraction of grazing flux into second zooplankton pool)
-grazEff3 = 0.8d0 ! NEW 3Zoo [] Grazing efficiency (fraction of grazing flux into microzooplankton pool)
-reminN = 0.165d0 ! [1/day] Temperature dependent remineralisation rate of detritus
+gfin = 0.3 ! First zooplankton grazing efficiency
+grazEff2 = 0.8 ! Second zooplankton grazing efficiency
+grazEff3 = 0.8 ! Third zooplankton grazing efficiency
+reminN = 0.165 ! Detritus N remineralization rate [1/day]
/
&padetritus_C
-reminC = 0.15d0 ! [1/day] Temperature dependent remineralisation rate of detritus
-rho_c2 = 0.1d0 ! [1/day] Temperature dependent C degradation of TEP-C
+reminC = 0.15 ! Detritus C remineralization rate [1/day]
+rho_c2 = 0.1 ! TEP-C degradation rate [1/day]
/
+! ============================================================================
+! ZOOPLANKTON LOSSES
+! ============================================================================
&paheterotrophs
-lossN_z = 0.1d0
-lossC_z = 0.1d0
+lossN_z = 0.1 ! First zooplankton N loss [1/day]
+lossC_z = 0.1 ! First zooplankton C loss [1/day]
/
&paseczooloss
-lossN_z2 = 0.02d0
-lossC_z2 = 0.02d0
+lossN_z2 = 0.02 ! Second zooplankton N loss [1/day]
+lossC_z2 = 0.02 ! Second zooplankton C loss [1/day]
/
&pathirdzooloss
-lossN_z3 = 0.05d0 ! NEW 3Zoo
-lossC_z3 = 0.05d0 ! NEW 3Zoo
-/
-
-&paco2lim ! NEW
-Cunits = 976.5625 ! Conversion factor between [mol/m3] (model) and [umol/kg] (function): (1000 * 1000) / 1024
-a_co2_phy = 1.162e+00 ! [dimensionless]
-a_co2_dia = 1.040e+00 ! [dimensionless]
-a_co2_cocco = 1.109e+00 ! [dimensionless]
-a_co2_calc = 1.102e+00 ! [dimensionless]
-b_co2_phy = 4.888e+01 ! [mol/kg]
-b_co2_dia = 2.890e+01 ! [mol/kg]
-b_co2_cocco = 3.767e+01 ! [mol/kg]
-b_co2_calc = 4.238e+01 ! [mol/kg]
-c_co2_phy = 2.255e-01 ! [kg/mol]
-c_co2_dia = 8.778e-01 ! [kg/mol]
-c_co2_cocco = 3.912e-01 ! [kg/mol]
-c_co2_calc = 7.079e-01 ! [kg/mol]
-d_co2_phy = 1.023e+07 ! [kg/mol]
-d_co2_dia = 2.640e+06 ! [kg/mol]
-d_co2_cocco = 9.450e+06 ! [kg/mol]
-d_co2_calc = 1.343e+07 ! [kg/mol]
+lossN_z3 = 0.05 ! Third zooplankton N loss [1/day]
+lossC_z3 = 0.05 ! Third zooplankton C loss [1/day]
+/
+
+! ============================================================================
+! CO2 LIMITATION PARAMETERS
+! ============================================================================
+&paco2lim
+Cunits = 976.5625 ! Unit conversion factor: mol/m³ → µmol/kg
+
+! --- Small Phytoplankton ---
+a_co2_phy = 1.162e+00 ! Dimensionless
+b_co2_phy = 4.888e+01 ! [mol/kg]
+c_co2_phy = 2.255e-01 ! [kg/mol]
+d_co2_phy = 1.023e+07 ! [kg/mol]
+
+! --- Diatoms ---
+a_co2_dia = 1.040e+00 ! Dimensionless
+b_co2_dia = 2.890e+01 ! [mol/kg]
+c_co2_dia = 8.778e-01 ! [kg/mol]
+d_co2_dia = 2.640e+06 ! [kg/mol]
+
+! --- Coccolithophores ---
+a_co2_cocco = 1.109e+00 ! Dimensionless (growth)
+b_co2_cocco = 3.767e+01 ! [mol/kg] (growth)
+c_co2_cocco = 3.912e-01 ! [kg/mol] (growth)
+d_co2_cocco = 9.450e+06 ! [kg/mol] (growth)
+
+a_co2_calc = 1.102e+00 ! Dimensionless (calcification)
+b_co2_calc = 4.238e+01 ! [mol/kg] (calcification)
+c_co2_calc = 7.079e-01 ! [kg/mol] (calcification)
+d_co2_calc = 1.343e+07 ! [kg/mol] (calcification)
/
&pairon
-Fe2N = 0.033d0 ! Fe2C * 6.625
-Fe2N_benthos = 0.15d0 ! test, default was 0.14 Fe2C_benthos * 6.625 - will have to be tuned. [umol/m2/day]
-kScavFe = 0.07d0
-dust_sol = 0.02d0 ! Dissolution of Dust for bioavaliable
-RiverFeConc = 100
+Fe2N = 0.033 ! Iron to nitrogen ratio (= Fe2C × 6.625)
+Fe2N_benthos = 0.15 ! Benthic flux ratio [micromol Fe : mmol N,]
+kScavFe = 0.07 ! Iron scavenging rate [1/day]
+dust_sol = 0.02 ! Dust iron solubility fraction
+RiverFeConc = 100 ! Riverine iron concentration [µmol/m³]
/
+! ============================================================================
+! CALCITE PRODUCTION AND DISSOLUTION
+! ============================================================================
&pacalc
-calc_prod_ratio = 0.02
-calc_diss_guts = 0.0d0
-calc_diss_rate = 0.005714 ! 20.d0/3500.d0
-calc_diss_rate2 = 0.005714d0
-calc_diss_omegac = 0.197d0 ! NEW DISS Value from Aumont et al. 2015, will be used with OmegaC_diss flag
-calc_diss_exp = 1.d0 ! NEW DISS Exponent in the dissolution rate of calcite, will be used with OmegaC_diss flag
+calc_prod_ratio = 0.02 ! Calcite production ratio (CaCO₃:POC)
+calc_diss_guts = 0.0 ! Gut dissolution fraction (set to 0 if OmegaC_diss=.false.)
+calc_diss_rate = 0.005714 ! Standard dissolution rate [1/day] = 20/3500
+calc_diss_rate2 = 0.005714 ! Standard dissolution rate [1/day]
+calc_diss_omegac = 0.197 ! Critical Ω_calcite (Aumont et al. 2015)
+calc_diss_exp = 1.0 ! Dissolution rate exponent
/
+! ============================================================================
+! BENTHIC PROCESSES
+! ============================================================================
&pabenthos_decay_rate
-decayRateBenN = 0.005d0
-decayRateBenC = 0.005d0
-decayRateBenSi = 0.005d0
-q_NC_Denit = 0.86d0 ! N:C quota of the denitrification process
+decayRateBenN = 0.005 ! Benthic N decay rate [1/day]
+decayRateBenC = 0.005 ! Benthic C decay rate [1/day]
+decayRateBenSi = 0.005 ! Benthic Si decay rate [1/day]
+q_NC_Denit = 0.86 ! N:C quota for denitrification
/
+! ============================================================================
+! AIR-SEA CO2 FLUX
+! ============================================================================
&paco2_flux_param
-permil = 0.000000976 ! 1.e-3/1024.5d0 ! Converting DIC from [mmol/m3] to [mol/kg]
-permeg = 1.e-6 ! [atm/uatm] Changes units from uatm to atm
-!X1 = exp(-5.d0*log(10.d0)) ! Lowest ph-value = 7.7 (phlo)
-!X2 = exp(-9.d0*log(10.d0)) ! Highest ph-value = 9.5 (phhi)
-Xacc = 1.e-12 ! Accuracy for ph-iteration (phacc)
-CO2_for_spinup = 278.d0 ! [uatm] Atmospheric partial pressure of CO2
+permil = 0.000000976 ! DIC conversion: mmol/m³ → mol/kg (1e-3/1024.5)
+permeg = 1.e-6 ! Pressure conversion: µatm → atm
+!X1 = exp(-5.0*log(10.0)) ! Lowest ph-value = 7.7 (phlo)
+!X2 = exp(-9.0*log(10.0)) ! Highest ph-value = 9.5 (phhi)
+Xacc = 1.e-12 ! pH iteration accuracy
+CO2_for_spinup = 278.0 ! Pre-industrial atmospheric pCO₂ [µatm]
/
+! ============================================================================
+! ALKALINITY RESTORING
+! ============================================================================
&paalkalinity_restoring
-surf_relax_Alk = 3.2e-07 !10.d0/31536000.d0
+surf_relax_Alk = 3.2e-07 ! Surface alkalinity relaxation [1/s] = 10 days⁻¹
/
+! ============================================================================
+! BALLASTING AND DENSITY-DEPENDENT SINKING
+! ============================================================================
&paballasting
-rho_POC = 1033.d0 ! kg m-3; density of POC (see Table 1 in Cram et al., 2018)
-rho_PON = 1033.d0 ! kg m-3; density of PON (see Table 1 in Cram et al., 2018)
-rho_CaCO3 = 2830.d0 ! kg m-3; density of CaCO3 (see Table 1 in Cram et al., 2018)
-rho_opal = 2090.d0 ! kg m-3; density of Opal (see Table 1 in Cram et al., 2018)
-rho_ref_part = 1230.d0 ! kg m-3; reference particle density (see Cram et al., 2018)
-rho_ref_water = 1027.d0 ! kg m-3; reference seawater density (see Cram et al., 2018)
-visc_ref_water = 0.00158d0 ! kg m-1 s-1; reference seawater viscosity, at Temp=4 degC (see Cram et al., 2018)
-w_ref1 = 10.d0 ! m s-1; reference sinking velocity of small detritus
-w_ref2 = 200.d0 ! m s-1; reference sinking velocity of large detritus
-depth_scaling1 = 0.015d0 ! s-1; factor to increase sinking speed of det1 with depth, set to 0 if not wanted
-depth_scaling2 = 0.d0 ! s-1; factor to increase sinking speed of det2 with depth, set to 0 if not wanted
-max_sinking_velocity = 250.d0 ! d-1; for numerical stability, set a maximum possible sinking velocity here (applies to both detritus classes)
-/
-
+! --- Particle Densities [kg/m³] ---
+rho_POC = 1033.0 ! POC density
+rho_PON = 1033.0 ! PON density
+rho_CaCO3 = 2830.0 ! Calcite density
+rho_opal = 2090.0 ! Biogenic opal density
+rho_ref_part = 1230.0 ! Reference particle density
+rho_ref_water = 1027.0 ! Reference seawater density
+
+! --- Viscosity and Sinking ---
+visc_ref_water = 0.00158 ! Reference seawater viscosity [kg·m⁻¹·s⁻¹] at 4°C
+w_ref1 = 10.0 ! Reference sinking velocity, small detritus [m/day]
+w_ref2 = 200.0 ! Reference sinking velocity, large detritus [m/day]
+depth_scaling1 = 0.01 ! Depth-dependent increase sinking speed of det1 [1/day]
+depth_scaling2 = 0.0 ! Depth-dependent increase sinking speed of det2 [1/day]
+max_sinking_velocity = 250.0 ! Maximum sinking velocity [m/day] (numerical stability)
+/
+
+! ============================================================================
+! CARBON ISOTOPES (¹³C AND ¹⁴C)
+! ============================================================================
&paciso
-ciso_init = .false. ! initial fractionation of bulk organic matter
-ciso_14 = .false. ! include inorganic radiocarbon
-ciso_organic_14 = .false. ! include organic radiocarbon
-lambda_14 = 3.8561e-12 ! corresponding to 1 year = 365.00 days
-delta_CO2_13 = -6.61 ! atmospheric d13C (permil), global-mean value
+ciso_init = .false. ! Initialize with fractionated organic matter
+ciso_14 = .false. ! Include inorganic radiocarbon (¹⁴C-DIC)
+ciso_organic_14 = .false. ! Include organic radiocarbon (¹⁴C-POC/DOC)
+lambda_14 = 3.8561e-12 ! ¹⁴C decay constant [s⁻¹] (5730 yr half-life)
+delta_CO2_13 = -6.61 ! Atmospheric δ¹³C [‰] (global mean)
+
+! --- Atmospheric Δ¹⁴C
big_delta_CO2_14(1) = 0. ! atmospheric D14C (permil), northern hemisphere polewards of 30°N
big_delta_CO2_14(2) = 0. ! atmospheric D14C (permil), (sub) tropical zone 30°N - 30°S
big_delta_CO2_14(3) = 0. ! atmospheric D14C (permil), southern hemisphere polewards of 30°S
-atbox_spinup = .false.
-cosmic_14_init = 2.0
+atbox_spinup = .false.
+cosmic_14_init = 2.0
/
-
diff --git a/config/bin_3p3z2d/namelist.config b/config/bin_3p3z2d/namelist.config
deleted file mode 100644
index 9a048d633..000000000
--- a/config/bin_3p3z2d/namelist.config
+++ /dev/null
@@ -1,67 +0,0 @@
-! This is the namelist file for model general configuration
-
-&modelname
-runid='fesom'
-/
-
-×tep
-step_per_day=32 !96 !96 !72 !72 !45 !72 !96
-run_length=1 !62 !62 !62 !28
-run_length_unit='y' ! y, m, d, s
-/
-
-&clockinit ! the model starts at
-timenew=0.0
-daynew=1
-yearnew=1958
-/
-
-&paths
-MeshPath='/albedo/work/projects/p_recompdaf/frbunsen/FESOM2/meshes/core2/'
-ClimateDataPath='/albedo/work/projects/MarESys/ogurses/input/corrected_input/'
-ResultPath='/albedo/scratch/user/ogurses/fesom2.5_recom_st1_vsink_vben_diags_3Zoo2Det_coccos/'
-/
-
-&restart_log
-restart_length=1 ! --> do netcdf restart ( only required for d,h,s cases, y, m take 1)
-restart_length_unit='y' !output period: y, d, h, s, off
-raw_restart_length=1 ! --> do core dump restart
-raw_restart_length_unit='off' ! e.g. y, d, h, s, off
-bin_restart_length=1 ! --> do derived type binary restart
-bin_restart_length_unit='off' ! e.g. y, d, h, s, off
-logfile_outfreq=960 !in logfile info. output frequency, # steps
-/
-
-&ale_def
-which_ALE='zstar' ! 'linfs','zlevel', 'zstar'
-use_partial_cell=.true.
-/
-
-&geometry
-cartesian=.false.
-fplane=.false.
-cyclic_length=360 ![degree]
-rotated_grid=.true. !option only valid for coupled model case now
-force_rotation=.true.
-alphaEuler=50. ![degree] Euler angles, convention:
-betaEuler=15. ![degree] first around z, then around new x,
-gammaEuler=-90. ![degree] then around new z.
-/
-
-&calendar
-include_fleapyear=.false.
-/
-
-&run_config
-use_ice=.true. ! ocean+ice
-use_cavity=.false. !
-use_cavity_partial_cell=.false.
-use_floatice = .false.
-use_sw_pene=.true.
-flag_debug=.false.
-/
-
-&machine
-n_levels=2
-n_part= 12, 36 ! 432 number of partitions on each hierarchy level
-/
diff --git a/config/bin_3p3z2d/job_albedo b/config/bin_4p3z2d/job_albedo
similarity index 78%
rename from config/bin_3p3z2d/job_albedo
rename to config/bin_4p3z2d/job_albedo
index 9eff795cb..23caf2e11 100755
--- a/config/bin_3p3z2d/job_albedo
+++ b/config/bin_4p3z2d/job_albedo
@@ -1,16 +1,15 @@
#!/bin/bash
-#SBATCH --account=nwg_hauck.maresys # edit your account
+#SBATCH --account=biogeo_model.biogeo_model # edit your account
#SBATCH --job-name=recom
#SBATCH --partition=mpp
#SBATCH --time=01:30:00
-####SBATCH --constraint="[rack1|rack3]"
#SBATCH --qos=12h
#SBATCH --nodes=9 # Number of tasks (MPI) tasks to be launched
#SBATCH --tasks-per-node 96 #8 #4 # using all 128CPus we exceed the maxload limit (>130) of many used nodes when us parallel I/O
#SBATCH --cpus-per-task 1
-#SBATCH -o fesom2o.out
-#SBATCH -e fesom2e.out
+#SBATCH -o slurm-out.out
+#SBATCH -e slurm-err.out
# disable hyperthreading
#SBATCH --hint=nomultithread
@@ -35,23 +34,22 @@ cp -n ../config/namelist.icepack .
#___DETERMINE SLURM JOBID+OUTPUTFILE____________________________________________
jobid=$(echo $SLURM_JOB_ID | cut -d"." -f1)
-fname="fesom2_${SLURM_JOB_NAME}_${jobid}.out"
+fname="fesom2.0.out"
#___PUT JOB IN QUEUE____________________________________________________________
date
-####srun --mpi=pmi2 ./fesom.x >> ${fname}
srun --mpi=pmi2 ./fesom.x > fesom2.0.out
date
#qstat -f $PBS_JOBID
#export EXITSTATUS=$?
#if [ ${EXITSTATUS} -eq 0 ] || [ ${EXITSTATUS} -eq 127 ] ; then
-#sbatch job_ollie
+#sbatch job_albedo
#fi
-#Resultpath='/albedo/scratch/user/ogurses/ocean_only/'
-Resultpath='/albedo/scratch/user/ogurses/fesom2.5_recom_st1_vsink_vben_diags_3Zoo2Det_coccos/'
-test -d $Resultpath/fesom.2019.oce.restart && exit
+
+Resultpath='/albedo/scratch/user/XXXX/'
+test -e $Resultpath/fesom.XXXX.oce.restart && exit
IsInFile=$( tail -3 fesom2.0.out | grep -c timesteps)
if (( IsInFile > 0 )); then
diff --git a/config/bin_4p3z2d/namelist.config b/config/bin_4p3z2d/namelist.config
new file mode 100644
index 000000000..27c3d140a
--- /dev/null
+++ b/config/bin_4p3z2d/namelist.config
@@ -0,0 +1,133 @@
+! ============================================================================
+! ============ Namelist file for FESOM2 general configuration ================
+! ============================================================================
+! This file contains the main configuration parameters for FESOM2, including:
+! - Model identification and run settings
+! - Time stepping and simulation duration
+! - Initial time/date settings
+! - File paths for mesh, forcing, and output
+! - Restart and logging configuration
+! - Vertical coordinate system (ALE)
+! - Grid geometry and rotation
+! - Calendar settings
+! - Model components (ice, cavities, etc.)
+! - Parallel decomposition
+! - Iceberg settings
+! ============================================================================
+
+! ============================================================================
+! RUN IDENTIFICATION
+! ============================================================================
+&modelname
+runid = 'fesom' ! run identifier (used in output filenames)
+/
+
+! ============================================================================
+! TIME STEPPING AND RUN LENGTH
+! ============================================================================
+×tep
+step_per_day = 36 ! number of time steps per day (determines dt = 86400/step_per_day seconds)
+ ! common values: 32 (45min), 48 (30min), 72 (20min), 96 (15min), 192 (7min 30sec),
+ ! 216 (6min 40sec), 240 (6min), 288 (5min), 360 (4min), 720 (2min), 1440 (1min), 2880 (30sec)
+run_length = 1 ! total length of simulation run
+run_length_unit = 'y' ! unit for run_length: 'y' (years), 'm' (months), 'd' (days), 's' (steps)
+/
+
+! ============================================================================
+! INITIAL TIME/DATE SETTINGS
+! ============================================================================
+&clockinit
+timenew = 0.0 ! initial time within the day [seconds] (0.0 = midnight)
+daynew = 1 ! initial day of the month (1-31)
+yearnew = 1958 ! initial year
+/
+
+! ============================================================================
+! MESH, INITIALIZATION & OUTPUT PATHS
+! ============================================================================
+&paths
+MeshPath = '/albedo/work/projects/p_recompdaf/frbunsen/FESOM2/meshes/core2/' ! path to mesh files (nod2d.out, elem2d.out, etc.)
+ClimateDataPath = '/albedo/work/projects/MarESys/ogurses/input/corrected_input/' ! path to initial conditions (temperature, salinity)
+ResultPath = '/albedo/scratch/user/XXXX'
+/
+
+! ============================================================================
+! RESTART AND LOGGING CONFIGURATION
+! ============================================================================
+&restart_log
+restart_length = 1 ! frequency for netCDF restart files (required for d,h,s; y,m use 1)
+restart_length_unit = 'y' ! unit: 'y' (years), 'm' (months), 'd' (days), 'h' (hours), 's' (steps), 'off' (disabled)
+raw_restart_length = 1 ! frequency for raw core dump restart files
+raw_restart_length_unit = 'off' ! unit: 'y', 'm', 'd', 'h', 's', 'off'
+bin_restart_length = 1 ! frequency for binary derived type restart files
+bin_restart_length_unit = 'off' ! unit: 'y', 'm', 'd', 'h', 's', 'off'
+logfile_outfreq = 960 ! log file output frequency [number of time steps]
+/
+
+! ============================================================================
+! VERTICAL COORDINATE SYSTEM (ALE - Arbitrary Lagrangian-Eulerian)
+! ============================================================================
+&ale_def
+which_ALE = 'zstar' ! vertical coordinate type:
+ ! 'linfs' = linear free surface
+ ! 'zlevel' = z-level (fixed depth levels)
+ ! 'zstar' = z-star (terrain-following with SSH scaling)
+use_partial_cell = .false. ! use partial bottom cells for better topography representation (not recommended)
+/
+
+! ============================================================================
+! GRID GEOMETRY AND ROTATION
+! ============================================================================
+&geometry
+cartesian = .false. ! use Cartesian coordinates (false = spherical Earth)
+fplane = .false. ! use f-plane approximation (constant Coriolis parameter)
+cyclic_length = 360 ! length of cyclic domain [degrees] (360 = global)
+rotated_grid = .true. ! use rotated grid (typically for coupled models to avoid pole singularity)
+force_rotation = .true. ! force grid rotation even if not coupled
+alphaEuler = 50. ! first Euler angle (rotation around z-axis) [degrees]
+betaEuler = 15. ! second Euler angle (rotation around new x-axis) [degrees]
+gammaEuler = -90. ! third Euler angle (rotation around new z-axis) [degrees]
+ ! Euler angle convention: rotate first around z, then around new x, then around new z
+/
+
+! ============================================================================
+! CALENDAR SETTINGS
+! ============================================================================
+&calendar
+include_fleapyear = .false. ! include leap years in calendar (false = 365-day year, true = 365/366-day year)
+/
+
+! ============================================================================
+! MODEL COMPONENTS AND FEATURES
+! ============================================================================
+&run_config
+use_ice = .true. ! enable sea ice model
+use_cavity = .false. ! enable ice shelf cavities
+use_cavity_partial_cell = .false. ! use partial cells in ice shelf cavities (not recommended)
+use_floatice = .false. ! enable floating ice (icebergs)
+use_sw_pene = .true. ! enable shortwave radiation penetration into ocean
+flag_debug = .false. ! enable debug output (verbose logging)
+use_transit = .false. ! enable transient tracer module (CFCs, SF6, etc.)
+/
+
+! ============================================================================
+! PARALLEL DECOMPOSITION (DOMAIN PARTITIONING)
+! ============================================================================
+&machine
+n_levels = 2 ! number of hierarchy levels for domain decomposition
+n_part = 2, 128 ! number of partitions at each level (total CPUs = product of n_part)
+ ! example: 2 x 128 = 256 MPI tasks
+ ! adjust based on mesh size and available compute resources
+ ! maximum scaling reached at ~300 FESOM2 2D nodes per CPU (see first line in nod2d.out for number of 2D nodes)
+/
+
+! ============================================================================
+! ICEBERG SETTINGS
+! ============================================================================
+&icebergs
+use_icesheet_coupling = .false. ! enable ice sheet model
+ib_num = 1 ! number of iceberg classes
+use_icebergs = .false. ! enable iceberg module
+steps_per_ib_step = 8 ! ocean time steps per iceberg time step (iceberg subcycling)
+ib_async_mode = 0 ! iceberg asynchronous mode (0=synchronous, 1=asynchronous)
+/
diff --git a/config/bin_3p3z2d/namelist.dyn b/config/bin_4p3z2d/namelist.dyn
similarity index 100%
rename from config/bin_3p3z2d/namelist.dyn
rename to config/bin_4p3z2d/namelist.dyn
diff --git a/config/bin_3p3z2d/namelist.forcing b/config/bin_4p3z2d/namelist.forcing
similarity index 65%
rename from config/bin_3p3z2d/namelist.forcing
rename to config/bin_4p3z2d/namelist.forcing
index a17799393..d890c69ec 100644
--- a/config/bin_3p3z2d/namelist.forcing
+++ b/config/bin_4p3z2d/namelist.forcing
@@ -23,11 +23,23 @@ ncar_bulk_z_shum=10.0 ! height at which humi forcing is located (CORE, JRA-do: 1
use_landice_water=.false.
landice_start_mon=5
landice_end_mon=10
+fwf_path='./mesh/'
+
+/
+
+&age_tracer
+use_age_tracer=.false.
+use_age_mask=.false.
+age_tracer_path='./mesh/'
+age_start_year=2000
+
/
&nam_sbc
nm_xwind_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/uas.clim61' ! name of file with winds, if nm_sbc=2
nm_ywind_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/vas.clim61' ! name of file with winds, if nm_sbc=2
+ nm_xstre_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/uas.clim61' ! name of file with winds, if nm_sbc=2
+ nm_ystre_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/vas.clim61' ! name of file with winds, if nm_sbc=2
nm_humi_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/huss.clim61' ! name of file with humidity
nm_qsr_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/rsds.clim61' ! name of file with solar heat
nm_qlw_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/rlds.clim61' ! name of file with Long wave
@@ -37,24 +49,32 @@ landice_end_mon=10
nm_mslp_file = '/albedo/work/projects/MarESys/FROM-OLLIE/forcing_JRA55-do-v1.4.0_clim61/psl.clim61' ! air_pressure_at_sea_level
nm_xwind_var = 'uas' ! name of variable in file with wind
nm_ywind_var = 'vas' ! name of variable in file with wind
- nm_humi_var = 'huss' ! name of variable in file with humidity
- nm_qsr_var = 'rsds' ! name of variable in file with solar heat
- nm_qlw_var = 'rlds' ! name of variable in file with Long wave
+ nm_xstre_var = 'uas' ! name of variable in file with wind
+ nm_ystre_var = 'vas' ! name of variable in file with wind
+ nm_humi_var = 'huss' ! name of variable in file with humidity
+ nm_qsr_var = 'rsds' ! name of variable in file with solar heat
+ nm_qlw_var = 'rlds' ! name of variable in file with Long wave
nm_tair_var = 'tas' ! name of variable in file with 2m air temperature
- nm_prec_var = 'prra' ! name of variable in file with total precipitation
- nm_snow_var = 'prsn' ! name of variable in file with total precipitation
- nm_mslp_var = 'psl' ! name of variable in file with air_pressure_at_sea_level
+ nm_prec_var = 'prra' ! name of variable in file with total precipitation
+ nm_snow_var = 'prsn' ! name of variable in file with total precipitation
+ nm_mslp_var = 'psl' ! name of variable in file with air_pressure_at_sea_level
nm_nc_iyear = 1900
nm_nc_imm = 1 ! initial month of time axis in netCDF
nm_nc_idd = 1 ! initial day of time axis in netCDF
nm_nc_freq = 1 ! data points per day (i.e. 86400 if the time axis is in seconds)
nm_nc_tmid = 0 ! 1 if the time stamps are given at the mid points of the netcdf file, 0 otherwise (i.e. 1 in CORE1, CORE2; 0 in JRA55)
y_perpetual=.true.
- l_xwind=.true. l_ywind=.true. l_humi=.true. l_qsr=.true. l_qlw=.true. l_tair=.true. l_prec=.true. l_mslp=.true. l_cloud=.false. l_snow=.true.
+ l_xwind=.true. l_ywind=.true. l_xstre=.false. l_ystre=.false. l_humi=.true. l_qsr=.true. l_qlw=.true. l_tair=.true. l_prec=.true. l_mslp=.true. l_cloud=.false. l_snow=.true.
nm_runoff_file ='/albedo/pool/FESOM/forcing/CORE2/runoff.nc'
runoff_data_source ='CORE2' !Dai09, CORE2
!runoff_data_source ='Dai09' !Dai09, CORE2, JRA55
!runoff_climatology =.true.
- nm_sss_data_file ='/albedo/pool/FESOM/forcing/CORE2/PHC2_salx.nc'
sss_data_source ='CORE2'
+ nm_sss_data_file ='/albedo/pool/FESOM/forcing/CORE2/PHC2_salx.nc'
+ chl_data_source ='None' !'Sweeney' monthly chlorophyll climatology or 'NONE' for constant chl_const (below). Make use_sw_pene=.TRUE. in namelist.config!
+ nm_chl_data_file ='/pool/data/AWICM/FESOM2/FORCING/JRA55-do-v1.4.0/Sweeney/Sweeney_2005.nc'
+ chl_const = 0.1
+ use_runoff_mapper = .FALSE.
+ runoff_basins_file = 'runoff_maps_regular.nc'
+ runoff_radius = 500000.
/
diff --git a/config/bin_3p3z2d/namelist.ice b/config/bin_4p3z2d/namelist.ice
similarity index 100%
rename from config/bin_3p3z2d/namelist.ice
rename to config/bin_4p3z2d/namelist.ice
diff --git a/config/bin_3p3z2d/namelist.icepack b/config/bin_4p3z2d/namelist.icepack
similarity index 100%
rename from config/bin_3p3z2d/namelist.icepack
rename to config/bin_4p3z2d/namelist.icepack
diff --git a/config/bin_3p3z2d/namelist.io b/config/bin_4p3z2d/namelist.io
similarity index 57%
rename from config/bin_3p3z2d/namelist.io
rename to config/bin_4p3z2d/namelist.io
index b1d4c18e6..b66adf757 100644
--- a/config/bin_3p3z2d/namelist.io
+++ b/config/bin_4p3z2d/namelist.io
@@ -12,7 +12,7 @@ ldiag_extflds =.false.
/
&nml_general
-io_listsize =100 !number of streams to allocate. shallbe large or equal to the number of streams in &nml_list
+io_listsize =150 !number of streams to allocate. shallbe large or equal to the number of streams in &nml_list
vec_autorotate =.false.
/
@@ -72,6 +72,25 @@ io_list = 'sst ',1, 'm', 4,
'NPPn ',1, 'm', 4,
'NPPc ',1, 'm', 4,
'PAR ',1, 'm', 4,
+ 'CO2 ',1, 'm', 4,
+ 'pH ',1, 'm', 4,
+ 'pCO2 ',1, 'm', 4,
+ 'HCO3 ',1, 'm', 4,
+ 'CO3 ',1, 'm', 4,
+ 'OmegaC ',1, 'm', 4,
+ 'kspc ',1, 'm', 4,
+ 'rhoSW ',1, 'm', 4,
+ 'wsink_det1',1, 'm', 8,
+ 'wsink_det2',1, 'm', 8,
+ 'rho_det1',1, 'm', 8,
+ 'rho_det2',1, 'm', 8,
+ 'scaling_rho_1',1, 'm', 8,
+ 'scaling_rho_2',1, 'm', 8,
+ 'scaling_visc',1, 'm', 8,
+ 'grazmeso_tot',1, 'm', 4,
+ 'grazmeso_n',1, 'm', 4,
+ 'grazmeso_d',1, 'm', 4,
+ 'grazmeso_c',1, 'm', 4,
'respmeso',1, 'm', 4,
'respmacro',1, 'm', 4,
'respmicro',1, 'm', 4,
@@ -86,4 +105,33 @@ io_list = 'sst ',1, 'm', 4,
'respn',1, 'm', 4,
'respd',1, 'm', 4,
'respc',1, 'm', 4,
+ 'NPPp ',1, 'm', 4,
+ 'GPPp ',1, 'm', 4,
+ 'NNAp ',1, 'm', 4,
+ 'Chldegp ',1, 'm', 4,
+ 'grazmeso_p',1, 'm', 4,
+ 'aggp ',1, 'm', 4,
+ 'respp ',1, 'm', 4,
+ 'docexp ',1, 'm', 4,
+ 'TTemp_diatoms',1, 'm', 4,
+ 'TTemp_phyto',1, 'm', 4,
+ 'TTemp_cocco',1, 'm', 4,
+ 'TTemp_phaeo',1, 'm', 4,
+ 'TPhyCO2 ',1, 'm', 4,
+ 'TDiaCO2 ',1, 'm', 4,
+ 'TCoccoCO2 ',1, 'm', 4,
+ 'TPhaeoCO2 ',1, 'm', 4,
+ 'TqLF_phyto ',1, 'm', 4,
+ 'TqLF_diatoms',1, 'm', 4,
+ 'TqLF_cocco ',1, 'm', 4,
+ 'TqLF_phaeo ',1, 'm', 4,
+ 'TCphotLL_phyto ',1, 'm', 4,
+ 'TCphotLL_dia ',1, 'm', 4,
+ 'TCphotLL_cocco ',1, 'm', 4,
+ 'TCphotLL_phaeo ',1, 'm', 4,
+ 'TCphot_phyto',1, 'm', 4,
+ 'TCphot_diatoms',1, 'm', 4,
+ 'TCphot_cocco',1, 'm', 4,
+ 'TCphot_phaeo',1, 'm', 4,
+ 'TSi_assimDia',1, 'm', 4,
/
diff --git a/config/bin_3p3z2d/namelist.oce b/config/bin_4p3z2d/namelist.oce
similarity index 100%
rename from config/bin_3p3z2d/namelist.oce
rename to config/bin_4p3z2d/namelist.oce
diff --git a/config/bin_4p3z2d/namelist.recom b/config/bin_4p3z2d/namelist.recom
new file mode 100644
index 000000000..ee098cc1e
--- /dev/null
+++ b/config/bin_4p3z2d/namelist.recom
@@ -0,0 +1,554 @@
+! ============================================================================
+! ============ Namelist file for REcoM Biogeochemical Model =================
+! ============================================================================
+! Regional Ecosystem Model (REcoM) configuration
+! This file controls biogeochemical processes including:
+! - Carbon, nitrogen, silicon, iron cycling
+! - Phytoplankton (small phyto, diatoms, coccolithophores)
+! - Zooplankton (micro, meso, krill)
+! - Organic matter remineralization and sinking
+! - Carbonate chemistry and air-sea CO2 fluxes
+! - External nutrient inputs (dust, rivers, erosion)
+! ============================================================================
+
+! ============================================================================
+! DATA SOURCES AND INPUT FILES
+! ============================================================================
+&nam_rsbc
+fe_data_source ='Albani'
+nm_fe_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/DustClimMonthlyAlbani.nc'
+nm_aen_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/AeolianNitrogenDep.nc'
+nm_river_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/RiverineInput.nc'
+nm_erosion_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/ErosionInput.nc'
+nm_co2_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/MonthlyAtmCO2_gcb2024.nc'
+/
+
+! ============================================================================
+! GENERAL MODEL CONFIGURATION
+! ============================================================================
+&parecomsetup
+enable_3zoo2det = .true. ! Enable 3 zooplankton + 2 detritus configuration
+enable_coccos = .true. ! Enable coccolithophores
+/
+
+! ============================================================================
+! MAIN MODEL SWITCHES AND SETTINGS
+! ============================================================================
+! --- Core Model Settings ---
+&pavariables
+use_REcoM = .true.
+REcoM_restart = .true.
+recom_debug = .false.
+
+! --- Tracer Configuration ---
+bgc_num = 36 ! Total number of BGC tracers
+diags3d_num = 31 ! Number of diagnostic 3D tracers
+bgc_base_num = 22 ! Number of standard tracers
+benthos_num = 4 ! Number of benthic BGC tracers (8 if ciso=.true., else 4)
+sedflx_num = 0 ! Sediment fluxes from MEDUSA (0 = use defaults)
+bottflx_num = 4 ! Bottom fluxes (8 if ciso & ciso_14, 6 if not ciso_14, 4 otherwise)
+
+! --- Sinking Velocities [m/day] ---
+VDet = 20.0 ! Small detritus sinking velocity (constant, positive down)
+VDet_zoo2 = 200.0 ! Large detritus sinking velocity
+VPhy = 0.0 ! Small phytoplankton (non-sinking)
+VDia = 0.0 ! Diatoms (variable sinking if allow_var_sinking=.true.)
+VCocco = 0.0 ! Coccolithophores
+VPhaeo = 0.0
+allow_var_sinking = .true. ! Enable variable sinking velocity
+
+! --- Time Stepping ---
+biostep = 1 ! Number of biology sub-steps per physical time step
+
+! --- Process Switches ---
+REcoM_Geider_limiter = .false. ! Use Geider limiter for nutrient limitation
+REcoM_Grazing_Variable_Preference = .true. ! Variable grazing preference (PhyN vs DiaN)
+Grazing_detritus = .true. ! Enable zooplankton grazing on detritus
+het_resp_noredfield = .true. ! Non-Redfield respiration for copepods
+diatom_mucus = .true. ! Nutrient-limited diatom aggregation
+O2dep_remin = .true. ! O2-dependent organic matter remineralization
+use_ballasting = .true. ! Ballast effect on sinking
+use_density_scaling = .true. ! Density-dependent sinking
+use_viscosity_scaling = .true. ! Viscosity-dependent sinking
+OmegaC_diss = .true. ! OmegaC-dependent calcite dissolution (set calc_diss_guts=0 if false)
+CO2lim = .true. ! CO2 effects on growth and calcification
+use_photodamage = .true. ! Chlorophyll photodamage (Alvarez et al. 2018)
+HetRespFlux_plus = .true. ! Stabilized zooplankton respiration computation
+Diags = .true. ! Enable diagnostics output
+
+! --- External Inputs ---
+constant_CO2 = .true.
+UseFeDust = .true. ! Enable iron input from dust
+UseDustClim = .true. ! Use dust climatology
+UseDustClimAlbani = .true. ! Use Albani dust fields (false = Mahowald)
+useRivers = .false. ! Enable riverine inputs
+useRivFe = .false. ! Enable riverine iron source
+useErosion = .false. ! Enable erosion inputs
+NitrogenSS = .false. ! Enable nitrogen sources/sinks (rivers, aeolian, denitrification)
+useAeolianN = .false. ! Enable aeolian nitrogen deposition
+
+! --- Time Period Configuration ---
+firstyearoffesomcycle = 1958 ! First year of physical forcing (e.g., JRA-55)
+lastyearoffesomcycle = 2024 ! Last year of physical forcing
+numofCO2cycles = 1 ! Number of forcing cycles
+currentCO2cycle = 1 ! Current forcing cycle number
+
+! --- Alkalinity and Carbon ---
+DIC_PI = .true. ! Use pre-industrial DIC
+restore_alkalinity = .true. ! Restore surface alkalinity
+Nmocsy = 1 ! Vector length for mocsy (always 1 for REcoM)
+
+! --- Data Path ---
+REcoMDataPath = '/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/'
+
+! --- Carbon Isotopes ---
+ciso = .false. ! Enable carbon isotopes (13C, 14C)
+
+! --- Sediment Model ---
+use_MEDUSA = .false. ! Enable MEDUSA sediment model
+add_loopback = .false. ! Add loopback fluxes through rivers
+lb_tscale = 1.0 ! Loopback timescale [1/year]
+
+! --- Miscellaneous ---
+use_atbox = .false. ! Use atmospheric box model
+/
+
+! ============================================================================
+! SINKING VELOCITY PARAMETERS
+! ============================================================================
+&pasinking
+Vdet_a = 0.0288 ! Slope of the linearly increasing sinking velocity [1/day]
+Vcalc = 0.0144 ! Depth dependence of calcite dissolution (when use_coccos disabled) [1/day]
+/
+
+! ============================================================================
+! INITIAL CONDITIONS
+! ============================================================================
+&painitialization_N
+cPhyN = 0.2 ! Initial small phytoplankton nitrogen [mmol N/m³]
+cHetN = 0.2 ! Initial microzooplankton nitrogen [mmol N/m³]
+cZoo2N = 0.2 ! Initial mesozooplankton nitrogen [mmol N/m³]
+/
+
+! ============================================================================
+! TEMPERATURE DEPENDENCE (ARRHENIUS)
+! ============================================================================
+&paArrhenius
+recom_Tref = 288.15 ! Reference temperature [K]
+C2K = 273.15 ! Celsius to Kelvin conversion
+Ae = 4500.0 ! Arrhenius slope [K]
+Tmax_phaeo = 16.0 ! [°C] For Blanchard temp fxn: maximum temperature
+Topt_phaeo = 6.7982 ! [°C] For Blanchard temp fxn: optimum temperature
+uopt_phaeo = 0.6903 ! [1/day] For Blanchard temp fxn: optimum growth rate
+beta_phaeo = 0.7114 ! [unitless] For Blanchard temp fxn
+ord_d = -0.2216 ! diatom ordonnée
+expon_d = 0.0406 ! diatom exponent
+ord_phy = -0.7338 ! small phyto ordonnée
+expon_phy = 0.06422 ! small phyto exponent
+ord_cocco = -0.2310 ! coccolitho ordonnée
+expon_cocco = 0.0327 ! coccolitho exponent
+ord_phaeo = -0.2310 ! phaeocystis ordonnée
+expon_phaeo = 0.0327 ! phaeocystis exponent
+reminSi = 0.02 ! Silicate remineralization base rate [1/day]
+k_o2_remin = 15.0 ! Half-saturation for O2 remineralization [mmol O2/m³]
+/
+
+&palimiter_function
+! --- Limitation Function Slopes ---
+NMinSlope = 50.0 ! Nitrogen minimum slope
+SiMinSlope = 1000.0 ! Silicon minimum slope
+
+! --- Minimum Quotas [mmol/mmol C] ---
+NCmin = 0.04 ! Small phytoplankton N:C minimum
+NCmin_d = 0.04 ! Diatom N:C minimum
+NCmin_c = 0.04 ! Coccolithophore N:C minimum
+NCmin_p = 0.04 ! Phaeocystis N:C minimum
+SiCmin = 0.04 ! Diatom Si:C minimum
+
+! --- Half-Saturation Constants ---
+k_Fe = 0.04 ! Small phyto iron half-sat [µmol Fe/m³]
+k_Fe_d = 0.12 ! Diatom iron half-sat [µmol Fe/m³]
+k_Fe_c = 0.09 ! Coccolith iron half-sat [µmol Fe/m³]
+k_Fe_p = 0.09 ! NEW for Phaeocystis (to be tuned)
+k_si = 4.0 ! Silicon half-sat [mmol Si/m³]
+
+! --- Maximum Photosynthesis Rates [1/day] ---
+P_cm = 3.0 ! Small phytoplankton max C-specific photosynthesis
+P_cm_d = 3.5 ! Diatom max C-specific photosynthesis
+P_cm_c = 2.8 ! Coccolithophore max C-specific photosynthesis
+P_cm_p = 0.75 ! NEW for Phaeocystis (to be tuned)
+/
+
+! ============================================================================
+! LIGHT ATTENUATION
+! ============================================================================
+&palight_calculations
+k_w = 0.04 ! Water attenuation coefficient [1/m]
+a_chl = 0.03 ! Chlorophyll-specific attenuation [1/m per mg Chl/m³]
+/
+
+! ============================================================================
+! PHOTOSYNTHESIS (P-I CURVE)
+! ============================================================================
+&paphotosynthesis
+alfa = 0.14 ! Small phyto initial P-I slope [(mmol C·m²)/(mg Chl·W·day)]
+alfa_d = 0.19 ! Diatom initial P-I slope
+alfa_c = 0.10 ! Coccolithophore initial P-I slope
+alfa_p = 0.17 ! Phaeocystis initial P-I slope (to be tuned)
+parFrac = 0.43 ! Fraction of shortwave that is PAR
+/
+
+! ============================================================================
+! NUTRIENT ASSIMILATION
+! ============================================================================
+&paassimilation
+! --- Maximum Uptake Scaling ---
+V_cm_fact = 0.7 ! Small phyto N-uptake scaling factor
+V_cm_fact_d = 0.7 ! Diatom N-uptake scaling factor
+V_cm_fact_c = 0.7 ! Coccolithophore N-uptake scaling factor
+V_cm_fact_p = 0.7 ! NEW for Phaeocystis
+
+! --- Limitation Function Slopes ---
+NMaxSlope = 1000.0 ! Nitrogen maximum slope
+SiMaxSlope = 1000.0 ! Silicon maximum slope
+
+! --- Maximum Cell Quotas [mmol/mmol C] ---
+NCmax = 0.2 ! Small phyto maximum N:C
+NCmax_d = 0.2 ! Diatom maximum N:C
+NCmax_c = 0.15 ! Coccolithophore maximum N:C
+NCmax_p = 0.15 ! Phaeocystis maximum N:C (to be tuned)
+SiCmax = 0.8 ! Diatom maximum Si:C
+
+! --- Maximum Uptake Ratios [mmol/mmol C] ---
+NCuptakeRatio = 0.2 ! Small phyto N:C uptake ratio
+NCUptakeRatio_d = 0.2 ! Diatom N:C uptake ratio
+NCUptakeRatio_c = 0.2 ! Coccolithophore N:C uptake ratio
+NCUptakeRatio_p = 0.2 ! NEW for Phaeocystis
+SiCUptakeRatio = 0.2 ! Diatom Si:C uptake ratio
+
+! --- Chlorophyll Parameters ---
+Chl2N_max = 3.15 ! Small phyto max Chl:N [mg Chl/mmol N]
+Chl2N_max_d = 4.2 ! Diatom max Chl:N [mg Chl/mmol N]
+Chl2N_max_c = 3.5 ! Coccolithophore max Chl:N [mg Chl/mmol N]
+Chl2N_max_p = 2.6 ! NEW for Phaeocystis
+
+! --- Half-Saturation Constants ---
+k_din = 0.55 ! Small phyto nitrate half-sat [mmol N/m³]
+k_din_d = 1.0 ! Diatom nitrate half-sat [mmol N/m³]
+k_din_c = 0.9 ! Coccolith nitrate half-sat [mmol N/m³]
+k_din_p = 0.7 ! NEW for Phaeocystis (to be tuned)
+
+! --- Respiration and Biosynthesis ---
+res_phy = 0.01 ! Small phyto maintenance respiration [1/day]
+res_phy_d = 0.01 ! Diatom maintenance respiration [1/day]
+res_phy_c = 0.01 ! Coccolithophore maintenance respiration [1/day]
+res_phy_p = 0.01 ! NEW for phaeocystis
+biosynth = 2.33 ! Cost of biosynthesis [mmol C/mmol N]
+biosynthSi = 0.0 ! Silicon biosynthesis cost [mmol C/mmol Si]
+/
+
+! ============================================================================
+! IRON CHEMISTRY
+! ============================================================================
+&pairon_chem
+totalligand = 1.0 ! Total free ligand concentration [µmol/m³]
+ligandStabConst = 100.0 ! Ligand-Fe stability constant [m³/µmol]
+/
+
+! ============================================================================
+! MICROZOOPLANKTON (FIRST ZOOPLANKTON)
+! ============================================================================
+&pazooplankton
+graz_max = 0.31 ! Maximum grazing rate [1/day]
+epsilonr = 0.09 ! Half-saturation constant [(mmol N)²/m⁶]
+res_het = 0.028 ! Respiration + mortality [1/day]
+Redfield = 6.625 ! C:N Redfield ratio [mmol C/mmol N]
+loss_het = 0.04 ! Extracellular N degradation [1/day]
+tiny_het = 1.d-5 ! Small number for stable computation
+
+! --- Grazing Preferences ---
+pzDia = 1.0 ! Diatom preference (maximum) NEW value for Phaeocystis
+sDiaNsq = 0.0 ! Diatom preference slope
+pzPhy = 0.5 ! Small phyto preference NEW value for Phaeocystis
+sPhyNsq = 0.0 ! Small phyto preference slope
+pzCocco = 0.666 ! Coccolithophore preference NEW value for Phaeocystis
+sCoccoNsq = 0.0 ! Coccolithophore preference slope
+pzPhaeo = 0.5 ! Phaeocystis preference
+sPhaeoNsq = 0.0 ! Phaeocystis preference slope
+pzMicZoo = 1.0 ! Microzooplankton preference (self-grazing)
+sMicZooNsq = 0.0 ! Microzooplankton preference slope
+/
+
+! ============================================================================
+! MESOZOOPLANKTON (SECOND ZOOPLANKTON)
+! ============================================================================
+&pasecondzooplankton
+graz_max2 = 0.25 ! Maximum grazing rate [1/day] NEW value for Phaeocystis
+epsilon2 = 0.0144 ! Half-saturation constant [(mmol N)²/m⁶]
+res_zoo2 = 0.0107 ! Respiration + mortality [1/day]
+loss_zoo2 = 0.003 ! Extracellular N degradation [1/day]
+
+! --- Fecal Pellet Production ---
+fecal_rate_n = 0.104 ! Nitrogen fecal rate [1/day]
+fecal_rate_c = 0.236 ! Carbon fecal rate [1/day]
+fecal_rate_n_mes = 0.25 ! Mesozooplankton N fecal rate [1/day]
+fecal_rate_c_mes = 0.32 ! Mesozooplankton C fecal rate [1/day]
+
+! --- Grazing Preferences ---
+pzDia2 = 1.5 !1.0 ! Diatom preference NEW value for Phaeocystis
+sDiaNsq2 = 0.0 ! Diatom preference slope
+pzPhy2 = 0.5 !0.07 ! Small phyto preference NEW value for Phaeocystis
+sPhyNsq2 = 0.0 ! Small phyto preference slope
+pzCocco2 = 0.5 !0.7 ! Coccolithophore preference NEW value for Phaeocystis
+sCoccoNsq2 = 0.0 ! Coccolithophore preference slope
+pzPhaeo2 = 0.5 ! Phaeocystis preference
+sPhaeoNsq2 = 0.0 ! Phaeocystis preference slope
+pzHet = 1.5 ! Microzooplankton preference
+sHetNsq = 0.0 ! Microzooplankton preference slope
+pzMicZoo2 = 1.0 ! Mesozooplankton preference
+sMicZooNsq2 = 0.0 ! Mesozooplankton preference slope
+
+! --- Temperature Function (Krill-specific) ---
+t1_zoo2 = 28145.0 ! Temperature function constant 1
+t2_zoo2 = 272.5 ! Temperature function constant 2 [K]
+t3_zoo2 = 105234.0 ! Temperature function constant 3
+t4_zoo2 = 274.15 ! Temperature function constant 4 [K]
+/
+
+! ============================================================================
+! MICROZOOPLANKTON (THIRD ZOOPLANKTON)
+! ============================================================================
+&pathirdzooplankton
+graz_max3 = 0.36 ! Maximum grazing rate [1/day] NEW value for Phaeocystis
+epsilon3 = 0.64 ! Half-saturation constant [(mmol N)²/m⁶]
+loss_miczoo = 0.01 ! Extracellular N degradation [1/day]
+res_miczoo = 0.01 ! Respiration + mortality [1/day] NEW value for Phaeocystis
+
+! --- Grazing Preferences ---
+pzDia3 = 0.5 !0.04 ! Maximum diatom preference NEW value for Phaeocystis
+sDiaNsq3 = 0.0 ! Diatom preference slope
+pzPhy3 = 1.0 !0.07 ! Small phyto preference NEW value for Phaeocystis
+sPhyNsq3 = 0.0 ! Small phyto preference slope
+pzCocco3 = 0.5 !0.7 ! Coccolithophore preference ATTENTION: This value needs to be tuned; I start with zero preference! ! NEW value for Phaeocystis
+sCoccoNsq3 = 0.0 ! Coccolithophore preference slope
+pzPhaeo3 = 0.25 ! Phaeocystis preference
+sPhaeoNsq3 = 0.0 ! Phaeocystis preference slope
+/
+
+! ============================================================================
+! GRAZING ON DETRITUS
+! ============================================================================
+&pagrazingdetritus
+! --- First Zooplankton (Microzooplankton) ---
+pzDet = 0.5 ! Small detritus preference
+sDetNsq = 0.0 ! Small detritus preference slope
+pzDetZ2 = 0.5 ! Large detritus preference
+sDetZ2Nsq = 0.0 ! Large detritus preference slope
+
+! --- Second Zooplankton (Mesozooplankton) ---
+pzDet2 = 0.5 ! Small detritus preference
+sDetNsq2 = 0.0 ! Small detritus preference slope
+pzDetZ22 = 0.5 ! Large detritus preference
+sDetZ2Nsq2 = 0.0 ! Large detritus preference slope
+/
+
+! ============================================================================
+! AGGREGATION
+! ============================================================================
+&paaggregation
+agg_PD = 0.165 ! Detritus aggregation rate [m³/(mmol N·day)]
+agg_PP = 0.015 ! Plankton aggregation rate [m³/(mmol N·day)]
+/
+
+! ============================================================================
+! DISSOLVED ORGANIC MATTER REMINERALIZATION
+! ============================================================================
+&padin_rho_N
+rho_N = 0.11 ! DON remineralization rate [1/day]
+rho_Nt = 0.67d0 ! [1/day] terrestrial N degradation of extracellular organic N (DONt) (Remineralization of terrestrial DON) ~ scale of 1.5 years ! R2OMIP
+/
+
+&padic_rho_C1
+rho_C1 = 0.1 ! DOC remineralization rate [1/day]
+/
+
+! ============================================================================
+! PHYTOPLANKTON LOSSES
+! ============================================================================
+&paphytoplankton_N
+lossN = 0.05 ! Small phyto N loss rate [1/day]
+lossN_d = 0.05 ! Diatom N loss rate [1/day]
+lossN_c = 0.05 ! Coccolithophore N loss rate [1/day]
+lossN_p = 0.05 ! NEW for Phaeocystis
+/
+
+&paphytoplankton_C
+lossC = 0.10 ! Small phyto C loss rate [1/day]
+lossC_d = 0.10 ! Diatom C loss rate [1/day]
+lossC_c = 0.10 ! Coccolithophore C loss rate [1/day]
+lossC_p = 0.10 ! NEW for Phaeocystis
+/
+
+&paphytoplankton_ChlA
+deg_Chl = 0.15 !0.25 !0.2 ! Small phyto Chl degradation [1/day]
+deg_Chl_d = 0.2 !0.15 ! Diatom Chl degradation [1/day]
+deg_Chl_c = 0.2 ! Coccolithophore Chl degradation [1/day]
+deg_Chl_p = 0.15 ! NEW for Phaeocystis
+/
+
+! ============================================================================
+! DETRITUS REMINERALIZATION
+! ============================================================================
+&padetritus_N
+gfin = 0.3 ! First zooplankton grazing efficiency
+grazEff2 = 0.8 ! Second zooplankton grazing efficiency
+grazEff3 = 0.8 ! Third zooplankton grazing efficiency
+reminN = 0.165 ! Detritus N remineralization rate [1/day]
+/
+
+&padetritus_C
+reminC = 0.15 ! Detritus C remineralization rate [1/day]
+rho_c2 = 0.1 ! TEP-C degradation rate [1/day]
+/
+
+! ============================================================================
+! ZOOPLANKTON LOSSES
+! ============================================================================
+&paheterotrophs
+lossN_z = 0.1 ! First zooplankton N loss [1/day]
+lossC_z = 0.1 ! First zooplankton C loss [1/day]
+/
+
+&paseczooloss
+lossN_z2 = 0.02 ! Second zooplankton N loss [1/day]
+lossC_z2 = 0.02 ! Second zooplankton C loss [1/day]
+/
+
+&pathirdzooloss
+lossN_z3 = 0.05 ! Third zooplankton N loss [1/day]
+lossC_z3 = 0.05 ! Third zooplankton C loss [1/day]
+/
+
+! ============================================================================
+! CO2 LIMITATION PARAMETERS
+! ============================================================================
+&paco2lim
+Cunits = 976.5625 ! Unit conversion factor: mol/m³ → µmol/kg
+
+! --- Small Phytoplankton ---
+a_co2_phy = 1.162e+00 ! Dimensionless
+b_co2_phy = 4.888e+01 ! [mol/kg]
+c_co2_phy = 2.255e-01 ! [kg/mol]
+d_co2_phy = 1.023e+07 ! [kg/mol]
+
+! --- Diatoms ---
+a_co2_dia = 1.040e+00 ! Dimensionless
+b_co2_dia = 2.890e+01 ! [mol/kg]
+c_co2_dia = 8.778e-01 ! [kg/mol]
+d_co2_dia = 2.640e+06 ! [kg/mol]
+
+! --- Coccolithophores ---
+a_co2_cocco = 1.109e+00 ! Dimensionless (growth)
+b_co2_cocco = 3.767e+01 ! [mol/kg] (growth)
+c_co2_cocco = 3.912e-01 ! [kg/mol] (growth)
+d_co2_cocco = 9.450e+06 ! [kg/mol] (growth)
+
+! --- Phaeocystis ---
+a_co2_phaeo = 1.162e+00 ! Dimensionless
+b_co2_phaeo = 4.888e+01 ! [mol/kg]
+c_co2_phaeo = 2.255e-01 ! [kg/mol]
+d_co2_phaeo = 1.023e+07 ! [kg/mol]
+
+a_co2_calc = 1.102e+00 ! Dimensionless (calcification)
+b_co2_calc = 4.238e+01 ! [mol/kg] (calcification)
+c_co2_calc = 7.079e-01 ! [kg/mol] (calcification)
+d_co2_calc = 1.343e+07 ! [kg/mol] (calcification)
+/
+
+&pairon
+Fe2N = 0.033 ! Iron to nitrogen ratio (= Fe2C × 6.625)
+Fe2N_benthos = 0.15 ! Benthic flux ratio [micromol Fe : mmol N,]
+kScavFe = 0.07 ! Iron scavenging rate [1/day]
+dust_sol = 0.02 ! Dust iron solubility fraction
+RiverFeConc = 100 ! Riverine iron concentration [µmol/m³]
+/
+
+! ============================================================================
+! CALCITE PRODUCTION AND DISSOLUTION
+! ============================================================================
+&pacalc
+calc_prod_ratio = 0.02 ! Calcite production ratio (CaCO₃:POC)
+calc_diss_guts = 0.5 ! Gut dissolution fraction (set to 0 if OmegaC_diss=.false.)
+calc_diss_rate = 0.005714 ! Standard dissolution rate [1/day] = 20/3500
+calc_diss_rate2 = 0.005714 ! Standard dissolution rate [1/day]
+calc_diss_omegac = 0.197 ! Critical Ω_calcite (Aumont et al. 2015)
+calc_diss_exp = 1.0 ! Dissolution rate exponent
+/
+
+! ============================================================================
+! BENTHIC PROCESSES
+! ============================================================================
+&pabenthos_decay_rate
+decayRateBenN = 0.005 ! Benthic N decay rate [1/day]
+decayRateBenC = 0.005 ! Benthic C decay rate [1/day]
+decayRateBenSi = 0.005 ! Benthic Si decay rate [1/day]
+q_NC_Denit = 0.86 ! N:C quota for denitrification
+/
+
+! ============================================================================
+! AIR-SEA CO2 FLUX
+! ============================================================================
+&paco2_flux_param
+permil = 0.000000976 ! DIC conversion: mmol/m³ → mol/kg (1e-3/1024.5)
+permeg = 1.e-6 ! Pressure conversion: µatm → atm
+!X1 = exp(-5.0*log(10.0)) ! Lowest ph-value = 7.7 (phlo)
+!X2 = exp(-9.0*log(10.0)) ! Highest ph-value = 9.5 (phhi)
+Xacc = 1.e-12 ! pH iteration accuracy
+CO2_for_spinup = 278.0 ! Pre-industrial atmospheric pCO₂ [µatm]
+/
+
+! ============================================================================
+! ALKALINITY RESTORING
+! ============================================================================
+&paalkalinity_restoring
+surf_relax_Alk = 3.2e-07 ! Surface alkalinity relaxation [1/s] = 10 days⁻¹
+/
+
+! ============================================================================
+! BALLASTING AND DENSITY-DEPENDENT SINKING
+! ============================================================================
+&paballasting
+! --- Particle Densities [kg/m³] ---
+rho_POC = 1033.0 ! POC density
+rho_PON = 1033.0 ! PON density
+rho_CaCO3 = 2830.0 ! Calcite density
+rho_opal = 2090.0 ! Biogenic opal density
+rho_ref_part = 1230.0 ! Reference particle density
+rho_ref_water = 1027.0 ! Reference seawater density
+
+! --- Viscosity and Sinking ---
+visc_ref_water = 0.00158 ! Reference seawater viscosity [kg·m⁻¹·s⁻¹] at 4°C
+w_ref1 = 10.0 ! Reference sinking velocity, small detritus [m/day]
+w_ref2 = 200.0 ! Reference sinking velocity, large detritus [m/day]
+depth_scaling1 = 0.01 ! Depth-dependent increase sinking speed of det1 [1/day]
+depth_scaling2 = 0.0 ! Depth-dependent increase sinking speed of det2 [1/day]
+max_sinking_velocity = 250.0 ! Maximum sinking velocity [m/day] (numerical stability)
+/
+
+! ============================================================================
+! CARBON ISOTOPES (¹³C AND ¹⁴C)
+! ============================================================================
+&paciso
+ciso_init = .false. ! Initialize with fractionated organic matter
+ciso_14 = .false. ! Include inorganic radiocarbon (¹⁴C-DIC)
+ciso_organic_14 = .false. ! Include organic radiocarbon (¹⁴C-POC/DOC)
+lambda_14 = 3.8561e-12 ! ¹⁴C decay constant [s⁻¹] (5730 yr half-life)
+delta_CO2_13 = -6.61 ! Atmospheric δ¹³C [‰] (global mean)
+
+! --- Atmospheric Δ¹⁴C
+big_delta_CO2_14(1) = 0. ! atmospheric D14C (permil), northern hemisphere polewards of 30°N
+big_delta_CO2_14(2) = 0. ! atmospheric D14C (permil), (sub) tropical zone 30°N - 30°S
+big_delta_CO2_14(3) = 0. ! atmospheric D14C (permil), southern hemisphere polewards of 30°S
+atbox_spinup = .false.
+cosmic_14_init = 2.0
+/
diff --git a/config/bin_3p3z2d/namelist.tra b/config/bin_4p3z2d/namelist.tra
similarity index 96%
rename from config/bin_3p3z2d/namelist.tra
rename to config/bin_4p3z2d/namelist.tra
index 33be191e7..7fd6837a2 100644
--- a/config/bin_3p3z2d/namelist.tra
+++ b/config/bin_4p3z2d/namelist.tra
@@ -39,6 +39,9 @@ nml_tracer_list =
1031, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
1032, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
1033, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1034, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1035, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1036, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
!101, 'UPW1', 'UPW1', 'NON ', 0., 0.
/
diff --git a/config/namelist.cvmix b/config/namelist.cvmix
index 5c73d9403..58969e414 100644
--- a/config/namelist.cvmix
+++ b/config/namelist.cvmix
@@ -146,11 +146,11 @@ kpp_reduce_tauuice = .false. ! reduce wind stress (u*) under sea ice
! (MOST). The code logic probably augments or replaces parts of the standard boundary
! (layer similarity (or nonlocal mixing) using a Stokes‐drift‐aware correction.
kpp_use_StokesMOST= .false. !.true.
-
+
! approximate proportionality between surface wind velocity and stokes velocity
! U_stokes ~ kpp_A_stokes * U_wind
kpp_A_stokes = 0.005 ! a
-
+
! Langmuir option
! Option of Langmuir enhanced mixing apply an enhancement factor to the
! turbulent velocity scale
@@ -159,7 +159,7 @@ kpp_A_stokes = 0.005 ! a
! (Langmuir_EFactor - cvmix_one)
! NONE - Langmuir switched off, MixingCoefEnhancement=1
kpp_langmuir_mixing= "NONE" !"LWF16"
-
+
! Option of Langmuir turbulence enhanced entrainment - modify the unresolved shear
! LWF16 - Li Q., Webb A., Fox-Kemper B., Craig A., Danabasoglu G.,
! Large W., Vertenstein M., 2016, Langmuir mixing effects on
diff --git a/setups/forcings.yml b/setups/forcings.yml
index 5e71d53dd..3ad3dd46c 100644
--- a/setups/forcings.yml
+++ b/setups/forcings.yml
@@ -254,4 +254,66 @@ test_global:
calendar:
include_fleapyear: False
+test_recom:
+ forcing_exchange_coeff:
+ Ce_atm_oce: 1.75e-3
+ Ch_atm_oce: 1.75e-3
+ Cd_atm_oce: 1.0e-3
+ Ce_atm_ice: 1.75e-3
+ Ch_atm_ice: 1.75e-3
+ Cd_atm_ice: 1.2e-3
+ forcing_bulk:
+ AOMIP_drag_coeff: False
+ ncar_bulk_formulae: True
+ ncar_bulk_z_wind: 10.0
+ ncar_bulk_z_tair: 10.0
+ ncar_bulk_z_shum: 10.0
+ land_ice:
+ use_landice_water: False
+ landice_start_mon: 5
+ landice_end_mon: 10
+ nam_sbc:
+ nm_xwind_file: u_10.
+ nm_ywind_file: v_10.
+ nm_humi_file: q_10.
+ nm_qsr_file: ncar_rad.
+ nm_qlw_file: ncar_rad.
+ nm_tair_file: t_10.
+ nm_prec_file: ncar_precip.
+ nm_snow_file: ncar_precip.
+ nm_mslp_file: slp.
+ nm_xwind_var: U_10_MOD
+ nm_ywind_var: V_10_MOD
+ nm_humi_var: Q_10_MOD
+ nm_qsr_var: SWDN_MOD
+ nm_qlw_var: LWDN_MOD
+ nm_tair_var: T_10_MOD
+ nm_prec_var: RAIN
+ nm_snow_var: SNOW
+ nm_mslp_var: SLP
+ nm_nc_iyear: 1948
+ nm_nc_imm: 1
+ nm_nc_idd: 1
+ nm_nc_freq: 1
+ nm_nc_tmid: 1
+ l_xwind: True
+ l_ywind: True
+ l_humi: True
+ l_qsr: True
+ l_qlw: True
+ l_tair: True
+ l_prec: True
+ l_mslp: False
+ l_cloud: False
+ l_snow: True
+ nm_runoff_file: runoff.nc
+ runoff_data_source: CORE2
+ nm_sss_data_file: PHC2_salx.nc
+ sss_data_source: CORE2
+ namelist.config:
+ clockinit:
+ yearnew: 1958
+ calendar:
+ include_fleapyear: True
+
diff --git a/setups/paths.yml b/setups/paths.yml
index 435cd6a86..09d5db735 100644
--- a/setups/paths.yml
+++ b/setups/paths.yml
@@ -62,9 +62,11 @@ docker:
forcing:
test_global: ./test/input/global/
test_icebergs: ./test/input/icebergs/
+ test_recom: ./test/input/global/
clim:
test_global: ./test/input/global/
test_icebergs: ./test/input/icebergs/
+ test_recom: ./test/input/recom/
opath:
opath: ./test/
diff --git a/setups/test_pi_recom/README.md b/setups/test_pi_recom/README.md
new file mode 100644
index 000000000..64b45572f
--- /dev/null
+++ b/setups/test_pi_recom/README.md
@@ -0,0 +1,74 @@
+ REcoM Biogeochemistry CI Test
+
+This test validates FESOM2 with REcoM (Regulated Ecosystem Model) biogeochemistry module.
+
+## Test Configuration
+
+- **Mesh**: PI mesh (test_global) - ~3k nodes
+- **Duration**: 1 day
+- **Time steps**: 32 per day
+- **Processes**: 2 MPI tasks
+- **Features**:
+ - REcoM biogeochemistry (30 tracers)
+ - 3 zooplankton, 2 detritus groups
+ - Iron chemistry with dust input
+ - CO2 system (without calcification for this test)
+
+## Required Input Files
+
+All files are located in `test/input/recom/`:
+
+### REcoM-specific files:
+- `DustClimMonthlyAlbani_pimesh.nc` - Dust deposition climatology
+- `MonthlyAtmCO2_gcb2024.nc` - Atmospheric CO2 concentration
+- `GLODAPv2.2016b.PI_TCO2_fesom2_mmol_fix_z_Fillvalue.nc` - Pre-industrial DIC (optional)
+
+### Initial conditions for biogeochemical tracers:
+- `fe5deg.nc` - Iron (Fe)
+- `oxy5deg.nc` - Oxygen
+- `si5deg.nc` - Silicate
+- `talk5deg.nc` - Total alkalinity
+- `tco2_5deg.nc` - Total dissolved inorganic carbon
+- `din5deg.nc` - Dissolved inorganic nitrogen
+- `woa18_netcdf_5deg.nc` - Temperature and salinity
+
+## Build Instructions
+
+Compile FESOM2 with REcoM support:
+
+```bash
+./configure.sh ubuntu -DRECOM_COUPLED=ON
+```
+
+## Running the Test
+
+### Local Docker Test:
+```bash
+mkrun recom test_pi_recom -m docker
+cd work_recom
+./job_docker_new
+```
+
+### CI Test (GitHub Actions):
+The test runs automatically via `.github/workflows/fesom2_recom.yml` on pull requests to main branch.
+
+## Expected Outputs
+
+The test outputs daily averages for:
+- Physical variables: SST, temperature, salinity, velocities, sea ice
+- Biogeochemical variables: DIN (nitrogen), DIC (carbon)
+
+## Validation
+
+The `fcheck` values in `setup.yml` validate that:
+1. Physical fields match baseline test_pi values
+2. Biogeochemical tracers are within expected ranges:
+ - DIN: ~15 mmol/m³ (global mean)
+ - DIC: ~2100 mmol/m³ (global mean)
+
+## Notes
+
+- This test uses `REcoM_restart=False` for initialization from climatology
+- Cavity is disabled (`use_cavity=False`)
+- Uses standard PI mesh without cavity features
+- Test follows the same pattern as icebergs and cavity tests
diff --git a/config/bin_3p3z2d/namelist.recom b/setups/test_pi_recom/namelist.recom
similarity index 72%
rename from config/bin_3p3z2d/namelist.recom
rename to setups/test_pi_recom/namelist.recom
index 3679e244f..7d3677575 100644
--- a/config/bin_3p3z2d/namelist.recom
+++ b/setups/test_pi_recom/namelist.recom
@@ -2,25 +2,30 @@
&nam_rsbc
fe_data_source ='Albani'
-nm_fe_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/DustClimMonthlyAlbani.nc'
-nm_aen_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/AeolianNitrogenDep.nc'
-nm_river_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/RiverineInput.nc'
-nm_erosion_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/ErosionInput.nc'
-nm_co2_data_file ='/albedo/work/projects/p_pool_recom/input/mesh_CORE2_finaltopo_mean/MonthlyAtmCO2_gcb2023.nc'
+nm_fe_data_file ='DustClimMonthlyAlbani_pimesh.nc'
+nm_aen_data_file =''
+nm_river_data_file =''
+nm_erosion_data_file =''
+nm_co2_data_file ='MonthlyAtmCO2_gcb2024.nc'
+/
+
+&parecomsetup
+enable_3zoo2det = .true.
+enable_coccos = .false.
/
&pavariables
use_REcoM =.true.
-REcoM_restart =.true.
+REcoM_restart =.false.
-bgc_num = 33 !30 !22 !33 !24 !38
+bgc_num = 30 !24 !38 !22
diags3d_num = 28 ! Number of diagnostic 3d tracers to be saved
bgc_base_num = 22 ! standard tracers
VDet = 20.d0 ! Sinking velocity, constant through the water column and positive downwards
VDet_zoo2 = 200.d0 ! Sinking velocity, constant through the water column
VPhy = 0.d0 !!! If the number of sinking velocities are different from 3, code needs to be changed !!!
VDia = 0.d0
-VCocco = 0.d0
+VCocco = 0.d0
allow_var_sinking = .true.
biostep = 1 ! Number of times biology should be stepped forward for each time step
REcoM_Geider_limiter = .false. ! Decides what routine should be used to calculate limiters in sms
@@ -29,10 +34,10 @@ Grazing_detritus = .true.
het_resp_noredfield = .true. ! Decides respiratation of copepod group
diatom_mucus = .true. ! Decides nutrient limitation effect on aggregation
O2dep_remin = .true. ! O2remin Add option for O2 dependency of organic matter remineralization
-use_ballasting = .true. ! BALL
-use_density_scaling = .true. ! BALL
-use_viscosity_scaling = .true. ! BALL
-OmegaC_diss = .true. ! DISS Use OmegaC from Mocsy to compute calcite dissolution (after Aumont et al. 2015 and Gehlen et al. 2007)
+use_ballasting = .true.
+use_density_scaling = .true.
+use_viscosity_scaling = .true.
+OmegaC_diss = .false. ! Use OmegaC from Mocsy to compute calcite dissolution (after Aumont et al. 2015 and Gehlen et al. 2007) -> set calc_diss_guts to zero if this is false!!!!
CO2lim = .true. ! CO2 dependence of growth and calcification
Diags = .true.
constant_CO2 = .true.
@@ -41,7 +46,7 @@ UseDustClim = .true.
UseDustClimAlbani = .true. ! Use Albani dustclim field (If it is false Mahowald will be used)
use_photodamage = .true. ! use Alvarez et al (2018) for chlorophyll degradation
HetRespFlux_plus = .true. !MB More stable computation of zooplankton respiration fluxes adding a small number to HetN
-REcoMDataPath = '/albedo/work/projects/MarESys/ogurses/input/mesh_CORE2_finaltopo_mean/'
+REcoMDataPath = './'
restore_alkalinity = .true.
useRivers = .false.
useRivFe = .false. ! When set to true, riverine Fe source is activated
@@ -49,7 +54,7 @@ useErosion = .false.
NitrogenSS = .false. ! When set to true, external sources and sinks of nitrogen are activated (Riverine, aeolian and denitrification)
useAeolianN = .false. ! When set to true, aeolian nitrogen deposition is activated
firstyearoffesomcycle = 1958 ! The first year of the actual physical forcing (e.g. JRA-55) used
-lastyearoffesomcycle = 2023 ! Last year of the actual physical forcing used
+lastyearoffesomcycle = 2024 ! Last year of the actual physical forcing used
numofCO2cycles = 1 ! Number of cycles of the forcing planned
currentCO2cycle = 1 ! Which CO2 cycle we are currently running
DIC_PI = .true.
@@ -81,23 +86,23 @@ recom_Tref = 288.15d0 ! [K]
C2K = 273.15d0 ! Conversion from degrees C to K
Ae = 4500.d0 ! [K] Slope of the linear part of the Arrhenius function
reminSi = 0.02d0
-k_o2_remin = 15.d0 ! NEW O2remin mmol m-3; Table 1 in Cram 2018 cites DeVries & Weber 2017 for a range of 0-30 mmol m-3
+k_o2_remin = 15.d0 ! O2remin mmol m-3; Table 1 in Cram 2018 cites DeVries & Weber 2017 for a range of 0-30 mmol m-3
/
&palimiter_function
NMinSlope = 50.d0
SiMinSlope = 1000.d0
-NCmin = 0.04d0 !0.05d0
-NCmin_d = 0.04d0 !0.05d0
-NCmin_c = 0.04d0 ! NEW
+NCmin = 0.04d0
+NCmin_d = 0.04d0
+NCmin_c = 0.04d0
SiCmin = 0.04d0
k_Fe = 0.04d0
k_Fe_d = 0.12d0
-k_Fe_c = 0.09d0 ! NEW
+k_Fe_c = 0.09d0
k_si = 4.d0
P_cm = 3.0d0 ! [1/day] Rate of C-specific photosynthesis
P_cm_d = 3.5d0
-P_cm_c = 2.8d0 ! NEW
+P_cm_c = 2.8d0
/
&palight_calculations
@@ -108,33 +113,33 @@ a_chl = 0.03d0 ! [1/m * 1/(mg Chl)] Chlorophyll specific at
&paphotosynthesis
alfa = 0.14d0 ! [(mmol C*m2)/(mg Chl*W*day)]
alfa_d = 0.19d0 ! An initial slope of the P-I curve
-alfa_c = 0.10d0 ! NEW
+alfa_c = 0.10d0
parFrac = 0.43d0
/
&paassimilation
V_cm_fact = 0.7d0 ! scaling factor for temperature dependent maximum of C-specific N-uptake
V_cm_fact_d = 0.7d0
-V_cm_fact_c = 0.7d0 ! NEW
+V_cm_fact_c = 0.7d0
NMaxSlope = 1000.d0 ! Max slope for limiting function
SiMaxSlope = 1000.d0
NCmax = 0.2d0 ! [mmol N/mmol C] Maximum cell quota of nitrogen (N:C)
NCmax_d = 0.2d0
-NCmax_c = 0.15d0 ! NEW
+NCmax_c = 0.15d0
SiCmax = 0.8d0
NCuptakeRatio = 0.2d0 ! [mmol N/mmol C] Maximum uptake ratio of N:C
NCUptakeRatio_d = 0.2d0
-NCUptakeRatio_c = 0.2d0 ! NEW
+NCUptakeRatio_c = 0.2d0
SiCUptakeRatio = 0.2d0
k_din = 0.55d0 ! [mmol N/m3] Half-saturation constant for nitrate uptake
k_din_d = 1.0d0
-k_din_c = 0.9d0 ! NEW
+k_din_c = 0.9d0
Chl2N_max = 3.15d0 ! [mg CHL/mmol N] Maximum CHL a : N ratio = 0.3 gCHL gN^-1
Chl2N_max_d = 4.2d0
-Chl2N_max_c = 3.5d0 ! NEW
+Chl2N_max_c = 3.5d0
res_phy = 0.01d0 ! [1/day] Maintenance respiration rate constant
res_phy_d = 0.01d0
-res_phy_c = 0.01d0 ! NEW
+res_phy_c = 0.01d0
biosynth = 2.33d0 ! [mmol C/mmol N] Cost of biosynthesis
biosynthSi = 0.d0
/
@@ -145,19 +150,19 @@ ligandStabConst = 100.d0 ! [m3/mumol] order 100. Ligand-free iron sta
/
&pazooplankton
-graz_max = 0.31d0 ! [mmol N/(m3 * day)] Maximum grazing loss parameter
+graz_max = 0.31d0 ! [mmol N/(m3 * day)] Maximum grazing loss parameter
epsilonr = 0.09d0 ! [(mmol N)2 /m6] Half saturation constant for grazing loss
-res_het = 0.028d0 ! [1/day] Respiration by heterotrophs and mortality (loss to detritus)
+res_het = 0.028d0 ! [1/day] Respiration by heterotrophs and mortality (loss to detritus)
Redfield = 6.625 ! [mmol C/mmol N] Redfield ratio of C:N = 106:16
loss_het = 0.04d0 ! [1/day] Temperature dependent N degradation of extracellular organic N (EON)
-pzDia = 0.5d0 !1.0d0 !0.5d0 ! Maximum diatom preference
+pzDia = 0.5d0 ! Maximum diatom preference
sDiaNsq = 0.d0
-pzPhy = 0.04d0 !0.5d0 !0.25d0 !1.0d0 ! Maximum nano-phytoplankton preference (NEW: 3/12)
+pzPhy = 0.04d0 ! Maximum small phytoplankton preference
sPhyNsq = 0.d0
-pzCocco = 0.4d0 !0.666d0 ! NEW (8/12)
-sCoccoNsq = 0.d0 ! NEW
-pzMicZoo = 1.0d0 ! NEW 3Zoo Maximum nano-phytoplankton preference
-sMicZooNsq = 0.d0 ! NEW 3Zoo
+pzCocco = 0.4d0 ! Maximum coccolithophore preference ! will not be used in the 2p3z3d version
+sCoccoNsq = 0.d0
+pzMicZoo = 1.0d0 ! Maximum microzooplankton preference
+sMicZooNsq = 0.d0
tiny_het = 1.d-5 ! for more stable computation of HetRespFlux (_plus). Value can be > tiny because HetRespFlux ~ hetC**2.
/
@@ -168,17 +173,17 @@ res_zoo2 = 0.0107d0 ! [1/day] Respiration by heterotrophs and mo
loss_zoo2 = 0.003d0 ! [1/day] Temperature dependent N degradation of extracellular organic N (EON)
fecal_rate_n = 0.104d0 ! [1/day] Temperature dependent N degradation of \
fecal_rate_c = 0.236d0
-fecal_rate_n_mes = 0.25d0 ! NEW 3Zoo
-fecal_rate_c_mes = 0.32d0 ! NEW 3Zoo
-pzDia2 = 1.0d0 !1.5d0 !1.d0 ! Maximum diatom preference
+fecal_rate_n_mes = 0.25d0
+fecal_rate_c_mes = 0.32d0
+pzDia2 = 1.0d0 ! Maximum diatom preference
sDiaNsq2 = 0.d0
-pzPhy2 = 0.07d0 !0.5d0 ! Maximum diatom preference
+pzPhy2 = 0.07d0 ! Maximum small phytoplankton preference
sPhyNsq2 = 0.d0
-pzCocco2 = 0.7 !0.5d0 ! NEW
-sCoccoNsq2 = 0.d0 ! NEW
-pzHet = 1.5d0 !0.8d0 ! Maximum diatom preference
+pzCocco2 = 0.7d0 ! Maximum coccolithophore preference ! will not be used in the 2p3z3d version
+sCoccoNsq2 = 0.d0
+pzHet = 1.5d0 ! Maximum mesozooplankton preference
sHetNsq = 0.d0
-pzMicZoo2 = 1.0d0 ! NEW 3Zoo Maximum nano-phytoplankton preference
+pzMicZoo2 = 1.0d0 ! Maximum microzooplankton preference
sMicZooNsq2 = 0.d0
t1_zoo2 = 28145.d0 ! Krill temp. function constant1
t2_zoo2 = 272.5d0 ! Krill temp. function constant2
@@ -187,16 +192,16 @@ t4_zoo2 = 274.15d0 ! Krill temp. function constant3
/
&pathirdzooplankton
-graz_max3 = 0.46d0 ! NEW 3Zoo [mmol N/(m3 * day)] Maximum grazing loss parameter
-epsilon3 = 0.64d0 ! NEW 3Zoo [(mmol N)2 /m6] Half saturation constant for grazing loss
-loss_miczoo = 0.01d0 ! NEW 3Zoo [1/day] Temperature dependent N degradation of extracellular organic N (EON)
-res_miczoo = 0.02d0 !0.01d0 ! NEW 3Zoo [1/day] Respiration by heterotrophs and mortality (loss to detritus)
-pzDia3 = 0.04d0 !0.5d0 ! NEW 3Zoo Maximum diatom preference
-sDiaNsq3 = 0.d0 ! NEW 3Zoo
-pzPhy3 = 0.07 !1.0d0 ! NEW 3Zoo Maximum nano-phytoplankton preference
-sPhyNsq3 = 0.d0 ! NEW 3Zoo
-pzCocco3 = 0.7d0 !0.d0 ! NEW 3Zoo Maximum coccolithophore preference ! ATTENTION: This value needs to be tuned; I start with zero preference!
-sCoccoNsq3 = 0.d0 ! NEW 3Zoo
+graz_max3 = 0.46d0 ! [mmol N/(m3 * day)] Maximum grazing loss parameter
+epsilon3 = 0.64d0 ! [(mmol N)2 /m6] Half saturation constant for grazing loss
+loss_miczoo = 0.01d0 ! [1/day] Temperature dependent N degradation of extracellular organic N (EON)
+res_miczoo = 0.02d0 ! [1/day] Respiration by heterotrophs and mortality (loss to detritus)
+pzDia3 = 0.04d0 ! Maximum diatom preference
+sDiaNsq3 = 0.d0
+pzPhy3 = 0.07d0 ! Maximum small phytoplankton preference
+sPhyNsq3 = 0.d0
+pzCocco3 = 0.7d0 ! Maximum coccolithophore preference ! will not be used in the 2p3z3d version
+sCoccoNsq3 = 0.d0
/
&pagrazingdetritus
@@ -204,10 +209,10 @@ pzDet = 0.5d0 ! Maximum small detritus prefence by first zoopl
sDetNsq = 0.d0
pzDetZ2 = 0.5d0 ! Maximum large detritus preference by first zooplankton
sDetZ2Nsq = 0.d0
-pzDet2 = 0.5d0 ! Maximum small detritus prefence by second zooplankton
-sDetNsq2 = 0.d0
-pzDetZ22 = 0.5d0 ! Maximum large detritus preference by second zooplankton
-sDetZ2Nsq2 = 0.d0
+pzDet2 = 0.5d0 ! Maximum small detritus prefence by second zooplankton
+sDetNsq2 = 0.d0
+pzDetZ22 = 0.5d0 ! Maximum large detritus preference by second zooplankton
+sDetZ2Nsq2 = 0.d0
/
&paaggregation
@@ -226,25 +231,25 @@ rho_C1 = 0.1d0 ! [1/day] Temperature dependent C degradatio
&paphytoplankton_N
lossN = 0.05d0 ! [1/day] Phytoplankton loss of organic N compounds
lossN_d = 0.05d0
-lossN_c = 0.05d0 ! NEW
+lossN_c = 0.05d0
/
&paphytoplankton_C
lossC = 0.10d0 ! [1/day] Phytoplankton loss of carbon
lossC_d = 0.10d0
-lossC_c = 0.10d0 ! NEW
+lossC_c = 0.10d0
/
&paphytoplankton_ChlA
-deg_Chl = 0.25d0 !0.2d0 !0.25d0 ! [1/day]
-deg_Chl_d = 0.15d0 !0.2d0 !0.15d0
-deg_Chl_c = 0.2d0 ! NEW (has been 0.5)
+deg_Chl = 0.25d0 !0.075 !0.2d0 !0.25d0 ! [1/day]
+deg_Chl_d = 0.15d0 !0.075 !0.2d0 !0.15d0
+deg_Chl_c = 0.2d0 !0.075 !0.2d0
/
&padetritus_N
-gfin = 0.3d0 ! NEW 3Zoo [] Grazing efficiency (fraction of grazing flux into zooplankton pool)
+gfin = 0.3d0 ! [] Grazing efficiency (fraction of grazing flux into zooplankton pool)
grazEff2 = 0.8d0 ! [] Grazing efficiency (fraction of grazing flux into second zooplankton pool)
-grazEff3 = 0.8d0 ! NEW 3Zoo [] Grazing efficiency (fraction of grazing flux into microzooplankton pool)
+grazEff3 = 0.8d0 ! [] Grazing efficiency (fraction of grazing flux into microzooplankton pool)
reminN = 0.165d0 ! [1/day] Temperature dependent remineralisation rate of detritus
/
@@ -264,11 +269,11 @@ lossC_z2 = 0.02d0
/
&pathirdzooloss
-lossN_z3 = 0.05d0 ! NEW 3Zoo
-lossC_z3 = 0.05d0 ! NEW 3Zoo
+lossN_z3 = 0.05d0
+lossC_z3 = 0.05d0
/
-&paco2lim ! NEW
+&paco2lim
Cunits = 976.5625 ! Conversion factor between [mol/m3] (model) and [umol/kg] (function): (1000 * 1000) / 1024
a_co2_phy = 1.162e+00 ! [dimensionless]
a_co2_dia = 1.040e+00 ! [dimensionless]
@@ -298,11 +303,11 @@ RiverFeConc = 100
&pacalc
calc_prod_ratio = 0.02
-calc_diss_guts = 0.5d0 !0.0d0
-calc_diss_rate = 0.005714d0 ! 20.d0/3500.d0
+calc_diss_guts = 0.0d0 ! set to zero if OmegaC_diss is set to false
+calc_diss_rate = 0.005714d0 ! 20.d0/3500.d0
calc_diss_rate2 = 0.005714d0
-calc_diss_omegac = 0.197d0 ! NEW DISS Value from Aumont et al. 2015, will be used with OmegaC_diss flag
-calc_diss_exp = 1.d0 ! NEW DISS Exponent in the dissolution rate of calcite, will be used with OmegaC_diss flag
+calc_diss_omegac = 0.197d0 ! Value from Aumont et al. 2015, is used with OmegaC_diss flag
+calc_diss_exp = 1.d0 ! Exponent in the dissolution rate of calcite, is used with OmegaC_diss flag
/
&pabenthos_decay_rate
@@ -333,9 +338,9 @@ rho_opal = 2090.d0 ! kg m-3; density of Opal (see Table 1 in Cram
rho_ref_part = 1230.d0 ! kg m-3; reference particle density (see Cram et al., 2018)
rho_ref_water = 1027.d0 ! kg m-3; reference seawater density (see Cram et al., 2018)
visc_ref_water = 0.00158d0 ! kg m-1 s-1; reference seawater viscosity, at Temp=4 degC (see Cram et al., 2018)
-w_ref1 = 10.d0 ! m s-1; reference sinking velocity of small detritus
+w_ref1 = 5.d0 ! m s-1; reference sinking velocity of small detritus
w_ref2 = 200.d0 ! m s-1; reference sinking velocity of large detritus
-depth_scaling1 = 0.01d0 !5d0 ! s-1; factor to increase sinking speed of det1 with depth, set to 0 if not wanted
+depth_scaling1 = 0.01d0 ! s-1; factor to increase sinking speed of det1 with depth, set to 0 if not wanted
depth_scaling2 = 0.d0 ! s-1; factor to increase sinking speed of det2 with depth, set to 0 if not wanted
max_sinking_velocity = 250.d0 ! d-1; for numerical stability, set a maximum possible sinking velocity here (applies to both detritus classes)
/
diff --git a/setups/test_pi_recom/namelist.tra b/setups/test_pi_recom/namelist.tra
new file mode 100644
index 000000000..c6f24dca8
--- /dev/null
+++ b/setups/test_pi_recom/namelist.tra
@@ -0,0 +1,90 @@
+&tracer_listsize
+num_tracers=100 !number of tracers to allocate. shallbe large or equal to the number of streams in &nml_list
+/
+
+&tracer_list
+nml_tracer_list =
+1 , 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+2 , 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1001, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1002, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1003, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1004, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1005, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1006, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1007, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1008, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1009, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1010, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1011, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1012, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1013, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1014, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1015, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1016, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1017, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1018, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1019, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1020, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1021, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1022, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1023, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1024, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1025, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1026, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1027, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1028, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1029, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+1030, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+!1031, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+!1032, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+!1033, 'MFCT', 'QR4C', 'FCT ', 1., 1.,
+!101, 'UPW1', 'UPW1', 'NON ', 0., 0.
+/
+
+&tracer_init3d ! initial conditions for tracers
+n_ic3d = 8 ! number of tracers to initialize
+idlist = 1019, 1022, 1018, 1003, 1002, 1001, 2, 1 ! their IDs (0 is temperature, 1 is salinity, etc.). The reading order is defined here!
+filelist = 'fe5deg.nc', 'oxy5deg.nc', 'si5deg.nc', 'talk5deg.nc', 'tco2_5deg.nc', 'din5deg.nc', 'woa18_netcdf_5deg.nc', 'woa18_netcdf_5deg.nc' ! list of files in ClimateDataPath to read (one file per tracer), same order as idlist
+varlist = 'Fe', 'oxygen_mmol', 'i_an', 'TAlk_mmol', 'TCO2_mmol', 'n_an', 'salt', 'temp' ! variables to read from specified files
+t_insitu = .true. ! if T is insitu it will be converted to potential after reading it
+/
+
+&tracer_init2d ! initial conditions for 2D tracers (sea ice)
+n_ic2d = 3 ! number of tracers to initialize
+idlist = 1, 2, 3 ! their IDs (0 is a_ice, 1 is m_ice, 3 m_snow). The reading order is defined here!
+filelist = 'a_ice.nc', 'm_ice.nc', 'm_snow.nc' ! list of files in ClimateDataPath to read (one file per tracer), same order as idlist
+varlist = 'a_ice', 'm_ice', 'm_snow' ! variables to read from specified files
+ini_ice_from_file=.false.
+/
+
+&tracer_general
+! bharmonic diffusion for tracers. We recommend to use this option in very high resolution runs (Redi is generally off there).
+smooth_bh_tra =.false. ! use biharmonic diffusion (filter implementation) for tracers
+gamma0_tra = 0.0005 ! gammaX_tra are analogous to those in the dynamical part
+gamma1_tra = 0.0125
+gamma2_tra = 0.
+i_vert_diff =.true.
+/
+
+&tracer_phys
+use_momix = .true. ! switch on/off !Monin-Obukhov -> TB04 mixing
+momix_lat = -50.0 ! latitidinal treshhold for TB04, =90 --> global
+momix_kv = 0.01 ! PP/KPP, mixing coefficient within MO length
+use_instabmix = .true. ! enhance convection in case of instable stratification
+instabmix_kv = 0.1
+use_windmix = .false. ! enhance mixing trough wind only for PP mixing (for stability)
+windmix_kv = 1.e-3
+windmix_nl = 2
+diff_sh_limit=5.0e-3 ! for KPP, max diff due to shear instability
+Kv0_const=.true.
+double_diffusion=.false. ! for KPP,dd switch
+K_ver=1.0e-5
+K_hor=3000.
+surf_relax_T=0.0
+surf_relax_S=1.929e-06 ! 50m/300days 6.43e-07! m/s 10./(180.*86400.)
+balance_salt_water =.true. ! balance virtual-salt or freshwater flux or not
+clim_relax=0.0 ! 1/s, geometrical information has to be supplied
+ref_sss_local=.true.
+ref_sss=34.
+/
diff --git a/setups/test_pi_recom/setup.yml b/setups/test_pi_recom/setup.yml
new file mode 100644
index 000000000..54c95dcd1
--- /dev/null
+++ b/setups/test_pi_recom/setup.yml
@@ -0,0 +1,151 @@
+mesh: test_global
+forcing: test_recom
+clim:
+ type: test_recom
+ filelist:
+ - 'fe5deg.nc'
+ - 'oxy5deg.nc'
+ - 'si5deg.nc'
+ - 'talk5deg.nc'
+ - 'tco2_5deg.nc'
+ - 'din5deg.nc'
+ - 'woa18_netcdf_5deg.nc'
+ - 'woa18_netcdf_5deg.nc'
+ varlist: ['Fe', 'oxygen_mmol', 'i_an', 'TAlk_mmol', 'TCO2_mmol', 'n_an', 'salt', 'temp']
+ntasks: 2
+time: "00:15:00"
+
+namelist.config:
+ run_config:
+ use_cavity: False
+ use_cavity_partial_cell: False
+ timestep:
+ step_per_day: 32
+ run_length: 1
+ run_length_unit: "d"
+ geometry:
+ force_rotation: True
+ restart_log:
+ restart_length: 1
+ restart_length_unit: "d"
+ logfile_outfreq: 10
+
+namelist.dyn:
+ dynamics_general:
+ use_wsplit: True
+
+namelist.ice:
+ ice_dyn:
+ whichEVP: 1
+ evp_rheol_steps: 120
+
+namelist.tra:
+ tracer_listsize:
+ num_tracers: 100
+ tracer_init3d:
+ n_ic3d: 8
+ idlist: [1019, 1022, 1018, 1003, 1002, 1001, 2, 1]
+ filelist: ['fe5deg.nc', 'oxy5deg.nc', 'si5deg.nc', 'talk5deg.nc', 'tco2_5deg.nc', 'din5deg.nc', 'woa18_netcdf_5deg.nc', 'woa18_netcdf_5deg.nc']
+ varlist: ['Fe', 'oxygen_mmol', 'i_an', 'TAlk_mmol', 'TCO2_mmol', 'n_an', 'salt', 'temp']
+ t_insitu: True
+
+namelist.recom:
+ nam_rsbc:
+ fe_data_source: 'Albani'
+ nm_fe_data_file: 'DustClimMonthlyAlbani_pimesh.nc'
+ nm_co2_data_file: 'MonthlyAtmCO2_gcb2024.nc'
+ parecomsetup:
+ enable_3zoo2det: True
+ enable_coccos: False
+ pavariables:
+ use_REcoM: True
+ REcoM_restart: False
+ bgc_num: 30
+ diags3d_num: 28
+ bgc_base_num: 22
+ biostep: 1
+ REcoM_Geider_limiter: False
+ REcoM_Grazing_Variable_Preference: True
+ Grazing_detritus: True
+ het_resp_noredfield: True
+ diatom_mucus: True
+ O2dep_remin: True
+ use_ballasting: True
+ use_density_scaling: True
+ use_viscosity_scaling: True
+ OmegaC_diss: False
+ CO2lim: True
+ Diags: True
+ constant_CO2: True
+ UseFeDust: True
+ UseDustClim: True
+ UseDustClimAlbani: True
+ use_photodamage: True
+ HetRespFlux_plus: True
+ restore_alkalinity: True
+ useRivers: False
+ useRivFe: False
+ useErosion: False
+ NitrogenSS: False
+ useAeolianN: False
+ firstyearoffesomcycle: 1958
+ lastyearoffesomcycle: 2024
+ numofCO2cycles: 1
+ currentCO2cycle: 1
+ DIC_PI: True
+ Nmocsy: 1
+ recom_debug: False
+ ciso: False
+ benthos_num: 4
+ use_MEDUSA: False
+ sedflx_num: 0
+ bottflx_num: 4
+ use_atbox: False
+ add_loopback: False
+ lb_tscale: 1.0
+
+namelist.io:
+ nml_list:
+ io_list:
+ "sst ":
+ freq: 1
+ unit: d
+ prec: 8
+ "a_ice ":
+ freq: 1
+ unit: d
+ prec: 8
+ "temp ":
+ freq: 1
+ unit: d
+ prec: 8
+ "salt ":
+ freq: 1
+ unit: d
+ prec: 8
+ "u ":
+ freq: 1
+ unit: d
+ prec: 8
+ "v ":
+ freq: 1
+ unit: d
+ prec: 8
+ "DIN ":
+ freq: 1
+ unit: d
+ prec: 8
+ "DIC ":
+ freq: 1
+ unit: d
+ prec: 8
+
+fcheck:
+ a_ice: 0.8751385167232245
+ salt: 34.730446281564674
+ sst: 8.553913157676204
+ temp: 2.4698052420959806
+ u: -0.0021267214031837154
+ v: 0.0002005313874256175
+ DIN: 15.0
+ DIC: 2100.0
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 65817d890..3b3c3bb5f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -310,7 +310,7 @@ if(OPENMP_REPRODUCIBLE)
endif()
if(${RECOM_COUPLED})
- target_compile_definitions(${PROJECT_NAME} PRIVATE __recom USE_PRECISION=2 __3Zoo2Det __coccos)# __usetp)
+ target_compile_definitions(${PROJECT_NAME} PRIVATE __recom USE_PRECISION=2) # __usetp)
endif()
if(${CISO_COUPLED})
diff --git a/src/MOD_TRACER.F90 b/src/MOD_TRACER.F90
index efeeed623..0d0d6a913 100644
--- a/src/MOD_TRACER.F90
+++ b/src/MOD_TRACER.F90
@@ -20,6 +20,9 @@ MODULE MOD_TRACER
real(kind=WP) :: tra_adv_pv = 1. ! a parameter to be used in horizontal advection (for QR4C it is the fraction of fourth-order contribution in the solution)
integer :: AB_order=2
integer :: ID
+!___________________________________________________________________________
+! TODO: Make it as a part of namelist.tra
+logical :: ltra_diag = .true. ! OG - tra_diag
contains
procedure WRITE_T_TRACER_DATA
@@ -41,7 +44,15 @@ MODULE MOD_TRACER
! compute Tstar = 0.5*( T^(n+1) + T^n)
real(kind=WP), allocatable, dimension(:,:,:) :: dvd_trflx_hor, dvd_trflx_ver
-!_______________________________________________________________________________
+! in case ltra_diag=.true. --> calculate tracer diags ! OG - tra_diag
+real(kind=WP), allocatable :: tra_advhoriz(:,:,:), tra_advvert(:,:,:)
+real(kind=WP), allocatable :: tra_diff_part_hor_redi(:,:,:)
+real(kind=WP), allocatable :: tra_diff_part_ver_expl(:,:,:)
+real(kind=WP), allocatable :: tra_diff_part_ver_redi_expl(:,:,:)
+real(kind=WP), allocatable :: tra_diff_part_ver_impl(:,:,:)
+real(kind=WP), allocatable :: tra_recom_sms(:,:,:)
+real(kind=WP), allocatable :: tra_advvert_LO(:,:,:), tra_advhoriz_LO(:,:,:)
+
! The fct part
real(kind=WP),allocatable,dimension(:,:) :: fct_LO ! Low-order solution
real(kind=WP),allocatable,dimension(:,:) :: adv_flux_hor ! Antidif. horiz. contrib. from edges / backup for iterafive fct scheme
diff --git a/src/fesom_module.F90 b/src/fesom_module.F90
index 50e379133..686882e71 100755
--- a/src/fesom_module.F90
+++ b/src/fesom_module.F90
@@ -183,7 +183,7 @@ subroutine fesom_init(fesom_total_nsteps)
f%npes =>f%partit%npes
-
+
if(f%mype==0) then
call plot_fesomlogo()
write(*,*)
@@ -206,10 +206,10 @@ subroutine fesom_init(fesom_total_nsteps)
#if defined (FESOM_PROFILING)
call fesom_profiler_end("setup_model")
#endif
-
+
if (flag_debug .and. f%mype==0) print *, achar(27)//'[34m'//' --> call clock_init'//achar(27)//'[0m'
call clock_init(f%partit) ! read the clock file
-
+
if (flag_debug .and. f%mype==0) print *, achar(27)//'[34m'//' --> call get_run_steps'//achar(27)//'[0m'
call get_run_steps(fesom_total_nsteps, f%partit)
f%total_nsteps=fesom_total_nsteps
diff --git a/src/gen_forcing_init.F90 b/src/gen_forcing_init.F90
index aa7afca18..2106db03f 100644
--- a/src/gen_forcing_init.F90
+++ b/src/gen_forcing_init.F90
@@ -142,7 +142,6 @@ subroutine forcing_array_setup(partit, mesh)
evaporation = 0.0_WP
ice_sublimation = 0.0_WP
-
#if defined (__oasis) || defined (__ifsinterface)
allocate(sublimation(n2), evap_no_ifrac(n2))
sublimation=0.0_WP
diff --git a/src/gen_model_setup.F90 b/src/gen_model_setup.F90
index 869b00a52..11d861893 100755
--- a/src/gen_model_setup.F90
+++ b/src/gen_model_setup.F90
@@ -175,6 +175,10 @@ subroutine setup_model(partit)
endif
call par_ex(partit%MPI_COMM_FESOM, partit%mype, 1)
endif
+
+ read (fileunit, NML=parecomsetup, iostat=istat)
+ if (istat /= 0) call check_namelist_read(fileunit, 'parecomsetup', nmlfile, partit)
+
read (fileunit, NML=pavariables, iostat=istat)
if (istat /= 0) call check_namelist_read(fileunit, 'pavariables', nmlfile, partit)
diff --git a/src/gen_surface_forcing.F90 b/src/gen_surface_forcing.F90
index b95a99af7..1240b5ac2 100644
--- a/src/gen_surface_forcing.F90
+++ b/src/gen_surface_forcing.F90
@@ -1457,6 +1457,7 @@ SUBROUTINE sbc_do(partit, mesh)
#if defined (__recom)
use recom_config
use recom_glovar
+ use REcoM_ciso
#endif
IMPLICIT NONE
@@ -1473,8 +1474,9 @@ SUBROUTINE sbc_do(partit, mesh)
integer :: firstyearofcurrentCO2cycle, totnumyear, currentCO2year
character(4) :: currentCO2year_char
real(kind=8), allocatable :: ncdata(:)
- integer :: CO2start, CO2count
- integer :: status, ncid, varid
+ integer :: CO2start, CO2count, RIstart, RIcount
+ real(kind=8) :: locmax, locmin, glo
+ integer :: status, ncid, varid, ierror, n
#endif
type(t_partit), intent(inout), target :: partit
type(t_mesh), intent(in), target :: mesh
@@ -1659,10 +1661,40 @@ SUBROUTINE sbc_do(partit, mesh)
! ******** Atmospheric CO2 *********
if (mstep == 1) then ! The year has changed
+ if (use_atbox) then
+! Atmospheric box model CO2 values
+ AtmCO2(:) = x_co2atm(1)
+ if (ciso) then
+ AtmCO2_13(:) = x_co2atm_13(1)
+ if (ciso_14) AtmCO2_14(:,1) = x_co2atm_14(1)
+ end if
+ else
+! Prescribed atmospheric CO2 values
+
if (constant_CO2) then
AtmCO2(:) = CO2_for_spinup
if (mype==0) write(*,*) 'Constant_CO2 = ', CO2_for_spinup
- if (mype==0) write(*,*),'Atm CO2=', AtmCO2
+ if (mype==0) write(*,*),'Atm CO2=', AtmCO2
+ if (ciso) then
+ AtmCO2_13 = CO2_for_spinup * (1. + 0.001 * delta_co2_13)
+ if (ciso_14) then
+! Atmospheric 14C varies with latitude
+ do i=1, myDim_nod2D
+! Latitude of atmospheric input data
+ lat_val = geo_coord_nod2D(2,i) / rad
+! Binning to latitude zones
+ if (ciso_organic_14) then
+! Convert Delta_14C to delta_14C
+ delta_co2_14 = (big_delta_co2_14(lat_zone(lat_val)) + 2. * delta_co2_13 + 50.) / &
+ (0.95 - 0.002 * delta_co2_13)
+ else
+! "Inorganic" 14C approximation: delta_14C := Delta_14C
+ delta_co2_14 = big_delta_co2_14(lat_zone(lat_val))
+ end if
+ AtmCO2_14(lat_zone(lat_val),:) = CO2_for_spinup * (1. + 0.001 * delta_co2_14)
+ end do
+ end if
+ end if
else
filename=trim(make_full_path(nm_co2_data_file))
if (mype==0) write(*,*) 'Updating CO2 climatology for month ', i,' from ', trim(filename)
@@ -1696,8 +1728,18 @@ SUBROUTINE sbc_do(partit, mesh)
if (mype==0) write(*,*),'Atm CO2=', AtmCO2
status=nf90_close(ncid)
end if
+ end if ! atmospheric box model or prescribed CO2 values
+
+! Control output of atmospheric CO2 values
+ if (mype==0) then !OG
+ print *, "In atm_input: AtmCO2 = ", AtmCO2(1)
+ if (ciso) then
+ print *, " AtmCO2_13 = ", AtmCO2_13(1)
+ if (ciso_14) print *, " AtmCO2_14 = ", AtmCO2_14(:,1)
+ end if
+ if (use_atbox) print *, " use_atbox = .true."
+ end if
end if
-
! ******** Fe deposition *********
if (fe_data_source=='Albani') then
if (update_monthly_flag) then
@@ -1737,44 +1779,228 @@ SUBROUTINE sbc_do(partit, mesh)
if (mstep==1 .and. mype==0) write(*,*) 'useAeolianN is switched off'
end if
-! ******** Riverine input (Nutrients) *********
+ !-----------------------------------------------------------------------------
+ ! Configure river nutrient inputs
+ !-----------------------------------------------------------------------------
+
if (useRivers) then
-!< read riverine input
+
! *** River inputs are in mmol/m2/s ***
- ! add river nutrients as surface boundary condition (surface_bc function in oce_ale_tracers)
+
if (recom_debug .and. mype==0) print *, achar(27)//'[36m'//' --> River_input'//achar(27)//'[0m'
+ ! add river nutrients as surface boundary condition (surface_bc function in oce_ale_tracers)
+ ! Enable river input flag
is_riverinput = 1.0d0
- if (update_monthly_flag) then
- i=month
- if (mstep > 1) i=i+1
- if (i > 12) i=1
- filename=trim(nm_river_data_file)
- if (mype==0) write(*,*) 'Updating riverine restoring data for month', i,' from ', trim(filename)
- call read_2ddata_on_grid_NetCDF(filename,'Alkalinity', i, RiverAlk2D, partit, mesh)
- ! write(*,*) mype, 'RiverAlk2D', maxval(RiverAlk2D(:)), minval(RiverAlk2D(:))
- ! molar convertion of [CaCo3] * 2 -> [total Alkalinity]
- RiverAlk2D = RiverAlk2D * 2
-
- call read_2ddata_on_grid_NetCDF(filename, 'DIC', i, RiverDIC2D, partit, mesh)
- ! write(*,*) mype, 'RiverDIC2D', maxval(RiverDIC2D(:)), minval(RiverDIC2D(:))
-
- call read_2ddata_on_grid_NetCDF(filename, 'DIN', i, RiverDIN2D, partit, mesh)
- ! write(*,*) mype, 'RiverDIN2D', maxval(RiverDIN2D(:)), minval(RiverDIN2D(:))
-
- call read_2ddata_on_grid_NetCDF(filename, 'DOC', i, RiverDOC2D, partit, mesh)
- ! write(*,*) mype, 'RiverDOC2D', maxval(RiverDOC2D(:)), minval(RiverDOC2D(:))
-
- call read_2ddata_on_grid_NetCDF(filename, 'DON', i, RiverDON2D, partit, mesh)
- ! write(*,*) mype, 'RiverDON2D', maxval(RiverDON2D(:)), minval(RiverDON2D(:))
-
- RiverDSi2D = RiverDIN2D * (16/15)
- end if
- else
- is_riverinput = 0.0d0
- if (mype==0 .and. mstep==1) write(*,*) 'No riverine input'
- end if
+ if (mstep == 1) then
+
+ ! Determine input type: constant pre-industrial or transient
+ if (mype==0) then
+ ! Use constant pre-industrial river inputs
+ if (constant_PI_Rivers) then
+ write(*,'(A)') 'INFO: Using constant pre-industrial riverine inputs'
+ filename = trim(REcoMDataPath) // 'Rivers_R2OMIP_PI.nc'
+ else
+ ! Use transient (year-specific) river inputs
+ write(*,'(A,A,A,A)') 'INFO: Using transient riverine inputs - model year = ', &
+ trim(cyearnew), ' from ', trim(filename)
+ ! Construct filename for current year
+ filename = trim(REcoMDataPath) // 'Rivers_R2OMIP_' // trim(cyearnew) // '.nc'
+ endif
+ ! open file
+ write(*,*), trim(filename)
+ status=nf90_open(filename, nf90_nowrite, ncid)
+ endif
+
+ call MPI_BCast(status, 1, MPI_INTEGER, 0, MPI_COMM_FESOM, ierror)
+
+ if (status.ne.nf90_noerr)then
+ print*,'ERROR: CANNOT READ runoff FILE CORRECTLY !!!!!'
+ print*,'Error in opening netcdf file '//filename
+ call par_ex(partit%MPI_COMM_FESOM, partit%mype)
+ stop
+ endif
+
+ call load_river_variable(ncid, 'DIC', RiverDIC2D, partit, mesh)
+ locmax = -66666
+ locmin = 66666
+ locmax = max(locmax,maxval(RiverDIC2D))
+ locmin = min(locmin,minval(RiverDIC2D))
+
+ if (mype==0) write(*,*) "Sanity check for Riverine input after reading Rivers_R2OMIP file"
+ call MPI_AllREDUCE(locmax , glo , 1, MPI_DOUBLE_PRECISION, MPI_MAX, MPI_COMM_FESOM, MPIerr)
+ if (mype==0) write(*,*) ' |-> global max init. riverine DIC. =', glo
+ call MPI_AllREDUCE(locmin , glo , 1, MPI_DOUBLE_PRECISION, MPI_MIN, MPI_COMM_FESOM, MPIerr)
+ if (mype==0) write(*,*) ' |-> global min init. riverine DIC. =', glo
+
+ call load_river_variable(ncid, 'DIN', RiverDIN2D, partit, mesh)
+ locmax = -66666
+ locmin = 66666
+ locmax = max(locmax,maxval(RiverDIN2D))
+ locmin = min(locmin,minval(RiverDIN2D))
+
+ if (mype==0) write(*,*) "Sanity check for Riverine input after reading Rivers_R2OMIP file"
+ call MPI_AllREDUCE(locmax , glo , 1, MPI_DOUBLE_PRECISION, MPI_MAX, MPI_COMM_FESOM, MPIerr)
+ if (mype==0) write(*,*) ' |-> global max init. riverine DIN. =', glo
+ call MPI_AllREDUCE(locmin , glo , 1, MPI_DOUBLE_PRECISION, MPI_MIN, MPI_COMM_FESOM, MPIerr)
+ if (mype==0) write(*,*) ' |-> global min init. riverine DIN. =', glo
+
+ call load_river_variable(ncid, 'DOC_l', RiverDOCl2D, partit, mesh)
+ locmax = -66666
+ locmin = 66666
+ locmax = max(locmax,maxval(RiverDOCl2D))
+ locmin = min(locmin,minval(RiverDOCl2D))
+
+ call MPI_AllREDUCE(locmax , glo , 1, MPI_DOUBLE_PRECISION, MPI_MAX, MPI_COMM_FESOM, MPIerr)
+ if (mype==0) write(*,*) ' |-> global max riverine DOCl. =', glo
+ call MPI_AllREDUCE(locmin , glo , 1, MPI_DOUBLE_PRECISION, MPI_MIN, MPI_COMM_FESOM, MPIerr)
+ if (mype==0) write(*,*) ' |-> global min riverine DOCl. =', glo
+
+ call load_river_variable(ncid, 'DOC_sl', RiverDOCsl2D, partit, mesh)
+ locmax = -66666
+ locmin = 66666
+ locmax = max(locmax,maxval(RiverDOCsl2D))
+ locmin = min(locmin,minval(RiverDOCsl2D))
+
+ call MPI_AllREDUCE(locmax , glo , 1, MPI_DOUBLE_PRECISION, MPI_MAX, MPI_COMM_FESOM, MPIerr)
+ if (mype==0) write(*,*) ' |-> global max riverine DOCsl. =', glo
+ call MPI_AllREDUCE(locmin , glo , 1, MPI_DOUBLE_PRECISION, MPI_MIN, MPI_COMM_FESOM, MPIerr)
+ if (mype==0) write(*,*) ' |-> global min riverine DOCsl. =', glo
+
+ call load_river_variable(ncid, 'POC', RiverPOC2D, partit, mesh)
+ locmax = -66666
+ locmin = 66666
+ locmax = max(locmax,maxval(RiverPOC2D))
+ locmin = min(locmin,minval(RiverPOC2D))
+
+ call MPI_AllREDUCE(locmax , glo , 1, MPI_DOUBLE_PRECISION, MPI_MAX, MPI_COMM_FESOM, MPIerr)
+ if (mype==0) write(*,*) ' |-> global max riverine POC. =', glo
+ call MPI_AllREDUCE(locmin , glo , 1, MPI_DOUBLE_PRECISION, MPI_MIN, MPI_COMM_FESOM, MPIerr)
+ if (mype==0) write(*,*) ' |-> global min riverine POC. =', glo
+
+ if (mype == 0) then
+ status = nf90_close(ncid) ! Close file once
+ endif
+
+ !allocate(ncdata(mesh%nod2D))
+ !if (mype==0) then
+ ! status=nf90_inq_varid(ncid, 'DIC', varid)
+ ! RIstart = 1
+ ! RIcount = mesh%nod2D
+ ! status=nf90_get_var(ncid, varid, ncdata, start=(/RIstart/), count=(/RIcount/))
+ ! status=nf90_close(ncid)
+ !endif
+ !call MPI_BCast(ncdata, nod2D, MPI_DOUBLE_PRECISION, 0, MPI_COMM_FESOM, ierror)
+ !RiverDIC2D=ncdata(myList_nod2D)
+ !deallocate(ncdata)
+ !write(*,*), 'here'
+
+ ! Read all nutrient fields from PI file
+ !i=1
+ !call read_2ddata_on_grid_NetCDF(filename, 'DIC', i, RiverDIC2D, partit, mesh)
+ !call read_2ddata_on_grid_NetCDF(filename, 'DIN', i, RiverDIN2D, partit, mesh)
+ !call read_2ddata_on_grid_NetCDF(filename, 'DOC_l', i, RiverDOCl2D, partit, mesh)
+ !call read_2ddata_on_grid_NetCDF(filename, 'DOC_sl', i, RiverDOCsl2D, partit, mesh)
+ !call read_2ddata_on_grid_NetCDF(filename, 'POC', i, RiverPOC2D, partit, mesh)
+
+
+
+ !if (mype==0) write(*,'(A)') 'INFO: Using constant pre-industrial riverine inputs'
+ ! Check for read errors
+ !if (i /= 0) then
+ ! if (mype==0) write(*,'(A,A)') 'ERROR: Failed to read PI river inputs from ', trim(filename)
+ ! stop
+ !endif
+ !endif
+
+ else
+
+ ! Use transient (year-specific) river inputs
+ !if (mstep == 1) then
+ !if (mype==0) write(*,'(A,A,A,A)') 'INFO: Using transient riverine inputs - model year = ', &
+ ! trim(cyearnew), ' from ', trim(filename)
+
+ ! Construct filename for current year
+ !filename = trim(REcoMDataPath) // 'Rivers_R2OMIP_' // trim(cyearnew) // '.nc'
+
+ ! Read all nutrient fields for current year
+ !call read_2ddata_on_grid_NetCDF(filename, 'DIC', i, RiverDIC2D, partit, mesh)
+ !if (i /= 0) then
+ !if (mype==0) write(*,'(A,A,A)') 'ERROR: Failed to read DIC from ', trim(filename)
+ !stop
+ ! endif
+
+ !call read_2ddata_on_grid_NetCDF(filename, 'DIN', i, RiverDIN2D, partit, mesh)
+ !if (i /= 0) then
+ !if (mype==0) write(*,'(A,A,A)') 'ERROR: Failed to read DIN from ', trim(filename)
+ !stop
+ !endif
+
+ !call read_2ddata_on_grid_NetCDF(filename, 'DOC_l', i, RiverDOCl2D, partit, mesh)
+ !if (i /= 0) then
+ !if (mype==0) write(*,'(A,A,A)') 'ERROR: Failed to read DOC_l from ', trim(filename)
+ !stop
+ !endif
+
+ !call read_2ddata_on_grid_NetCDF(filename, 'DOC_sl', i, RiverDOCsl2D, partit, mesh)
+ !if (i /= 0) then
+ !if (mype==0) write(*,'(A,A,A)') 'ERROR: Failed to read DOC_sl from ', trim(filename)
+ !stop
+ !endif
+
+ !call read_2ddata_on_grid_NetCDF(filename, 'POC', i, RiverPOC2D, partit, mesh)
+ !if (i /= 0) then
+ !if (mype==0) write(*,'(A,A,A)') 'ERROR: Failed to read POC from ', trim(filename)
+ !stop
+ !endif
+ !endif
+
+ endif
+
+ else
+
+ ! Rivers disabled: set all inputs to zero
+ is_riverinput = 0.0d0
+ RiverDIC2D = 0.0d0
+ RiverDIN2D = 0.0d0
+ RiverDOCl2D = 0.0d0
+ RiverDOCsl2D = 0.0d0
+ RiverPOC2D = 0.0d0
+
+ endif
+
+!IF (.FALSE.) THEN ! CHECK OG
+! if (update_monthly_flag) then
+! i=month
+! if (mstep > 1) i=i+1
+! if (i > 12) i=1
+! filename=trim(nm_river_data_file)
+! if (mype==0) write(*,*) 'Updating riverine restoring data for month', i,' from ', trim(filename)
+! call read_2ddata_on_grid_NetCDF(filename,'Alkalinity', i, RiverAlk2D, partit, mesh)
+! ! write(*,*) mype, 'RiverAlk2D', maxval(RiverAlk2D(:)), minval(RiverAlk2D(:))
+! ! molar convertion of [CaCo3] * 2 -> [total Alkalinity]
+! RiverAlk2D = RiverAlk2D * 2
+!
+! call read_2ddata_on_grid_NetCDF(filename, 'DIC', i, RiverDIC2D, partit, mesh)
+! ! write(*,*) mype, 'RiverDIC2D', maxval(RiverDIC2D(:)), minval(RiverDIC2D(:))
+!
+! call read_2ddata_on_grid_NetCDF(filename, 'DIN', i, RiverDIN2D, partit, mesh)
+! ! write(*,*) mype, 'RiverDIN2D', maxval(RiverDIN2D(:)), minval(RiverDIN2D(:))
+!
+! call read_2ddata_on_grid_NetCDF(filename, 'DOC', i, RiverDOC2D, partit, mesh)
+! ! write(*,*) mype, 'RiverDOC2D', maxval(RiverDOC2D(:)), minval(RiverDOC2D(:))
+!
+! call read_2ddata_on_grid_NetCDF(filename, 'DON', i, RiverDON2D, partit, mesh)
+! ! write(*,*) mype, 'RiverDON2D', maxval(RiverDON2D(:)), minval(RiverDON2D(:))
+!
+! RiverDSi2D = RiverDIN2D * (16/15)
+! end if
+! else
+! is_riverinput = 0.0d0
+! if (mype==0 .and. mstep==1) write(*,*) 'No riverine input'
+! end if
+!ENDIF
! ******** Riverine input of iron *********
if (useRivFe) then
diff --git a/src/int_recom/recom/gasx.F90 b/src/int_recom/recom/gasx.F90
index bd5473527..c4d2d8b01 100755
--- a/src/int_recom/recom/gasx.F90
+++ b/src/int_recom/recom/gasx.F90
@@ -6,7 +6,7 @@ MODULE gasx
!> Computes air-sea CO2 flux & surface-ocean carbonate system vars (pH, CO2*, HCO3- and CO32-, OmegaA, OmegaC, R)
!! from T, S, P, ALK, DIC, total inorganic silicon, total inorganic phosphorus, all as 1-D arrays
SUBROUTINE flxco2(co2flux, co2ex, dpco2, &
- ph, pco2, fco2, co2, hco3, co3, OmegaA, OmegaC, BetaD, rhoSW, p, tempis, &
+ ph, pco2, fco2, co2, hco3, co3, OmegaA, OmegaC, BetaD, rhoSW, p, tempis, K0, &
temp, sal, alk, dic, sil, phos, kw660, xco2, Patm, dz1, N, lon, lat, &
optCON, optT, optP, optB, optK1K2, optKf, optGAS, optS )
! Purpose:
@@ -127,6 +127,8 @@ SUBROUTINE flxco2(co2flux, co2ex, dpco2,
! rhoSW = in-situ density of seawater; rhoSW = f(s, t, p)
! p = pressure [decibars]; p = f(depth, latitude) if computed from depth [m] OR p = depth if [db]
! tempis = in-situ temperature [degrees C]
+ ! K0 = CO2 solubility [(mol/kg) / atm]
+
#if USE_PRECISION == 2
# define SGLE(x) (x)
@@ -237,10 +239,12 @@ SUBROUTINE flxco2(co2flux, co2ex, dpco2,
REAL(kind=rx), INTENT(out), DIMENSION(N) :: p
!> in-situ temperature \b [degrees C]
REAL(kind=rx), INTENT(out), DIMENSION(N) :: tempis
+ !> K0, solubility of CO2 \b [(mol/kg) / atm]
+ REAL(kind=rx), INTENT(out), DIMENSION(N) :: K0
! Local variables
REAL(kind=r8) :: tk, invtk, dtemp
- REAL(kind=r8) :: tmp, K0, co2star, co2starair, kwco2
+ REAL(kind=r8) :: tmp, co2star, co2starair, kwco2 ! K0
REAL(kind=rx), DIMENSION(N) :: pCO2atm, fCO2atm
REAL(kind=rx), DIMENSION(N) :: depth0, lat0
@@ -361,7 +365,7 @@ SUBROUTINE flxco2(co2flux, co2ex, dpco2,
K0 = EXP( tmp + DBLE(salprac(i))*(0.023517d0 - 0.00023656d0*tk + 0.0047036e-4_r8*tk*tk) )
! "Atmospheric" [CO2*], air-sea CO2 flux, sfc DIC rate of change, & Delta pCO2
- co2starair = K0 * DBLE(fco2atm(i)) * 1.0e-6_r8 * DBLE(rhoSW(i)) !Equil. [CO2*] for atm CO2 at Patm & sfc-water T,S [mol/m3]
+ co2starair = K0(i) * DBLE(fco2atm(i)) * 1.0e-6_r8 * DBLE(rhoSW(i)) !Equil. [CO2*] for atm CO2 at Patm & sfc-water T,S [mol/m3]
co2star = DBLE(co2(i)) !Oceanic [CO2*] in [mol/m3] from vars.f90
co2flux(i) = SGLE(kwco2 * (co2starair - co2star)) !Air-sea CO2 flux [mol/(m2 * s)]
! the conversion from co2flux to impact on dic is done in recom_forcing/recom_sms
diff --git a/src/int_recom/recom/vars.F90 b/src/int_recom/recom/vars.F90
index 2ef70defa..d20069a10 100755
--- a/src/int_recom/recom/vars.F90
+++ b/src/int_recom/recom/vars.F90
@@ -570,7 +570,7 @@ SUBROUTINE vars_sprac (ph, pco2, fco2, co2, hco3, co3, OmegaA, OmegaC, kspc_out,
! If Absolute salinity is given
IF (trim(opS) == 'Sabs') THEN
! If in-situ or potential temperature is given
- IF (trim(optT) /= 'Scsv') THEN
+ IF (trim(optT) /= 'Scsv') THEN !!!!!!!!! Is it a bug? OG 20.03.2025 Scsv -> Tcsv .OR. tcsv
! First compute conservative temperature
tempcsv = gsw_ct_from_t (DBLE(ssal), tempis90, DBLE(p(i)))
ELSE
diff --git a/src/int_recom/recom_atbox.F90 b/src/int_recom/recom_atbox.F90
new file mode 100644
index 000000000..4474d44ee
--- /dev/null
+++ b/src/int_recom/recom_atbox.F90
@@ -0,0 +1,91 @@
+ subroutine recom_atbox(partit, mesh)
+! Simple 0-d box model to calculate the temporal evolution of atmospheric CO2.
+! Initially the box model was part of module recom_ciso. Now it can be run also
+! without carbon isotopes (ciso==.false.)
+! mbutzin, 2021-07-08
+
+! Settings are copied from subroutine bio_fluxes,
+! some of the following modules may be unnecessary here
+! use REcoM_declarations
+! use REcoM_LocVar
+ use REcoM_GloVar
+ use recom_config
+ use recom_ciso
+
+ use mod_mesh
+ USE MOD_PARTIT
+ USE MOD_PARSUP
+
+ use g_config
+ use o_arrays
+ use g_comm_auto
+ use g_forcing_arrays
+ use g_support
+
+
+ implicit none
+ integer :: n, elem, elnodes(3),n1
+ real(kind=WP) :: total_co2flux, & ! (mol / s)
+ total_co2flux_13, & ! (mol / s) carbon-13
+ total_co2flux_14 ! (mol / s) radiocarbon
+ real(kind=WP), parameter :: mol_allatm = 1.7726e20 ! atmospheric inventory of all compounds (mol)
+ type(t_partit), intent(inout), target :: partit
+ type(t_mesh) , intent(inout), target :: mesh
+
+#include "../associate_part_def.h"
+#include "../associate_mesh_def.h"
+#include "../associate_part_ass.h"
+#include "../associate_mesh_ass.h"
+
+! Globally integrated air-sea CO2 flux (mol / s)
+ total_co2flux = 0.
+ call integrate_nod(0.001 * GloCO2flux_seaicemask , total_CO2flux, partit, mesh)
+
+! Atmospheric carbon budget (mol)
+! mass of the dry atmosphere = 5.1352e18 kg (Trenberth & Smith 2005, doi:10.1175/JCLI-3299.1)
+! mean density of air = 0.02897 kg / mol (https://nssdc.gsfc.nasa.gov/planetary/factsheet/earthfact.html)
+! => total molecular inventory of the dry atmosphere: moles_atm = 1.7726e20 mol == constant.
+! mol_co2atm = mol_co2atm - total_co2flux * dt
+! Atmospheric mixing ratios in ppm
+! x_co2atm(1) = mol_co2atm / mol_allatm * 1.e6 ! ppm
+ x_co2atm(1) = x_co2atm(1) - total_co2flux / mol_allatm * dt * 1.e6
+ x_co2atm = x_co2atm(1)
+
+ if (ciso) then
+! Consider 13CO2 (and maybe also 14CO2)
+
+! Globally integrated air-sea 13CO2 flux (mol / s)
+ total_co2flux_13 = 0.
+ call integrate_nod(0.001 * GloCO2flux_seaicemask_13, total_co2flux_13, partit, mesh)
+
+! Atmospheric carbon-13 budget (mol)
+! mol_co2atm_13 = mol_co2atm_13 - total_co2flux_13 * dt
+! Budget in terms of the 13C / 12C volume mixing ratio
+! x_co2atm_13(1) = mol_co2atm_13 / mol_allatm * 1.e6
+ x_co2atm_13(1) = x_co2atm_13(1) - total_co2flux_13 / mol_allatm * dt * 1.e6
+ x_co2atm_13 = x_co2atm_13(1)
+
+ if (ciso_14) then
+ total_co2flux_14 = 0. ! globally integrated air-sea 14CO2 flux (mol / s)
+ call integrate_nod(0.001 * GloCO2flux_seaicemask_14, total_co2flux_14, partit, mesh)
+! Atmospheric radiocarbon budget in mol:
+! mol_co2atm_14 = mol_co2atm_14 + dt * (cosmic_14(1) - mol_co2atm_14 * lambda_14 - total_co2flux_14)
+! = (mol_co2atm_14 + dt * (cosmic_14(1) - total_co2flux_14)) / (1 + lambda_14 * dt)
+! Budget in terms of the 14C / 12C volume mixing ratio
+ x_co2atm_14(1) = (x_co2atm_14(1) + dt * (cosmic_14(1) - total_co2flux_14) / mol_allatm * 1.e6) / &
+ (1 + lambda_14 * dt)
+ x_co2atm_14 = x_co2atm_14(1)
+
+! Adjust cosmogenic 14C production (mol / s) in spinup runs,
+ r_atm_14 = x_co2atm_14(1) / x_co2atm(1)
+! r_atm_spinup_14 is calculated once-only in subroutine recom_init
+ if (atbox_spinup .and. abs(r_atm_14 - r_atm_spinup_14) > 0.001) then
+ cosmic_14(1) = cosmic_14(1) * (r_atm_spinup_14 / r_atm_14)
+! cosmic_14(1) = cosmic_14(1) * (1 + 0.01 * (r_atm_14_spinup / r_atm_14))
+ end if
+ cosmic_14 = cosmic_14(1)
+ endif
+ end if
+
+ return
+ end subroutine recom_atbox
diff --git a/src/int_recom/recom_extra.F90 b/src/int_recom/recom_extra.F90
index 5495e0c8f..bdc752315 100644
--- a/src/int_recom/recom_extra.F90
+++ b/src/int_recom/recom_extra.F90
@@ -1,34 +1,35 @@
!===============================================================================
! Subroutine for calculating flux-depth and thickness of control volumes
!===============================================================================
-subroutine Depth_calculations(n,Nn,wF,zF,thick,recipthick, partit, mesh)
- use recom_config
+subroutine Depth_calculations(n, nn, wf, zf, thick, recipthick, partit, mesh)
+ use recom_config
use mod_mesh
- USE MOD_PARTIT
- USE MOD_PARSUP
- USE o_PARAM
- USE o_ARRAYS
- USE g_CONFIG
- use g_forcing_arrays
- use g_comm_auto
-
- use g_clock
- use g_rotate_grid
+ use MOD_PARTIT
+ use MOD_PARSUP
+ use o_PARAM
+ use o_ARRAYS
+ use g_CONFIG
+ use g_forcing_arrays
+ use g_comm_auto
+ use g_clock
+ use g_rotate_grid
- implicit none
-! Input
- type(t_partit), intent(inout), target :: partit
- type(t_mesh) , intent(inout), target :: mesh
-
- Integer, intent(in) :: Nn ! Total number of nodes
-! Output
- real(kind=8),dimension(mesh%nl), intent(out) :: zF ! [m] Depth of vertical fluxes
+ implicit none
- real(kind=8),dimension(mesh%nl-1), intent(out) :: thick ! [m] Distance between two nodes = thickness
- real(kind=8),dimension(mesh%nl-1), intent(out) :: recipthick ! [1/m] reciprocal of thickness
+ ! Input parameters
+ type(t_partit), intent(inout), target :: partit
+ type(t_mesh) , intent(inout), target :: mesh
+ integer , intent(in) :: n ! Current node
+ integer , intent(in) :: nn ! Total number of vertical nodes
- real(kind=8),dimension(mesh%nl,5), intent(out) :: wF ! [m/day] Velocities of fluxes at the border of the control volumes
- Integer :: k, n ! Index for depth
+ ! Output arrays
+ real(kind=8), dimension(mesh%nl,6), intent(out) :: wf ! [m/day] Flux velocities at the border of the control volumes
+ real(kind=8), dimension(mesh%nl), intent(out) :: zf ! [m] Depth of vertical fluxes
+ real(kind=8), dimension(mesh%nl-1), intent(out) :: thick ! [m] Distance between two nodes = layer thickness
+ real(kind=8), dimension(mesh%nl-1), intent(out) :: recipthick ! [1/m] Reciprocal thickness
+
+ ! Local variables
+ integer :: k ! Layer index
#include "../associate_part_def.h"
#include "../associate_mesh_def.h"
@@ -48,16 +49,17 @@ subroutine Depth_calculations(n,Nn,wF,zF,thick,recipthick, partit, mesh)
! allocate(Z_3d_n(nl-1,myDim_nod2D+eDim_nod2D))
! ============================================================================== modular
-!! Background sinking speed
-
- wF(2:Nn,ivphy) = VPhy
- wF(2:Nn,ivdia) = VDia
- wF(2:Nn,ivdet) = VDet
- wF(2:Nn,ivdetsc) = VDet_zoo2
- wF(2:Nn,ivcoc) = VCocco
+ !! Background sinking speed
+ wF(2:Nn, ivphy) = VPhy ! Phytoplankton sinking velocity
+ wF(2:Nn, ivdia) = VDia ! Diatoms sinking velocity
+ wF(2:Nn, ivdet) = VDet ! Detritus sinking velocity
+ wF(2:Nn, ivdetsc) = VDet_zoo2 ! Second detritus sinking velocity
+ wF(2:Nn, ivcoc) = VCocco ! Coccolithophores sinking velocity
+ wF(2:Nn, ivpha) = VPhaeo ! Phaeocystis sinking velocity
- wF(1,:) = 0.d0
- wF(Nn+1,:) = 0.d0
+ !! Boundary conditions (surface and bottom)
+ wF(1,:) = 0.d0
+ wF(Nn+1,:) = 0.d0
!if (allow_var_sinking) then
!! wF(2:Nn+1,ivdet) = Vdet_a * abs(zbar_n(2:Nn+1)) + VDet
@@ -65,31 +67,25 @@ subroutine Depth_calculations(n,Nn,wF,zF,thick,recipthick, partit, mesh)
! wF(2:Nn+1,ivdet) = Vcalc * abs(zbar_3d_n(2:Nn+1, n)) + VDet
!end if
-!----------------------------------------------------
-! Vertical layers thickness
-
- thick =0.0_WP
- recipthick=0.0_WP
- zF=0.0_WP
+ !! Calculate layer thickness and reciprocal of it
+ thick = 0.0_WP
+ recipthick = 0.0_WP
+ zf = 0.0_WP
-!do n=1,myDim_nod2D+eDim_nod2D
- do k=1, Nn !nlevels_nod2D(n)-1
- thick(k)=hnode(k,n)
- if (hnode(k,n) > 0._WP) then
- recipthick(k)=1./hnode(k,n)
- else
- recipthick(k)=0._WP
- end if
- end do
-!end do
-
-! layer depth (negative)
+ do k=1, nn
+ thick(k) = hnode(k,n)
+ if (hnode(k,n) > 0.0_WP) then
+! if thick(k) > 0.0_WP) then ! alternative
+ recipthick(k) = 1.0/hnode(k,n)
+ else
+ recipthick(k) = 0.0_WP
+ end if
+ end do
-!do n=1,myDim_nod2D+eDim_nod2D
- do k=1, Nn+1 !nlevels_nod2D(n)
- zF(k)=zbar_3d_n(k,n)
- end do
-!end do
+ !! set layer depth (negative)
+ do k=1, nn+1
+ zf(k)=zbar_3d_n(k,n)
+ end do
end subroutine Depth_calculations
@@ -100,24 +96,26 @@ subroutine Cobeta(partit, mesh)
use REcoM_GloVar
use g_clock
use mod_mesh
- USE MOD_PARTIT
- USE MOD_PARSUP
+ use MOD_PARTIT
+ use MOD_PARSUP
use o_PARAM
use g_comm_auto
- Implicit none
+
+ implicit none
-! Declarations
- real(kind=8) :: yearfrac ! The fraction of the year that has passed [0 1]
- real(kind=8) :: yDay ! yearfrac in radians [0 2*pi]
- real(kind=8) :: declination = 0.d0 ! Declination of the sun at present lat and time
- real(kind=8) :: CosAngleNoon = 0.d0 ! Cos(Angle of Incidence) at Noon ?
- integer :: n
+ ! Input parameters
+ type(t_partit), intent(inout), target :: partit
+ type(t_mesh) , intent(inout), target :: mesh
-! Constants
- real(kind=8) :: nWater = 1.33
+ ! Local variables
+ real(kind=8) :: yearfrac ! Fraction of year [0 1]
+ real(kind=8) :: yDay ! Year fraction in radians [0 2*pi]
+ real(kind=8) :: declination = 0.d0 ! Declination of the sun at present lat and time
+ real(kind=8) :: CosAngleNoon = 0.d0 ! Cosine of Angle of Incidence at noon
+ integer :: n
- type(t_partit), intent(inout), target :: partit
- type(t_mesh) , intent(inout), target :: mesh
+ ! Constants
+ real(kind=8), parameter :: nWater = 1.33 ! Refractive indices of water
#include "../associate_part_def.h"
#include "../associate_mesh_def.h"
@@ -131,9 +129,11 @@ subroutine Cobeta(partit, mesh)
!! Publishing Company, Amsterdam, Oxford,
!! New York, 1976, ISBN 0-444-41444-4.
- yearfrac = mod(real(daynew),real(ndpyr))/real(ndpyr)
- yDay = 2 * pi * yearfrac
- declination = 0.006918 &
+ !! Calculate solar declination using Paltridge & Platt (1976) formula
+ yearfrac = mod(real(daynew), real(ndpyr)) / real(ndpyr)
+ yDay = 2.0d0 * pi * yearfrac
+
+ declination = 0.006918 &
- 0.399912 * cos( yDay) &
+ 0.070257 * sin( yDay) &
- 0.006758 * cos(2 * yDay) &
@@ -141,33 +141,35 @@ subroutine Cobeta(partit, mesh)
- 0.002697 * cos(3 * yDay) &
+ 0.001480 * sin(3 * yDay)
- do n=1, myDim_nod2D!+eDim_nod2D
-
- cosAngleNoon = sin(geo_coord_nod2D(2,n)) * sin(declination) &
- + cos(geo_coord_nod2D(2,n)) * cos(declination)
- cosAI(n) = sqrt(1-(1-cosAngleNoon**2)/nWater**2)
+ !! Calculate cosine of angle of incidence for each node
+ do n = 1, myDim_nod2D
+ cosAngleNoon = sin(geo_coord_nod2D(2, n)) * sin(declination) &
+ + cos(geo_coord_nod2D(2, n)) * cos(declination)
- end do
+ cosAI(n) = sqrt(1.0d0 - (1.0d0 - cosAngleNoon**2) / nWater**2)
+ end do
end subroutine Cobeta
!================================================================================
! Calculating second zooplankton respiration rates
!================================================================================
subroutine krill_resp(n, partit, mesh)
- use REcoM_declarations
- use REcoM_LocVar
- use REcoM_GloVar
- use g_clock
- use o_PARAM
-! use g_PARSUP
+ use REcoM_declarations
+ use REcoM_LocVar
+ use REcoM_GloVar
+ use g_clock
+ use o_PARAM
use mod_mesh
- USE MOD_PARTIT
- USE MOD_PARSUP
- use g_comm_auto
- implicit none
- integer :: n
-
- type(t_partit), intent(inout), target :: partit
- type(t_mesh) , intent(inout), target :: mesh
+ use MOD_PARTIT
+ use MOD_PARSUP
+ use g_comm_auto
+
+ implicit none
+
+ ! Input parameters
+ integer :: n
+ type(t_partit), intent(inout), target :: partit
+ type(t_mesh) , intent(inout), target :: mesh
+
#include "../associate_part_def.h"
#include "../associate_mesh_def.h"
#include "../associate_part_ass.h"
@@ -202,3 +204,62 @@ subroutine krill_resp(n, partit, mesh)
endif
end subroutine krill_resp
+
+! Load river biogeochemical variables from NetCDF file R2OMIP
+! Variables: DIN, DOCl, DOCs, POC
+
+! Subroutine to read and broadcast a single variable
+
+subroutine load_river_variable(ncid, vari, model_2Darray, partit, mesh)
+
+ use, intrinsic :: ISO_FORTRAN_ENV, only: real64
+
+ use g_config
+ use o_param
+ USE MOD_MESH
+ USE MOD_PARTIT
+ USE MOD_PARSUP
+ use g_rotate_grid
+ use netcdf
+ implicit none
+
+ type(t_mesh), intent(in) , target :: mesh
+ type(t_partit), intent(inout), target :: partit
+ integer :: n
+ integer :: status, ncid, varid
+ integer :: RIstart, RIcount
+
+ real(real64), allocatable :: ncdata(:)
+
+ real(real64), intent(out) :: model_2Darray(partit%myDim_nod2D+partit%eDim_nod2D)
+
+ character(*), intent(in) :: vari
+ integer :: ierror
+
+#include "../associate_part_def.h"
+#include "../associate_mesh_def.h"
+#include "../associate_part_ass.h"
+#include "../associate_mesh_ass.h"
+
+ ! Allocate temporary array for full domain
+ allocate(ncdata(mesh%nod2D))
+
+ if (mype == 0) then
+ status = nf90_inq_varid(ncid, trim(vari), varid)
+ RIstart = 1
+ RIcount = nod2D
+ status = nf90_get_var(ncid, varid, ncdata, start=(/RIstart/), count=(/RIcount/))
+ endif
+
+ ! Broadcast to all processes
+ call MPI_BCast(ncdata, nod2D, MPI_DOUBLE_PRECISION, 0, MPI_COMM_FESOM, ierror)
+
+ ! Extract local partition
+ model_2Darray=ncdata(myList_nod2D)
+
+ ! Clean up
+ deallocate(ncdata)
+
+end subroutine load_river_variable
+
+
diff --git a/src/int_recom/recom_forcing.F90 b/src/int_recom/recom_forcing.F90
index 81650779d..ae314f16b 100644
--- a/src/int_recom/recom_forcing.F90
+++ b/src/int_recom/recom_forcing.F90
@@ -1,7 +1,7 @@
!===============================================================================
! REcoM_Forcing
!===============================================================================
-subroutine REcoM_Forcing(zNodes, n, Nn, state, SurfSW, Loc_slp , Temp, Sali, Sali_depth &
+subroutine REcoM_Forcing(zNodes, n, Nn, state, SurfSW, Loc_slp, Temp, Sali, Sali_depth &
, CO2_watercolumn &
, pH_watercolumn &
, pCO2_watercolumn &
@@ -66,7 +66,7 @@ subroutine REcoM_Forcing(zNodes, n, Nn, state, SurfSW, Loc_slp , Temp, Sali, Sal
!!---- Subroutine Depth
real(kind=8),dimension(mesh%nl) :: zF ! [m] Depth of fluxes
- real(kind=8),dimension(mesh%nl,5) :: SinkVel ! [m/day]
+ real(kind=8),dimension(mesh%nl,6) :: SinkVel ! [m/day]
real(kind=8),dimension(mesh%nl-1) :: thick ! [m] Vertical distance between two nodes = Thickness
real(kind=8),dimension(mesh%nl-1) :: recipthick ! [1/m] reciprocal of thick
@@ -110,10 +110,13 @@ subroutine REcoM_Forcing(zNodes, n, Nn, state, SurfSW, Loc_slp , Temp, Sali, Sal
tiny_Si = tiny_C_d/SiCmax ! SiCmax = 0.8d0
-#if defined (__coccos)
- tiny_N_c = tiny_chl/chl2N_max_c ! 0.00001/ 3.5d0
+if (enable_coccos) then
+ tiny_N_c = tiny_chl/chl2N_max_c ! 0.00001/ 3.5d0
tiny_C_c = tiny_N_c/NCmax_c ! NCmax_c = 0.15d0
-#endif
+
+ tiny_N_p = tiny_chl/chl2N_max_p ! 0.00001/ 3.5d0
+ tiny_C_p = tiny_N_p/NCmax_p ! NCmax_c = 0.15d0
+endif
call Cobeta(partit, mesh)
call Depth_calculations(n, Nn,SinkVel,zF,thick,recipthick, partit, mesh)
@@ -134,7 +137,7 @@ subroutine REcoM_Forcing(zNodes, n, Nn, state, SurfSW, Loc_slp , Temp, Sali, Sal
REcoM_T = min(REcoM_T, 40.d0)
!!---- minimum set to 21: K1/K2 Lueker valid between 2degC-35degC and 19-43psu, else causes trouble in regions with S between 19 and 21 and ice conc above 97%
- REcoM_S = max(21.d0, Sali(1))
+ REcoM_S = max(21.d0, Sali(1))
!!---- maximum set to 43: K1/K2 Lueker valid between 2degC-35degC and 19-43psu, else causes trouble REcoM_S = min(REcoM_S, 43.d0) !!!!!!!!
!!---- convert from Pa to atm.
@@ -183,7 +186,7 @@ subroutine REcoM_Forcing(zNodes, n, Nn, state, SurfSW, Loc_slp , Temp, Sali, Sal
endif
call flxco2(co2flux, co2ex, dpco2surf, &
- ph, pco2surf, fco2, co2, hco3, co3, OmegaA, OmegaC, BetaD, rhoSW, p, tempis, &
+ ph, pco2surf, fco2, co2, hco3, co3, OmegaA, OmegaC, BetaD, rhoSW, p, tempis, K0, &
REcoM_T, REcoM_S, REcoM_Alk, REcoM_DIC, REcoM_Si, REcoM_Phos, kw660, LocAtmCO2, Patm, thick(One), Nmocsy, Lond,Latd, &
optCON='mol/m3',optT='Tpot ',optP='m ',optB='u74',optK1K2='l ',optKf='dg',optGAS='Pinsitu',optS='Sprc')
@@ -259,19 +262,71 @@ subroutine REcoM_Forcing(zNodes, n, Nn, state, SurfSW, Loc_slp , Temp, Sali, Sal
state(1:nn,idiac) = max(tiny_C_d,state(1:nn,idiac))
state(1:nn,idiasi) = max(tiny_Si, state(1:nn,idiasi))
-#if defined (__coccos)
+if (enable_coccos) then
state(1:nn,icchl) = max(tiny_chl,state(1:nn,icchl))
state(1:nn,icocn) = max(tiny_N_c,state(1:nn,icocn))
state(1:nn,icocc) = max(tiny_C_c,state(1:nn,icocc))
-#endif
-#if defined (__3Zoo2Det)
+ state(1:nn,iphachl) = max(tiny_chl,state(1:nn,iphachl))
+ state(1:nn,iphan) = max(tiny_N_p,state(1:nn,iphan))
+ state(1:nn,iphac) = max(tiny_C_p,state(1:nn,iphac))
+endif
+
+if (enable_3zoo2det) then
state(1:nn,imiczoon) = max(tiny,state(1:nn,imiczoon))
state(1:nn,imiczooc) = max(tiny,state(1:nn,imiczooc))
-#endif
+endif
if (recom_debug .and. mype==0) print *, achar(27)//'[36m'//' --> ciso after REcoM_Forcing'//achar(27)//'[0m'
+ if (ciso) then
+! Calculate carbon-isotopic fractionation, radioactive decay is calculated in oce_ale_tracer.F90
+
+! Fractionation due to air-sea exchange and chemical speciation of CO2
+ call recom_ciso_airsea(recom_t(1), co3(1), recom_dic(1)) ! -> alpha_aq, alpha_dic. CO3 is taken from mocsy
+
+! Isotopic ratios of dissolved CO2, also needed to calculate biogenic fractionation
+ r_dic_13 = max(tiny*1e-3,state(1,idic_13)*1e-3) / recom_dic(1)
+ r_co2s_13 = alpha_aq_13 / alpha_dic_13 * r_dic_13
+! Calculate air-sea fluxes of 13|14CO2 in mmol / m**2 / s
+ kwco2 = kw660(1) * (660/scco2(REcoM_T(1)))**0.5 ! Piston velocity (via mocsy)
+ co2sat = co2flux(1) / (kwco2 + tiny) + co2(1) ! Saturation concentration of CO2 (via mocsy)
+! co2flux_13 = kwco2 * alpha_k_13 * (alpha_aq_13 * r_atm_13 * co2sat - r_co2s_13 * co2(1))
+! co2flux_13 = alpha_k_13 * alpha_aq_13 * kwco2 * (r_atm_13 * co2sat - r_dic_13 * co2(1) / alpha_dic_13)
+! Fractionation factors were determined for freshwater, include a correction for enhanced fractionation in seawater
+ co2flux_13 = (alpha_k_13 * alpha_aq_13 - 0.0002) * kwco2 * (r_atm_13 * co2sat - r_dic_13 * co2(1) / alpha_dic_13)
+ co2flux_seaicemask_13 = co2flux_13 * 1.e3
+
+! Biogenic fractionation due to photosynthesis of plankton
+! phyc_13|14 and diac_13|14 are only used in REcoM_sms to calculate DIC_13|14, DOC_13|14 and DetC_13|14
+
+ call recom_ciso_photo(co2(1)) ! -> alpha_p
+ r_phyc_13 = r_co2s_13 / alpha_p_13
+ r_diac_13 = r_co2s_13 / alpha_p_dia_13
+ state(1:nn,iphyc_13) = max((tiny_C * r_phyc_13), (state(1:nn,iphyc) * r_phyc_13))
+ state(1:nn,idiac_13) = max((tiny_C_d * r_diac_13), (state(1:nn,idiac) * r_diac_13))
+
+! The same for radiocarbon, fractionation factors have been already derived above
+ if (ciso_14) then
+! Air-sea exchange
+ r_dic_14 = max(tiny*1e-3,state(1,idic_14)*1e-3) / recom_dic(1)
+ r_co2s_14 = alpha_aq_14 / alpha_dic_14 * r_dic_14
+! co2flux_14 = kwco2 * alpha_k_14 * (alpha_aq_14 * r_atm_14 * co2sat - r_co2s_14 * co2(1))
+! Fractionation factors were determined for freshwater, include a correction for enhanced fractionation seawater
+ co2flux_14 = (alpha_k_14 * alpha_aq_14 - 0.0004) * kwco2 * (r_atm_14 * co2sat - r_dic_14 * co2(1) / alpha_dic_14)
+ co2flux_seaicemask_14 = co2flux_14 * 1.e3
+! Biogenic fractionation
+ if (ciso_organic_14) then
+ r_phyc_14 = r_co2s_14 / alpha_p_14
+ r_diac_14 = r_co2s_14 / alpha_p_dia_14
+ state(1:nn,iphyc_14) = max((tiny_C * r_phyc_14), (state(1:nn,iphyc) * r_phyc_14))
+ state(1:nn,idiac_14) = max((tiny_C_d * r_diac_14), (state(1:nn,idiac) * r_diac_14))
+ end if
+ end if
+! Radiocarbon
+ end if
+! ciso
+
!-------------------------------------------------------------------------------
! Diagnostics
if (Diags) then
@@ -291,10 +346,66 @@ subroutine REcoM_Forcing(zNodes, n, Nn, state, SurfSW, Loc_slp , Temp, Sali, Sal
locNNAd = sum(vertNNAd(1:nn) * thick(1:nn))
locChldegd = sum(vertChldegd(1:nn) * thick(1:nn))
+if (enable_coccos) then
locNPPc = sum(vertNPPc(1:nn) * thick(1:nn))
locGPPc = sum(vertGPPc(1:nn) * thick(1:nn))
locNNAc = sum(vertNNAc(1:nn) * thick(1:nn))
locChldegc = sum(vertChldegc(1:nn) * thick(1:nn))
+ locNPPp = sum(vertNPPp(1:nn) * thick(1:nn))
+ locGPPp = sum(vertGPPp(1:nn) * thick(1:nn))
+ locNNAp = sum(vertNNAp(1:nn) * thick(1:nn))
+ locChldegp = sum(vertChldegp(1:nn) * thick(1:nn))
+endif
+
+ if (Grazing_detritus) then ! only for the case if grazing detritus is used, as probably only needed for tuning which uses detritus grazing
+ ! Mesozooplankton
+ locgrazmeso_tot = sum(vertgrazmeso_tot(1:nn) * thick(1:nn))
+ locgrazmeso_n = sum(vertgrazmeso_n(1:nn) * thick(1:nn))
+ locgrazmeso_d = sum(vertgrazmeso_d(1:nn) * thick(1:nn))
+ if (enable_coccos) then
+ locgrazmeso_c = sum(vertgrazmeso_c(1:nn) * thick(1:nn))
+ locgrazmeso_p = sum(vertgrazmeso_p(1:nn) * thick(1:nn))
+ endif
+ locgrazmeso_det = sum(vertgrazmeso_det(1:nn) * thick(1:nn))
+ if (enable_3zoo2det) then
+ locgrazmeso_mic = sum(vertgrazmeso_mic(1:nn) * thick(1:nn))
+ locgrazmeso_det2= sum(vertgrazmeso_det2(1:nn) * thick(1:nn))
+ endif
+
+ if (enable_3zoo2det) then
+ ! Macrozooplankton
+ locgrazmacro_tot = sum(vertgrazmacro_tot(1:nn) * thick(1:nn))
+ locgrazmacro_n = sum(vertgrazmacro_n(1:nn) * thick(1:nn))
+ locgrazmacro_d = sum(vertgrazmacro_d(1:nn) * thick(1:nn))
+ if (enable_coccos) then
+ locgrazmacro_c = sum(vertgrazmacro_c(1:nn) * thick(1:nn))
+ locgrazmacro_p = sum(vertgrazmacro_p(1:nn) * thick(1:nn))
+ endif
+ locgrazmacro_mes = sum(vertgrazmacro_mes(1:nn) * thick(1:nn))
+ locgrazmacro_det = sum(vertgrazmacro_det(1:nn) * thick(1:nn))
+ locgrazmacro_mic = sum(vertgrazmacro_mic(1:nn) * thick(1:nn))
+ locgrazmacro_det2 = sum(vertgrazmacro_det2(1:nn) * thick(1:nn))
+
+ ! Microzooplankton
+ locgrazmicro_tot = sum(vertgrazmicro_tot(1:nn) * thick(1:nn))
+ locgrazmicro_n = sum(vertgrazmicro_n(1:nn) * thick(1:nn))
+ locgrazmicro_d = sum(vertgrazmicro_d(1:nn) * thick(1:nn))
+ if (enable_coccos) then
+ locgrazmicro_c = sum(vertgrazmicro_c(1:nn) * thick(1:nn))
+ locgrazmicro_p = sum(vertgrazmicro_p(1:nn) * thick(1:nn))
+ endif
+
+ endif
+ endif
+
+ ! Dissolution and remineralization ! R2OMIP
+ locDISSOC = sum(vertDISSOC(1:nn) * thick(1:nn))
+ locDISSON = sum(vertDISSON(1:nn) * thick(1:nn))
+ locDISSOSi = sum(vertDISSOSi(1:nn) * thick(1:nn))
+ locREMOC = sum(vertREMOC(1:nn) * thick(1:nn))
+ locREMOCt = sum(vertREMOCt(1:nn) * thick(1:nn))
+ locREMON = sum(vertREMON(1:nn) * thick(1:nn))
+
end if
end subroutine REcoM_Forcing
diff --git a/src/int_recom/recom_init.F90 b/src/int_recom/recom_init.F90
index e9b5aebbf..d622b83c2 100644
--- a/src/int_recom/recom_init.F90
+++ b/src/int_recom/recom_init.F90
@@ -45,6 +45,9 @@ subroutine recom_init(tracers, partit, mesh)
type(t_partit), intent(inout), target :: partit
type(t_mesh), intent(in) , target :: mesh
+ ! After reading tracer namelist - validate actual IDs
+ integer, dimension(tracers%num_tracers) :: tracer_id_array
+
#include "../associate_part_def.h"
#include "../associate_mesh_def.h"
#include "../associate_part_ass.h"
@@ -63,14 +66,24 @@ subroutine recom_init(tracers, partit, mesh)
allocate(GloNDust ( node_size ))
allocate(AtmNInput ( node_size ))
+ ! calcite dissolution at the ocean bottom
+ allocate(OmegaC_bottom(node_size)) !R2OMIP
+
!! * River nutrients as surface boundary condition *
- allocate(RiverDIN2D ( node_size ))
+! allocate(RiverDIN2D ( node_size ))
allocate(RiverDON2D ( node_size ))
- allocate(RiverDOC2D ( node_size ))
+! allocate(RiverDOC2D ( node_size ))
allocate(RiverDSi2D ( node_size ))
- allocate(RiverDIC2D ( node_size ))
+! allocate(RiverDIC2D ( node_size ))
allocate(RiverAlk2D ( node_size ))
+ allocate(RiverDIC2D ( node_size )) ! R2OMIP
+ allocate(RiverDIN2D ( node_size )) ! R2OMIP
+ allocate(RiverDOCl2D ( node_size )) ! R2OMIP
+ allocate(RiverDOCsl2D ( node_size )) ! R2OMIP
+ allocate(RiverPOC2D ( node_size )) ! R2OMIP
+ allocate(RiverFe ( node_size ))
+
!! * Erosion nutrients as surface boundary condition *
allocate(ErosionTON2D ( node_size ))
allocate(ErosionTOC2D ( node_size ))
@@ -90,26 +103,49 @@ subroutine recom_init(tracers, partit, mesh)
allocate(GlodecayBenthos ( node_size, benthos_num ))
allocate(Benthos ( node_size, benthos_num ))
allocate(Benthos_tr ( node_size, benthos_num, num_tracers )) ! kh 25.03.22 buffer per tracer index
+
+ allocate(LocDenit ( node_size ))
+ allocate(LocBurial ( benthos_num, node_size )) ! R2OMIP
+ allocate(Burial ( benthos_num, node_size )) ! R2OMIP
+ allocate(BurialBen ( benthos_num )) ! R2OMIP
+ allocate(Sed_2_Ocean_Flux ( node_size, 6 )) ! DIN, DIC, Alk, DSi, DFe, O2 ! R2OMIP
+ allocate(Ocean_2_Sed_Flux ( node_size, benthos_num )) ! C, Si, N, Calc ! R2OMIP
+
allocate(GloHplus ( node_size ))
allocate(DenitBen ( node_size ))
+ allocate(PistonVelocity ( node_size ))
+ allocate(alphaCO2 ( node_size ))
+
allocate(LocBenthos ( benthos_num ))
allocate(decayBenthos ( benthos_num )) ! [1/day] Decay rate of detritus in the benthic layer
allocate(PAR3D ( nl-1, node_size ))
+
GloFeDust = 0.d0
AtmFeInput = 0.d0
GloNDust = 0.d0
AtmNInput = 0.d0
- RiverDIN2D = 0.d0
+ ! calcite dissolution at the ocean bottom !R2OMIP
+ OmegaC_bottom = 0.d0
+
+! RiverDIN2D = 0.d0
RiverDON2D = 0.d0
- RiverDOC2D = 0.d0
+! RiverDOC2D = 0.d0
RiverDSi2D = 0.d0
- RiverDIC2D = 0.d0
+! RiverDIC2D = 0.d0
RiverAlk2D = 0.d0
- ErosionTON2D = 0.d0
+ RiverDIC2D = 0.d0
+ RiverDIN2D = 0.d0
+ RiverDOCl2D = 0.d0
+ RiverDOCsl2D = 0.d0
+ RiverPOC2D = 0.d0
+
+ RiverFe = 0.d0
+
+ ErosionTOC2D = 0.d0
ErosionTON2D = 0.d0
ErosionTSi2D = 0.d0
@@ -127,11 +163,15 @@ subroutine recom_init(tracers, partit, mesh)
Benthos_tr(:,:,:) = 0.0d0 ! kh 25.03.22
GloHplus = exp(-8.d0 * log(10.d0)) ! = 10**(-8)
DenitBen = 0.d0
+ PistonVelocity = 0.d0
+ alphaCO2 = 0.d0
+
+ Burial = 0.d0 ! R2OMIP
+ Sed_2_Ocean_Flux = 0.0d0 ! R2OMIP
+ Ocean_2_Sed_Flux = 0.0d0 ! R2OMIP
LocBenthos = 0.d0
decayBenthos = 0.d0
- wFluxPhy = 0.d0
- wFluxDia = 0.d0
PAR3D = 0.d0
! pco2surf = 0.d0
@@ -148,28 +188,100 @@ subroutine recom_init(tracers, partit, mesh)
allocate(NPPn ( node_size ))
allocate(NPPd ( node_size ))
allocate(NPPc ( node_size ))
+ allocate(NPPp ( node_size ))
allocate(GPPn ( node_size ))
allocate(GPPd ( node_size ))
allocate(GPPc ( node_size ))
+ allocate(GPPp ( node_size ))
allocate(NNAn ( node_size ))
allocate(NNAd ( node_size ))
allocate(NNAc ( node_size ))
+ allocate(NNAp ( node_size ))
allocate(Chldegn ( node_size ))
allocate(Chldegd ( node_size ))
allocate(Chldegc ( node_size ))
+ allocate(Chldegp ( node_size ))
NPPn = 0.d0
NPPd = 0.d0
NPPc = 0.d0
+ NPPp = 0.d0
GPPn = 0.d0
GPPd = 0.d0
GPPc = 0.d0
+ GPPp = 0.d0
NNAn = 0.d0
NNAd = 0.d0
NNAc = 0.d0
+ NNAp = 0.d0
Chldegn = 0.d0
Chldegd = 0.d0
Chldegc = 0.d0
+ Chldegp = 0.d0
+
+ allocate(grazmeso_tot(node_size))
+ allocate(grazmeso_n(node_size))
+ allocate(grazmeso_d(node_size))
+ allocate(grazmeso_c(node_size))
+ allocate(grazmeso_p(node_size))
+ allocate(grazmeso_det(node_size))
+ allocate(grazmeso_mic(node_size))
+ allocate(grazmeso_det2(node_size))
+
+ grazmeso_tot = 0.d0
+ grazmeso_n = 0.d0
+ grazmeso_d = 0.d0
+ grazmeso_c = 0.d0
+ grazmeso_p = 0.d0
+ grazmeso_det = 0.d0
+ grazmeso_mic = 0.d0
+ grazmeso_det2= 0.d0
+
+ allocate(grazmacro_tot(node_size))
+ allocate(grazmacro_n(node_size))
+ allocate(grazmacro_d(node_size))
+ allocate(grazmacro_c(node_size))
+ allocate(grazmacro_p(node_size))
+ allocate(grazmacro_mes(node_size))
+ allocate(grazmacro_det(node_size))
+ allocate(grazmacro_mic(node_size))
+ allocate(grazmacro_det2(node_size))
+
+ grazmacro_tot = 0.d0
+ grazmacro_n = 0.d0
+ grazmacro_d = 0.d0
+ grazmacro_c = 0.d0
+ grazmacro_p = 0.d0
+ grazmacro_mes = 0.d0
+ grazmacro_det = 0.d0
+ grazmacro_mic = 0.d0
+ grazmacro_det2= 0.d0
+
+ allocate(grazmicro_tot(node_size))
+ allocate(grazmicro_n(node_size))
+ allocate(grazmicro_d(node_size))
+ allocate(grazmicro_c(node_size))
+ allocate(grazmicro_p(node_size))
+
+ grazmicro_tot = 0.d0
+ grazmicro_n = 0.d0
+ grazmicro_d = 0.d0
+ grazmicro_c = 0.d0
+ grazmicro_p = 0.d0
+
+ ! Dissolution and remineralization ! R2OMIP
+ allocate(DISSOC(node_size))
+ allocate(DISSON(node_size))
+ allocate(DISSOSi(node_size))
+ allocate(REMOC(node_size))
+ allocate(REMOCt(node_size))
+ allocate(REMON(node_size))
+ DISSOC = 0.d0
+ DISSON = 0.d0
+ DISSOSi = 0.d0
+ REMOC = 0.d0
+ REMOCt = 0.d0
+ REMON = 0.d0
!! *** Allocate 3D diagnostics ***
allocate(respmeso ( nl-1, node_size ))
@@ -180,15 +292,34 @@ subroutine recom_init(tracers, partit, mesh)
allocate(aggn ( nl-1, node_size ))
allocate(aggd ( nl-1, node_size ))
allocate(aggc ( nl-1, node_size ))
+ allocate(aggp ( nl-1, node_size ))
allocate(docexn ( nl-1, node_size ))
allocate(docexd ( nl-1, node_size ))
allocate(docexc ( nl-1, node_size ))
+ allocate(docexp ( nl-1, node_size ))
allocate(respn ( nl-1, node_size ))
allocate(respd ( nl-1, node_size ))
allocate(respc ( nl-1, node_size ))
+ allocate(respp ( nl-1, node_size ))
allocate(NPPn3D ( nl-1, node_size ))
allocate(NPPd3D ( nl-1, node_size ))
allocate(NPPc3D ( nl-1, node_size ))
+ allocate(NPPp3D ( nl-1, node_size ))
+
+ allocate(photn ( nl-1, node_size ))
+ allocate(photd ( nl-1, node_size ))
+ allocate(photc ( nl-1, node_size ))
+ allocate(photp ( nl-1, node_size ))
+ allocate(DOCremin ( nl-1, node_size ))
+ allocate(Nassimn ( nl-1, node_size ))
+ allocate(Nassimd ( nl-1, node_size ))
+ allocate(Nassimc ( nl-1, node_size ))
+ allocate(Nassimp ( nl-1, node_size ))
+ allocate(DONremin ( nl-1, node_size ))
+ allocate(fastcdis ( nl-1, node_size ))
+ allocate(mesocdis ( nl-1, node_size ))
+ allocate(microcdis ( nl-1, node_size ))
+ allocate(macrocdis ( nl-1, node_size ))
respmeso = 0.d0
respmacro = 0.d0
@@ -198,15 +329,93 @@ subroutine recom_init(tracers, partit, mesh)
aggn = 0.d0
aggd = 0.d0
aggc = 0.d0
+ aggp = 0.d0
docexn = 0.d0
docexd = 0.d0
docexc = 0.d0
+ docexp = 0.d0
respn = 0.d0
respd = 0.d0
respc = 0.d0
+ respp = 0.d0
NPPn3D = 0.d0
NPPd3D = 0.d0
NPPc3D = 0.d0
+ NPPp3D = 0.d0
+
+ photn = 0.d0
+ photd = 0.d0
+ photc = 0.d0
+ photp = 0.d0
+ DOCremin = 0.d0
+ Nassimn = 0.d0
+ Nassimd = 0.d0
+ Nassimc = 0.d0
+ Nassimp = 0.d0
+ DONremin = 0.d0
+ fastcdis = 0.d0
+ mesocdis = 0.d0
+ microcdis = 0.d0
+ macrocdis = 0.d0
+
+!! From Hannahs new temperature function (not sure if needed as diagnostic):
+
+ allocate(TTemp_diatoms (nl-1,node_size))
+ allocate(TTemp_phyto (nl-1,node_size))
+ allocate(TTemp_cocco (nl-1,node_size))
+ allocate(TTemp_phaeo (nl-1,node_size))
+
+ TTemp_diatoms (:,:) = 0.d0
+ TTemp_phyto (:,:) = 0.d0
+ TTemp_cocco (:,:) = 0.d0
+ TTemp_phaeo (:,:) = 0.d0
+
+ allocate(TPhyCO2 (nl-1,node_size))
+ allocate(TDiaCO2 (nl-1,node_size))
+ allocate(TCoccoCO2 (nl-1,node_size))
+ allocate(TPhaeoCO2 (nl-1,node_size))
+
+ TPhyCO2 (:,:) = 0.d0
+ TDiaCO2 (:,:) = 0.d0
+ TCoccoCO2 (:,:) = 0.d0
+ TPhaeoCO2 (:,:) = 0.d0
+
+ allocate(TqlimitFac_phyto (nl-1,node_size))
+ allocate(TqlimitFac_diatoms (nl-1,node_size))
+ allocate(TqlimitFac_cocco (nl-1,node_size))
+ allocate(TqlimitFac_phaeo (nl-1,node_size))
+
+ TqlimitFac_phyto (:,:) = 0.d0
+ TqlimitFac_diatoms (:,:) = 0.d0
+ TqlimitFac_cocco (:,:) = 0.d0
+ TqlimitFac_phaeo (:,:) = 0.d0
+
+
+ allocate(TCphotLigLim_diatoms (nl-1,node_size))
+ allocate(TCphotLigLim_phyto (nl-1,node_size))
+ allocate(TCphotLigLim_cocco (nl-1,node_size))
+ allocate(TCphotLigLim_phaeo (nl-1,node_size))
+
+
+ TCphotLigLim_diatoms (:,:) = 0.d0
+ TCphotLigLim_phyto (:,:) = 0.d0
+ TCphotLigLim_cocco (:,:) = 0.d0
+ TCphotLigLim_phaeo (:,:) = 0.d0
+
+ allocate(TCphot_diatoms (nl-1,node_size))
+ allocate(TCphot_phyto (nl-1,node_size))
+ allocate(TCphot_cocco (nl-1,node_size))
+ allocate(TCphot_phaeo (nl-1,node_size))
+
+ TCphot_diatoms (:,:) = 0.d0
+ TCphot_phyto (:,:) = 0.d0
+ TCphot_cocco (:,:) = 0.d0
+ TCphot_phaeo (:,:) = 0.d0
+
+ allocate(TSi_assimDia (nl-1,node_size))
+
+ TSi_assimDia (:,:) = 0.d0
+
end if
!! *** Allocate 3D mocsy ***
@@ -246,125 +455,258 @@ subroutine recom_init(tracers, partit, mesh)
Sinkingvel1(:,:) = 0.d0
Sinkingvel2(:,:) = 0.d0
+ allocate(Sinkvel1_tr(nl,node_size,num_tracers), Sinkvel2_tr(nl,node_size,num_tracers)) ! OG 16.03.23
+ Sinkvel1_tr(:,:,:) = 0.0d0
+ Sinkvel2_tr(:,:,:) = 0.0d0
+
+ allocate(dtr_bf_dic(nl,node_size,num_tracers),dtr_bflux_dic(nl,node_size)) ! RP on 26.09.2025
+ dtr_bflux_dic(:,:) = 0.0d0 !RP on 26.09.2025
+ dtr_bf_dic(:,:,:) = 0.0d0 !RP on 26.09.2025
+
+ allocate(dtr_bf_din(nl,node_size,num_tracers),dtr_bflux_din(nl,node_size))
+ dtr_bflux_din(:,:) = 0.0d0
+ dtr_bf_din(:,:,:) = 0.0d0
+
+ allocate(dtr_bf_alk(nl,node_size,num_tracers),dtr_bflux_alk(nl,node_size))
+ dtr_bflux_alk(:,:) = 0.0d0
+ dtr_bf_alk(:,:,:) = 0.0d0
+
+ allocate(dtr_bf_dsi(nl,node_size,num_tracers),dtr_bflux_dsi(nl,node_size))
+ dtr_bflux_dsi(:,:) = 0.0d0
+ dtr_bf_dsi(:,:,:) = 0.0d0
+
+ if (use_MEDUSA) then
+ allocate(GloSed(node_size,sedflx_num))
+ allocate(SinkFlx(node_size,bottflx_num))
+ allocate(SinkFlx_tr(node_size,bottflx_num,num_tracers)) ! kh 25.03.22 buffer sums per tracer index
+
+ SinkFlx(:,:) = 0.d0
+ SinkFlx_tr(:,:,:) = 0.0d0 ! kh 25.03.22
+ GloSed(:,:) = 0.d0
+ allocate(lb_flux(node_size,9))
+ lb_flux(:,:) = 0.d0
+ end if
+
+ ! After reading parecomsetup namelist
+ call initialize_tracer_indices
+
+ ! Validation check here
+ call validate_recom_tracers(num_tracers, mype)
+
+ ! ... populate tracer_id_array from namelist ...
+ tracer_id_array = tracers%data(1:tracers%num_tracers)%ID
+ call validate_tracer_id_sequence(tracer_id_array, num_tracers, mype)
+
+ !===============================================================================
+ ! Model Configuration Summary
+ !===============================================================================
+ ! Configuration 1: Base model (enable_3zoo2det=F, enable_coccos=F)
+ ! - 2 Phytoplankton: General Phy, Diatoms
+ ! - 1 Zooplankton: Heterotrophs
+ ! - 1 Detritus pool
+ !
+ ! Configuration 2: 3Zoo2Det (enable_3zoo2det=T, enable_coccos=F)
+ ! - 2 Phytoplankton: General Phy, Diatoms
+ ! - 3 Zooplankton: Het, Zoo2, Zoo3
+ ! - 2 Detritus pools
+ !
+ ! Configuration 3: Coccos (enable_3zoo2det=F, enable_coccos=T)
+ ! - 4 Phytoplankton: General Phy, Diatoms, Coccos, Phaeo
+ ! - 1 Zooplankton: Heterotrophs
+ ! - 1 Detritus pool
+ !
+ ! Configuration 4: Full model (enable_3zoo2det=T, enable_coccos=T)
+ ! - 4 Phytoplankton: General Phy, Diatoms, Coccos, Phaeo
+ ! - 3 Zooplankton: Het, Zoo2, Zoo3
+ ! - 2 Detritus pools
+ !===============================================================================
+
DO i=num_tracers-bgc_num+1, num_tracers
id=tracers%data(i)%ID
SELECT CASE (id)
-! *******************
-! CASE 2phy 1zoo 1det
-! *******************
-! Skip: DIN, DIC, Alk, DSi and O2 are read from files
-! Fe [mol/L] => [umol/m3] Check the units again!
+ !---------------------------------------------------------------------------
+ ! Base Model: 2 Phytoplankton + 1 Zooplankton + 1 Detritus
+ !---------------------------------------------------------------------------
+ ! Skip: DIN, DIC, Alk, DSi and O2 are read from files
+ ! Fe [mol/L] => [umol/m3] Check the units again!
+
+ ! --- Small Phytoplankton
+ CASE (1004) ! PhyN - Phytoplankton Nitrogen
+ tracers%data(i)%values(:,:) = tiny_chl/chl2N_max
- CASE (1004)
- tracers%data(i)%values(:,:) = tiny_chl/chl2N_max ! PhyN
+ CASE (1005) ! PhyC - Phytoplankton Carbon
+ tracers%data(i)%values(:,:) = tiny_chl/chl2N_max/NCmax
- CASE (1005)
- tracers%data(i)%values(:,:) = tiny_chl/chl2N_max/NCmax ! PhyC
+ CASE (1006) ! PhyChl - Phytoplankton Chlorophyll
+ tracers%data(i)%values(:,:) = tiny_chl
- CASE (1006)
- tracers%data(i)%values(:,:) = tiny_chl ! PhyChl
+ ! --- Detritus (Non-living organic matter) ---
+ CASE (1007) ! DetN - Detrital Nitrogen
+ tracers%data(i)%values(:,:) = tiny
- CASE (1007)
- tracers%data(i)%values(:,:) = tiny ! DetN
+ CASE (1008) ! DetC - Detrital Carbon
+ tracers%data(i)%values(:,:) = tiny
- CASE (1008)
- tracers%data(i)%values(:,:) = tiny ! DetC
+ ! --- Mesozooplankton (Heterotrophs) ---
+ CASE (1009) ! HetN - Heterotroph Nitrogen
+ tracers%data(i)%values(:,:) = tiny
- CASE (1009)
- tracers%data(i)%values(:,:) = tiny ! HetN
+ CASE (1010) ! HetC - Heterotroph Carbon (using Redfield ratio)
+ tracers%data(i)%values(:,:) = tiny * Redfield
- CASE (1010)
- tracers%data(i)%values(:,:) = tiny * Redfield ! HetC
+ ! --- Dissolved Organic Matter ---
+ CASE (1011) ! DON - Dissolved Organic Nitrogen
+ tracers%data(i)%values(:,:) = tiny
- CASE (1011)
- tracers%data(i)%values(:,:) = tiny ! DON
+ CASE (1012) ! DOC - Dissolved Organic Carbon
+ tracers%data(i)%values(:,:) = tiny
- CASE (1012)
- tracers%data(i)%values(:,:) = tiny ! DOC
+ ! --- Diatoms ---
+ CASE (1013) ! DiaN - Diatom Nitrogen
+ tracers%data(i)%values(:,:) = tiny_chl/chl2N_max
- CASE (1013)
- tracers%data(i)%values(:,:) = tiny_chl/chl2N_max ! DiaN
+ CASE (1014) ! DiaC - Diatom Carbon
+ tracers%data(i)%values(:,:) = tiny_chl/chl2N_max/NCmax
- CASE (1014)
- tracers%data(i)%values(:,:) = tiny_chl/chl2N_max/NCmax ! DiaC
+ CASE (1015) ! DiaChl - Diatom Chlorophyll
+ tracers%data(i)%values(:,:) = tiny_chl
- CASE (1015)
- tracers%data(i)%values(:,:) = tiny_chl ! DiaChl
+ CASE (1016) ! DiaSi - Diatom Silica
+ tracers%data(i)%values(:,:) = tiny_chl/chl2N_max_d/NCmax_d/SiCmax
- CASE (1016)
- tracers%data(i)%values(:,:) = tiny_chl/chl2N_max_d/NCmax_d/SiCmax ! DiaSi
+ CASE (1017) ! DetSi - Detrital Silica
+ tracers%data(i)%values(:,:) = tiny
- CASE (1017)
- tracers%data(i)%values(:,:) = tiny ! DetSi
+ ! --- Iron (micronutrient) ---
+ CASE (1019) ! Fe - Iron (unit conversion: mol/L => umol/m3)
+ tracers%data(i)%values(:,:) = tracers%data(i)%values(:,:)* 1.e9
- CASE (1019)
- tracers%data(i)%values(:,:) = tracers%data(i)%values(:,:)* 1.e9 ! Fe [mol/L] => [umol/m3] Check the units again!
+ ! --- Calcium Carbonate (Calcite) ---
+ CASE (1020) ! PhyCalc - Phytoplankton Calcite
+ tracers%data(i)%values(:,:) = tiny * Redfield
- CASE (1020)
- tracers%data(i)%values(:,:) = tiny * Redfield ! PhyCalc
+ CASE (1021) ! DetCalc - Detrital Calcite
+ tracers%data(i)%values(:,:) = tiny
- CASE (1021)
- tracers%data(i)%values(:,:) = tiny ! DetCalc
+ !---------------------------------------------------------------------------
+ ! Extended Model: Additional Zooplankton and Detritus (enable_3zoo2det)
+ !---------------------------------------------------------------------------
-! *******************
-! CASE 2phy 2zoo 2det
-! *******************
-#if defined (__3Zoo2Det)
CASE (1023)
- tracers%data(i)%values(:,:) = tiny ! Zoo2N
+ IF (enable_3zoo2det .AND. .NOT. enable_coccos) THEN
+ ! Zoo2N - Macrozooplankton Nitrogen
+ tracers%data(i)%values(:,:) = tiny
+ ELSE IF (enable_coccos .AND. .NOT. enable_3zoo2det) THEN
+ ! CoccoN - Coccolithophore Nitrogen
+ tracers%data(i)%values(:,:) = tiny_chl / chl2N_max
+ END IF
+
CASE (1024)
- tracers%data(i)%values(:,:) = tiny * Redfield ! Zoo2C
+ IF (enable_3zoo2det .AND. .NOT. enable_coccos) THEN
+ ! Zoo2C - Macrozooplankton Carbon
+ tracers%data(i)%values(:,:) = tiny * Redfield
+ ELSE IF (enable_coccos .AND. .NOT. enable_3zoo2det) THEN
+ ! CoccoC - Coccolithophore Carbon
+ tracers%data(i)%values(:,:) = tiny_chl / chl2N_max / NCmax
+ END IF
+
CASE (1025)
- tracers%data(i)%values(:,:) = tiny ! DetZ2N
+ IF (enable_3zoo2det .AND. .NOT. enable_coccos) THEN
+ ! DetZ2N - Macrozooplankton Detrital Nitrogen
+ tracers%data(i)%values(:,:) = tiny
+ ELSE IF (enable_coccos .AND. .NOT. enable_3zoo2det) THEN
+ ! CoccoChl - Coccolithophore Chlorophyll
+ tracers%data(i)%values(:,:) = tiny_chl
+ END IF
+
CASE (1026)
- tracers%data(i)%values(:,:) = tiny ! DetZ2C
+ IF (enable_3zoo2det .AND. .NOT. enable_coccos) THEN
+ ! DetZ2C - Macrozooplankton Detrital Carbon
+ tracers%data(i)%values(:,:) = tiny
+ ELSE IF (enable_coccos .AND. .NOT. enable_3zoo2det) THEN
+ ! PhaeoN - Phaeocystis Nitrogen
+ tracers%data(i)%values(:,:) = tiny_chl / chl2N_max
+ END IF
+
CASE (1027)
- tracers%data(i)%values(:,:) = tiny ! DetZ2Si
+ IF (enable_3zoo2det .AND. .NOT. enable_coccos) THEN
+ ! DetZ2Si - Zooplankton 2 Detrital Silica
+ tracers%data(i)%values(:,:) = tiny
+ ELSE IF (enable_coccos .AND. .NOT. enable_3zoo2det) THEN
+ ! PhaeoC - Phaeocystis Carbon
+ tracers%data(i)%values(:,:) = tiny_chl / chl2N_max / NCmax
+ END IF
+
CASE (1028)
- tracers%data(i)%values(:,:) = tiny ! DetZ2Calc
-#endif
+ IF (enable_3zoo2det .AND. .NOT. enable_coccos) THEN
+ ! DetZ2Calc - Macrozooplankton Detrital Calcite
+ tracers%data(i)%values(:,:) = tiny
+ ELSE IF (enable_coccos .AND. .NOT. enable_3zoo2det) THEN
+ ! PhaeoChl - Phaeocystis Chlorophyll
+ tracers%data(i)%values(:,:) = tiny_chl
+ END IF
+
+ !---------------------------------------------------------------------------
+ ! Extended Model: Coccolithophores with 3Zoo2Det
+ !---------------------------------------------------------------------------
-! *******************
-! CASE 3phy 2zoo 2det
-! *******************
-#if defined (__coccos) & defined (__3Zoo2Det)
CASE (1029)
- tracers%data(i)%values(:,:) = tiny_chl/chl2N_max ! CoccoN
+ IF (enable_coccos .AND. enable_3zoo2det) THEN
+ ! CoccoN - Coccolithophore Nitrogen
+ tracers%data(i)%values(:,:) = tiny_chl / chl2N_max
+ ELSE IF (enable_3zoo2det .AND. .NOT. enable_coccos) THEN
+ ! Zoo3N - Microzooplankton Nitrogen
+ tracers%data(i)%values(:,:) = tiny
+ END IF
+
CASE (1030)
- tracers%data(i)%values(:,:) = tiny_chl/chl2N_max/NCmax ! CoccoC
+ IF (enable_coccos .AND. enable_3zoo2det) THEN
+ ! CoccoC - Coccolithophore Carbon
+ tracers%data(i)%values(:,:) = tiny_chl / chl2N_max / NCmax
+ ELSE IF (enable_3zoo2det .AND. .NOT. enable_coccos) THEN
+ ! Zoo3C - Microzooplankton Carbon
+ tracers%data(i)%values(:,:) = tiny * Redfield
+ END IF
+
CASE (1031)
- tracers%data(i)%values(:,:) = tiny_chl ! CoccoChl
-! *******************
-! CASE 3phy 1zoo 1det
-! *******************
-#elif defined (__coccos) & !defined (__3Zoo2Det)
- CASE (1023)
- tracers%data(i)%values(:,:) = tiny_chl/chl2N_max ! CoccoN
- CASE (1024)
- tracers%data(i)%values(:,:) = tiny_chl/chl2N_max/NCmax ! CoccoC
- CASE (1025)
- tracers%data(i)%values(:,:) = tiny_chl ! CoccoChl
-#endif
+ IF (enable_coccos .AND. enable_3zoo2det) THEN
+ ! CoccoChl - Coccolithophore Chlorophyll
+ tracers%data(i)%values(:,:) = tiny_chl
+ ELSE IF (useRivers) THEN
+ tracers%data(i)%values(:,:) = 0.0_WP !tiny !R2OMIP
+ END IF
-! *******************
-! CASE 3phy 3zoo 2det
-! *******************
-#if defined (__coccos) & defined (__3Zoo2Det)
CASE (1032)
- tracers%data(i)%values(:,:) = tiny ! Zoo3N
+ IF (enable_coccos .AND. enable_3zoo2det) THEN
+ ! PhaeoN - Phaeocystis Nitrogen
+ tracers%data(i)%values(:,:) = tiny_chl / chl2N_max
+ END IF
+
CASE (1033)
- tracers%data(i)%values(:,:) = tiny * Redfield ! Zoo3C
-#elif !defined (__coccos) & defined (__3Zoo2Det)
-! *******************
-! CASE 2phy 3zoo 2det
-! *******************
- CASE (1029)
- tracers%data(i)%values(:,:) = tiny ! Zoo3N
- CASE (1030)
- tracers%data(i)%values(:,:) = tiny * Redfield ! Zoo3C
-#endif
+ IF (enable_coccos .AND. enable_3zoo2det) THEN
+ ! PhaeoC - Phaeocystis Carbon
+ tracers%data(i)%values(:,:) = tiny_chl / chl2N_max / NCmax
+ END IF
+
+ CASE (1034)
+ IF (enable_coccos .AND. enable_3zoo2det) THEN
+ ! PhaeoChl - Phaeocystis Chlorophyll
+ tracers%data(i)%values(:,:) = tiny_chl
+ END IF
+
+ CASE (1035)
+ IF (enable_coccos .AND. enable_3zoo2det) THEN
+ ! Zoo3N - Zooplankton 3 Nitrogen
+ tracers%data(i)%values(:,:) = tiny
+ END IF
+
+ CASE (1036)
+ IF (enable_coccos .AND. enable_3zoo2det) THEN
+ ! Zoo3C - Zooplankton 3 Carbon
+ tracers%data(i)%values(:,:) = tiny * Redfield
+ END IF
END SELECT
END DO
@@ -445,5 +787,16 @@ subroutine recom_init(tracers, partit, mesh)
call MPI_AllREDUCE(locO2min , glo , 1, MPI_DOUBLE_PRECISION, MPI_MIN, MPI_COMM_FESOM, MPIerr)
if (mype==0) write(*,*) ' `-> gobal min init. O2. =', glo
+ if (enable_3zoo2det) then
+ is_3zoo2det=1.0_WP
+ else
+ is_3zoo2det=0.0_WP
+ endif
+
+ if (enable_coccos) then
+ is_coccos=1.0_WP
+ else
+ is_coccos=0.0_WP
+ endif
end subroutine recom_init
diff --git a/src/int_recom/recom_main.F90 b/src/int_recom/recom_main.F90
index c9c5575e5..8158049ef 100755
--- a/src/int_recom/recom_main.F90
+++ b/src/int_recom/recom_main.F90
@@ -6,8 +6,8 @@ module recom_interface
interface
subroutine recom(ice, dynamics, tracers, partit, mesh)
use mod_mesh
- USE MOD_PARTIT
- USE MOD_PARSUP
+ use MOD_PARTIT
+ use MOD_PARSUP
use mod_tracer
use MOD_DYN
use MOD_ICE
@@ -29,8 +29,8 @@ subroutine bio_fluxes(tracers, partit, mesh)
use recom_config
use mod_mesh
- USE MOD_PARTIT
- USE MOD_PARSUP
+ use MOD_PARTIT
+ use MOD_PARSUP
use mod_tracer
use g_config
@@ -52,11 +52,11 @@ subroutine recom(ice, dynamics, tracers, partit, mesh)
use MOD_MESH
use MOD_TRACER
use MOD_DYN
- USE MOD_ICE
+ use MOD_ICE
use o_ARRAYS
use o_PARAM
- USE MOD_PARTIT
- USE MOD_PARSUP
+ use MOD_PARTIT
+ use MOD_PARSUP
use recom_declarations
use bio_fluxes_interface
@@ -64,10 +64,12 @@ subroutine recom(ice, dynamics, tracers, partit, mesh)
use recom_glovar
use recom_config
use recom_ciso
+ use recom_diags_management
use g_clock
use g_forcing_arrays, only: press_air, u_wind, v_wind, shortwave
use g_comm_auto
- IMPLICIT NONE
+
+ implicit none
type(t_dyn) , intent(inout), target :: dynamics
type(t_tracer), intent(inout), target :: tracers
@@ -98,6 +100,7 @@ subroutine recom(ice, dynamics, tracers, partit, mesh)
integer :: idiags
real(kind=8) :: Sali
+ logical :: do_update = .false.
real(kind=8), allocatable :: Temp(:), Sali_depth(:), zr(:), PAR(:)
real(kind=8), allocatable :: C(:,:)
@@ -113,6 +116,7 @@ subroutine recom(ice, dynamics, tracers, partit, mesh)
real(kind=8), allocatable :: OmegaC_watercolumn(:)
real(kind=8), allocatable :: kspc_watercolumn(:)
real(kind=8), allocatable :: rhoSW_watercolumn(:)
+ real(kind=WP) :: ttf_rhs_bak (mesh%nl-1, tracers%num_tracers) ! local variable
#include "../associate_part_def.h"
#include "../associate_mesh_def.h"
@@ -135,6 +139,17 @@ subroutine recom(ice, dynamics, tracers, partit, mesh)
if (restore_alkalinity) call bio_fluxes(tracers, partit, mesh)
if (recom_debug .and. mype==0) print *, achar(27)//'[36m'//' --> bio_fluxes'//achar(27)//'[0m'
+ if (use_atbox) then ! MERGE
+! Prognostic atmospheric isoCO2
+ call recom_atbox(partit,mesh)
+! optional I/O of isoCO2 and inferred cosmogenic 14C production; this may cost some CPU time
+ if (ciso .and. ciso_14) then
+ call annual_event(do_update)
+ if (do_update .and. mype==0) write (*, fmt = '(a50,2x,i6,4(2x,f6.2))') &
+ 'Year, xCO2 (ppm), cosmic 14C flux (at / cm² / s):', &
+ yearold, x_co2atm(1), x_co2atm_13(1), x_co2atm_14(1), cosmic_14(1) * production_rate_to_flux_14
+ end if
+ end if
! ======================================================================================
!********************************* LOOP STARTS *****************************************
@@ -160,6 +175,9 @@ subroutine recom(ice, dynamics, tracers, partit, mesh)
!!---- Benthic layers
LocBenthos(1:benthos_num) = Benthos(n,1:benthos_num)
+ !!---- Burial in Benthic layers
+ BurialBen(1:benthos_num) = Burial(1:benthos_num,n) ! R2OMIP
+
!!---- Local conc of [H+]-ions from last time step. Decleared and saved in LocVar.
!!---- used as first guess for H+ conc. in subroutine CO2flux (provided by recom_init)
Hplus = GloHplus(n)
@@ -176,6 +194,31 @@ subroutine recom(ice, dynamics, tracers, partit, mesh)
!!---- Atmospheric CO2 in LocVar
LocAtmCO2 = AtmCO2(month)
+! Update of prognostic atmospheric CO2 values
+ if (use_atbox) then
+ LocAtmCO2 = x_co2atm(1)
+ if (ciso) then
+ LocAtmCO2_13 = x_co2atm_13(1)
+ if (ciso_14) LocAtmCO2_14 = x_co2atm_14(1)
+ end if
+ else
+! Consider prescribed atmospheric CO2 values
+ if (ciso) then
+ LocAtmCO2_13 = AtmCO2_13(month)
+ if (ciso_14) then
+! Latitude of nodal point n
+ lat_val = geo_coord_nod2D(2,n) / rad
+! Zonally binned NH / SH / TZ 14CO2 input values
+ LocAtmCO2_14 = AtmCO2_14(lat_zone(lat_val), month)
+ end if
+ end if
+ end if ! use_atbox
+
+ if (ciso) then
+ r_atm_13 = LocAtmCO2_13(1) / LocAtmCO2(1)
+ if (ciso_14) r_atm_14 = LocAtmCO2_14(1) / LocAtmCO2(1)
+ end if
+
!!---- Shortwave penetration
SW = parFrac * shortwave(n)
SW = SW * (1.d0 - a_ice(n))
@@ -206,6 +249,15 @@ subroutine recom(ice, dynamics, tracers, partit, mesh)
C(1:nzmax, tr_num-2) = tracers%data(tr_num)%values(1:nzmax, n)
end do
+ ttf_rhs_bak = 0.0
+
+
+ do tr_num=1, num_tracers
+ if (tracers%data(tr_num)%ltra_diag) then
+ ttf_rhs_bak(1:nzmax,tr_num) = tracers%data(tr_num)%values(1:nzmax, n)
+ end if
+ end do
+
!!---- Depth of the nodes in the water column
zr(1:nzmax) = Z_3d_n(1:nzmax, n)
@@ -217,57 +269,151 @@ subroutine recom(ice, dynamics, tracers, partit, mesh)
NDust = GloNDust(n) * (1.d0 - a_ice(n))
if (Diags) then
-
- !! * Allocate 3D diagnostics *
- allocate(vertrespmeso(nl-1), vertrespmacro(nl-1), vertrespmicro(nl-1))
- vertrespmeso = 0.d0
- vertrespmacro = 0.d0
- vertrespmicro = 0.d0
-
- allocate(vertcalcdiss(nl-1), vertcalcif(nl-1))
- vertcalcdiss = 0.d0
- vertcalcif = 0.d0
-
- allocate(vertaggn(nl-1), vertaggd(nl-1), vertaggc(nl-1))
- vertaggn = 0.d0
- vertaggd = 0.d0
- vertaggc = 0.d0
-
- allocate(vertdocexn(nl-1), vertdocexd(nl-1), vertdocexc(nl-1))
- vertdocexn = 0.d0
- vertdocexd = 0.d0
- vertdocexc = 0.d0
-
- allocate(vertrespn(nl-1), vertrespd(nl-1), vertrespc(nl-1))
- vertrespn = 0.d0
- vertrespd = 0.d0
- vertrespc = 0.d0
-
- !! * Allocate 2D diagnostics *
- allocate(vertNPPn(nl-1), vertGPPn(nl-1), vertNNAn(nl-1), vertChldegn(nl-1))
- vertNPPn = 0.d0
- vertGPPn = 0.d0
- vertNNAn = 0.d0
- vertChldegn = 0.d0
-
- allocate(vertNPPd(nl-1), vertGPPd(nl-1), vertNNAd(nl-1), vertChldegd(nl-1))
- vertNPPd = 0.d0
- vertGPPd = 0.d0
- vertNNAd = 0.d0
- vertChldegd = 0.d0
-
- allocate(vertNPPc(nl-1), vertGPPc(nl-1), vertNNAc(nl-1), vertChldegc(nl-1))
- vertNPPc = 0.d0
- vertGPPc = 0.d0
- vertNNAc = 0.d0
- vertChldegc = 0.d0
+ ! Allocate and initialize all diagnostic arrays for a water column
+ call allocate_and_init_diags(nl)
+ allocate(vertmesocdis(nl-1))
+ vertmesocdis = 0.d0
+
+if (enable_3zoo2det) then
+ allocate(vertfastcdis(nl-1))
+ vertfastcdis = 0.d0 !RP 14.07.2025
+ allocate( vertmicrocdis(nl-1), vertmacrocdis(nl-1)) !RP 14.07.2025
+ vertmicrocdis = 0.d0
+ vertmacrocdis = 0.d0
+endif
+ allocate(vertphotn(nl-1), vertphotd(nl-1)) !RP 14.07.2025
+ vertphotn = 0.d0
+ vertphotd = 0.d0
+ allocate(vertNassimn(nl-1), vertNassimd(nl-1)) !RP 14.07.2025
+ vertNassimn = 0.d0
+ vertNassimd = 0.d0
+ allocate(vertDONremin(nl-1), vertDOCremin(nl-1)) !RP 15.07.2025
+ vertDONremin = 0.d0
+ vertDOCremin = 0.d0
+if (enable_coccos) then
+ allocate(vertphotc(nl-1), vertphotp(nl-1)) !RP 14.07.2025
+ vertphotc = 0.d0
+ vertphotp = 0.d0
+ allocate(vertNassimc(nl-1), vertNassimp(nl-1)) !RP 14.07.2025
+ vertNassimc = 0.d0
+ vertNassimp = 0.d0
+endif
end if
+!
+! !! * Allocate 3D diagnostics *
+! allocate(vertrespmeso(nl-1))
+! vertrespmeso = 0.d0
+!
+!if (enable_3zoo2det) then
+! allocate(vertrespmacro(nl-1), vertrespmicro(nl-1))
+! vertrespmacro = 0.d0
+! vertrespmicro = 0.d0
+!endif
+! allocate(vertcalcdiss(nl-1), vertcalcif(nl-1))
+! vertcalcdiss = 0.d0
+! vertcalcif = 0.d0
+!
+! allocate(vertaggn(nl-1), vertaggd(nl-1))
+! vertaggn = 0.d0
+! vertaggd = 0.d0
+!
+! allocate(vertdocexn(nl-1), vertdocexd(nl-1))
+! vertdocexn = 0.d0
+! vertdocexd = 0.d0
+!
+! allocate(vertrespn(nl-1), vertrespd(nl-1))
+! vertrespn = 0.d0
+! vertrespd = 0.d0
+!
+! allocate(VTPhyCO2(nl-1), VTDiaCO2(nl-1))
+! VTPhyCO2 = 0.d0
+! VTDiaCO2 = 0.d0
+!
+! allocate(VTCphotLigLim_phyto(nl-1), VTCphotLigLim_diatoms(nl-1))
+! VTCphotLigLim_phyto = 0.d0
+! VTCphotLigLim_diatoms = 0.d0
+!
+! allocate(VTCphot_phyto(nl-1), VTCphot_diatoms(nl-1))
+! VTCphot_phyto = 0.d0
+! VTCphot_diatoms = 0.d0
+!
+!if (enable_coccos) then
+! allocate(VTTemp_diatoms(nl-1), VTTemp_phyto(nl-1))
+! VTTemp_diatoms = 0.d0
+! VTTemp_phyto = 0.d0
+!
+! allocate(VTqlimitFac_phyto(nl-1), VTqlimitFac_diatoms(nl-1))
+! VTqlimitFac_phyto = 0.d0
+! VTqlimitFac_diatoms = 0.d0
+!
+! allocate(VTSi_assimDia(nl-1))
+! VTSi_assimDia = 0.d0
+!
+! allocate(vertaggc(nl-1), vertdocexc(nl-1), vertrespc(nl-1))
+! vertaggc = 0.d0
+! vertdocexc = 0.d0
+! vertrespc = 0.d0
+!
+! allocate(vertaggp(nl-1), vertdocexp(nl-1), vertrespp(nl-1)) ! Phaeocystis
+! vertaggp = 0.d0
+! vertdocexp = 0.d0
+! vertrespp = 0.d0
+!
+! allocate(VTTemp_cocco(nl-1), VTTemp_phaeo(nl-1))
+! VTTemp_cocco = 0.d0
+! VTTemp_phaeo = 0.d0
+!
+! allocate(VTCoccoCO2(nl-1), VTPhaeoCO2(nl-1))
+! VTCoccoCO2 = 0.d0
+! VTPhaeoCO2 = 0.d0
+!
+! allocate(VTqlimitFac_cocco(nl-1), VTqlimitFac_phaeo(nl-1))
+! VTqlimitFac_cocco = 0.d0
+! VTqlimitFac_phaeo = 0.d0
+!
+! allocate(VTCphotLigLim_cocco(nl-1), VTCphotLigLim_phaeo(nl-1))
+! VTCphotLigLim_cocco = 0.d0
+! VTCphotLigLim_phaeo = 0.d0
+!
+! allocate(VTCphot_cocco(nl-1), VTCphot_phaeo(nl-1))
+! VTCphot_cocco = 0.d0
+! VTCphot_phaeo = 0.d0
+!
+!
+!endif
+!
+! !! * Allocate 2D diagnostics *
+! allocate(vertNPPn(nl-1), vertGPPn(nl-1), vertNNAn(nl-1), vertChldegn(nl-1))
+! vertNPPn = 0.d0
+! vertGPPn = 0.d0
+! vertNNAn = 0.d0
+! vertChldegn = 0.d0
+!
+! allocate(vertNPPd(nl-1), vertGPPd(nl-1), vertNNAd(nl-1), vertChldegd(nl-1))
+! vertNPPd = 0.d0
+! vertGPPd = 0.d0
+! vertNNAd = 0.d0
+! vertChldegd = 0.d0
+!
+!if (enable_coccos) then
+! allocate(vertNPPc(nl-1), vertGPPc(nl-1), vertNNAc(nl-1), vertChldegc(nl-1))
+! vertNPPc = 0.d0
+! vertGPPc = 0.d0
+! vertNNAc = 0.d0
+! vertChldegc = 0.d0
+!
+! allocate(vertNPPp(nl-1), vertGPPp(nl-1), vertNNAp(nl-1), vertChldegp(nl-1))
+! vertNPPp = 0.d0
+! vertGPPp = 0.d0
+! vertNNAp = 0.d0
+! vertChldegp = 0.d0
+!endif
if (recom_debug .and. mype==0) print *, achar(27)//'[36m'//' --> REcoM_Forcing'//achar(27)//'[0m'
! ======================================================================================
!******************************** RECOM FORCING ****************************************
- call REcoM_Forcing(zr, n, nzmax, C, SW, Loc_slp , Temp, Sali, Sali_depth &
+ call REcoM_Forcing(zr, n, nzmax, C, SW, Loc_slp, Temp, Sali, Sali_depth &
, CO2_watercolumn & ! NEW MOCSY CO2 for the whole watercolumn
, pH_watercolumn & ! NEW MOCSY pH for the whole watercolumn
, pCO2_watercolumn & ! NEW MOCSY pCO2 for the whole watercolumn
@@ -282,69 +428,192 @@ subroutine recom(ice, dynamics, tracers, partit, mesh)
tracers%data(tr_num)%values(1:nzmax, n) = C(1:nzmax, tr_num-2)
end do
+ ! recom_sms
+
+ do tr_num=1, num_tracers
+ if (tracers%data(tr_num)%ltra_diag) then
+ tracers%work%tra_recom_sms(1:nzmax,n,tr_num) = tracers%data(tr_num)%values(1:nzmax, n) - ttf_rhs_bak(1:nzmax,tr_num)
+ !if (mype==0) print *, tra_recom_sms(:,:,tr_num)
+ end if
+
+ end do
+
!!---- Local variables that have been changed during the time-step are stored so they can be saved
Benthos(n,1:benthos_num) = LocBenthos(1:benthos_num)
GlodecayBenthos(n, 1:benthos_num) = decayBenthos(1:benthos_num)/SecondsPerDay ! convert from [mmol/m2/d] to [mmol/m2/s]
- if (Diags) then
-
- !! * Update 2D diagnostics *
- NPPn(n) = locNPPn
- NPPd(n) = locNPPd
- NPPc(n) = locNPPc
- GPPn(n) = locGPPn
- GPPd(n) = locGPPd
- GPPc(n) = locGPPc
- NNAn(n) = locNNAn
- NNAd(n) = locNNAd
- NNAc(n) = locNNAc
- Chldegn(n) = locChldegn
- Chldegd(n) = locChldegd
- Chldegc(n) = locChldegc
-
- !! * Update 3D diagnostics *
- respmeso (1:nzmax,n) = vertrespmeso (1:nzmax)
- respmacro (1:nzmax,n) = vertrespmacro (1:nzmax)
- respmicro (1:nzmax,n) = vertrespmicro (1:nzmax)
- calcdiss (1:nzmax,n) = vertcalcdiss (1:nzmax)
- calcif (1:nzmax,n) = vertcalcif (1:nzmax)
- aggn (1:nzmax,n) = vertaggn (1:nzmax)
- aggd (1:nzmax,n) = vertaggd (1:nzmax)
- aggc (1:nzmax,n) = vertaggc (1:nzmax)
- docexn (1:nzmax,n) = vertdocexn (1:nzmax)
- docexd (1:nzmax,n) = vertdocexd (1:nzmax)
- docexc (1:nzmax,n) = vertdocexc (1:nzmax)
- respn (1:nzmax,n) = vertrespn (1:nzmax)
- respd (1:nzmax,n) = vertrespd (1:nzmax)
- respc (1:nzmax,n) = vertrespc (1:nzmax)
- NPPn3D (1:nzmax,n) = vertNPPn (1:nzmax)
- NPPd3D (1:nzmax,n) = vertNPPd (1:nzmax)
- NPPc3D (1:nzmax,n) = vertNPPc (1:nzmax)
-if (recom_debug .and. mype==0) print *, achar(27)//'[36m'//' --> ciso after REcoM_Forcing'//achar(27)//'[0m'
-
- !! * Deallocating 2D diagnostics *
- deallocate(vertNPPn, vertGPPn, vertNNAn, vertChldegn)
- deallocate(vertNPPd, vertGPPd, vertNNAd, vertChldegd)
- deallocate(vertNPPc, vertGPPc, vertNNAc, vertChldegc)
-
- !! * Deallocating 3D Diagnostics *
- deallocate(vertrespmeso, vertrespmacro, vertrespmicro )
- deallocate(vertcalcdiss, vertcalcif )
- deallocate(vertaggn, vertaggd, vertaggc )
- deallocate(vertdocexn, vertdocexd, vertdocexc )
- deallocate(vertrespn, vertrespd, vertrespc )
+ if (recom_debug .and. mype==0) print *, achar(27)//'[36m'//' --> ciso after REcoM_Forcing'//achar(27)//'[0m'
- end if
+ if (Diags) then
+ call update_2d_diags(n)
+ mesocdis (1:nzmax,n) = vertmesocdis (1:nzmax)
+if (enable_3zoo2det) then
+ microcdis (1:nzmax,n) = vertmicrocdis (1:nzmax) !RP 14.07.2025
+ macrocdis (1:nzmax,n) = vertmacrocdis (1:nzmax) !RP 14.07.2025
+ fastcdis (1:nzmax,n) = vertfastcdis (1:nzmax) !RP 14.07.2025
+endif
+ photn (1:nzmax,n) = vertphotn (1:nzmax) !RP 14.07.2025
+ photd (1:nzmax,n) = vertphotd (1:nzmax) !RP 14.07.2025
+ Nassimn (1:nzmax,n) = vertNassimn (1:nzmax) !RP 14.07.2025
+ Nassimd (1:nzmax,n) = vertNassimd (1:nzmax) !RP 14.07.2025
+if (enable_coccos) then
+ photc (1:nzmax,n) = vertphotc (1:nzmax) !RP 14.07.2025
+ photp (1:nzmax,n) = vertphotp (1:nzmax) !RP 14.07.2025
+ Nassimc (1:nzmax,n) = vertNassimc (1:nzmax) !RP 14.07.2025
+ Nassimp (1:nzmax,n) = vertNassimp (1:nzmax) !RP 14.07.2025
+endif
+ DONremin (1:nzmax,n) = vertDONremin (1:nzmax) !RP 14.07.2025
+ DOCremin (1:nzmax,n) = vertDOCremin (1:nzmax) !RP 15.07.2025
+
+ call update_3d_diags(n, nzmax)
+ ! Deallocate vertical tracer array
+ call deallocate_diags()
+
+ deallocate(vertmesocdis)
+
+if (enable_3zoo2det) then
+ deallocate(vertfastcdis)
+ deallocate(vertmicrocdis,vertmacrocdis) ! RP 14.07.2025
+endif
+ deallocate(vertDONremin, vertDOCremin) !RP 15.07.2025
+ deallocate(vertphotn, vertNassimn) !RP 14.07.2025
+ deallocate(vertphotd, vertNassimd) !RP 14.07.2025
+if (enable_coccos) then
+ deallocate(vertphotc, vertNassimc) !RP 14.07.2025
+ deallocate(vertphotp, vertNassimp) !RP 08.01.2026
+endif
+ endif
+! !! * Update 2D diagnostics *
+! NPPn(n) = locNPPn
+! NPPd(n) = locNPPd
+! GPPn(n) = locGPPn
+! GPPd(n) = locGPPd
+! NNAn(n) = locNNAn
+! NNAd(n) = locNNAd
+! Chldegn(n) = locChldegn
+! Chldegd(n) = locChldegd
+!
+!if (enable_coccos) then
+! NPPc(n) = locNPPc
+! GPPc(n) = locGPPc
+! NNAc(n) = locNNAc
+! Chldegc(n) = locChldegc
+! NPPp(n) = locNPPp
+! GPPp(n) = locGPPp
+! NNAp(n) = locNNAp
+! Chldegp(n) = locChldegp
+!endif
+!
+! !! * Update 3D diagnostics *
+! respmeso (1:nzmax,n) = vertrespmeso (1:nzmax)
+!if (enable_3zoo2det) then
+! respmacro (1:nzmax,n) = vertrespmacro (1:nzmax)
+! respmicro (1:nzmax,n) = vertrespmicro (1:nzmax)
+!endif
+! calcdiss (1:nzmax,n) = vertcalcdiss (1:nzmax)
+! calcif (1:nzmax,n) = vertcalcif (1:nzmax)
+!
+! aggn (1:nzmax,n) = vertaggn (1:nzmax)
+! docexn (1:nzmax,n) = vertdocexn (1:nzmax)
+! respn (1:nzmax,n) = vertrespn (1:nzmax)
+! NPPn3D (1:nzmax,n) = vertNPPn (1:nzmax)
+!
+! aggd (1:nzmax,n) = vertaggd (1:nzmax)
+! docexd (1:nzmax,n) = vertdocexd (1:nzmax)
+! respd (1:nzmax,n) = vertrespd (1:nzmax)
+! NPPd3D (1:nzmax,n) = vertNPPd (1:nzmax)
+!
+! TPhyCO2 (1:nzmax,n) = VTPhyCO2 (1:nzmax)
+! TDiaCO2 (1:nzmax,n) = VTDiaCO2 (1:nzmax)
+! TCphotLigLim_phyto (1:nzmax,n) = VTCphotLigLim_phyto (1:nzmax)
+! TCphotLigLim_diatoms(1:nzmax,n) = VTCphotLigLim_diatoms (1:nzmax)
+! TCphot_phyto (1:nzmax,n) = VTCphot_phyto (1:nzmax)
+! TCphot_diatoms (1:nzmax,n) = VTCphot_diatoms (1:nzmax)
+!
+!if (enable_coccos) then
+!
+! TTemp_phyto (1:nzmax,n) = VTTemp_phyto (1:nzmax)
+! TqlimitFac_phyto (1:nzmax,n) = VTqlimitFac_phyto (1:nzmax)
+! TTemp_diatoms (1:nzmax,n) = VTTemp_diatoms (1:nzmax) !! NEW from here tracking vars
+! TqlimitFac_diatoms (1:nzmax,n) = VTqlimitFac_diatoms (1:nzmax)
+! TSi_assimDia (1:nzmax,n) = VTSi_assimDia (1:nzmax)
+!
+! aggc (1:nzmax,n) = vertaggc (1:nzmax)
+! docexc (1:nzmax,n) = vertdocexc (1:nzmax)
+! respc (1:nzmax,n) = vertrespc (1:nzmax)
+! NPPc3D (1:nzmax,n) = vertNPPc (1:nzmax)
+!
+! aggp (1:nzmax,n) = vertaggp (1:nzmax)
+! docexp (1:nzmax,n) = vertdocexp (1:nzmax)
+! respp (1:nzmax,n) = vertrespp (1:nzmax)
+! NPPp3D (1:nzmax,n) = vertNPPp (1:nzmax)
+!
+! TTemp_cocco (1:nzmax,n) = VTTemp_cocco (1:nzmax)
+! TCoccoCO2 (1:nzmax,n) = VTCoccoCO2 (1:nzmax)
+! TqlimitFac_cocco (1:nzmax,n) = VTqlimitFac_cocco (1:nzmax)
+! TCphotLigLim_cocco (1:nzmax,n) = VTCphotLigLim_cocco (1:nzmax)
+! TCphot_cocco (1:nzmax,n) = VTCphot_cocco (1:nzmax)
+!
+! TTemp_phaeo (1:nzmax,n) = VTTemp_phaeo (1:nzmax)
+! TPhaeoCO2 (1:nzmax,n) = VTPhaeoCO2 (1:nzmax)
+! TqlimitFac_phaeo (1:nzmax,n) = VTqlimitFac_phaeo (1:nzmax)
+! TCphotLigLim_phaeo (1:nzmax,n) = VTCphotLigLim_phaeo (1:nzmax)
+! TCphot_phaeo (1:nzmax,n) = VTCphot_phaeo (1:nzmax)
+!
+! endif
+!
+!if (recom_debug .and. mype==0) print *, achar(27)//'[36m'//' --> ciso after REcoM_Forcing'//achar(27)//'[0m'
+!
+! !! * Deallocating 2D diagnostics *
+! deallocate(vertNPPn, vertGPPn, vertNNAn, vertChldegn)
+! deallocate(vertNPPd, vertGPPd, vertNNAd, vertChldegd)
+!if (enable_coccos) then
+! deallocate(vertNPPc, vertGPPc, vertNNAc, vertChldegc)
+! deallocate(vertNPPp, vertGPPp, vertNNAp, vertChldegp)
+!endif
+!
+! !! * Deallocating 3D Diagnostics *
+! deallocate(vertrespmeso)
+!if (enable_3zoo2det) then
+! deallocate(vertrespmacro, vertrespmicro)
+!endif
+! deallocate(vertcalcdiss, vertcalcif)
+! deallocate(vertaggn, vertdocexn, vertrespn)
+! deallocate(vertaggd, vertdocexd, vertrespd)
+! deallocate(VTPhyCO2, VTCphotLigLim_phyto, VTCphot_phyto)
+! deallocate(VTDiaCO2, VTCphotLigLim_diatoms, VTCphot_diatoms)
+!
+!if (enable_coccos) then
+! deallocate(vertgrazmeso_c)
+! deallocate(VTTemp_phyto, VTqlimitFac_phyto)
+! deallocate(VTTemp_diatoms, VTqlimitFac_diatoms)
+!
+! deallocate(VTSi_assimDia)
+! deallocate(vertaggc, vertdocexc, vertrespc)
+! deallocate(vertaggp, vertdocexp, vertrespp)
+!
+! deallocate(VTTemp_cocco, VTCoccoCO2, VTqlimitFac_cocco, VTCphotLigLim_cocco, VTCphot_cocco)
+! deallocate(VTTemp_phaeo, VTPhaeoCO2, VTqlimitFac_phaeo, VTCphotLigLim_phaeo, VTCphot_phaeo)
+!
+!endif
AtmFeInput(n) = FeDust
AtmNInput(n) = NDust
GloHplus(n) = ph(1)
+ PistonVelocity(n) = kw660(1)
+ alphaCO2(n) = K0(1)
GloPCO2surf(n) = pco2surf(1)
GlodPCO2surf(n) = dpco2surf(1)
GloCO2flux(n) = dflux(1) ! [mmol/m2/d]
GloCO2flux_seaicemask(n) = co2flux_seaicemask(1) ! [mmol/m2/s]
GloO2flux_seaicemask(n) = o2flux_seaicemask(1) ! [mmol/m2/s]
+ if (ciso) then
+ GloCO2flux_seaicemask_13(n) = co2flux_seaicemask_13(1) ! [mmol/m2/s]
+ if (ciso_14) then
+ GloCO2flux_seaicemask_14(n) = co2flux_seaicemask_14(1) ! [mmol/m2/s]
+ end if
+ end if
GloO2flux(n) = oflux(1) ! [mmol/m2/d]
PAR3D(1:nzmax,n) = PAR(1:nzmax)
@@ -375,6 +644,16 @@ subroutine recom(ice, dynamics, tracers, partit, mesh)
call exchange_nod(GloCO2flux_seaicemask, partit)
call exchange_nod(GloO2flux_seaicemask, partit)
+ if (ciso) then
+ call exchange_nod(GloPCO2surf_13, partit)
+ call exchange_nod(GloCO2flux_13, partit)
+ call exchange_nod(GloCO2flux_seaicemask_13, partit)
+ if (ciso_14) then
+ call exchange_nod(GloPCO2surf_14, partit)
+ call exchange_nod(GloCO2flux_14, partit)
+ call exchange_nod(GloCO2flux_seaicemask_14, partit)
+ end if
+ end if
do n=1, benthos_num
call exchange_nod(Benthos(:,n), partit)
end do
@@ -388,16 +667,56 @@ subroutine recom(ice, dynamics, tracers, partit, mesh)
call exchange_nod(NNAd, partit)
call exchange_nod(Chldegn, partit)
call exchange_nod(Chldegd, partit)
- call exchange_nod(NPPc, partit)
- call exchange_nod(GPPc, partit)
- call exchange_nod(NNAc, partit)
- call exchange_nod(Chldegc, partit)
+ if (enable_coccos) then
+ call exchange_nod(NPPc, partit)
+ call exchange_nod(GPPc, partit)
+ call exchange_nod(NNAc, partit)
+ call exchange_nod(Chldegc, partit)
+ call exchange_nod(NPPp, partit)
+ call exchange_nod(GPPp, partit)
+ call exchange_nod(NNAp, partit)
+ call exchange_nod(Chldegp, partit)
+ endif
+ call exchange_nod(grazmeso_tot, partit)
+ call exchange_nod(grazmeso_n, partit)
+ call exchange_nod(grazmeso_d, partit)
+ if (enable_coccos) then
+ call exchange_nod(grazmeso_c, partit)
+ call exchange_nod(grazmeso_p, partit)
+ endif
+ call exchange_nod(grazmeso_det, partit)
+ if (enable_3zoo2det) then
+ call exchange_nod(grazmeso_mic, partit)
+ call exchange_nod(grazmeso_det2, partit)
+ call exchange_nod(grazmacro_tot, partit)
+ call exchange_nod(grazmacro_n, partit)
+ call exchange_nod(grazmacro_d, partit)
+ if (enable_coccos) then
+ call exchange_nod(grazmacro_c, partit)
+ call exchange_nod(grazmacro_p, partit)
+ endif
+ call exchange_nod(grazmacro_mes, partit)
+ call exchange_nod(grazmacro_det, partit)
+ call exchange_nod(grazmacro_mic, partit)
+ call exchange_nod(grazmacro_det2, partit)
+ call exchange_nod(grazmicro_tot, partit)
+ call exchange_nod(grazmicro_n, partit)
+ call exchange_nod(grazmicro_d, partit)
+ if (enable_coccos) then
+ call exchange_nod(grazmicro_c, partit)
+ call exchange_nod(grazmicro_p, partit)
+ endif
+ endif
endif
do n=1, benthos_num
call exchange_nod(GlodecayBenthos(:,n), partit)
end do
+ do n=1, 6
+ call exchange_nod(Sed_2_Ocean_Flux(:,n), partit) ! Diagnose the flux back from Sediment to Ocean - R2OMIP
+ end do
+
call exchange_nod(GloHplus, partit)
call exchange_nod(AtmFeInput, partit)
call exchange_nod(AtmNInput, partit)
@@ -412,6 +731,7 @@ subroutine recom(ice, dynamics, tracers, partit, mesh)
call exchange_nod(OmegaC3D, partit)
call exchange_nod(kspc3D, partit)
call exchange_nod(rhoSW3D, partit)
+
end subroutine recom
! ======================================================================================
@@ -425,8 +745,8 @@ subroutine bio_fluxes(tracers, partit, mesh)
use recom_config
use mod_mesh
- USE MOD_PARTIT
- USE MOD_PARSUP
+ use MOD_PARTIT
+ use MOD_PARSUP
use mod_tracer
use g_config
@@ -496,4 +816,4 @@ subroutine bio_fluxes(tracers, partit, mesh)
relax_alk=relax_alk-net/ocean_area ! at ocean surface layer
-end subroutine bio_fluxes
\ No newline at end of file
+end subroutine bio_fluxes
diff --git a/src/int_recom/recom_modules.F90 b/src/int_recom/recom_modules.F90
index c4113377c..763e82c98 100644
--- a/src/int_recom/recom_modules.F90
+++ b/src/int_recom/recom_modules.F90
@@ -30,69 +30,53 @@ module recom_config
isi = 18, ife = 19, iphycal = 20, idetcal = 21, &
ioxy = 22
-#if defined (__3Zoo2Det)
-! *******************
-! CASE 2phy 2zoo 2det
-! *******************
Integer :: izoo2n = 23, izoo2c = 24, idetz2n = 25, &
idetz2c = 26, idetz2si = 27, idetz2calc = 28
-#endif
-#if defined (__coccos) & defined (__3Zoo2Det)
-! *******************
-! CASE 3phy 2zoo 2det
-! *******************
- Integer :: icocn = 29, icocc = 30, icchl = 31
+ ! Microzooplankton (third zooplankton group)
+ integer :: imiczoon = 0 ! Microzooplankton Nitrogen (set below)
+ integer :: imiczooc = 0 ! Microzooplankton Carbon (set below)
-#elif defined (__coccos) & !defined (__3Zoo2Det)
-! *******************
-! CASE 3phy 1zoo 1det
-! *******************
- Integer :: icocn = 23, icocc = 24, icchl = 25
-#endif
+ ! ---------------------------------------------------------------------------
+ ! PHYTOPLANKTON GROUPS (coccos configuration)
+ ! ---------------------------------------------------------------------------
+ ! Coccolithophores and Phaeocystis when enable_coccos = .true.
-#if defined (__coccos) & defined (__3Zoo2Det)
-! *******************
-! CASE 3phy 3zoo 2det
-! *******************
- Integer :: imiczoon = 32, imiczooc = 33
+ integer :: icocn = 0 ! Coccolithophore Nitrogen (set below)
+ integer :: icocc = 0 ! Coccolithophore Carbon (set below)
+ integer :: icchl = 0 ! Coccolithophore Chlorophyll (set below)
-#elif !defined (__coccos) & defined (__3Zoo2Det)
-! *******************
-! CASE 2phy 3zoo 2det
-! *******************
- Integer :: imiczoon = 29, imiczooc = 30
-#endif
+ integer :: iphan = 0 ! Phaeocystis Nitrogen (set below)
+ integer :: iphac = 0 ! Phaeocystis Carbon (set below)
+ integer :: iphachl = 0 ! Phaeocystis Chlorophyll (set below)
+
+ ! Terrestrial DOC input (when useRivers is enabled)
+ integer :: idoct = 0
!=============================================================================
- Integer :: ivphy = 1, ivdia = 2, ivdet = 3, ivdetsc = 4, ivcoc = 5
-
+ Integer :: ivphy = 1, ivdia = 2, ivdet = 3, ivdetsc = 4, ivcoc = 5, ivpha = 6
+
!=============================================================================
integer, dimension(8) :: recom_remin_tracer_id = (/1001, 1002, 1003, 1018, 1019, 1022, 1302, 1402/)
! OG
! Todo: Make recom_sinking_tracer_id case sensitive
- integer, dimension(29) :: recom_sinking_tracer_id = (/1007, 1008, 1017, 1021, 1004, 1005, 1020, 1006, &
+ integer, dimension(32) :: recom_sinking_tracer_id = (/1007, 1008, 1017, 1021, 1004, 1005, 1020, 1006, &
1013, 1014, 1016, 1015, 1025, 1026, 1027, 1028, &
1029, 1030, 1031, &
+ 1032, 1033, 1034, &
1308, 1321, 1305, 1320, &
1314, 1408, 1421, 1405, 1420, 1414/)
integer, dimension(8) :: recom_det_tracer_id = (/1007, 1008, 1017, 1021, 1308, 1321, 1408, 1421/)
integer, dimension(8) :: recom_phy_tracer_id = (/1004, 1005, 1020, 1305, 1320, 1405, 1420, 1006/)
integer, dimension(6) :: recom_dia_tracer_id = (/1013, 1014, 1314, 1414, 1016, 1015/)
-#if defined (__coccos) & defined (__3Zoo2Det)
- integer, dimension(3) :: recom_cocco_tracer_id = (/1029, 1030, 1031/)
-
-#elif defined (__coccos) & !defined (__3Zoo2Det)
- integer, dimension(3) :: recom_cocco_tracer_id = (/1023, 1024, 1025/)
-#endif
-
-#if defined (__3Zoo2Det)
- integer, dimension(4) :: recom_det2_tracer_id = (/1025, 1026, 1027, 1028/)
-#endif
+ ! Configuration-dependent tracer arrays (allocated during initialization)
+ integer, dimension(3) :: recom_cocco_tracer_id
+ integer, dimension(3) :: recom_phaeo_tracer_id
+ integer, dimension(4) :: recom_det2_tracer_id
!=============================================================================
@@ -104,19 +88,25 @@ module recom_config
Real(kind=8) :: Pa2atm = 101325.d0 ! [Pa/atm]
Real(kind=8) :: redO2C = 1.453 ! O2:C ratio Anderson and Sarmiento, 1994
+!! *** REcoM setup ***
+ Logical :: enable_3zoo2det = .false. ! Control extended zooplankton variables
+ Logical :: enable_coccos = .false. ! Control coccolithophore variables
+ namelist /parecomsetup/ enable_3zoo2det, enable_coccos
+
!! *** General configuration ***
Logical :: use_REcoM = .true.
Logical :: REcoM_restart = .false.
- Integer :: bgc_num = 33 ! NEW increased the number from 28 to 34 (added coccos and respiration) ! NEW 3Zoo changed from 31 to 33
+ Integer :: bgc_num = 36 ! NEW increased the number from 28 to 34 (added coccos and respiration) ! NEW 3Zoo changed from 31 to 33 ! added phaeocystis: changed from 33 to 36
integer :: bgc_base_num = 22 ! standard tracers
- Integer :: diags3d_num = 28 ! Number of diagnostic 3d tracers to be saved
+ Integer :: diags3d_num = 31 ! Number of diagnostic 3d tracers to be saved
Real(kind=8) :: VDet = 20.d0 ! Sinking velocity, constant through the water column and positive downwards
Real(kind=8) :: VDet_zoo2 = 200.d0 ! Sinking velocity, constant through the water column
Real(kind=8) :: VPhy = 0.d0 !!! If the number of sinking velocities are different from 3, code needs to be changed !!!
Real(kind=8) :: VDia = 0.d0
Real(kind=8) :: VCocco = 0.d0 ! NEW
+ Real(kind=8) :: VPhaeo = 0.d0 ! Phaeocystis
Logical :: allow_var_sinking = .true.
Integer :: biostep = 1 ! Number of times biology should be stepped forward for each time step
Logical :: REcoM_Geider_limiter = .false. ! Decides what routine should be used to calculate limiters in sms
@@ -141,6 +131,7 @@ module recom_config
character(100) :: REcoMDataPath = '/albedo/work/projects/MarESys/ogurses/input/mesh_CORE2_finaltopo_mean/'
logical :: restore_alkalinity = .true.
logical :: useRivers = .false.
+ logical :: constant_PI_Rivers = .true.
logical :: useRivFe = .false. ! river input of Fe
logical :: useErosion = .false.
logical :: NitrogenSS = .false. ! This one only activates rivers! And in principle denitrification, but denitrification is commented out. When set to true, external sources and sinks of nitrogen are activated (Riverine, aeolian and denitrification)
@@ -168,6 +159,7 @@ module recom_config
bgc_num, diags3d_num, bgc_base_num, &
VDet, VDet_zoo2, &
VPhy, VDia, VCocco, &
+ VPhaeo, &
allow_var_sinking, biostep, REcoM_Geider_limiter, &
REcoM_Grazing_Variable_Preference, &
Grazing_detritus, &
@@ -178,7 +170,8 @@ module recom_config
Diags , constant_CO2, &
UseFeDust, UseDustClim, UseDustClimAlbani, &
use_photodamage, HetRespFlux_plus, REcoMDataPath, &
- restore_alkalinity, useRivers, useRivFe, &
+ restore_alkalinity, useRivers, constant_PI_Rivers, &
+ useRivFe, &
useErosion, NitrogenSS, useAeolianN, &
firstyearoffesomcycle, lastyearoffesomcycle, numofCO2cycles, &
currentCO2cycle, DIC_PI, Nmocsy, &
@@ -201,13 +194,31 @@ module recom_config
namelist /painitialization_N/ cPhyN, cHetN, cZoo2N
!!------------------------------------------------------------------------------
-!! *** Arrhenius function ***
+!! *** Temperature and Arrhenius functions ***
Real(kind=8) :: recom_Tref = 288.15d0 ! [K]
Real(kind=8) :: C2K = 273.15d0 ! Conversion from degrees C to K
Real(kind=8) :: Ae = 4500.d0 ! [K] Slope of the linear part of the Arrhenius function
+
+!! *** Temperature variables for Blanchard function ***
+ Real(kind=8) :: Tmax_phaeo = 16d0 ! [degC] For Blanchard temp fxn: maximum temperature
+ Real(kind=8) :: Topt_phaeo = 7.5272d0 ! [degC] For Blanchard temp fxn: optimum temperature
+ Real(kind=8) :: uopt_phaeo = 0.7328d0 ! [1/day] For Blanchard function: optimum growth date
+ Real(kind=8) :: beta_phaeo = 0.7829d0 ! [unitless] For Blanchard function
+
+! NEW MODIFIED parameters
+ Real(kind=8) :: ord_d = -0.2216d0 ! parameters for diatom temperature function
+ Real(kind=8) :: expon_d = 0.0406d0 ! diatom exponent
+ Real(kind=8) :: ord_phy = -1.2154d0 ! small phyto ordonnee
+ Real(kind=8) :: expon_phy = 0.0599d0 ! small phyto exponent
+ Real(kind=8) :: ord_cocco = -0.2310d0 ! coccolith ordonnee
+ Real(kind=8) :: expon_cocco = 0.0327d0 ! small phyto ordonnee
+ Real(kind=8) :: ord_phaeo = -0.2310d0 ! phaeocystis ordonnee
+ Real(kind=8) :: expon_phaeo = 0.0327d0 ! phaeocystis ordonnee
+
Real(kind=8) :: reminSi = 0.02d0
Real(kind=8) :: k_o2_remin = 15.d0 ! NEW O2remin mmol m-3; Table 1 in Cram 2018 cites DeVries & Weber 2017 for a range of 0-30 mmol m-3
- namelist /paArrhenius/ recom_Tref, C2K, Ae, reminSi, k_o2_remin
+ namelist /paArrhenius/ recom_Tref, C2K, Ae, Tmax_phaeo, Topt_phaeo, uopt_phaeo, beta_phaeo, ord_d, expon_d, ord_phy, expon_phy, ord_cocco, expon_cocco, ord_phaeo, expon_phaeo, reminSi, k_o2_remin
+
!!------------------------------------------------------------------------------
!! *** For limiter function ***
Real(kind=8) :: NMinSlope = 50.d0
@@ -215,15 +226,19 @@ module recom_config
Real(kind=8) :: NCmin = 0.04d0
Real(kind=8) :: NCmin_d = 0.04d0
Real(kind=8) :: NCmin_c = 0.04d0 ! NEW
+ Real(kind=8) :: NCmin_p = 0.04d0 ! Phaeocystis
Real(kind=8) :: SiCmin = 0.04d0
Real(kind=8) :: k_Fe = 0.04d0
Real(kind=8) :: k_Fe_d = 0.12d0
Real(kind=8) :: k_Fe_c = 0.04 ! NEW
+ Real(kind=8) :: k_Fe_p = 0.09 ! Phaeocystis (to be tuned)
Real(kind=8) :: k_si = 4.d0
Real(kind=8) :: P_cm = 3.0d0 ! [1/day] the rate of C-specific photosynthesis
Real(kind=8) :: P_cm_d = 3.5d0
Real(kind=8) :: P_cm_c = 3.3d0 ! NEW
- namelist /palimiter_function/ NMinSlope, SiMinSlope, NCmin, NCmin_d, NCmin_c, SiCmin, k_Fe, k_Fe_d, k_Fe_c, k_si, P_cm, P_cm_d, P_cm_c
+ Real(kind=8) :: P_cm_p = 3.4d0 ! NEW for Phaeocystis ( to be tuned)
+ namelist /palimiter_function/ NMinSlope, SiMinSlope, NCmin, NCmin_d, NCmin_c, NCmin_p, SiCmin, k_Fe, k_Fe_d, k_Fe_c, k_Fe_p, k_si, P_cm, P_cm_d, P_cm_c, P_cm_p
+
!!------------------------------------------------------------------------------
!! *** For light calculations ***
Real(kind=8) :: k_w = 0.04d0 ! [1/m] Light attenuation coefficient
@@ -231,40 +246,47 @@ module recom_config
namelist /palight_calculations/ k_w, a_chl
!!------------------------------------------------------------------------------
!! *** Photosynthesis ***
- Real(kind=8) :: alfa = 0.14d0 ! [(mmol C*m2)/(mg Chl*W*day)]
+ Real(kind=8) :: alfa = 0.14d0 ! [(mmol C*m2)/(mg Chl*W*day)]
Real(kind=8) :: alfa_d = 0.19d0 ! An initial slope of the P-I curve
Real(kind=8) :: alfa_c = 0.10d0 ! NEW
+ Real(kind=8) :: alfa_p = 0.10d0 ! Phaeocystis (to be tuned)
Real(kind=8) :: parFrac = 0.43d0
- namelist /paphotosynthesis/ alfa, alfa_d, alfa_c, parFrac
+ namelist /paphotosynthesis/ alfa, alfa_d, alfa_c, alfa_p, parFrac
!!------------------------------------------------------------------------------
!! *** Assimilation ***
Real(kind=8) :: V_cm_fact = 0.7d0 ! scaling factor for temperature dependent maximum of C-specific N-uptake
Real(kind=8) :: V_cm_fact_d = 0.7d0
- Real(kind=8) :: V_cm_fact_c = 0.7d0 ! NEW
+ Real(kind=8) :: V_cm_fact_c = 0.7d0 ! NEW
+ Real(kind=8) :: V_cm_fact_p = 0.7d0 ! Phaeocystis
Real(kind=8) :: NMaxSlope = 1000.d0 ! Max slope for limiting function
Real(kind=8) :: SiMaxSlope = 1000.d0
Real(kind=8) :: NCmax = 0.2d0 ! [mmol N/mmol C] Maximum cell quota of nitrogen (N:C)
Real(kind=8) :: NCmax_d = 0.2d0
Real(kind=8) :: NCmax_c = 0.15d0 ! NEW
+ Real(kind=8) :: NCmax_p = 0.1d0 ! Phaeocystis (to be tuned)
Real(kind=8) :: SiCmax = 0.8d0
Real(kind=8) :: NCuptakeRatio = 0.2d0 ! [mmol N/mmol C] Maximum uptake ratio of N:C
Real(kind=8) :: NCUptakeRatio_d = 0.2d0
Real(kind=8) :: NCUptakeRatio_c = 0.2d0 ! NEW
+ Real(kind=8) :: NCUptakeRatio_p = 0.2d0 ! Phaeocystis
Real(kind=8) :: SiCUptakeRatio = 0.2d0
Real(kind=8) :: k_din = 0.55d0 ! [mmol N/m3] Half-saturation constant for nitrate uptake
Real(kind=8) :: k_din_d = 1.0d0
Real(kind=8) :: k_din_c = 0.55d0 ! NEW
+ Real(kind=8) :: k_din_p = 0.55d0 ! Phaeocystis (to be tuned)
Real(kind=8) :: Chl2N_max = 3.15d0 ! [mg CHL/mmol N] Maximum CHL a : N ratio = 0.3 gCHL gN^-1
Real(kind=8) :: Chl2N_max_d = 4.2d0
Real(kind=8) :: Chl2N_max_c = 3.5d0 ! NEW
+ Real(kind=8) :: Chl2N_max_p = 3.5d0 ! Phaeocystis (to be tuned (?))
Real(kind=8) :: res_phy = 0.01d0 ! [1/day] Maintenance respiration rate constant
Real(kind=8) :: res_phy_d = 0.01d0
Real(kind=8) :: res_phy_c = 0.0075d0 ! NEW
+ Real(kind=8) :: res_phy_p = 0.008d0 ! Phaeocystis (to be tuned (?))
Real(kind=8) :: biosynth = 2.33d0 ! [mmol C/mmol N] Cost of biosynthesis
Real(kind=8) :: biosynthSi = 0.d0
- namelist /paassimilation/ V_cm_fact, V_cm_fact_d, V_cm_fact_c, NMaxSlope, SiMaxSlope, NCmax, NCmax_d, NCmax_c, SiCmax, &
- NCuptakeRatio, NCUptakeRatio_d, NCUptakeRatio_c, SiCUptakeRatio, k_din, k_din_d, k_din_c, &
- Chl2N_max, Chl2N_max_d, Chl2N_max_c, res_phy, res_phy_d, res_phy_c, biosynth, biosynthSi
+ namelist /paassimilation/ V_cm_fact, V_cm_fact_d, V_cm_fact_c, V_cm_fact_p, NMaxSlope, SiMaxSlope, NCmax, NCmax_d, NCmax_c, NCmax_p, SiCmax, &
+ NCuptakeRatio, NCUptakeRatio_d, NCUptakeRatio_c, NCUptakeRatio_p, SiCUptakeRatio, k_din, k_din_d, k_din_c, k_din_p, &
+ Chl2N_max, Chl2N_max_d, Chl2N_max_c, Chl2N_max_p, res_phy, res_phy_d, res_phy_c, res_phy_p, biosynth, biosynthSi
!!------------------------------------------------------------------------------
!! *** Iron chemistry ***
Real(kind=8) :: totalligand = 1.d0 ! [mumol/m3] order 1. Total free ligand
@@ -283,26 +305,30 @@ module recom_config
Real(kind=8) :: sPhyNsq = 0.d0
Real(kind=8) :: pzCocco = 0.5d0 ! NEW (value is just a guess)
Real(kind=8) :: sCoccoNsq = 0.d0 ! NEW
+ Real(kind=8) :: pzPhaeo = 1.0d0 ! Phaeocystis (to be tuned)
+ Real(kind=8) :: sPhaeoNsq = 0.d0 ! Phaeocystis
Real(kind=8) :: pzMicZoo = 1.0d0 ! NEW 3Zoo Maximum nano-phytoplankton preference
Real(kind=8) :: sMicZooNsq = 0.d0 ! NEW 3Zoo
real(kind=8) :: tiny_het = 1.d-5 ! for more stable computation of HetRespFlux (_plus). Value can be > tiny because HetRespFlux ~ hetC**2.
- namelist /pazooplankton/ graz_max, epsilonr, res_het, Redfield, loss_het, pzDia, sDiaNsq, pzPhy, sPhyNsq, pzCocco, sCoccoNsq, pzMicZoo, sMicZooNsq, tiny_het
+ namelist /pazooplankton/ graz_max, epsilonr, res_het, Redfield, loss_het, pzDia, sDiaNsq, pzPhy, sPhyNsq, pzCocco, sCoccoNsq, pzPhaeo, sPhaeoNsq, pzMicZoo, sMicZooNsq, tiny_het
!!-------------------------------------------------------------------------------
-!! *** SecondZooplankton ***
+!! *** SecondZooplankton (Macrozooplankton) ***
Real(kind=8) :: graz_max2 = 0.1d0 ! [mmol N/(m3 * day)] Maximum grazing loss parameter
Real(kind=8) :: epsilon2 = 0.0144d0 ! [(mmol N)2 /m6] Half saturation constant for grazing loss
Real(kind=8) :: res_zoo2 = 0.0107d0 ! [1/day] Respiration by heterotrophs and mortality (loss to detritus)
Real(kind=8) :: loss_zoo2 = 0.003d0 ! [1/day] Temperature dependent N degradation of extracellular organic N
- Real(kind=8) :: fecal_rate_n = 0.13d0
+ Real(kind=8) :: fecal_rate_n = 0.13d0
Real(kind=8) :: fecal_rate_c = 0.295d0
Real(kind=8) :: fecal_rate_n_mes = 0.25d0 ! NEW 3Zoo
- Real(kind=8) :: fecal_rate_c_mes = 0.32d0 ! NEW 3Zoo
+ Real(kind=8) :: fecal_rate_c_mes = 0.32d0 ! NEW 3Zoo
Real(kind=8) :: pzDia2 = 1.d0 ! Maximum diatom preference
Real(kind=8) :: sDiaNsq2 = 0.d0
Real(kind=8) :: pzPhy2 = 0.5d0 ! Maximum diatom preference
Real(kind=8) :: sPhyNsq2 = 0.d0
Real(kind=8) :: pzCocco2 = 0.2d0 ! NEW (value is just a guess)
Real(kind=8) :: sCoccoNsq2 = 0.d0 ! NEW
+ Real(kind=8) :: pzPhaeo2 = 0.5d0 ! Phaeocystis (to be tuned)
+ Real(kind=8) :: sPhaeoNsq2 = 0.d0 ! Phaeocystis
Real(kind=8) :: pzHet = 0.8d0 ! Maximum diatom preference
Real(kind=8) :: sHetNsq = 0.d0
Real(kind=8) :: pzMicZoo2 = 0.8d0 ! NEW Zoo3 Maximum microzooplankton preference
@@ -313,7 +339,7 @@ module recom_config
Real(kind=8) :: t4_zoo2 = 274.15d0 ! Krill temp. function constant3
namelist /pasecondzooplankton/ graz_max2, epsilon2, res_zoo2, &
loss_zoo2, fecal_rate_n, fecal_rate_c, fecal_rate_n_mes, fecal_rate_c_mes, & ! NEW 3Zoo
- pzDia2, sDiaNsq2, pzPhy2, sPhyNsq2, pzCocco2, sCoccoNsq2, pzHet, sHetNsq, &
+ pzDia2, sDiaNsq2, pzPhy2, sPhyNsq2, pzCocco2, sCoccoNsq2, pzPhaeo2, sPhaeoNsq2, pzHet, sHetNsq, &
pzMicZoo2, sMicZooNsq2, &
t1_zoo2, t2_zoo2, t3_zoo2, t4_zoo2
!-------------------------------------------------------------------------------
@@ -328,7 +354,9 @@ module recom_config
Real(kind=8) :: sPhyNsq3 = 0.d0 ! NEW 3Zoo
Real(kind=8) :: pzCocco3 = 0.d0 ! NEW 3Zoo Maximum coccolithophore preference ! ATTENTION: This value needs to be tuned; I start with zero preference!
Real(kind=8) :: sCoccoNsq3 = 0.d0 ! NEW 3Zoo
- namelist /pathirdzooplankton/ graz_max3, epsilon3, loss_miczoo, res_miczoo, pzDia3, sDiaNsq3, pzPhy3, sPhyNsq3, pzCocco3, sCoccoNsq3
+ Real(kind=8) :: pzPhaeo3 = 1.0d0 ! Phaeocystis 3Zoo Maximum phaeocystis preference (to be tuned (?))
+ Real(kind=8) :: sPhaeoNsq3 = 0.d0 ! Phaeocystis 3Zoo
+ namelist /pathirdzooplankton/ graz_max3, epsilon3, loss_miczoo, res_miczoo, pzDia3, sDiaNsq3, pzPhy3, sPhyNsq3, pzCocco3, sCoccoNsq3, pzPhaeo3, sPhaeoNsq3
!-------------------------------------------------------------------------------
!! *** Detritus Grazing Params ***
@@ -350,29 +378,34 @@ module recom_config
!!------------------------------------------------------------------------------
!! *** DIN ***
Real(kind=8) :: rho_N = 0.11d0 ! [1/day] Temperature dependent N degradation of extracellular organic N (EON) (Remineralization of DON)
- namelist /padin_rho_N/ rho_N
+ Real(kind=8) :: rho_Nt = 0.67d0 ! [1/day] terrestrial N degradation of extracellular organic N (DONt) (Remineralization of terrestrial DON) ~ scale of 1.5 years ! R2OMIP
+ namelist /padin_rho_N/ rho_N, rho_Nt
!!------------------------------------------------------------------------------
!! *** DIC ***
Real(kind=8) :: rho_C1 = 0.1d0 ! [1/day] Temperature dependent C degradation of extracellular organic C (EOC)
- namelist /padic_rho_C1/ rho_C1
+ Real(kind=8) :: rho_C1t = 0.0018d0 ! [1/day] terrestrial C degradation of extracellular organic C (EOC)
+ namelist /padic_rho_C1/ rho_C1, rho_C1t
!!------------------------------------------------------------------------------
!! *** Phytoplankton N ***
Real(kind=8) :: lossN = 0.05d0 ! [1/day] Phytoplankton loss of organic N compounds
Real(kind=8) :: lossN_d = 0.05d0
- Real(kind=8) :: lossN_c = 0.05d0
- namelist /paphytoplankton_N/ lossN, lossN_d, lossN_c
+ Real(kind=8) :: lossN_c = 0.05d0
+ Real(kind=8) :: lossN_p = 0.05d0 ! Phaeocystis
+ namelist /paphytoplankton_N/ lossN, lossN_d, lossN_c, lossN_p
!!------------------------------------------------------------------------------
!! *** Phytoplankton C ***
Real(kind=8) :: lossC = 0.10d0 ! [1/day] Phytoplankton loss of carbon
Real(kind=8) :: lossC_d = 0.10d0
- Real(kind=8) :: lossC_c = 0.10d0
- namelist /paphytoplankton_C/ lossC, lossC_d, lossC_c
+ Real(kind=8) :: lossC_c = 0.10d0
+ Real(kind=8) :: lossC_p = 0.10d0 ! Phaeocystis
+ namelist /paphytoplankton_C/ lossC, lossC_d, lossC_c, lossC_p
!!------------------------------------------------------------------------------
!! *** Phytoplankton ChlA ***
Real(8) :: deg_Chl = 0.25d0 ! [1/day]
Real(kind=8) :: deg_Chl_d = 0.25d0
Real(kind=8) :: deg_Chl_c = 0.20d0 ! (value is just a guess)
- namelist /paphytoplankton_ChlA/ deg_Chl, deg_Chl_d, deg_Chl_c
+ Real(kind=8) :: deg_Chl_p = 0.25d0 ! Phaeocystis
+ namelist /paphytoplankton_ChlA/ deg_Chl, deg_Chl_d, deg_Chl_c, deg_Chl_p
!!------------------------------------------------------------------------------
!! *** Detritus N ***
Real(kind=8) :: gfin = 0.3d0 ! 3Zoo [] Grazing efficiency (fraction of grazing flux into zooplankton pool)
@@ -405,32 +438,36 @@ module recom_config
Real(kind=8) :: Cunits = 976.5625 ! Conversion factor between [mol/m3] (model) and [umol/kg] (function): (1000 * 1000) / 1024
Real(kind=8) :: a_co2_phy = 1.162e+00 ! [unitless]
- Real(kind=8) :: a_co2_dia = 1.040e+00 ! [unitless]
- Real(kind=8) :: a_co2_cocco = 1.109e+00 ! [unitless]
- Real(kind=8) :: a_co2_calc = 1.102e+00 ! [unitless]
- Real(kind=8) :: b_co2_phy = 4.888e+01 ! [mol/kg]
+ Real(kind=8) :: a_co2_dia = 1.040e+00 ! [unitless]
+ Real(kind=8) :: a_co2_cocco = 1.109e+00 ! [unitless]
+ Real(kind=8) :: a_co2_phaeo = 1.162e+00 ! [unitless]
+ Real(kind=8) :: a_co2_calc = 1.102e+00 ! [unitless]
+ Real(kind=8) :: b_co2_phy = 4.888e+01 ! [mol/kg]
Real(kind=8) :: b_co2_dia = 2.890e+01 ! [mol/kg]
Real(kind=8) :: b_co2_cocco = 3.767e+01 ! [mol/kg]
+ Real(kind=8) :: b_co2_phaeo = 4.888e+01 ! [mol/kg]
Real(kind=8) :: b_co2_calc = 4.238e+01 ! [mol/kg]
Real(kind=8) :: c_co2_phy = 2.255e-01 ! [kg/mol]
- Real(kind=8) :: c_co2_dia = 8.778e-01 ! [kg/mol]
- Real(kind=8) :: c_co2_cocco = 3.912e-01 ! [kg/mol]
- Real(kind=8) :: c_co2_calc = 7.079e-01 ! [kg/mol]
- Real(kind=8) :: d_co2_phy = 1.023e+07 ! [kg/mol]
- Real(kind=8) :: d_co2_dia = 2.640e+06 ! [kg/mol]
- Real(kind=8) :: d_co2_cocco = 9.450e+06 ! [kg/mol]
- Real(kind=8) :: d_co2_calc = 1.343e+07 ! [kg/mol]
- namelist /paco2lim/ Cunits, a_co2_phy, a_co2_dia, a_co2_cocco, a_co2_calc, &
- b_co2_phy, b_co2_dia, b_co2_cocco, b_co2_calc, &
- c_co2_phy, c_co2_dia, c_co2_cocco, c_co2_calc, &
- d_co2_phy, d_co2_dia, d_co2_cocco, d_co2_calc
+ Real(kind=8) :: c_co2_dia = 8.778e-01 ! [kg/mol]
+ Real(kind=8) :: c_co2_cocco = 3.912e-01 ! [kg/mol]
+ Real(kind=8) :: c_co2_phaeo = 2.255e-01 ! [kg/mol]
+ Real(kind=8) :: c_co2_calc = 7.079e-01 ! [kg/mol]
+ Real(kind=8) :: d_co2_phy = 1.023e+07 ! [kg/mol]
+ Real(kind=8) :: d_co2_dia = 2.640e+06 ! [kg/mol]
+ Real(kind=8) :: d_co2_cocco = 9.450e+06 ! [kg/mol]
+ Real(kind=8) :: d_co2_phaeo = 1.023e+07 ! [kg/mol]
+ Real(kind=8) :: d_co2_calc = 1.343e+07 ! [kg/mol]
+ namelist /paco2lim/ Cunits, a_co2_phy, a_co2_dia, a_co2_cocco, a_co2_phaeo, a_co2_calc, &
+ b_co2_phy, b_co2_dia, b_co2_cocco, b_co2_phaeo, b_co2_calc, &
+ c_co2_phy, c_co2_dia, c_co2_cocco, c_co2_phaeo, c_co2_calc, &
+ d_co2_phy, d_co2_dia, d_co2_cocco, d_co2_phaeo, d_co2_calc
!!------------------------------------------------------------------------------
!! *** Iron ***
Real(kind=8) :: Fe2N = 0.033d0 ! Fe2C * 6.625 (Fe2C = 0.005d0)
Real(kind=8) :: Fe2N_benthos = 0.15d0 ! default was 0.14 Fe2C_benthos (=0.02125=0.68d0/32.d0) * 6.625 - will have to be tuned. [umol/m2/day]
Real(kind=8) :: kScavFe = 0.07d0
Real(kind=8) :: dust_sol = 0.02d0 !Dissolution of Dust for bioavaliable
- Real(kind=8) :: RiverFeConc = 100d0 ! mean DFe concentration in rivers
+ Real(kind=8) :: RiverFeConc = 100d0 ! mean DFe concentration in rivers
namelist /pairon/ Fe2N, Fe2N_benthos, kScavFe, dust_sol, RiverFeConc
!!------------------------------------------------------------------------------
!! *** Calcification ***
@@ -477,6 +514,728 @@ module recom_config
namelist /paballasting/ rho_POC, rho_PON, rho_CaCO3, rho_opal, rho_ref_part, &
rho_ref_water, visc_ref_water, w_ref1, w_ref2, depth_scaling1, &
depth_scaling2, max_sinking_velocity
+
+contains
+
+ ! ---------------------------------------------------------------------------
+ ! SUBROUTINE: initialize_tracer_indices
+ ! ---------------------------------------------------------------------------
+ ! Purpose: Set up tracer indices based on model configuration
+ ! ---------------------------------------------------------------------------
+ subroutine initialize_tracer_indices()
+ implicit none
+
+ if (enable_3zoo2det .and. enable_coccos) then
+ ! =======================================================================
+ ! CASE: 4 phytoplankton + 3 zooplankton + 2 detritus
+ ! =======================================================================
+ ! Phytoplankton: small phyto, diatoms, coccolithophores, phaeocystis
+ ! Zooplankton: mesozoo, macrozoo, microzoo
+ ! Detritus: det1, det2
+
+ icocn = 29
+ icocc = 30
+ icchl = 31
+ iphan = 32
+ iphac = 33
+ iphachl = 34
+ imiczoon = 35
+ imiczooc = 36
+
+ ! Terrestrial DOC input (when useRivers is enabled)
+ if (useRivers) then
+ idoct = 37
+ end if
+
+! allocate(recom_cocco_tracer_id(3))
+ recom_cocco_tracer_id = (/1029, 1030, 1031/)
+
+! allocate(recom_phaeo_tracer_id(3))
+ recom_phaeo_tracer_id = (/1032, 1033, 1034/)
+
+! allocate(recom_det2_tracer_id(4))
+ recom_det2_tracer_id = (/1025, 1026, 1027, 1028/)
+
+ else if (enable_coccos .and. .not. enable_3zoo2det) then
+ ! =======================================================================
+ ! CASE: 4 phytoplankton + 1 zooplankton + 1 detritus
+ ! =======================================================================
+ ! Phytoplankton: small phyto, diatoms, coccolithophores, phaeocystis
+ ! Zooplankton: mesozoo only
+ ! Detritus: det1 only
+
+ icocn = 23
+ icocc = 24
+ icchl = 25
+ iphan = 26
+ iphac = 27
+ iphachl = 28
+
+ ! Terrestrial DOC input (when useRivers is enabled)
+ if (useRivers) then
+ idoct = 29
+ end if
+
+! allocate(recom_cocco_tracer_id(3))
+ recom_cocco_tracer_id = (/1023, 1024, 1025/)
+
+! allocate(recom_phaeo_tracer_id(3))
+ recom_phaeo_tracer_id = (/1026, 1027, 1028/)
+
+ else if (enable_3zoo2det .and. .not. enable_coccos) then
+ ! =======================================================================
+ ! CASE: 2 phytoplankton + 3 zooplankton + 2 detritus
+ ! =======================================================================
+ ! Phytoplankton: small phyto, diatoms only
+ ! Zooplankton: mesozoo, macrozoo, microzoo
+ ! Detritus: det1, det2
+
+ imiczoon = 29
+ imiczooc = 30
+
+ ! Terrestrial DOC input (when useRivers is enabled)
+ if (useRivers) then
+ idoct = 31
+ end if
+
+! allocate(recom_det2_tracer_id(4))
+ recom_det2_tracer_id = (/1025, 1026, 1027, 1028/)
+ else
+ ! =======================================================================
+ ! CASE: 2 phytoplankton + 1 zooplankton + 1 detritus (BASE CONFIGURATION)
+ ! =======================================================================
+ ! Phytoplankton: small phyto, diatoms only
+ ! Zooplankton: mesozoo only
+ ! Detritus: det1 only
+ ! (All indices already set to default values)
+
+ ! Terrestrial DOC input (when useRivers is enabled)
+ if (useRivers) then
+ idoct = 23
+ end if
+ endif
+ end subroutine initialize_tracer_indices
+
+! ==============================================================================
+! SUBROUTINE: validate_recom_tracers
+! ==============================================================================
+! Purpose: Validate consistency between namelist tracer configuration and
+! biogeochemical model setup (enable_3zoo2det, enable_coccos)
+! ==============================================================================
+subroutine validate_recom_tracers(num_tracers, mype)
+
+ use g_forcing_param, only: use_age_tracer !---age-code
+
+ implicit none
+
+ ! Arguments
+ integer, intent(in) :: num_tracers ! Total number of tracers from namelist
+ integer, intent(in) :: mype ! MPI rank
+
+ ! Local variables
+ integer :: expected_bgc_num
+ integer :: actual_bgc_num
+ integer :: expected_total_tracers
+ integer :: num_physical_tracers
+ integer :: doc_tracers
+ logical :: config_error
+ character(len=200) :: error_msg
+
+ ! For tracer ID validation
+ integer :: i, tracer_id
+ integer, dimension(:), allocatable :: expected_tracer_ids
+ logical, dimension(:), allocatable :: tracer_found
+ integer :: num_expected_tracers
+ logical :: id_error
+
+ ! Physical tracers (temperature, salinity, etc.) - typically first 2
+ num_physical_tracers = 2
+
+ ! DOC tracers count
+ if (useRivers) then
+ doc_tracers = 1
+ else
+ doc_tracers = 0
+ end if
+
+ ! Calculate actual BGC tracer count from namelist
+ actual_bgc_num = num_tracers - num_physical_tracers
+
+ ! ===========================================================================
+ ! Determine expected BGC tracer count based on configuration
+ ! ===========================================================================
+ config_error = .false.
+
+ if (enable_3zoo2det .and. enable_coccos) then
+ ! ---------------------------------------------------------------------------
+ ! Configuration 4: Full model (4 phyto + 3 zoo + 2 detritus)
+ ! ---------------------------------------------------------------------------
+ ! Base: 22 tracers (1001-1022)
+ ! Additional 3zoo2det: 4 tracers for det2 (1025-1028)
+ ! Additional coccos: 6 tracers for coccos (1029-1031)
+ ! Additional phaeocystis: 3 tracers (1032-1034)
+ ! Additional microzoo: 2 tracers (1035-1036)
+ ! Total: 22 + 4 + 6 + 3 + 2 = 36 (actually 22 + 14 = 36)
+ ! Plus DOC: +1 if useRivers
+ expected_bgc_num = 36 + doc_tracers
+
+ else if (enable_coccos .and. .not. enable_3zoo2det) then
+ ! ---------------------------------------------------------------------------
+ ! Configuration 3: Coccos only (4 phyto + 1 zoo + 1 detritus)
+ ! ---------------------------------------------------------------------------
+ ! Base: 22 tracers (1001-1022)
+ ! Additional coccos: 3 tracers (1023-1025)
+ ! Additional phaeocystis: 3 tracers (1026-1028)
+ ! Total: 22 + 6 = 28
+ ! Plus DOC: +1 if useRivers
+ expected_bgc_num = 28 + doc_tracers
+
+ else if (enable_3zoo2det .and. .not. enable_coccos) then
+ ! ---------------------------------------------------------------------------
+ ! Configuration 2: 3Zoo2Det only (2 phyto + 3 zoo + 2 detritus)
+ ! ---------------------------------------------------------------------------
+ ! Base: 22 tracers (1001-1022)
+ ! Additional zoo2: 2 tracers (1023-1024)
+ ! Additional det2: 4 tracers (1025-1028)
+ ! Additional microzoo: 2 tracers (1029-1030)
+ ! Total: 22 + 8 = 30
+ ! Plus DOC: +1 if useRivers
+ expected_bgc_num = 30 + doc_tracers
+
+ else
+ ! ---------------------------------------------------------------------------
+ ! Configuration 1: Base model (2 phyto + 1 zoo + 1 detritus)
+ ! ---------------------------------------------------------------------------
+ ! Base: 22 tracers (1001-1022)
+ ! Plus DOC: +1 if useRivers
+ expected_bgc_num = 22 + doc_tracers
+
+ end if
+
+ if (use_age_tracer) then
+ expected_bgc_num = expected_bgc_num + 1
+ end if
+
+ expected_total_tracers = num_physical_tracers + expected_bgc_num
+
+ ! ===========================================================================
+ ! Build expected tracer ID list for current configuration
+ ! ===========================================================================
+
+ ! Determine total expected tracers
+ num_expected_tracers = expected_total_tracers
+ allocate(expected_tracer_ids(num_expected_tracers))
+ allocate(tracer_found(num_expected_tracers))
+ tracer_found = .false.
+
+ ! Physical tracers (always present)
+ expected_tracer_ids(1) = 1 ! Temperature
+ expected_tracer_ids(2) = 2 ! Salinity
+
+ ! Base BGC tracers (always present for all configurations)
+ do i = 1, 22
+ expected_tracer_ids(num_physical_tracers + i) = 1000 + i
+ end do
+
+ ! Configuration-specific tracers
+ if (enable_3zoo2det .and. enable_coccos) then
+ ! Full model: 1001-1022 (base) + 1023-1024 (zoo2) + 1025-1028 (det2) + 1029-1036 (coccos+phaeo+zoo3)
+ expected_tracer_ids(25) = 1023 ! Zoo2N
+ expected_tracer_ids(26) = 1024 ! Zoo2C
+ expected_tracer_ids(27) = 1025 ! DetZ2N
+ expected_tracer_ids(28) = 1026 ! DetZ2C
+ expected_tracer_ids(29) = 1027 ! DetZ2Si
+ expected_tracer_ids(30) = 1028 ! DetZ2Calc
+ expected_tracer_ids(31) = 1029 ! CoccoN
+ expected_tracer_ids(32) = 1030 ! CoccoC
+ expected_tracer_ids(33) = 1031 ! CoccoChl
+ expected_tracer_ids(34) = 1032 ! PhaeoN
+ expected_tracer_ids(35) = 1033 ! PhaeoC
+ expected_tracer_ids(36) = 1034 ! PhaeoChl
+ expected_tracer_ids(37) = 1035 ! Zoo3N
+ expected_tracer_ids(38) = 1036 ! Zoo3C
+ if (useRivers) then
+ expected_tracer_ids(39) = 1037 ! DOCt (terrestrial DOC)
+ end if
+
+ else if (enable_coccos .and. .not. enable_3zoo2det) then
+ ! Coccos only: 1001-1022 (base) + 1023-1028 (coccos+phaeo)
+ expected_tracer_ids(25) = 1023 ! CoccoN
+ expected_tracer_ids(26) = 1024 ! CoccoC
+ expected_tracer_ids(27) = 1025 ! CoccoChl
+ expected_tracer_ids(28) = 1026 ! PhaeoN
+ expected_tracer_ids(29) = 1027 ! PhaeoC
+ expected_tracer_ids(30) = 1028 ! PhaeoChl
+ if (useRivers) then
+ expected_tracer_ids(31) = 1029 ! DOCt (terrestrial DOC)
+ end if
+
+ else if (enable_3zoo2det .and. .not. enable_coccos) then
+ ! 3Zoo2Det only: 1001-1022 (base) + 1023-1030 (zoo2+det2+zoo3)
+ expected_tracer_ids(25) = 1023 ! Zoo2N
+ expected_tracer_ids(26) = 1024 ! Zoo2C
+ expected_tracer_ids(27) = 1025 ! DetZ2N
+ expected_tracer_ids(28) = 1026 ! DetZ2C
+ expected_tracer_ids(29) = 1027 ! DetZ2Si
+ expected_tracer_ids(30) = 1028 ! DetZ2Calc
+ expected_tracer_ids(31) = 1029 ! Zoo3N
+ expected_tracer_ids(32) = 1030 ! Zoo3C
+ if (useRivers) then
+ expected_tracer_ids(33) = 1031 ! DOCt (terrestrial DOC)
+ end if
+
+ else
+ ! Base configuration: only tracers 1, 2, 1001-1022
+ if (useRivers) then
+ expected_tracer_ids(25) = 1023 ! DOCt (terrestrial DOC)
+ end if
+ end if
+
+ if (use_age_tracer) then
+ expected_tracer_ids(num_expected_tracers) = 100
+ end if
+
+ ! else: base configuration only needs tracers 1, 2, 1001-1022
+
+ ! ===========================================================================
+ ! Perform validation checks
+ ! ===========================================================================
+
+ if (mype == 0) then
+ write(*,*) ''
+ write(*,*) '=========================================================================='
+ write(*,*) 'REcoM TRACER CONFIGURATION VALIDATION'
+ write(*,*) '=========================================================================='
+ write(*,*) 'Model configuration:'
+ write(*,*) ' enable_3zoo2det = ', enable_3zoo2det
+ write(*,*) ' enable_coccos = ', enable_coccos
+ write(*,*) ' useRivers = ', useRivers
+ write(*,*) ''
+ write(*,*) 'Tracer counts:'
+ write(*,*) ' Physical tracers (T, S, ...) = ', num_physical_tracers
+ write(*,*) ' DOC tracers (terrestrial input) = ', doc_tracers
+ write(*,*) ' Expected BGC tracers = ', expected_bgc_num
+ write(*,*) ' Expected TOTAL tracers = ', expected_total_tracers
+ write(*,*) ' Actual tracers from namelist = ', num_tracers
+ write(*,*) ' Actual BGC tracers from namelist = ', actual_bgc_num
+ write(*,*) ''
+ end if
+
+ ! Check for inconsistencies
+ if (actual_bgc_num /= expected_bgc_num) then
+ config_error = .true.
+ if (mype == 0) then
+ write(*,*) '=========================================================================='
+ write(*,*) 'ERROR: TRACER COUNT MISMATCH!'
+ write(*,*) '=========================================================================='
+ write(*,*) 'The number of BGC tracers in the namelist does not match'
+ write(*,*) 'the expected count for the current configuration.'
+ write(*,*) ''
+ write(*,*) ' Expected BGC tracers: ', expected_bgc_num
+ write(*,*) ' Actual BGC tracers: ', actual_bgc_num
+ write(*,*) ' Difference: ', actual_bgc_num - expected_bgc_num
+ write(*,*) ''
+ write(*,*) 'Required tracer IDs for current configuration:'
+ write(*,*) ' Base tracers (always): 1001-1022 (22 tracers)'
+
+ if (enable_3zoo2det .and. .not. enable_coccos) then
+ write(*,*) ' 3Zoo2Det extension: 1023-1030 (8 tracers)'
+ write(*,*) ' - Zoo2N, Zoo2C: 1023-1024'
+ write(*,*) ' - DetZ2 pool: 1025-1028'
+ write(*,*) ' - MicZooN, MicZooC: 1029-1030'
+ if (useRivers) then
+ write(*,*) ' Terrestrial DOC: 1031 (1 tracer)'
+ end if
+ else if (enable_coccos .and. .not. enable_3zoo2det) then
+ write(*,*) ' Coccos extension: 1023-1028 (6 tracers)'
+ write(*,*) ' - CoccoN, C, Chl: 1023-1025'
+ write(*,*) ' - PhaeoN, C, Chl: 1026-1028'
+ if (useRivers) then
+ write(*,*) ' Terrestrial DOC: 1029 (1 tracer)'
+ end if
+ else if (enable_3zoo2det .and. enable_coccos) then
+ write(*,*) ' - Zoo2N, Zoo2C: 1023-1024'
+ write(*,*) ' 3Zoo2Det extension: 1025-1028 (4 tracers for det2)'
+ write(*,*) ' Coccos extension: 1029-1034 (6 tracers)'
+ write(*,*) ' - CoccoN, C, Chl: 1029-1031'
+ write(*,*) ' - PhaeoN, C, Chl: 1032-1034'
+ write(*,*) ' MicroZoo extension: 1035-1036 (2 tracers)'
+ if (useRivers) then
+ write(*,*) ' Terrestrial DOC: 1037 (1 tracer)'
+ end if
+ else
+ if (useRivers) then
+ write(*,*) ' Terrestrial DOC: 1023 (1 tracer)'
+ end if
+ end if
+
+ write(*,*) ''
+ write(*,*) 'ACTION REQUIRED:'
+ write(*,*) ' 1. Check your namelist.config tracer_list section'
+ write(*,*) ' 2. Ensure enable_3zoo2det, enable_coccos, and useRivers match your setup'
+ write(*,*) ' 3. Add/remove tracers to match the expected configuration'
+ write(*,*) '=========================================================================='
+ write(*,*) ''
+ end if
+ else
+ ! Validation passed
+ if (mype == 0) then
+ write(*,*) '=========================================================================='
+ write(*,*) 'VALIDATION PASSED: Tracer configuration is consistent!'
+ write(*,*) '=========================================================================='
+ write(*,*) ''
+ end if
+ end if
+
+ ! ===========================================================================
+ ! Additional sanity check: verify bgc_num variable matches
+ ! ===========================================================================
+ if (bgc_num /= expected_bgc_num) then
+ if (mype == 0) then
+ write(*,*) '=========================================================================='
+ write(*,*) 'WARNING: bgc_num variable inconsistency!'
+ write(*,*) '=========================================================================='
+ write(*,*) 'The bgc_num parameter does not match the expected value.'
+ write(*,*) ' Current bgc_num value: ', bgc_num
+ write(*,*) ' Expected value: ', expected_bgc_num
+ write(*,*) ''
+ write(*,*) 'This may indicate that bgc_num was not updated after changing'
+ write(*,*) 'enable_3zoo2det, enable_coccos flags, or useRivers flags.'
+ write(*,*) '=========================================================================='
+ write(*,*) ''
+ end if
+ config_error = .true.
+ end if
+
+ ! ===========================================================================
+ ! Validate tracer IDs: Check for correct IDs and detect clashes
+ ! ===========================================================================
+ id_error = .false.
+
+ ! This check requires access to the actual tracer IDs from the namelist
+ ! We'll validate against the expected list
+ if (mype == 0) then
+ write(*,*) '=========================================================================='
+ write(*,*) 'VALIDATING TRACER IDs'
+ write(*,*) '=========================================================================='
+ write(*,*) 'Expected tracer ID sequence:'
+ write(*,*) ''
+
+ ! Display expected IDs in a readable format
+ write(*,*) 'Physical tracers:'
+ write(*,*) ' ', expected_tracer_ids(1:num_physical_tracers)
+ write(*,*) ''
+ write(*,*) 'Base BGC tracers (1001-1022):'
+ write(*,*) ' ', expected_tracer_ids(3:24)
+ write(*,*) ''
+
+ if (expected_bgc_num > 22) then
+ write(*,*) 'Extended configuration tracers:'
+ write(*,*) ' ', expected_tracer_ids(25:num_expected_tracers)
+ write(*,*) ''
+ end if
+
+ write(*,*) 'CRITICAL: The tracer IDs in your namelist MUST match this sequence'
+ write(*,*) ' exactly, in the same order!'
+ write(*,*) ''
+ write(*,*) 'Common errors to avoid:'
+ write(*,*) ' - Using wrong tracer ID numbers (e.g., 1023 instead of 1025)'
+ write(*,*) ' - Tracer ID clashes between configurations'
+ write(*,*) ' - Incorrect order of tracer IDs in namelist'
+ write(*,*) ' - Missing or duplicate tracer IDs'
+ write(*,*) ' - Forgetting to add DOCt tracer when useRivers is enabled'
+ write(*,*) ''
+
+ ! Configuration-specific warnings
+ if (enable_3zoo2det .and. enable_coccos) then
+ write(*,*) 'IMPORTANT for FULL MODEL (3zoo2det + coccos):'
+ ! write(*,*) ' - Tracers 1023-1024 are NOT used (reserved for other configs)'
+ write(*,*) ' - Zoo2 uses: 1023-1024'
+ write(*,*) ' - Det2 pool uses: 1025-1028'
+ write(*,*) ' - Coccos uses: 1029-1031'
+ write(*,*) ' - Phaeocystis uses: 1032-1034'
+ write(*,*) ' - Microzooplankton: 1035-1036'
+ if (useRivers) then
+ write(*,*) ' - Terrestrial DOC: 1037'
+ end if
+ write(*,*) ''
+ else if (enable_coccos .and. .not. enable_3zoo2det) then
+ write(*,*) 'IMPORTANT for COCCOS-ONLY configuration:'
+ write(*,*) ' - Coccos uses: 1023-1025 (NOT 1029-1031)'
+ write(*,*) ' - Phaeocystis uses: 1026-1028 (NOT 1032-1034)'
+ if (useRivers) then
+ write(*,*) ' - Terrestrial DOC: 1029'
+ write(*,*) ' - Tracers 1030+ are NOT used in this configuration'
+ else
+ write(*,*) ' - Tracers 1029+ are NOT used in this configuration'
+ end if
+ write(*,*) ''
+ else if (enable_3zoo2det .and. .not. enable_coccos) then
+ write(*,*) 'IMPORTANT for 3ZOO2DET-ONLY configuration:'
+ write(*,*) ' - Zoo2 uses: 1023-1024'
+ write(*,*) ' - Det2 pool uses: 1025-1028'
+ write(*,*) ' - Microzoo uses: 1029-1030 (NOT 1035-1036)'
+ if (useRivers) then
+ write(*,*) ' - Terrestrial DOC: 1031'
+ write(*,*) ' - Tracers 1032+ are NOT used in this configuration'
+ else
+ write(*,*) ' - Tracers 1031+ are NOT used in this configuration'
+ end if
+ write(*,*) ''
+ else
+ write(*,*) 'IMPORTANT for BASE configuration:'
+ write(*,*) ' - Only tracers 1-2, 1001-1022 should be present'
+ if (useRivers) then
+ write(*,*) ' - Plus terrestrial DOC: 1023'
+ write(*,*) ' - Tracers 1024+ are NOT used in base configuration'
+ else
+ write(*,*) ' - Tracers 1023+ are NOT used in base configuration'
+ endif
+ end if
+ write(*,*) ''
+ write(*,*) '=========================================================================='
+ write(*,*) ''
+ end if
+
+ ! ===========================================================================
+ ! Check for tracer ID clashes based on configuration
+ ! ===========================================================================
+ if (mype == 0) then
+ write(*,*) '=========================================================================='
+ write(*,*) 'CHECKING FOR TRACER ID CONFLICTS'
+ write(*,*) '=========================================================================='
+
+ ! Warn about potential clashes between configurations
+ if (enable_3zoo2det .and. enable_coccos) then
+ write(*,*) 'Full model configuration active.'
+ ! write(*,*) 'Ensure you are NOT using tracer IDs 1023-1024 in your namelist!'
+ ! write(*,*) 'These are reserved for configurations WITHOUT full model.'
+ else if (enable_coccos) then
+ write(*,*) 'Coccos-only configuration active.'
+ write(*,*) 'Coccos MUST use IDs 1023-1025 (NOT 1029-1031).'
+ write(*,*) 'Phaeocystis MUST use IDs 1026-1028 (NOT 1032-1034).'
+ else if (enable_3zoo2det) then
+ write(*,*) '3Zoo2Det-only configuration active.'
+ write(*,*) 'Microzoo MUST use IDs 1029-1030 (NOT 1035-1036).'
+ end if
+
+ if (useRivers) then
+ write(*,*) ''
+ write(*,*) 'Rivers enabled (useRivers = .true.)'
+ write(*,*) 'Terrestrial DOC tracer is REQUIRED as the last BGC tracer.'
+ end if
+
+ write(*,*) ''
+ ! write(*,*) 'No automated clash detection available without tracer array access.'
+ write(*,*) 'Please manually verify your namelist tracer_list against the'
+ write(*,*) 'expected sequence shown above.'
+ write(*,*) '=========================================================================='
+ write(*,*) ''
+ end if
+
+ ! ===========================================================================
+ ! Stop execution if configuration error detected
+ ! ===========================================================================
+ if (config_error) then
+ if (mype == 0) then
+ write(*,*) ''
+ write(*,*) '******************************************************************'
+ write(*,*) '*** FATAL ERROR: MODEL CONFIGURATION INCONSISTENCY DETECTED ***'
+ write(*,*) '*** MODEL EXECUTION STOPPED ***'
+ write(*,*) '******************************************************************'
+ write(*,*) ''
+ end if
+ deallocate(expected_tracer_ids, tracer_found)
+ call par_ex(0) ! Stop execution (use appropriate stop routine for your model)
+ stop
+ end if
+
+ ! Clean up
+ deallocate(expected_tracer_ids, tracer_found)
+
+end subroutine validate_recom_tracers
+
+! ==============================================================================
+! SUBROUTINE: validate_tracer_id_sequence
+! ==============================================================================
+! Purpose: Validate that actual tracer IDs from namelist match expected sequence
+! Call this after reading the tracer namelist
+! ==============================================================================
+subroutine validate_tracer_id_sequence(tracer_ids, num_tracers, mype)
+
+ use g_forcing_param, only: use_age_tracer !---age-code
+
+ implicit none
+
+ ! Arguments
+ integer, dimension(:), intent(in) :: tracer_ids ! Actual IDs from namelist
+ integer, intent(in) :: num_tracers ! Number of tracers
+ integer, intent(in) :: mype ! MPI rank
+
+ ! Local variables
+ integer :: i, j
+ integer, dimension(:), allocatable :: expected_ids
+ integer :: num_expected
+ logical :: error_found
+ logical :: duplicate_found
+ integer :: num_physical_tracers
+ integer :: doc_tracers
+
+ error_found = .false.
+ duplicate_found = .false.
+ num_physical_tracers = 2
+
+ ! DOC tracers count
+ if (useRivers) then
+ doc_tracers = 1
+ else
+ doc_tracers = 0
+ end if
+
+ ! Allocate expected IDs array
+ allocate(expected_ids(num_tracers))
+
+ ! Build expected ID sequence
+ expected_ids(1) = 1
+ expected_ids(2) = 2
+
+ do i = 1, 22
+ expected_ids(num_physical_tracers + i) = 1000 + i
+ end do
+
+ if (enable_3zoo2det .and. enable_coccos) then
+ ! Full model configuration
+ expected_ids(25:30) = (/1023, 1024, 1025, 1026, 1027, 1028/)
+ expected_ids(31:36) = (/1029, 1030, 1031, 1032, 1033, 1034/)
+ expected_ids(37:38) = (/1035, 1036/)
+ if (useRivers) then
+ expected_ids(39) = 1037 ! DOCt
+ end if
+
+ else if (enable_coccos .and. .not. enable_3zoo2det) then
+ expected_ids(25:30) = (/1023, 1024, 1025, 1026, 1027, 1028/)
+ if (useRivers) then
+ expected_ids(31) = 1029 ! DOCt
+ end if
+
+ else if (enable_3zoo2det .and. .not. enable_coccos) then
+ expected_ids(25:32) = (/1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030/)
+ if (useRivers) then
+ expected_ids(33) = 1031 ! DOCt
+ end if
+
+ else
+ ! Base configuration
+ if (useRivers) then
+ expected_ids(25) = 1023 ! DOCt
+ end if
+ end if
+
+ if (use_age_tracer) then
+ expected_ids(num_tracers) = 100
+ end if
+
+ ! ===========================================================================
+ ! Check 1: Compare actual vs expected tracer IDs
+ ! ===========================================================================
+ if (mype == 0) then
+ write(*,*) ''
+ write(*,*) '=========================================================================='
+ write(*,*) 'VALIDATING TRACER ID SEQUENCE FROM NAMELIST'
+ write(*,*) '=========================================================================='
+ end if
+
+ do i = 1, num_tracers
+ if (tracer_ids(i) /= expected_ids(i)) then
+ error_found = .true.
+ if (mype == 0) then
+ write(*,*) 'ERROR at position ', i, ':'
+ write(*,*) ' Expected tracer ID: ', expected_ids(i)
+ write(*,*) ' Found tracer ID: ', tracer_ids(i)
+ write(*,*) ''
+ end if
+ end if
+ end do
+
+ ! ===========================================================================
+ ! Check 2: Detect duplicate tracer IDs
+ ! ===========================================================================
+ do i = 1, num_tracers - 1
+ do j = i + 1, num_tracers
+ if (tracer_ids(i) == tracer_ids(j)) then
+ duplicate_found = .true.
+ if (mype == 0) then
+ write(*,*) 'ERROR: Duplicate tracer ID detected!'
+ write(*,*) ' Tracer ID ', tracer_ids(i), ' appears at positions ', i, ' and ', j
+ write(*,*) ''
+ end if
+ end if
+ end do
+ end do
+
+ ! ===========================================================================
+ ! Check 3: Detect forbidden tracer IDs for current configuration
+ ! ===========================================================================
+ !if (enable_3zoo2det .and. enable_coccos) then
+ ! Check for forbidden IDs 1023-1024 in full model
+ !do i = 1, num_tracers
+ !if (tracer_ids(i) == 1023 .or. tracer_ids(i) == 1024) then
+ !error_found = .true.
+ !if (mype == 0) then
+ !write(*,*) 'ERROR: Forbidden tracer ID in full model configuration!'
+ !write(*,*) ' Tracer ID ', tracer_ids(i), ' at position ', i
+ !write(*,*) ' IDs 1023-1024 are NOT used when both flags are enabled'
+ !write(*,*) ''
+ !end if
+ !end if
+ !end do
+ !end if
+
+ ! ===========================================================================
+ ! Report results
+ ! ===========================================================================
+ if (error_found .or. duplicate_found) then
+ if (mype == 0) then
+ write(*,*) '=========================================================================='
+ write(*,*) 'TRACER ID VALIDATION FAILED!'
+ write(*,*) '=========================================================================='
+ write(*,*) ''
+ write(*,*) 'Expected tracer ID sequence for current configuration:'
+ write(*,*) expected_ids
+ write(*,*) ''
+ write(*,*) 'Actual tracer ID sequence from namelist:'
+ write(*,*) tracer_ids
+ write(*,*) ''
+ write(*,*) 'ACTION REQUIRED:'
+ write(*,*) ' Correct the tracer IDs in your namelist.config file'
+ write(*,*) ' Ensure the sequence matches exactly as expected'
+ write(*,*) '=========================================================================='
+ write(*,*) ''
+ write(*,*) '******************************************************************'
+ write(*,*) '*** FATAL ERROR: INVALID TRACER ID SEQUENCE ***'
+ write(*,*) '*** MODEL EXECUTION STOPPED ***'
+ write(*,*) '******************************************************************'
+ write(*,*) ''
+ end if
+ deallocate(expected_ids)
+ call par_ex(0)
+ stop
+ else
+ if (mype == 0) then
+ write(*,*) '=========================================================================='
+ write(*,*) 'TRACER ID VALIDATION PASSED!'
+ write(*,*) 'All tracer IDs match expected sequence - no clashes detected.'
+ write(*,*) '=========================================================================='
+ write(*,*) ''
+ end if
+ end if
+
+ deallocate(expected_ids)
+
+end subroutine validate_tracer_id_sequence
+
+
+
end module recom_config
!
!===============================================================================
@@ -489,16 +1248,22 @@ Module REcoM_declarations
Real(kind=8) :: tiny_N ! Min PhyN
Real(kind=8) :: tiny_N_d ! Min DiaN
Real(kind=8) :: tiny_N_c ! Min CocN ! NEW
+ Real(kind=8) :: tiny_N_p ! Min PhaN ! Phaeocystis
Real(kind=8) :: tiny_C ! Min PhyC
Real(kind=8) :: tiny_C_d ! Min DiaC
Real(kind=8) :: tiny_C_c ! Min CocC ! NEW
+ Real(kind=8) :: tiny_C_p ! Min PhaC ! Phaeocystis
Real(kind=8) :: tiny_Si ! Min DiaSi
!!------------------------------------------------------------------------------
!! *** Temperature dependence of rates ***
Real(kind=8) :: rTref ! [1/K] Reciproque value of reference temp for Arrhenius function
Real(kind=8) :: rTloc ! [1/K] Reciproque of local ocean temp
- Real(kind=8) :: arrFunc ! [] Temp dependence of rates
+ Real(kind=8) :: arrFunc ! [] Temp dependence of rates (also for Phaeocystis)
Real(kind=8) :: CoccoTFunc ! [] Temp dependence of coccolithophores
+ Real(kind=8) :: Temp_diatoms ! [] Temp dependence of diatoms
+ Real(kind=8) :: Temp_phyto ! [] Temp dependence of small phyto
+ Real(kind=8) :: Temp_cocco ! [] Temp dependence of coccolithophores
+ Real(kind=8) :: Temp_phaeo ! [] Temp dependence of phaeocystis
Real(kind=8) :: arrFuncZoo2 ! [] Temperature function for krill
Real(kind=8) :: q10_mic ! 3Zoo
Real(kind=8) :: q10_mic_res ! 3Zoo
@@ -515,13 +1280,15 @@ Module REcoM_declarations
Real(kind=8) :: CoccoCO2
Real(kind=8) :: DiaCO2
Real(kind=8) :: PhyCO2
+ Real(kind=8) :: PhaeoCO2
+
!!------------------------------------------------------------------------------
!! *** Quotas ***
- Real(kind=8) :: quota, quota_dia, quota_cocco ! [mmol N/mmol C] Quota between phytoplankton N and C (NEW changed term)
- Real(kind=8) :: recipQuota, recipQuota_dia, recipQuota_cocco ! [mmol C/mmol N] Reciproque of 'quota' (NEW changed term)
- Real(kind=8) :: Chl2C, Chl2C_dia, Chl2C_cocco ! [mg ChlA/mmol C] Quota between phytoplankton ChlA and C (NEW changed term)
- Real(kind=8) :: Chl2C_plast, Chl2C_plast_dia, CHL2C_plast_cocco ! [mg ChlA/mmol C] needed for photodamage (NEW changed term)
- Real(kind=8) :: Chl2N, Chl2N_dia, Chl2N_cocco ! [mg ChlA/mmol N] Quota between phytoplankton ChlA and N (NEW changed term)
+ Real(kind=8) :: quota, quota_dia, quota_cocco, quota_phaeo ! [mmol N/mmol C] Quota between phytoplankton N and C (NEW changed term)
+ Real(kind=8) :: recipQuota, recipQuota_dia, recipQuota_cocco, recipQuota_phaeo ! [mmol C/mmol N] Reciproque of 'quota' (NEW changed term)
+ Real(kind=8) :: Chl2C, Chl2C_dia, Chl2C_cocco, Chl2C_phaeo ! [mg ChlA/mmol C] Quota between phytoplankton ChlA and C (NEW changed term)
+ Real(kind=8) :: Chl2C_plast, Chl2C_plast_dia, CHL2C_plast_cocco, CHL2C_plast_phaeo ! [mg ChlA/mmol C] needed for photodamage (NEW changed term)
+ Real(kind=8) :: Chl2N, Chl2N_dia, Chl2N_cocco, Chl2N_phaeo ! [mg ChlA/mmol N] Quota between phytoplankton ChlA and N (NEW changed term)
Real(kind=8) :: qSiC
Real(kind=8) :: qSiN
Real(kind=8) :: recipQZoo ! [mmol C/mmol N] Quota between heterotrophic C and N
@@ -535,8 +1302,8 @@ Module REcoM_declarations
!! *** For limiter function ***
Real(kind=8) :: qlimitFac, qlimitFacTmp ! Factor that regulates photosynthesis
Real(kind=8),external :: recom_limiter ! Function calculating qlimitFac
- Real(kind=8) :: FeLimitFac ! [Mumol/m3] Half sat constant for iron
- Real(kind=8) :: pMax, pMax_dia, pMax_cocco ! [1/day] Maximum rate of C-specific photosynthesis
+ Real(kind=8) :: FeLimitFac ! [Mumol/m3] Half sat constant for iron
+ Real(kind=8) :: pMax, pMax_dia, pMax_cocco, pMax_phaeo ! [1/day] Maximum rate of C-specific photosynthesis
!!------------------------------------------------------------------------------
!! *** Light ***
Real(kind=8) :: kappar ! [1/m] Light attenuation coefficient modified by chla
@@ -548,48 +1315,59 @@ Module REcoM_declarations
Real(kind=8) :: PARave ! [?] Average light in the control volumes
!!------------------------------------------------------------------------------
!! *** Photosynthesis ***
- Real(kind=8) :: Cphot, Cphot_dia, Cphot_cocco ! [1/day] C-specific rate of photosynthesis
+ Real(kind=8) :: Cphot, Cphot_dia, Cphot_cocco, Cphot_phaeo ! [1/day] C-specific rate of photosynthesis
!!------------------------------------------------------------------------------
!! *** Assimilation ***
Real(kind=8) :: V_cm ! scaling factor for temperature dependent maximum of C-specific N-uptake
- Real(kind=8) :: limitFacN,limitFacN_dia,limitFacN_cocco ! Factor that regulates N-assimilation. Calc from function recom_limiter
+ Real(kind=8) :: limitFacN,limitFacN_dia,limitFacN_cocco, limitFacN_phaeo ! Factor that regulates N-assimilation. Calc from function recom_limiter
Real(kind=8) :: limitFacSi
- Real(kind=8) :: N_assim, N_assim_dia, N_assim_Cocco ! [mmol N/(mmol C * day)] C specific N utilization rate
+ Real(kind=8) :: N_assim, N_assim_dia, N_assim_Cocco, N_assim_phaeo ! [mmol N/(mmol C * day)] C specific N utilization rate
Real(kind=8) :: Si_assim
!!------------------------------------------------------------------------------
!! *** Chlorophyll ***
- Real(kind=8) :: ChlSynth, ChlSynth_dia, ChlSynth_cocco ! [mg CHL/ mmol N] CHL a synthesis regulation term
- Real(kind=8) :: phyRespRate, phyRespRate_dia, phyRespRate_cocco ! [1/day] Phytoplankton respiration rate
- Real(kind=8) :: KOchl, KOchl_dia, KOchl_cocco ! coefficient for damage to the photosynthetic apparatus
+ Real(kind=8) :: ChlSynth, ChlSynth_dia, ChlSynth_cocco, ChlSynth_phaeo ! [mg CHL/ mmol N] CHL a synthesis regulation term
+ Real(kind=8) :: phyRespRate, phyRespRate_dia, phyRespRate_cocco, phyRespRate_phaeo ! [1/day] Phytoplankton respiration rate
+ Real(kind=8) :: KOchl, KOchl_dia, KOchl_cocco, KOchl_phaeo ! coefficient for damage to the photosynthetic apparatus
+!!------------------------------------------------------------------------------
+!! *** Vertical only Decomposition of phytoplankton growth components ***
+ Real(kind=8),allocatable,dimension(:) :: VTTemp_diatoms, VTTemp_phyto, VTTemp_cocco, VTTemp_phaeo ! Vertical 1D temperature effect on phytoplankton photosynthesis
+ Real(kind=8),allocatable,dimension(:) :: VTPhyCO2, VTDiaCO2, VTCoccoCO2, VTPhaeoCO2 ! CO2 effect
+ Real(kind=8),allocatable,dimension(:) :: VTqlimitFac_phyto, VTqlimitFac_diatoms, VTqlimitFac_cocco, VTqlimitFac_phaeo ! nutrient effect
+ Real(kind=8),allocatable,dimension(:) :: VTCphotLigLim_phyto, VTCphotLigLim_diatoms, VTCphotLigLim_cocco, VTCphotLigLim_phaeo ! light limitation
+ Real(kind=8),allocatable,dimension(:) :: VTCphot_phyto, VTCphot_diatoms, VTCphot_cocco, VTCphot_phaeo
+ Real(kind=8),allocatable,dimension(:) :: VTSi_assimDia
+
!!------------------------------------------------------------------------------
!! *** Iron chemistry ***
Real(kind=8),external :: iron_chemistry, iron_chemistry_2ligands
- Real(kind=8) :: logK1, logK2, Klig1, Klig2
+ Real(kind=8) :: logK1, logK2, Klig1, Klig2
!!------------------------------------------------------------------------------
!! *** Zooplankton ***
Real(kind=8) :: DiaNsq
- Real(kind=8) :: varpzdia, fDiaN ! Part of Diatoms available for food
- Real(kind=8) :: PhyNsq
- Real(kind=8) :: varpzPhy, fPhyN ! Part of Nano available for food
- Real(kind=8) :: CoccoNsq ! NEW
- Real(kind=8) :: varpzCocco,fCoccoN ! NEW
- Real(kind=8) :: MicZooNsq ! NEW 3Zoo
- Real(kind=8) :: varpzMicZoo, fMicZooN ! NEW 3Zoo Part of microzooplankton available for food
- Real(kind=8) :: food, foodsq ! [(mmol N)2/m6]
- Real(kind=8) :: grazingFlux_phy, grazingFlux_Dia, grazingFlux_Cocco ! [mmol N / (m3 * day)] (NEW changed term)
- Real(kind=8) :: grazingFlux_miczoo ! NEW 3Zoo
+ Real(kind=8) :: varpzdia, fDiaN ! Part of Diatoms available for food
+ Real(kind=8) :: PhyNsq
+ Real(kind=8) :: varpzPhy, fPhyN ! Part of Nano available for food
+ Real(kind=8) :: CoccoNsq
+ Real(kind=8) :: varpzCocco,fCoccoN
+ Real(kind=8) :: PhaeoNsq
+ Real(kind=8) :: varpzPhaeo,fPhaeoN
+ Real(kind=8) :: MicZooNsq ! NEW 3Zoo
+ Real(kind=8) :: varpzMicZoo, fMicZooN ! NEW 3Zoo Part of microzooplankton available for food
+ Real(kind=8) :: food, foodsq ! [(mmol N)2/m6]
+ Real(kind=8) :: grazingFlux_phy, grazingFlux_Dia, grazingFlux_Cocco, grazingFlux_Phaeo ! [mmol N / (m3 * day)] (NEW changed term)
+ Real(kind=8) :: grazingFlux_miczoo ! NEW 3Zoo
Real(kind=8) :: grazingFlux
- Real(kind=8) :: grazEff ! NEW 3Zoo
+ Real(kind=8) :: grazEff ! NEW 3Zoo
Real(kind=8) :: HetRespFlux ! Zooplankton respiration
Real(kind=8) :: HetLossFlux ! [(mmol N)2/(m6 * day)] Zooplankton mortality (quadratic loss)
!!------------------------------------------------------------------------------
!! *** Second Zooplankton ***
- Real(kind=8) :: DiaNsq2, PhyNsq2, CoccoNsq2, HetNsq ! NEW (changed term)
- Real(kind=8) :: varpzDia2, fDiaN2, varpzPhy2, fPhyN2, varpzCocco2, fCoccoN2, varpzHet, fHetN ! Part of Diatoms available for food
+ Real(kind=8) :: DiaNsq2, PhyNsq2, CoccoNsq2, PhaeoNsq2, HetNsq ! NEW (changed term)
+ Real(kind=8) :: varpzDia2, fDiaN2, varpzPhy2, fPhyN2, varpzCocco2, fCoccoN2, varpzPhaeo2, fPhaeoN2, varpzHet, fHetN ! Part of Diatoms available for food
Real(kind=8) :: MicZooNsq2 ! NEW Zoo3
Real(kind=8) :: varpzMicZoo2, fMicZooN2 ! NEW Zoo3
- Real(kind=8) :: food2, foodsq2 ! [(mmol N)2/m6]
- Real(kind=8) :: grazingFlux_phy2, grazingFlux_Dia2, grazingFlux_Cocco2, grazingFlux_het2 ! [mmol N / (m3 * day) (NEW changed term)
+ Real(kind=8) :: food2, foodsq2 ! [(mmol N)2/m6]
+ Real(kind=8) :: grazingFlux_phy2, grazingFlux_Dia2, grazingFlux_Cocco2, grazingFlux_Phaeo2, grazingFlux_het2 ! [mmol N / (m3 * day) (NEW changed term)
Real(kind=8) :: grazingFlux_miczoo2 ! NEW Zoo3
Real(kind=8) :: grazingFlux2
Real(kind=8) :: Zoo2RespFlux ! Zooplankton respiration
@@ -615,8 +1393,10 @@ Module REcoM_declarations
Real(kind=8) :: varpzPhy3, fPhyN3 ! Part of small phytoplankton available for food
Real(kind=8) :: CoccoNsq3
Real(kind=8) :: varpzCocco3, fCoccoN3 ! Part of coccolithophores available for food
+ Real(kind=8) :: PhaeoNsq3
+ Real(kind=8) :: varpzPhaeo3, fPhaeoN3 ! Part of phaeocystis available for food
Real(kind=8) :: food3, foodsq3 ! [(mmol N)2/m6]
- Real(kind=8) :: grazingFlux_phy3, grazingFlux_Dia3, grazingFlux_Cocco3 ! [mmol N / (m3 * day)]
+ Real(kind=8) :: grazingFlux_phy3, grazingFlux_Dia3, grazingFlux_Cocco3, grazingFlux_Phaeo3 ! [mmol N / (m3 * day)]
Real(kind=8) :: grazingFlux3
Real(kind=8) :: MicZooRespFlux ! Zooplankton respiration
Real(kind=8) :: MicZooLossFlux ! [(mmol N)2/(m6 * day)] Zooplankton mortality (quadratic loss)
@@ -640,18 +1420,85 @@ Module REcoM_declarations
!! *** Diagnostics ***
Real(kind=8) :: recipbiostep ! 1/number of steps per recom cycle
Real(kind=8),allocatable,dimension(:,:) :: Diags3Dloc
- Real(kind=8) :: locNPPn, locGPPn, locNNAn, locChldegn
- Real(kind=8) :: locNPPd, locGPPd, locNNAd, locChldegd
- Real(kind=8) :: locNPPc, locGPPc, locNNAc, locChldegc
+
+ ! ==================================================================
+ ! SMALL PHYTOPLANKTON (n suffix)
+ ! ==================================================================
+ Real(kind=8) :: locNPPn, locGPPn, locNNAn, locChldegn
Real(kind=8),allocatable,dimension(:) :: vertNPPn, vertGPPn, vertNNAn, vertChldegn
+ Real(kind=8),allocatable,dimension(:) :: vertrespn
+ Real(kind=8),allocatable,dimension(:) :: vertdocexn
+ Real(kind=8),allocatable,dimension(:) :: vertaggn
+
+ ! ==================================================================
+ ! DIATOMS (d suffix)
+ ! ==================================================================
+ Real(kind=8) :: locNPPd, locGPPd, locNNAd, locChldegd
Real(kind=8),allocatable,dimension(:) :: vertNPPd, vertGPPd, vertNNAd, vertChldegd
+ Real(kind=8),allocatable,dimension(:) :: vertrespd
+ Real(kind=8),allocatable,dimension(:) :: vertdocexd
+ Real(kind=8),allocatable,dimension(:) :: vertaggd
+
+ ! ==================================================================
+ ! COCCOLITHOPHORES (c suffix)
+ ! ==================================================================
+ Real(kind=8) :: locNPPc, locGPPc, locNNAc, locChldegc
Real(kind=8),allocatable,dimension(:) :: vertNPPc, vertGPPc, vertNNAc, vertChldegc
- Real(kind=8),allocatable,dimension(:) :: vertgrazmeso_tot, vertgrazmeso_n, vertgrazmeso_d, vertgrazmeso_c
- Real(kind=8),allocatable,dimension(:) :: vertrespmeso, vertrespmacro, vertrespmicro
+ Real(kind=8),allocatable,dimension(:) :: vertrespc
+ Real(kind=8),allocatable,dimension(:) :: vertdocexc
+ Real(kind=8),allocatable,dimension(:) :: vertaggc
Real(kind=8),allocatable,dimension(:) :: vertcalcdiss, vertcalcif
- Real(kind=8),allocatable,dimension(:) :: vertaggn, vertaggd, vertaggc
- Real(kind=8),allocatable,dimension(:) :: vertdocexn, vertdocexd, vertdocexc
- Real(kind=8),allocatable,dimension(:) :: vertrespn, vertrespd, vertrespc
+
+ ! ==================================================================
+ ! PHAEOCYSTIS (p suffix)
+ ! ==================================================================
+ Real(kind=8) :: locNPPp, locGPPp, locNNAp, locChldegp
+ Real(kind=8),allocatable,dimension(:) :: vertNPPp, vertGPPp, vertNNAp, vertChldegp
+ Real(kind=8),allocatable,dimension(:) :: vertrespp
+ Real(kind=8),allocatable,dimension(:) :: vertdocexp
+ Real(kind=8),allocatable,dimension(:) :: vertaggp
+
+ ! ==================================================================
+ ! MICROZOOPLANKTON
+ ! ==================================================================
+ Real(kind=8) :: locgrazmicro_tot, locgrazmicro_n, locgrazmicro_d, locgrazmicro_c, locgrazmicro_p
+ Real(kind=8),allocatable,dimension(:) :: vertgrazmicro_tot, vertgrazmicro_n, vertgrazmicro_d, vertgrazmicro_c, vertgrazmicro_p
+ Real(kind=8),allocatable,dimension(:) :: vertrespmicro
+
+ ! ==================================================================
+ ! MESOZOOPLANKTON
+ ! ==================================================================
+ Real(kind=8) :: locgrazmeso_tot, locgrazmeso_n, locgrazmeso_d, locgrazmeso_c, locgrazmeso_p
+ Real(kind=8) :: locgrazmeso_det, locgrazmeso_mic, locgrazmeso_det2
+ Real(kind=8),allocatable,dimension(:) :: vertgrazmeso_tot, vertgrazmeso_n, vertgrazmeso_d, vertgrazmeso_c, vertgrazmeso_p
+ Real(kind=8),allocatable,dimension(:) :: vertgrazmeso_det, vertgrazmeso_mic, vertgrazmeso_det2
+ Real(kind=8),allocatable,dimension(:) :: vertrespmeso
+
+ ! ==================================================================
+ ! MACROZOOPLANKTON
+ ! ==================================================================
+ Real(kind=8) :: locgrazmacro_tot, locgrazmacro_n, locgrazmacro_d, locgrazmacro_c, locgrazmacro_p
+ Real(kind=8) :: locgrazmacro_mes, locgrazmacro_det, locgrazmacro_mic, locgrazmacro_det2
+ Real(kind=8),allocatable,dimension(:) :: vertgrazmacro_tot, vertgrazmacro_n, vertgrazmacro_d, vertgrazmacro_c, vertgrazmacro_p
+ Real(kind=8),allocatable,dimension(:) :: vertgrazmacro_mes, vertgrazmacro_det, vertgrazmacro_mic, vertgrazmacro_det2
+ Real(kind=8),allocatable,dimension(:) :: vertrespmacro
+
+ Real(kind=8),allocatable,dimension(:) :: vertfastcdis
+ Real(kind=8),allocatable,dimension(:) :: vertphotn, vertphotd, vertphotc, vertphotp !Phytoplankton photosynthesis terms
+ Real(kind=8),allocatable,dimension(:) :: vertmesocdis, vertmicrocdis, vertmacrocdis !Additional zooplankton calcium dissolution terms
+ Real(kind=8),allocatable,dimension(:) :: vertNassimn, vertNassimd, vertNassimc, vertNassimp !N assimilation by phytoplanktons
+ Real(kind=8),allocatable,dimension(:) :: vertDONremin !DON remineralization term
+ Real(kind=8),allocatable,dimension(:) :: vertDOCremin !DOC remineralization term
+ Real(kind=8),allocatable,dimension(:,:,:) :: dtr_bf_din ! Diagnostics for DIN bottom flux RP on 26.09.2025
+ Real(kind=8),allocatable,dimension(:,:,:) :: dtr_bf_dic ! Diagnostics for DIC bottom flux
+ Real(kind=8),allocatable,dimension(:,:,:) :: dtr_bf_alk ! Diagnostics for Alk bottom flux
+ Real(kind=8),allocatable,dimension(:,:,:) :: dtr_bf_dsi ! Diagnostics for DSi bottom flux
+
+ !===================================================================
+ ! DISSOLUTION AND REMINERALIZATION ! R2OMIP
+ !===================================================================
+ Real(kind=8) :: locDISSOC, locDISSON, locDISSOSi, locREMOC, locREMOCt, locREMON
+ Real(kind=8),allocatable,dimension(:) :: vertDISSOC, vertDISSON, vertDISSOSi, vertREMOC, vertREMOCt, vertREMON
!!------------------------------------------------------------------------------
!! *** Benthos ***
Real(kind=8),allocatable,dimension(:) :: decayBenthos ! [1/day] Decay rate of detritus in the benthic layer
@@ -659,11 +1506,13 @@ Module REcoM_declarations
Real(kind=8),allocatable,dimension(:) :: wFluxPhy ! [mmol/(m2 * day)] Flux of N,C, calc and chl through sinking of phytoplankton
Real(kind=8),allocatable,dimension(:) :: wFluxDia ! [mmol/(m2 * day)] Flux of N,C, Si and chl through sinking of diatoms
Real(kind=8),allocatable,dimension(:) :: wFluxCocco ! NEW [mmol/(m2 * day)] Flux of N,C, calc and chl through sinking of coccos
+ Real(kind=8),allocatable,dimension(:) :: wFluxPhaeo ! NEW [mmol/(m2 * day)] Flux of N,C, calc and chl through sinking of Phaeocystis
Real(kind=8) :: Vben_det ! [m/day] speed of sinking into benthos from water column
Real(kind=8) :: Vben_det_seczoo !second zooplankton sinking benthos
Real(kind=8) :: Vben_phy
Real(kind=8) :: Vben_dia
Real(kind=8) :: Vben_coc
+ Real(kind=8) :: Vben_pha ! Phaeocystis
Real(kind=8) :: Ironflux ! [umol Fe/(m2*day)] Flux of Fe from sediment to water
!_______________________________________________________________________________
! Arrays added for RECOM implementation:
@@ -678,6 +1527,9 @@ Module REcoM_declarations
real(kind=8) :: is_riverinput
real(kind=8) :: is_erosioninput
+real(kind=8) :: is_3zoo2det
+real(kind=8) :: is_coccos
+
end module REcoM_declarations
!===============================================================================
@@ -686,13 +1538,14 @@ end module REcoM_declarations
Module REcoM_GloVar
implicit none
save
-
+
Real(kind=8),allocatable,dimension(:,:) :: Benthos ! 4 types of benthos-tracers with size [4 n2d]
Real(kind=8),allocatable,dimension(:,:,:) :: Benthos_tr ! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
Real(kind=8),allocatable,dimension(:) :: GloFeDust ! [umol/m2/s] Monthly 2D field of iron soluted in surface water from dust
Real(kind=8),allocatable,dimension(:) :: GloNDust ! [mmol/m2/s] 10-year mean 2D fields of nitrogen soluted in surface water from dust
Real(kind=8),dimension(12) :: AtmCO2 ! [uatm] Atmospheric CO2 partial pressure. One value for the whole planet for each month
+ Real(kind=8),allocatable,dimension(:) :: OmegaC_bottom !< calcite saturation state at the ocean bottom !R2OMIP
Real(kind=8),allocatable,dimension(:) :: AtmFeInput ! [umol/m2/s] Includes ice, but is, other than that identlical to GloFeDust
Real(kind=8),allocatable,dimension(:) :: AtmNInput ! [umol/m2/s] Includes ice, but is, other than that identlical to GloNDust
@@ -721,11 +1574,17 @@ Module REcoM_GloVar
Real(kind=8),allocatable,dimension(:) :: GlodPCO2surf ! [mmol/m2/day] ocean-atmosphere
Real(kind=8),allocatable,dimension(:,:) :: GlodecayBenthos ! [1/day] Decay rate of detritus in the benthic layer saved for oce_ale_tracer.F90
+ Real(kind=8),allocatable,dimension(:,:) :: Sed_2_Ocean_Flux ! Flux from the sediment back to the bottom ocean ! R2OMIP
+ Real(kind=8),allocatable,dimension(:,:) :: Ocean_2_Sed_Flux ! Flux from the bottom ocean to the sediment ! R2OMIP
+ Real(kind=8),allocatable,dimension(:,:) :: Burial ! Benthic permanent burial Field in 2D [n2d 1] ! R2OMIP
+ Real(kind=8),allocatable,dimension(:) :: PistonVelocity ! [m s-1]
+ Real(kind=8),allocatable,dimension(:) :: alphaCO2 ! [mol L-1 atm-1]
Real(kind=8),allocatable,dimension(:,:) :: GlowFluxDet !
Real(kind=8),allocatable,dimension(:,:) :: GlowFluxPhy !
Real(kind=8),allocatable,dimension(:,:) :: GlowFluxDia !
- Real(kind=8),allocatable,dimension(:,:) :: GlowFluxCocco !
+ Real(kind=8),allocatable,dimension(:,:) :: GlowFluxCocco !
+ Real(kind=8),allocatable,dimension(:,:) :: GlowFluxPhaeo !
Real(kind=8),allocatable,dimension(:,:) :: diags2D ! Diagnostics in 2D [8 n2d]
Real(kind=8),allocatable,dimension(:) :: NPPn
@@ -740,10 +1599,38 @@ Module REcoM_GloVar
Real(kind=8),allocatable,dimension(:) :: GPPc
Real(kind=8),allocatable,dimension(:) :: NNAc
Real(kind=8),allocatable,dimension(:) :: Chldegc
- Real(kind=8),allocatable,dimension(:,:) :: grazmeso_tot
- Real(kind=8),allocatable,dimension(:,:) :: grazmeso_n
- Real(kind=8),allocatable,dimension(:,:) :: grazmeso_d
- Real(kind=8),allocatable,dimension(:,:) :: grazmeso_c
+ Real(kind=8),allocatable,dimension(:) :: NPPp ! Phaeocystis
+ Real(kind=8),allocatable,dimension(:) :: GPPp
+ Real(kind=8),allocatable,dimension(:) :: NNAp
+ Real(kind=8),allocatable,dimension(:) :: Chldegp
+ Real(kind=8),allocatable,dimension(:) :: grazmeso_tot
+ Real(kind=8),allocatable,dimension(:) :: grazmeso_n
+ Real(kind=8),allocatable,dimension(:) :: grazmeso_d
+ Real(kind=8),allocatable,dimension(:) :: grazmeso_c
+ Real(kind=8),allocatable,dimension(:) :: grazmeso_p
+ Real(kind=8),allocatable,dimension(:) :: grazmeso_det
+ Real(kind=8),allocatable,dimension(:) :: grazmeso_mic
+ Real(kind=8),allocatable,dimension(:) :: grazmeso_det2
+ Real(kind=8),allocatable,dimension(:) :: grazmacro_tot
+ Real(kind=8),allocatable,dimension(:) :: grazmacro_n
+ Real(kind=8),allocatable,dimension(:) :: grazmacro_d
+ Real(kind=8),allocatable,dimension(:) :: grazmacro_c
+ Real(kind=8),allocatable,dimension(:) :: grazmacro_p
+ Real(kind=8),allocatable,dimension(:) :: grazmacro_mes
+ Real(kind=8),allocatable,dimension(:) :: grazmacro_det
+ Real(kind=8),allocatable,dimension(:) :: grazmacro_mic
+ Real(kind=8),allocatable,dimension(:) :: grazmacro_det2
+ Real(kind=8),allocatable,dimension(:) :: grazmicro_tot
+ Real(kind=8),allocatable,dimension(:) :: grazmicro_n
+ Real(kind=8),allocatable,dimension(:) :: grazmicro_d
+ Real(kind=8),allocatable,dimension(:) :: grazmicro_c
+ Real(kind=8),allocatable,dimension(:) :: grazmicro_p
+ Real(kind=8),allocatable,dimension(:) :: DISSOC
+ Real(kind=8),allocatable,dimension(:) :: DISSON
+ Real(kind=8),allocatable,dimension(:) :: DISSOSi
+ Real(kind=8),allocatable,dimension(:) :: REMOC
+ Real(kind=8),allocatable,dimension(:) :: REMOCt
+ Real(kind=8),allocatable,dimension(:) :: REMON
Real(kind=8),allocatable,dimension(:,:) :: respmeso
Real(kind=8),allocatable,dimension(:,:) :: respmacro
Real(kind=8),allocatable,dimension(:,:) :: respmicro
@@ -752,15 +1639,56 @@ Module REcoM_GloVar
Real(kind=8),allocatable,dimension(:,:) :: aggn
Real(kind=8),allocatable,dimension(:,:) :: aggd
Real(kind=8),allocatable,dimension(:,:) :: aggc
+ Real(kind=8),allocatable,dimension(:,:) :: aggp ! Phaeocystis
Real(kind=8),allocatable,dimension(:,:) :: docexn
Real(kind=8),allocatable,dimension(:,:) :: docexd
Real(kind=8),allocatable,dimension(:,:) :: docexc
+ Real(kind=8),allocatable,dimension(:,:) :: docexp ! Phaeocystis
Real(kind=8),allocatable,dimension(:,:) :: respn
Real(kind=8),allocatable,dimension(:,:) :: respd
Real(kind=8),allocatable,dimension(:,:) :: respc
+ Real(kind=8),allocatable,dimension(:,:) :: respp ! Phaeocystis
Real(kind=8),allocatable,dimension(:,:) :: NPPn3D
Real(kind=8),allocatable,dimension(:,:) :: NPPd3D
Real(kind=8),allocatable,dimension(:,:) :: NPPc3D
+ Real(kind=8),allocatable,dimension(:,:) :: NPPp3D ! Phaeocystis
+
+ Real(kind=8),allocatable,dimension(:,:) :: photn
+ Real(kind=8),allocatable,dimension(:,:) :: photd
+ Real(kind=8),allocatable,dimension(:,:) :: photc
+ Real(kind=8),allocatable,dimension(:,:) :: photp
+ Real(kind=8),allocatable,dimension(:,:) :: DOCremin
+ Real(kind=8),allocatable,dimension(:,:) :: Nassimn
+ Real(kind=8),allocatable,dimension(:,:) :: Nassimd
+ Real(kind=8),allocatable,dimension(:,:) :: Nassimc
+ Real(kind=8),allocatable,dimension(:,:) :: Nassimp
+ Real(kind=8),allocatable,dimension(:,:) :: DONremin
+ Real(kind=8),allocatable,dimension(:,:) :: fastcdis
+ Real(kind=8),allocatable,dimension(:,:) :: mesocdis
+ Real(kind=8),allocatable,dimension(:,:) :: microcdis
+ Real(kind=8),allocatable,dimension(:,:) :: macrocdis
+
+ Real(kind=8),allocatable,dimension(:,:) :: TTemp_diatoms ! my new variables to track
+ Real(kind=8),allocatable,dimension(:,:) :: TTemp_phyto ! new Temperature effect
+ Real(kind=8),allocatable,dimension(:,:) :: TTemp_cocco ! new
+ Real(kind=8),allocatable,dimension(:,:) :: TTemp_phaeo ! new
+ Real(kind=8),allocatable,dimension(:,:) :: TPhyCO2 ! new CO2 effect
+ Real(kind=8),allocatable,dimension(:,:) :: TDiaCO2
+ Real(kind=8),allocatable,dimension(:,:) :: TCoccoCO2
+ Real(kind=8),allocatable,dimension(:,:) :: TPhaeoCO2
+ Real(kind=8),allocatable,dimension(:,:) :: TqlimitFac_phyto ! new nutrient limitation
+ Real(kind=8),allocatable,dimension(:,:) :: TqlimitFac_diatoms
+ Real(kind=8),allocatable,dimension(:,:) :: TqlimitFac_cocco
+ Real(kind=8),allocatable,dimension(:,:) :: TqlimitFac_phaeo
+ Real(kind=8),allocatable,dimension(:,:) :: TCphotLigLim_phyto ! new light limitation
+ Real(kind=8),allocatable,dimension(:,:) :: TCphot_phyto ! new
+ Real(kind=8),allocatable,dimension(:,:) :: TCphotLigLim_diatoms ! new light limitation
+ Real(kind=8),allocatable,dimension(:,:) :: TCphot_diatoms
+ Real(kind=8),allocatable,dimension(:,:) :: TCphotLigLim_cocco ! new light limitation
+ Real(kind=8),allocatable,dimension(:,:) :: TCphot_cocco
+ Real(kind=8),allocatable,dimension(:,:) :: TCphotLigLim_phaeo ! new light limitation
+ Real(kind=8),allocatable,dimension(:,:) :: TCphot_phaeo
+ Real(kind=8),allocatable,dimension(:,:) :: TSi_assimDia ! tracking the assimilation of Si by Diatoms
Real(kind=8),allocatable,dimension(:) :: DenitBen ! Benthic denitrification Field in 2D [n2d 1]
@@ -770,13 +1698,17 @@ Module REcoM_GloVar
Real(kind=8),allocatable,dimension(:,:) :: Sinkingvel1 ! Diagnostics for vertical sinking
Real(kind=8),allocatable,dimension(:,:) :: Sinkingvel2 ! Diagnostics for vertical sinking
Real(kind=8),allocatable,dimension(:,:,:) :: Sinkvel1_tr ! Sinking speed of particle class 1 OG 16.03.23
- Real(kind=8),allocatable,dimension(:,:,:) :: Sinkvel2_tr ! Sinking speed of particle class 2 OG 16.03.23
+ Real(kind=8),allocatable,dimension(:,:,:) :: Sinkvel2_tr ! Sinking speed of particle class 2 OG 16.03.23
+ Real(kind=8),allocatable,dimension(:,:) :: dtr_bflux_din ! Diagnostics for DIN bottom flux RP on 30.09.2025
+ Real(kind=8),allocatable,dimension(:,:) :: dtr_bflux_dic ! Diagnostics for DIC bottom flux
+ Real(kind=8),allocatable,dimension(:,:) :: dtr_bflux_alk ! Diagnostics for Alk bottom flux
+ Real(kind=8),allocatable,dimension(:,:) :: dtr_bflux_dsi ! Diagnostics for DSi bottom flux
Real(kind=8),allocatable,dimension(:,:) :: GloSed ! Yearly input into bottom water from sediments [n2d 5] or [n2d 7] with ciso
Real(kind=8),allocatable,dimension(:,:) :: lb_flux ! Yearly burial from medusa: [n2d 5] or [n2d 9] with ciso_14
! atmospheric box model:
- real(kind=8),allocatable,dimension(:) :: x_co2atm ! atmospheric CO2 mixing ratio (mole fraction)
+ Real(kind=8),allocatable,dimension(:) :: x_co2atm ! atmospheric CO2 mixing ratio (mole fraction)
Real(kind=8), allocatable,dimension(:) :: Alk_surf ! Surface alkalinity field used for restoring
Real(kind=8), allocatable,dimension(:) :: relax_alk
@@ -784,7 +1716,12 @@ Module REcoM_GloVar
real(kind=8), allocatable,dimension(:,:) :: PAR3D ! Light in the water column [nl-1 n2d]
real(kind=8), allocatable,dimension(:) :: RiverineLonOrig, RiverineLatOrig, RiverineDINOrig, RiverineDONOrig, RiverineDOCOrig, RiverineDSiOrig ! Variables to save original values for riverine nutrients
- real(kind=8), allocatable,dimension(:) :: RiverDIN2D, RiverDON2D, RiverDOC2D, RiverDSi2D, RiverAlk2D, RiverDIC2D, RiverFe
+ real(kind=8), allocatable,dimension(:) :: RiverDIC2D, RiverDIN2D, RiverDOCl2D, RiverDOCsl2D, RiverPOC2D, RiverFe
+ real(kind=8), allocatable,dimension(:) :: RiverDON2D, RiverDSi2D, RiverAlk2D ! RiverDOC2D
+ Real(kind=8),allocatable,dimension(:) :: LocDenit
+ Real(kind=8),allocatable,dimension(:,:) :: LocBurial ! R2OMIP
+ Real(kind=8),allocatable,dimension(:) :: BurialBen ! R2OMIP
+
real(kind=8), allocatable,dimension(:) :: ErosionTSi2D, ErosionTON2D, ErosionTOC2D
!! Cobeta, Cos(Angle of incidence)
Real(kind=8), allocatable,dimension(:) :: cosAI
@@ -865,7 +1802,7 @@ Module REcoM_locVar
Real(kind=8) :: PICPOCN ! (to make calcification dependent on N-limitation)
Real(kind=8) :: calc_prod_final ! (added to make the calcification dependent on nutrients (N, Fe), after Krumhardt et al. 2017/2019)
Integer :: currentCO2year
-
+
end module REcoM_LocVar
!===============================================================================
! Specific declarations related to carbon isotope simulations
@@ -1167,3 +2104,496 @@ end function wind_10
end module REcoM_ciso
+
+
+module recom_diags_management
+ use recom_config
+ implicit none
+
+contains
+
+! ==============================================================================
+! SUBROUTINE: allocate_and_init_diags
+! Purpose: Allocate and initialize all diagnostic arrays for a water column
+! ==============================================================================
+subroutine allocate_and_init_diags(nl)
+ use recom_locvar
+ use REcoM_declarations
+ implicit none
+
+ integer, intent(in) :: nl ! Number of vertical levels
+
+ ! --------------------------------------------------------------------------
+ ! Small Phytoplankton
+ ! --------------------------------------------------------------------------
+ allocate(vertNPPn(nl-1), vertGPPn(nl-1), vertNNAn(nl-1), vertChldegn(nl-1))
+ allocate(vertrespn(nl-1), vertdocexn(nl-1), vertaggn(nl-1))
+
+ vertNPPn = 0.d0
+ vertGPPn = 0.d0
+ vertNNAn = 0.d0
+ vertChldegn = 0.d0
+ vertrespn = 0.d0
+ vertdocexn = 0.d0
+ vertaggn = 0.d0
+
+ ! --------------------------------------------------------------------------
+ ! Diatoms
+ ! --------------------------------------------------------------------------
+ allocate(vertNPPd(nl-1), vertGPPd(nl-1), vertNNAd(nl-1), vertChldegd(nl-1))
+ allocate(vertrespd(nl-1), vertdocexd(nl-1), vertaggd(nl-1))
+
+ vertNPPd = 0.d0
+ vertGPPd = 0.d0
+ vertNNAd = 0.d0
+ vertChldegd = 0.d0
+ vertrespd = 0.d0
+ vertdocexd = 0.d0
+ vertaggd = 0.d0
+
+ ! --------------------------------------------------------------------------
+ ! Coccolithophores (if enabled)
+ ! --------------------------------------------------------------------------
+ if (enable_coccos) then
+ allocate(vertNPPc(nl-1), vertGPPc(nl-1), vertNNAc(nl-1), vertChldegc(nl-1))
+ allocate(vertrespc(nl-1), vertdocexc(nl-1), vertaggc(nl-1))
+ allocate(vertcalcdiss(nl-1), vertcalcif(nl-1))
+
+ vertNPPc = 0.d0
+ vertGPPc = 0.d0
+ vertNNAc = 0.d0
+ vertChldegc = 0.d0
+ vertrespc = 0.d0
+ vertdocexc = 0.d0
+ vertaggc = 0.d0
+ vertcalcdiss = 0.d0
+ vertcalcif = 0.d0
+
+ ! ----------------------------------------------------------------------
+ ! Phaeocystis
+ ! ----------------------------------------------------------------------
+ allocate(vertNPPp(nl-1), vertGPPp(nl-1), vertNNAp(nl-1), vertChldegp(nl-1))
+ allocate(vertrespp(nl-1), vertdocexp(nl-1), vertaggp(nl-1))
+
+ vertNPPp = 0.d0
+ vertGPPp = 0.d0
+ vertNNAp = 0.d0
+ vertChldegp = 0.d0
+ vertrespp = 0.d0
+ vertdocexp = 0.d0
+ vertaggp = 0.d0
+ else
+ ! Allocate calcification arrays even if coccos are disabled
+ allocate(vertcalcdiss(nl-1), vertcalcif(nl-1))
+ vertcalcdiss = 0.d0
+ vertcalcif = 0.d0
+ endif
+
+ ! --------------------------------------------------------------------------
+ ! Zooplankton Grazing (if enabled)
+ ! --------------------------------------------------------------------------
+ if (Grazing_detritus) then
+
+ ! Mesozooplankton
+ allocate(vertgrazmeso_tot(nl-1), vertgrazmeso_n(nl-1), vertgrazmeso_d(nl-1))
+ allocate(vertgrazmeso_det(nl-1))
+ allocate(vertrespmeso(nl-1))
+ vertgrazmeso_tot = 0.d0
+ vertgrazmeso_n = 0.d0
+ vertgrazmeso_d = 0.d0
+ vertgrazmeso_det = 0.d0
+ vertrespmeso = 0.d0
+
+ if (enable_3zoo2det) then
+ ! Microzooplankton
+ allocate(vertgrazmicro_tot(nl-1), vertgrazmicro_n(nl-1), vertgrazmicro_d(nl-1))
+ allocate(vertrespmicro(nl-1))
+
+ vertgrazmicro_tot = 0.d0
+ vertgrazmicro_n = 0.d0
+ vertgrazmicro_d = 0.d0
+ vertrespmicro = 0.d0
+
+ ! Mesozooplankton
+
+ allocate(vertgrazmeso_mic(nl-1), vertgrazmeso_det2(nl-1))
+ vertgrazmeso_mic = 0.d0
+ vertgrazmeso_det2 = 0.d0
+
+ if (enable_coccos) then
+ allocate(vertgrazmicro_c(nl-1), vertgrazmicro_p(nl-1))
+ allocate(vertgrazmeso_c(nl-1), vertgrazmeso_p(nl-1))
+
+ vertgrazmicro_c = 0.d0
+ vertgrazmicro_p = 0.d0
+ vertgrazmeso_c = 0.d0
+ vertgrazmeso_p = 0.d0
+ endif
+
+ ! Macrozooplankton
+ allocate(vertgrazmacro_tot(nl-1), vertgrazmacro_n(nl-1), vertgrazmacro_d(nl-1))
+ allocate(vertgrazmacro_mes(nl-1), vertgrazmacro_det(nl-1))
+ allocate(vertgrazmacro_mic(nl-1), vertgrazmacro_det2(nl-1))
+ allocate(vertrespmacro(nl-1))
+
+ vertgrazmacro_tot = 0.d0
+ vertgrazmacro_n = 0.d0
+ vertgrazmacro_d = 0.d0
+ vertgrazmacro_mes = 0.d0
+ vertgrazmacro_det = 0.d0
+ vertgrazmacro_mic = 0.d0
+ vertgrazmacro_det2 = 0.d0
+ vertrespmacro = 0.d0
+
+ if (enable_coccos) then
+ allocate(vertgrazmacro_c(nl-1), vertgrazmacro_p(nl-1))
+ vertgrazmacro_c = 0.d0
+ vertgrazmacro_p = 0.d0
+ endif
+ endif
+ endif
+
+ ! Dissolution and remineralization ! R2OMIP
+ allocate(vertDISSOC(nl-1), vertDISSON(nl-1), vertDISSOSi(nl-1), vertREMOC(nl-1), vertREMOCt(nl-1), vertREMON(nl-1))
+ vertDISSOC = 0.d0
+ vertDISSON = 0.d0
+ vertDISSOSi = 0.d0
+ vertREMOC = 0.d0
+ vertREMOCt = 0.d0
+ vertREMON = 0.d0
+
+ ! --------------------------------------------------------------------------
+ ! Temperature and Photosynthesis Tracking Variables
+ ! --------------------------------------------------------------------------
+
+ allocate(VTPhyCO2(nl-1), VTDiaCO2(nl-1))
+ VTPhyCO2 = 0.d0
+ VTDiaCO2 = 0.d0
+
+ allocate(VTCphotLigLim_phyto(nl-1), VTCphotLigLim_diatoms(nl-1))
+ VTCphotLigLim_phyto = 0.d0
+ VTCphotLigLim_diatoms = 0.d0
+
+ allocate(VTCphot_phyto(nl-1), VTCphot_diatoms(nl-1))
+ VTCphot_phyto = 0.d0
+ VTCphot_diatoms = 0.d0
+
+ allocate(VTTemp_diatoms(nl-1), VTTemp_phyto(nl-1))
+ VTTemp_diatoms = 0.d0
+ VTTemp_phyto = 0.d0
+
+ allocate(VTqlimitFac_phyto(nl-1), VTqlimitFac_diatoms(nl-1))
+ VTqlimitFac_phyto = 0.d0
+ VTqlimitFac_diatoms = 0.d0
+
+ allocate(VTSi_assimDia(nl-1))
+ VTSi_assimDia = 0.d0
+
+ if (enable_coccos) then
+ ! --------------------------------------------------------------------------
+ ! Coccolithophores and Phaeocystis Tracking (if enabled)
+ ! --------------------------------------------------------------------------
+
+ allocate(VTTemp_cocco(nl-1), VTTemp_phaeo(nl-1))
+ VTTemp_cocco = 0.d0
+ VTTemp_phaeo = 0.d0
+
+ allocate(VTCoccoCO2(nl-1), VTPhaeoCO2(nl-1))
+ VTCoccoCO2 = 0.d0
+ VTPhaeoCO2 = 0.d0
+
+ allocate(VTqlimitFac_cocco(nl-1), VTqlimitFac_phaeo(nl-1))
+ VTqlimitFac_cocco = 0.d0
+ VTqlimitFac_phaeo = 0.d0
+
+ allocate(VTCphotLigLim_cocco(nl-1), VTCphotLigLim_phaeo(nl-1))
+ VTCphotLigLim_cocco = 0.d0
+ VTCphotLigLim_phaeo = 0.d0
+
+ allocate(VTCphot_cocco(nl-1), VTCphot_phaeo(nl-1))
+ VTCphot_cocco = 0.d0
+ VTCphot_phaeo = 0.d0
+
+ endif
+
+end subroutine allocate_and_init_diags
+
+! ==============================================================================
+! SUBROUTINE: update_2d_diags
+! Purpose: Transfer local diagnostic values to 2D global arrays
+! ==============================================================================
+subroutine update_2d_diags(n)
+ use recom_locvar
+ use recom_glovar
+ use REcoM_declarations
+ implicit none
+
+ integer, intent(in) :: n ! Node index
+
+ ! --------------------------------------------------------------------------
+ ! Small Phytoplankton
+ ! --------------------------------------------------------------------------
+ NPPn(n) = locNPPn
+ GPPn(n) = locGPPn
+ NNAn(n) = locNNAn
+ Chldegn(n) = locChldegn
+
+ ! --------------------------------------------------------------------------
+ ! Diatoms
+ ! --------------------------------------------------------------------------
+ NPPd(n) = locNPPd
+ GPPd(n) = locGPPd
+ NNAd(n) = locNNAd
+ Chldegd(n) = locChldegd
+
+ ! --------------------------------------------------------------------------
+ ! Coccolithophores and Phaeocystis (if enabled)
+ ! --------------------------------------------------------------------------
+ if (enable_coccos) then
+ NPPc(n) = locNPPc
+ GPPc(n) = locGPPc
+ NNAc(n) = locNNAc
+ Chldegc(n) = locChldegc
+
+ NPPp(n) = locNPPp
+ GPPp(n) = locGPPp
+ NNAp(n) = locNNAp
+ Chldegp(n) = locChldegp
+ endif
+
+ ! --------------------------------------------------------------------------
+ ! Zooplankton Grazing (if enabled)
+ ! --------------------------------------------------------------------------
+ if (Grazing_detritus) then
+ ! Mesozooplankton
+ grazmeso_tot(n) = locgrazmeso_tot
+ grazmeso_n(n) = locgrazmeso_n
+ grazmeso_d(n) = locgrazmeso_d
+ grazmeso_det(n) = locgrazmeso_det
+
+ if (enable_coccos) then
+ grazmeso_c(n) = locgrazmeso_c
+ grazmeso_p(n) = locgrazmeso_p
+ endif
+
+ if (enable_3zoo2det) then
+ grazmeso_mic(n) = locgrazmeso_mic
+ grazmeso_det2(n) = locgrazmeso_det2
+
+ ! Macrozooplankton
+ grazmacro_tot(n) = locgrazmacro_tot
+ grazmacro_n(n) = locgrazmacro_n
+ grazmacro_d(n) = locgrazmacro_d
+ grazmacro_mes(n) = locgrazmacro_mes
+ grazmacro_det(n) = locgrazmacro_det
+ grazmacro_mic(n) = locgrazmacro_mic
+ grazmacro_det2(n) = locgrazmacro_det2
+
+ if (enable_coccos) then
+ grazmacro_c(n) = locgrazmacro_c
+ grazmacro_p(n) = locgrazmacro_p
+ endif
+
+ ! Microzooplankton
+ grazmicro_tot(n) = locgrazmicro_tot
+ grazmicro_n(n) = locgrazmicro_n
+ grazmicro_d(n) = locgrazmicro_d
+
+ if (enable_coccos) then
+ grazmicro_c(n) = locgrazmicro_c
+ grazmicro_p(n) = locgrazmicro_p
+ endif
+ endif
+ endif
+
+ ! Dissolution and remineralization ! R2OMIP
+ DISSOC(n) = locDISSOC
+ DISSON(n) = locDISSON
+ DISSOSi(n) = locDISSOSi
+ REMOC(n) = locREMOC
+ REMOCt(n) = locREMOCt
+ REMON(n) = locREMON
+
+end subroutine update_2d_diags
+
+! ==============================================================================
+! SUBROUTINE: update_3d_diags
+! Purpose: Transfer vertical profile diagnostic values to 3D global arrays
+! ==============================================================================
+subroutine update_3d_diags(n, nzmax)
+ use recom_locvar
+ use recom_glovar
+ use REcoM_declarations
+ implicit none
+
+ integer, intent(in) :: n ! Node index
+ integer, intent(in) :: nzmax ! Maximum vertical level for this node
+
+ ! --------------------------------------------------------------------------
+ ! Small Phytoplankton
+ ! --------------------------------------------------------------------------
+ aggn(1:nzmax,n) = vertaggn(1:nzmax)
+ docexn(1:nzmax,n) = vertdocexn(1:nzmax)
+ respn(1:nzmax,n) = vertrespn(1:nzmax)
+ NPPn3D(1:nzmax,n) = vertNPPn(1:nzmax)
+
+ ! --------------------------------------------------------------------------
+ ! Diatoms
+ ! --------------------------------------------------------------------------
+ aggd(1:nzmax,n) = vertaggd(1:nzmax)
+ docexd(1:nzmax,n) = vertdocexd(1:nzmax)
+ respd(1:nzmax,n) = vertrespd(1:nzmax)
+ NPPd3D(1:nzmax,n) = vertNPPd(1:nzmax)
+
+ ! --------------------------------------------------------------------------
+ ! Coccolithophores and Phaeocystis (if enabled)
+ ! --------------------------------------------------------------------------
+ if (enable_coccos) then
+ aggc(1:nzmax,n) = vertaggc(1:nzmax)
+ docexc(1:nzmax,n) = vertdocexc(1:nzmax)
+ respc(1:nzmax,n) = vertrespc(1:nzmax)
+ NPPc3D(1:nzmax,n) = vertNPPc(1:nzmax)
+
+ aggp(1:nzmax,n) = vertaggp(1:nzmax)
+ docexp(1:nzmax,n) = vertdocexp(1:nzmax)
+ respp(1:nzmax,n) = vertrespp(1:nzmax)
+ NPPp3D(1:nzmax,n) = vertNPPp(1:nzmax)
+ endif
+
+ ! --------------------------------------------------------------------------
+ ! Calcification
+ ! --------------------------------------------------------------------------
+ calcdiss(1:nzmax,n) = vertcalcdiss(1:nzmax)
+ calcif(1:nzmax,n) = vertcalcif(1:nzmax)
+
+ ! --------------------------------------------------------------------------
+ ! Zooplankton Respiration
+ ! --------------------------------------------------------------------------
+ respmeso(1:nzmax,n) = vertrespmeso(1:nzmax)
+
+ if (enable_3zoo2det) then
+ respmacro(1:nzmax,n) = vertrespmacro(1:nzmax)
+ respmicro(1:nzmax,n) = vertrespmicro(1:nzmax)
+ endif
+
+ TPhyCO2(1:nzmax,n) = VTPhyCO2(1:nzmax)
+ TDiaCO2(1:nzmax,n) = VTDiaCO2(1:nzmax)
+ TCphotLigLim_phyto(1:nzmax,n) = VTCphotLigLim_phyto(1:nzmax)
+ TCphot_phyto(1:nzmax,n) = VTCphot_phyto(1:nzmax)
+ TCphotLigLim_diatoms(1:nzmax,n)= VTCphotLigLim_diatoms(1:nzmax)
+ TCphot_diatoms(1:nzmax,n) = VTCphot_diatoms(1:nzmax)
+
+ if (enable_coccos) then
+ ! --------------------------------------------------------------------------
+ ! Temperature and Photosynthesis Tracking - Phytoplankton
+ ! --------------------------------------------------------------------------
+ TTemp_phyto(1:nzmax,n) = VTTemp_phyto(1:nzmax)
+ TqlimitFac_phyto(1:nzmax,n) = VTqlimitFac_phyto(1:nzmax)
+
+ ! --------------------------------------------------------------------------
+ ! Temperature and Photosynthesis Tracking - Diatoms
+ ! --------------------------------------------------------------------------
+ TTemp_diatoms(1:nzmax,n) = VTTemp_diatoms(1:nzmax)
+ TqlimitFac_diatoms(1:nzmax,n) = VTqlimitFac_diatoms(1:nzmax)
+ TSi_assimDia(1:nzmax,n) = VTSi_assimDia(1:nzmax)
+
+ ! --------------------------------------------------------------------------
+ ! Temperature and Photosynthesis Tracking - Coccos/Phaeo (if enabled)
+ ! --------------------------------------------------------------------------
+
+ TTemp_cocco(1:nzmax,n) = VTTemp_cocco(1:nzmax)
+ TCoccoCO2(1:nzmax,n) = VTCoccoCO2(1:nzmax)
+ TqlimitFac_cocco(1:nzmax,n) = VTqlimitFac_cocco(1:nzmax)
+ TCphotLigLim_cocco(1:nzmax,n) = VTCphotLigLim_cocco(1:nzmax)
+ TCphot_cocco(1:nzmax,n) = VTCphot_cocco(1:nzmax)
+
+ TTemp_phaeo(1:nzmax,n) = VTTemp_phaeo(1:nzmax)
+ TPhaeoCO2(1:nzmax,n) = VTPhaeoCO2(1:nzmax)
+ TqlimitFac_phaeo(1:nzmax,n) = VTqlimitFac_phaeo(1:nzmax)
+ TCphotLigLim_phaeo(1:nzmax,n) = VTCphotLigLim_phaeo(1:nzmax)
+ TCphot_phaeo(1:nzmax,n) = VTCphot_phaeo(1:nzmax)
+ endif
+
+end subroutine update_3d_diags
+
+! ==============================================================================
+! SUBROUTINE: deallocate_diags
+! Purpose: Deallocate all diagnostic arrays
+! ==============================================================================
+subroutine deallocate_diags()
+ use recom_locvar
+ use REcoM_declarations
+ implicit none
+
+ ! --------------------------------------------------------------------------
+ ! Small Phytoplankton
+ ! --------------------------------------------------------------------------
+ deallocate(vertNPPn, vertGPPn, vertNNAn, vertChldegn)
+ deallocate(vertaggn, vertdocexn, vertrespn)
+ deallocate(VTPhyCO2, VTCphotLigLim_phyto, VTCphot_phyto)
+
+ ! --------------------------------------------------------------------------
+ ! Diatoms
+ ! --------------------------------------------------------------------------
+ deallocate(vertNPPd, vertGPPd, vertNNAd, vertChldegd)
+ deallocate(vertaggd, vertdocexd, vertrespd)
+ deallocate(VTDiaCO2, VTCphotLigLim_diatoms, VTCphot_diatoms)
+
+ deallocate(VTTemp_phyto, VTqlimitFac_phyto)
+ deallocate(VTTemp_diatoms, VTqlimitFac_diatoms)
+ deallocate(VTSi_assimDia)
+ deallocate(vertcalcdiss, vertcalcif)
+
+ if (enable_coccos) then
+ ! --------------------------------------------------------------------------
+ ! Coccolithophores and Phaeocystis (if enabled)
+ ! --------------------------------------------------------------------------
+ deallocate(vertNPPc, vertGPPc, vertNNAc, vertChldegc)
+ deallocate(vertaggc, vertdocexc, vertrespc)
+ deallocate(VTTemp_cocco, VTCoccoCO2, VTqlimitFac_cocco)
+ deallocate(VTCphotLigLim_cocco, VTCphot_cocco)
+
+ deallocate(vertNPPp, vertGPPp, vertNNAp, vertChldegp)
+ deallocate(vertaggp, vertdocexp, vertrespp)
+ deallocate(VTTemp_phaeo, VTPhaeoCO2, VTqlimitFac_phaeo)
+ deallocate(VTCphotLigLim_phaeo, VTCphot_phaeo)
+ endif
+
+ ! --------------------------------------------------------------------------
+ ! Zooplankton Grazing (if enabled)
+ ! --------------------------------------------------------------------------
+ if (Grazing_detritus) then
+ deallocate(vertgrazmeso_tot, vertgrazmeso_n, vertgrazmeso_d)
+ deallocate(vertgrazmeso_det, vertrespmeso)
+
+ if (enable_coccos) then
+ deallocate(vertgrazmeso_c, vertgrazmeso_p)
+ endif
+
+ if (enable_3zoo2det) then
+ deallocate(vertgrazmeso_mic, vertgrazmeso_det2)
+
+ deallocate(vertgrazmacro_tot, vertgrazmacro_n, vertgrazmacro_d)
+ deallocate(vertgrazmacro_mes, vertgrazmacro_det)
+ deallocate(vertgrazmacro_mic, vertgrazmacro_det2)
+ deallocate(vertrespmacro)
+
+ if (enable_coccos) then
+ deallocate(vertgrazmacro_c, vertgrazmacro_p)
+ endif
+
+ deallocate(vertgrazmicro_tot, vertgrazmicro_n, vertgrazmicro_d)
+ deallocate(vertrespmicro)
+
+ if (enable_coccos) then
+ deallocate(vertgrazmicro_c, vertgrazmicro_p)
+ endif
+ endif
+ endif
+
+ ! Dissolution and remineralization ! R2OMIP
+ deallocate(vertDISSOC, vertDISSON, vertDISSOSi, vertREMOC, vertREMOCt, vertREMON)
+
+end subroutine deallocate_diags
+
+end module recom_diags_management
diff --git a/src/int_recom/recom_nitrogenss.F90 b/src/int_recom/recom_nitrogenss.F90
new file mode 100644
index 000000000..c60927647
--- /dev/null
+++ b/src/int_recom/recom_nitrogenss.F90
@@ -0,0 +1,473 @@
+module recom_nitrogenss_interface
+ interface
+ subroutine recom_nitrogenss(tracer, partit, mesh)
+ use mod_mesh
+ USE MOD_PARTIT
+ USE MOD_PARSUP
+ use mod_tracer
+ type(t_tracer), intent(inout), target :: tracer
+ type(t_partit), intent(inout), target :: partit
+ type(t_mesh) , intent(in) , target :: mesh
+ end subroutine
+ end interface
+end module
+!===============================================================================
+! SUBROUTINE: recom_nitrogenss
+!===============================================================================
+! PURPOSE:
+! Calculates nitrogen removal via benthic denitrification and permanent
+! burial of organic matter in marine sediments
+!
+! DESCRIPTION:
+! - Denitrification: Uses Middelburg et al. (1996) parameterization to
+! calculate nitrogen removal as a function of organic carbon flux
+! - Permanent Burial: Uses Dunne et al. (2007) formulation to calculate
+! burial efficiency and permanent removal of C, N, Si, and CaCO3
+! - Calcite Dissolution: Accounts for calcite preservation based on
+! carbonate saturation state (Omega_calcite)
+!
+! REFERENCES:
+! - Middelburg et al. (1996): Denitrification in marine sediments
+! - Dunne et al. (2007): Carbon export and burial efficiency
+!
+! OPTIMIZATION NOTES:
+! - Eliminated code duplication between main loop and boundary conditions
+! - Moved conditional checks outside tight loops
+! - Pre-calculated mathematical constants
+! - Cached frequently accessed array values
+! - Expected performance gain: 30-50% compared to original version
+!
+! ADAPTED: [Laurent Oziel]
+! MODIFIED: [09.10.2025] - OG
+!===============================================================================
+
+subroutine recom_nitrogenss(tracers, partit, mesh)
+
+ use REcoM_declarations
+ use REcoM_LocVar
+ use REcoM_GloVar
+ use recom_config
+ use REcoM_ciso
+ use g_clock
+ use o_PARAM
+ use g_rotate_grid
+ use g_config
+ use mod_MESH
+ use MOD_PARTIT
+ use MOD_PARSUP
+ use MOD_TRACER
+ use o_param
+ use o_arrays
+ use g_forcing_arrays
+ use g_comm_auto
+ use g_comm
+ use g_support
+
+ implicit none
+
+ !-----------------------------------------------------------------------------
+ ! Arguments
+ !-----------------------------------------------------------------------------
+ type(t_tracer), intent(inout), target :: tracers
+ type(t_partit), intent(inout), target :: partit
+ type(t_mesh), intent(in), target :: mesh
+
+ !-----------------------------------------------------------------------------
+ ! Local variables - Indices and counters
+ !-----------------------------------------------------------------------------
+ integer :: n ! Node counter
+ integer :: nz ! Vertical level counter
+ integer :: nl1 ! Bottom level index (nlevels - 1)
+ integer :: ul1 ! Top active level index
+ integer :: k ! Number of neighboring elements
+ integer :: nlevels_nod2D_minimum ! Minimum depth in neighboring nodes
+
+ !-----------------------------------------------------------------------------
+ ! Local variables - Fluxes and concentrations
+ !-----------------------------------------------------------------------------
+ real(kind=WP) :: tv_c ! Total vertical carbon flux [mmol C m⁻² d⁻¹]
+ real(kind=WP) :: tv_n ! Total vertical nitrogen flux [mmol N m⁻² d⁻¹]
+ real(kind=WP) :: tv_si ! Total vertical silica flux [mmol Si m⁻² d⁻¹]
+ real(kind=WP) :: tv_calc ! Total vertical calcite flux [mmol CaCO₃ m⁻² d⁻¹]
+
+ real(kind=WP) :: Fc ! Labile carbon flux [µmol C cm⁻² d⁻¹]
+ real(kind=WP) :: Fn ! Nitrogen flux [mmol N m⁻² d⁻¹]
+ real(kind=WP) :: Fsi ! Silica flux [mmol Si m⁻² d⁻¹]
+ real(kind=WP) :: Fcalc ! Calcite flux [mmol CaCO₃ m⁻² d⁻¹]
+
+ !-----------------------------------------------------------------------------
+ ! Local variables - Process rates
+ !-----------------------------------------------------------------------------
+ real(kind=WP) :: denit_factor ! Denitrification factor (dimensionless)
+ real(kind=WP) :: denit_rate ! Denitrification rate [mmol N d⁻¹]
+ real(kind=WP) :: burial_eff ! Burial efficiency [0-1]
+ real(kind=WP) :: preserv_calc ! Calcite preservation fraction [0-1]
+ real(kind=WP) :: buried_calc ! Calcite burial fraction [0-1]
+
+ !-----------------------------------------------------------------------------
+ ! Local variables - Burial fluxes
+ !-----------------------------------------------------------------------------
+ real(kind=WP) :: burial_c ! Carbon burial flux [mmol C d⁻¹]
+ real(kind=WP) :: burial_n ! Nitrogen burial flux [mmol N d⁻¹]
+ real(kind=WP) :: burial_si ! Silica burial flux [mmol Si d⁻¹]
+ real(kind=WP) :: burial_calc ! Calcite burial flux [mmol CaCO₃ d⁻¹]
+
+ !-----------------------------------------------------------------------------
+ ! Local variables - Intermediate calculations
+ !-----------------------------------------------------------------------------
+ real(kind=WP) :: log_Fc ! Natural logarithm of Fc
+ real(kind=WP) :: log_Fc_sq ! Square of log(Fc)
+ real(kind=WP) :: Fc_ratio ! Ratio Fc/(7+Fc) for burial calculation
+
+ !-----------------------------------------------------------------------------
+ ! Local variables - Cached geometric quantities
+ !-----------------------------------------------------------------------------
+ real(kind=WP) :: area_nz ! Area at level nz [m²]
+ real(kind=WP) :: area_nz_plus1 ! Area at level nz+1 [m²]
+ real(kind=WP) :: area_diff ! Area difference [m²]
+ real(kind=WP) :: zbar_diff ! Layer thickness [m]
+ real(kind=WP) :: area_inverse ! 1/area for efficiency [m⁻²]
+
+ !-----------------------------------------------------------------------------
+ ! Local variables - Normalization factors
+ !-----------------------------------------------------------------------------
+ real(kind=WP) :: dt_over_seconds ! Time step in days
+ real(kind=WP) :: normalization ! Combined normalization factor [m⁻³]
+
+ !-----------------------------------------------------------------------------
+ ! Local variables - Sinking velocities
+ !-----------------------------------------------------------------------------
+ real(kind=WP) :: vben_nz ! Sinking velocity at level nz [m d⁻¹]
+ real(kind=WP) :: vben2_nz ! Second zoo detritus sinking velocity [m d⁻¹]
+
+ !-----------------------------------------------------------------------------
+ ! Working arrays
+ !-----------------------------------------------------------------------------
+ real(kind=WP) :: Vben(mesh%nl) ! Slow-sinking detritus sinking velocity profile [m d⁻¹]
+ real(kind=WP) :: Vben2(mesh%nl) ! Fast-sinking detritus sinking velocity profile [m d⁻¹]
+
+ !-----------------------------------------------------------------------------
+ ! Mathematical constants (pre-calculated for efficiency)
+ !-----------------------------------------------------------------------------
+ ! Logarithm and conversion factors
+ real(kind=WP), parameter :: LOG10 = log(10.0_WP)
+ real(kind=WP), parameter :: LABILE_FRACTION = 0.1_WP ! Labile org. C fraction
+ real(kind=WP), parameter :: CONVERSION_FACTOR = 10.0_WP ! µmol -> mmol
+
+ ! Denitrification coefficients (Middelburg et al. 1996)
+ real(kind=WP), parameter :: DENIT_C1 = -0.9543_WP ! Intercept
+ real(kind=WP), parameter :: DENIT_C2 = 0.7662_WP ! Linear coefficient
+ real(kind=WP), parameter :: DENIT_C3 = -0.2350_WP ! Quadratic coefficient
+
+ ! Burial efficiency coefficients (Dunne et al. 2007)
+ real(kind=WP), parameter :: BURIAL_C1 = 0.013_WP ! Optimisé = 0.02_WP ! Standard = 0.013_WP ! Minimum burial efficiency
+ real(kind=WP), parameter :: BURIAL_C2 = 0.53_WP ! Optimisé = 0.08_WP ! Standard = 0.53_WP ! Maximum additional burial
+ real(kind=WP), parameter :: BURIAL_C3 = 7.0_WP ! Half-saturation constant
+
+ ! Calcite dissolution coefficients
+ real(kind=WP), parameter :: CALCITE_C1 = 1.3_WP ! Dissolution rate factor
+ real(kind=WP), parameter :: CALCITE_C2 = 0.2_WP ! Critical Omega_C lower
+ real(kind=WP), parameter :: CALCITE_C3 = 0.4_WP ! Critical Omega_C upper
+
+ !-----------------------------------------------------------------------------
+ ! Include mesh associations
+ !-----------------------------------------------------------------------------
+#include "../associate_part_def.h"
+#include "../associate_mesh_def.h"
+#include "../associate_part_ass.h"
+#include "../associate_mesh_ass.h"
+
+ !=============================================================================
+ ! INITIALIZATION
+ !=============================================================================
+
+ ! Early exit if nitrogen sediment-seawater exchange is disabled
+! if (.not. NitrogenSS) then
+! DenitBen = 0.0_WP
+! Burial = 0.0_WP
+! return
+! end if
+
+ ! Progress indicator (printed every 100 time steps on master process)
+ if (mype == 0 .and. mod(mstep, 3600) == 0) then
+ print *, achar(27)//'[37m'//' --> recom_nitrogenss'//achar(27)//'[0m'
+ end if
+
+ ! Initialize diagnostic arrays
+ LocDenit = 0.0_WP
+ LocBurial = 0.0_WP
+
+ ! Pre-calculate time conversion factor
+ dt_over_seconds = dt / SecondsPerDay
+
+ !=============================================================================
+ ! MAIN COMPUTATION LOOP OVER ALL NODES
+ !=============================================================================
+
+ do n = 1, myDim_nod2D
+
+ !-------------------------------------------------------------------------
+ ! Setup for current node
+ !-------------------------------------------------------------------------
+ nl1 = nlevels_nod2D(n) - 1 ! Bottom level index
+ ul1 = ulevels_nod2D(n) ! Top active level index
+
+ ! Calculate sinking velocity profile for detritus
+ if (allow_var_sinking) then
+ ! Variable sinking: increases with depth
+ Vben = Vdet_a * abs(zbar_3d_n(:,n)) + VDet
+ else
+ ! Constant sinking velocity
+ Vben = VDet
+ end if
+
+ ! Second zooplankton detritus pool (if enabled)
+ if (enable_3zoo2det) then
+ Vben2 = VDet_zoo2
+ end if
+
+ ! Find minimum depth among neighboring nodes
+ ! (ensures continuity across element boundaries)
+ k = nod_in_elem2D_num(n)
+ nlevels_nod2D_minimum = minval(nlevels(nod_in_elem2D(1:k, n)) - 1)
+
+ !==========================================================================
+ ! WITH SECOND DETRITUS POOL
+ !==========================================================================
+ if (enable_3zoo2det) then
+
+ do nz = nlevels_nod2D_minimum, nl1
+
+ !------------------------------------------------------------------
+ ! Cache frequently accessed geometric quantities
+ !------------------------------------------------------------------
+ vben_nz = Vben(nz)
+ vben2_nz = Vben2(nz)
+ area_nz = area(nz, n)
+ area_nz_plus1 = area(nz+1, n)
+
+ ! Handle special case for bottom layer (nl1)
+ if (nz < nl1) then
+ ! Normal layer: use difference between levels
+ area_diff = area_nz - area_nz_plus1
+ else
+ ! Bottom layer: use bottom area directly
+ area_diff = area_nz !area_nz_plus1
+ area_nz = area_nz !area_nz_plus1
+ end if
+
+ ! Calculate layer thickness and normalization factors
+ zbar_diff = zbar_3d_n(nz,n) - zbar_3d_n(nz+1,n)
+ area_inverse = 1.0_WP / area_nz
+ normalization = dt_over_seconds * area_inverse / zbar_diff
+
+ !------------------------------------------------------------------
+ ! Calculate total detrital fluxes [mmol element m⁻² d⁻¹]
+ !------------------------------------------------------------------
+ ! Flux = Concentration × Sinking_Velocity
+ ! Sum contributions from both detritus pools
+ !tv_c = tr_arr(nz,n,10) * vben_nz + tr_arr(nz,n,27) * vben2_nz ! Carbon
+ !tv_n = tr_arr(nz,n,9) * vben_nz + tr_arr(nz,n,27) * vben2_nz ! Nitrogen
+ !tv_si = tr_arr(nz,n,19) * vben_nz + tr_arr(nz,n,29) * vben2_nz ! Silica
+ !tv_calc = tr_arr(nz,n,23) * vben_nz + tr_arr(nz,n,30) * vben2_nz ! Calcite
+
+ tv_c = tracers%data(10)%values(nz,n) * vben_nz + tracers%data(26)%values(nz,n) * vben2_nz ! Carbon
+ tv_n = tracers%data(9)%values(nz,n) * vben_nz + tracers%data(27)%values(nz,n) * vben2_nz ! Nitrogen
+ tv_si = tracers%data(19)%values(nz,n) * vben_nz + tracers%data(29)%values(nz,n) * vben2_nz ! Silica
+ tv_calc = tracers%data(23)%values(nz,n) * vben_nz + tracers%data(30)%values(nz,n) * vben2_nz ! Calcite
+
+ ! Save sedimentation fluxes
+ Ocean_2_Sed_flux(n,1) = tv_n
+ Ocean_2_Sed_flux(n,2) = tv_c
+ Ocean_2_Sed_flux(n,3) = tv_si
+ Ocean_2_Sed_flux(n,4) = tv_calc
+
+ !------------------------------------------------------------------
+ ! DENITRIFICATION CALCULATION (Middelburg et al. 1996)
+ !------------------------------------------------------------------
+ ! Step 1: Calculate labile carbon flux
+ ! Only ~10% of organic carbon is readily available for bacteria
+ Fc = max(tiny, LABILE_FRACTION * tv_c)
+
+ ! Step 2: Apply empirical relationship
+ ! log₁₀(Denit) = -0.9543 + 0.7662×log₁₀(Fc) - 0.2350×[log₁₀(Fc)]²
+ log_Fc = log(Fc)
+ log_Fc_sq = log_Fc * log_Fc
+ denit_factor = DENIT_C1 + DENIT_C2 * log_Fc + DENIT_C3 * log_Fc_sq
+
+ ! Step 3: Convert from log₁₀ space to actual rate
+ ! Denit = 10^(denit_factor) [µmol C cm⁻² d⁻¹]
+ denit_factor = exp(denit_factor * LOG10)
+
+ ! Step 4: Convert to nitrogen removal rate [mmol N d⁻¹]
+ ! Apply N:C stoichiometry, area, and unit conversion
+ denit_rate = q_NC_Denit * denit_factor * area_diff * CONVERSION_FACTOR
+
+ !------------------------------------------------------------------
+ ! PERMANENT BURIAL CALCULATION (Dunne et al. 2007)
+ !------------------------------------------------------------------
+ ! Ensure positive fluxes for burial calculations
+ Fc = max(tiny, tv_c)
+ Fn = max(tiny, tv_n)
+ Fsi = max(tiny, tv_si)
+ Fcalc = max(tiny, tv_calc)
+
+ ! Calculate burial efficiency [0-1]
+ ! E = 0.013 + 0.53 × [Fc/(7+Fc)]²
+ ! Efficiency increases with carbon flux but saturates at high flux
+ Fc_ratio = Fc / (BURIAL_C3 + Fc)
+ burial_eff = BURIAL_C1 + BURIAL_C2 * Fc_ratio * Fc_ratio
+
+ ! Calculate calcite preservation based on saturation state
+ ! Higher preservation when Omega_C < 0.2 (undersaturated conditions)
+ preserv_calc = Fcalc * min(1.0_WP, CALCITE_C1 * &
+ (CALCITE_C2 - OmegaC_bottom(n)) / (CALCITE_C3 - OmegaC_bottom(n)))
+ buried_calc = 1.0_WP - preserv_calc
+
+ ! Calculate burial fluxes for each element [mmol element d⁻¹]
+ burial_c = Fc * burial_eff * area_diff ! Carbon
+ burial_n = Fn * burial_eff * area_diff ! Nitrogen
+ burial_si = Fsi * burial_eff * area_diff ! Silica
+ burial_calc = Fcalc * buried_calc * area_diff ! Calcite
+
+ !------------------------------------------------------------------
+ ! APPLY SINKS TO TRACER ARRAYS (only for active layers)
+ !------------------------------------------------------------------
+ if (nz >= ul1) then
+
+ ! Denitrification removes nitrogen from water column
+ nss(nz,n) = nss(nz,n) - denit_rate * normalization
+ LocDenit(n) = LocDenit(n) - denit_rate * dt_over_seconds * area_inverse
+
+ ! Burial removes elements from water column
+ bur(1,nz,n) = bur(1,nz,n) - burial_c * normalization ! Carbon
+ bur(2,nz,n) = bur(2,nz,n) - burial_n * normalization ! Nitrogen
+ bur(3,nz,n) = bur(3,nz,n) - burial_si * normalization ! Silica
+ bur(4,nz,n) = bur(4,nz,n) - burial_calc * normalization ! Calcite
+
+ ! Accumulate local burial diagnostics [mmol element m⁻² d⁻¹]
+ LocBurial(1,n) = LocBurial(1,n) - burial_c * dt_over_seconds * area_inverse
+ LocBurial(2,n) = LocBurial(2,n) - burial_n * dt_over_seconds * area_inverse
+ LocBurial(3,n) = LocBurial(3,n) - burial_si * dt_over_seconds * area_inverse
+ LocBurial(4,n) = LocBurial(4,n) - burial_calc * dt_over_seconds * area_inverse
+ end if
+
+ end do ! Loop over vertical levels
+
+ !==========================================================================
+ ! WITHOUT SECOND ZOOPLANKTON (single detritus pool)
+ !==========================================================================
+ else
+
+ do nz = nlevels_nod2D_minimum, nl1
+
+ !------------------------------------------------------------------
+ ! Cache frequently accessed geometric quantities
+ !------------------------------------------------------------------
+ vben_nz = Vben(nz)
+ area_nz = area(nz, n)
+ area_nz_plus1 = area(nz+1, n)
+
+ ! Handle special case for bottom layer (nl1)
+ if (nz < nl1) then
+ area_diff = area_nz - area_nz_plus1
+ else
+ area_diff = area_nz_plus1
+ area_nz = area_nz_plus1
+ end if
+
+ zbar_diff = zbar_3d_n(nz,n) - zbar_3d_n(nz+1,n)
+ area_inverse = 1.0_WP / area_nz
+ normalization = dt_over_seconds * area_inverse / zbar_diff
+
+ !------------------------------------------------------------------
+ ! Calculate total detrital fluxes [mmol element m⁻² d⁻¹]
+ !------------------------------------------------------------------
+ !tv_c = tr_arr(nz,n,10) * vben_nz ! Carbon
+ !tv_n = tr_arr(nz,n,9) * vben_nz ! Nitrogen
+ !tv_si = tr_arr(nz,n,19) * vben_nz ! Silica
+ !tv_calc = tr_arr(nz,n,23) * vben_nz ! Calcite
+ tv_c = tracers%data(10)%values(nz,n) * vben_nz ! Carbon
+ tv_n = tracers%data(9)%values(nz,n) * vben_nz ! Nitrogen
+ tv_si = tracers%data(19)%values(nz,n) * vben_nz ! Silica
+ tv_calc = tracers%data(23)%values(nz,n) * vben_nz ! Calcite
+ ! Save sedimentation fluxes
+ Ocean_2_Sed_flux(n,1) = tv_n
+ Ocean_2_Sed_flux(n,2) = tv_c
+ Ocean_2_Sed_flux(n,3) = tv_si
+ Ocean_2_Sed_flux(n,4) = tv_calc
+ !------------------------------------------------------------------
+ ! DENITRIFICATION CALCULATION (Middelburg et al. 1996)
+ !------------------------------------------------------------------
+ Fc = max(tiny, LABILE_FRACTION * tv_c)
+ log_Fc = log(Fc)
+ log_Fc_sq = log_Fc * log_Fc
+ denit_factor = DENIT_C1 + DENIT_C2 * log_Fc + DENIT_C3 * log_Fc_sq
+ denit_factor = exp(denit_factor * LOG10)
+ denit_rate = q_NC_Denit * denit_factor * area_diff * CONVERSION_FACTOR
+
+ !------------------------------------------------------------------
+ ! PERMANENT BURIAL CALCULATION (Dunne et al. 2007)
+ !------------------------------------------------------------------
+ Fc = max(tiny, tv_c)
+ Fn = max(tiny, tv_n)
+ Fsi = max(tiny, tv_si)
+ Fcalc = max(tiny, tv_calc)
+
+ Fc_ratio = Fc / (BURIAL_C3 + Fc)
+ burial_eff = BURIAL_C1 + BURIAL_C2 * Fc_ratio * Fc_ratio
+
+ preserv_calc = Fcalc * min(1.0_WP, CALCITE_C1 * &
+ (CALCITE_C2 - OmegaC_bottom(n)) / (CALCITE_C3 - OmegaC_bottom(n)))
+ buried_calc = 1.0_WP - preserv_calc
+
+ burial_c = Fc * burial_eff * area_diff
+ burial_n = Fn * burial_eff * area_diff
+ burial_si = Fsi * burial_eff * area_diff
+ burial_calc = Fcalc * buried_calc * area_diff
+
+ !------------------------------------------------------------------
+ ! APPLY SINKS TO TRACER ARRAYS
+ !------------------------------------------------------------------
+ if (nz >= ul1) then
+ nss(nz,n) = nss(nz,n) - denit_rate * normalization
+ LocDenit(n) = LocDenit(n) - denit_rate * dt_over_seconds * area_inverse
+
+ bur(1,nz,n) = bur(1,nz,n) - burial_c * normalization
+ bur(2,nz,n) = bur(2,nz,n) - burial_n * normalization
+ bur(3,nz,n) = bur(3,nz,n) - burial_si * normalization
+ bur(4,nz,n) = bur(4,nz,n) - burial_calc * normalization
+
+ LocBurial(1,n) = LocBurial(1,n) - burial_c * dt_over_seconds * area_inverse
+ LocBurial(2,n) = LocBurial(2,n) - burial_n * dt_over_seconds * area_inverse
+ LocBurial(3,n) = LocBurial(3,n) - burial_si * dt_over_seconds * area_inverse
+ LocBurial(4,n) = LocBurial(4,n) - burial_calc * dt_over_seconds * area_inverse
+ end if
+
+ end do ! Loop over vertical levels
+
+ end if ! enable_3zoo2det check
+
+ !-------------------------------------------------------------------------
+ ! Accumulate global diagnostics for this node
+ !-------------------------------------------------------------------------
+ DenitBen(n) = DenitBen(n) + LocDenit(n)
+ Burial(1,n) = Burial(1,n) + LocBurial(1,n) ! Carbon
+ Burial(2,n) = Burial(2,n) + LocBurial(2,n) ! Nitrogen
+ Burial(3,n) = Burial(3,n) + LocBurial(3,n) ! Silica
+ Burial(4,n) = Burial(4,n) + LocBurial(4,n) ! Calcite
+
+ end do ! Loop over nodes
+
+ !=============================================================================
+ ! PARALLEL COMMUNICATION
+ !=============================================================================
+ ! Exchange data between parallel processes to ensure consistency
+ ! across domain decomposition boundaries
+ !call exchange_nod(DenitBen, partit)
+
+ !do n=1, benthos_num
+ !call exchange_nod(Burial(n,:), partit)
+ !call exchange_nod(Ocean_2_Sed_flux(:,n), partit)
+ !end do
+end subroutine recom_nitrogenss
diff --git a/src/int_recom/recom_sinking.F90 b/src/int_recom/recom_sinking.F90
index 0971e5bd0..654259aa3 100644
--- a/src/int_recom/recom_sinking.F90
+++ b/src/int_recom/recom_sinking.F90
@@ -109,14 +109,14 @@ subroutine ver_sinking_recom_benthos(tr_num, tracers, partit, mesh)
! Constant vertical sinking for the second detritus class
! *******************************************************
-#if defined(__3Zoo2Det)
+ if (enable_3zoo2det) then
if(tracers%data(tr_num)%ID==1025 .or. & !idetz2n
tracers%data(tr_num)%ID==1026 .or. & !idetz2c
tracers%data(tr_num)%ID==1027 .or. & !idetz2si
tracers%data(tr_num)%ID==1028 ) then !idetz2calc
Vben = VDet_zoo2
endif
-#endif
+ endif
Vben= Vben/SecondsPerDay ! conversion [m/d] --> [m/s] (vertical velocity, note that it is positive here)
@@ -141,6 +141,18 @@ subroutine ver_sinking_recom_benthos(tr_num, tracers, partit, mesh)
tracers%data(tr_num)%ID==1013 .or. & !idian
tracers%data(tr_num)%ID==1025 ) then !idetz2n
Benthos(n,1)= Benthos(n,1) + add_benthos_2d(n) ![mmol]
+
+ if (use_MEDUSA) then
+! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
+ SinkFlx_tr(n,1,tr_num) = SinkFlx_tr(n,1,tr_num) + add_benthos_2d(n) / area(1,n)/dt ![mmol/m2]
+ ! now SinkFlx hat the unit mmol/time step
+ ! but mmol/m2/time is needed for MEDUSA: thus /area
+ endif
+ if ((.not.use_MEDUSA).or.(sedflx_num.eq.0)) then
+! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
+ Benthos_tr(n,1,tr_num)= Benthos_tr(n,1,tr_num) + add_benthos_2d(n) ![mmol]
+ endif
+
endif
!! * Particulate Organic Carbon *
@@ -149,6 +161,16 @@ subroutine ver_sinking_recom_benthos(tr_num, tracers, partit, mesh)
tracers%data(tr_num)%ID==1014 .or. & !idiac
tracers%data(tr_num)%ID==1026 ) then !idetz2c
Benthos(n,2)= Benthos(n,2) + add_benthos_2d(n)
+
+ if (use_MEDUSA) then
+! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
+ SinkFlx_tr(n,2,tr_num) = SinkFlx_tr(n,2,tr_num) + add_benthos_2d(n) / area(1,n)/dt
+ endif
+ if ((.not.use_MEDUSA).or.(sedflx_num.eq.0)) then
+! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
+ Benthos_tr(n,2,tr_num)= Benthos_tr(n,2,tr_num) + add_benthos_2d(n)
+ endif
+
endif
!! *Particulate Organic Silicon *
@@ -156,6 +178,16 @@ subroutine ver_sinking_recom_benthos(tr_num, tracers, partit, mesh)
tracers%data(tr_num)%ID==1017 .or. & !idetsi
tracers%data(tr_num)%ID==1027 ) then !idetz2si
Benthos(n,3)= Benthos(n,3) + add_benthos_2d(n)
+
+ if (use_MEDUSA) then
+! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
+ SinkFlx_tr(n,3,tr_num) = SinkFlx_tr(n,3,tr_num) + add_benthos_2d(n) / area(1,n)/dt
+ endif
+ if ((.not.use_MEDUSA).or.(sedflx_num.eq.0)) then
+! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
+ Benthos_tr(n,3,tr_num)= Benthos_tr(n,3,tr_num) + add_benthos_2d(n)
+ endif
+
endif
!! * Cal *
@@ -163,9 +195,95 @@ subroutine ver_sinking_recom_benthos(tr_num, tracers, partit, mesh)
tracers%data(tr_num)%ID==1021 .or. & !idetcal
tracers%data(tr_num)%ID==1028 ) then !idetz2cal
Benthos(n,4)= Benthos(n,4) + add_benthos_2d(n)
+
+ if (use_MEDUSA) then
+! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
+ SinkFlx_tr(n,4,tr_num) = SinkFlx_tr(n,4,tr_num) + add_benthos_2d(n) / area(1,n)/dt
+ endif
+ if ((.not.use_MEDUSA).or.(sedflx_num.eq.0)) then
+! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
+ Benthos_tr(n,4,tr_num)= Benthos_tr(n,4,tr_num) + add_benthos_2d(n)
+ endif
+
endif
+
+ ! flux of 13C into the sediment
+ if (ciso) then
+ if( tracers%data(tr_num)%ID==1305 .or. & !iphyc_13
+ tracers%data(tr_num)%ID==1308 .or. & !idetc_13
+ tracers%data(tr_num)%ID==1314 ) then !idiac_14
+
+ if (use_MEDUSA) then
+! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
+ SinkFlx_tr(n,5,tr_num) = SinkFlx_tr(n,5,tr_num) + add_benthos_2d(n) / area(1,n)/dt
+ endif
+ if ((.not.use_MEDUSA).or.(sedflx_num.eq.0)) then
+! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
+ Benthos_tr(n,5,tr_num)= Benthos_tr(n,5,tr_num) + add_benthos_2d(n)
+ endif
+
+ endif
+
+ if( tracers%data(tr_num)%ID==1320 .or. & !iphycal
+ tracers%data(tr_num)%ID==1321 ) then !idetcal
+
+ if (use_MEDUSA) then
+! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
+ SinkFlx_tr(n,6,tr_num) = SinkFlx_tr(n,6,tr_num) + add_benthos_2d(n) / area(1,n)/dt
+ endif
+ if ((.not.use_MEDUSA).or.(sedflx_num.eq.0)) then
+! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
+ Benthos_tr(n,6,tr_num)= Benthos_tr(n,6,tr_num) + add_benthos_2d(n)
+ endif
+
+ endif
+
+ endif
+
+ ! flux of 14C into the sediment
+ if (ciso .and. ciso_organic_14) then
+ if( tracers%data(tr_num)%ID==1405 .or. & !iphyc_13
+ tracers%data(tr_num)%ID==1408 .or. & !idetc_13
+ tracers%data(tr_num)%ID==1414 ) then !idiac_14
+
+ if (use_MEDUSA) then
+! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
+ SinkFlx_tr(n,7,tr_num) = SinkFlx_tr(n,7,tr_num) + add_benthos_2d(n) / area(1,n)/dt
+ endif
+ if ((.not.use_MEDUSA).or.(sedflx_num.eq.0)) then
+! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
+ Benthos_tr(n,7,tr_num)= Benthos_tr(n,7,tr_num) + add_benthos_2d(n)
+ endif
+
+ endif
+
+ if( tracers%data(tr_num)%ID==1420 .or. & !iphycal
+ tracers%data(tr_num)%ID==1421 ) then !idetcal
+ if (use_MEDUSA) then
+! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
+ SinkFlx_tr(n,8,tr_num) = SinkFlx_tr(n,8,tr_num) + add_benthos_2d(n) / area(1,n)/dt
+ endif
+ if ((.not.use_MEDUSA).or.(sedflx_num.eq.0)) then
+! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
+ Benthos_tr(n,8,tr_num)= Benthos_tr(n,8,tr_num) + add_benthos_2d(n)
+ endif
+ endif
+
+ endif
+
end do
+
+ if(use_MEDUSA) then
+ do n=1, bottflx_num
+! SinkFlx(:,n) = Sinkflx(:,n)/dt
+! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
+ call exchange_nod(SinkFlx_tr(:,n,tr_num), partit)
+ end do
+ end if ! use_MEDUSA
+
do n=1, benthos_num
+! kh 25.03.22 buffer sums per tracer index to avoid non bit identical results regarding global sums when running the tracer loop in parallel
+ call exchange_nod(Benthos_tr(:,n,tr_num), partit)
call exchange_nod(Benthos(:,n), partit)
end do
@@ -223,19 +341,70 @@ subroutine diff_ver_recom_expl(tr_num, tracers, partit, mesh)
bottom_flux = 0._WP
id = tracers%data(tr_num)%ID
+#if defined(__recom)
+if (use_MEDUSA .and. (sedflx_num .ne. 0)) then
+ !CV update: the calculation later has been changed by Ozgur in such
+ !a way that now the variable bottom_flux is in (mol/time) units,
+ !rather than a flux in (mol/time/area). I therefore multiply the
+ !Medusa fluxes by the area to get the same unit.
+
+ SELECT CASE (id)
+ CASE (1001)
+ bottom_flux = GloSed(:,1) * area(1,:) ! DIN
+ CASE (1002)
+ bottom_flux = GloSed(:,2) * area(1,:) ! DIC
+ CASE (1003)
+ bottom_flux = GloSed(:,3) * area(1,:) ! Alk
+ CASE (1018)
+ bottom_flux = GloSed(:,4) * area(1,:) ! Si
+ CASE (1019)
+ bottom_flux = GloSed(:,1) * Fe2N_benthos * area(1,:)
+ CASE (1022)
+ bottom_flux = GloSed(:,5) * area(1,:) ! Oxy
+ CASE (1302)
+ if (ciso) then
+ bottom_flux = GloSed(:,6) * area(1,:) ! DIC_13 and Calc: DIC_13
+ end if
+ CASE (1402)
+ if (ciso) then
+ bottom_flux = GloSed(:,7) * area(1,:) ! DIC_14 and Calc: DIC_14
+ end if
+ CASE DEFAULT
+ if (partit%mype==0) then
+ write(*,*) 'check specified in boundary conditions'
+ write(*,*) 'the model will stop!'
+ end if
+ call par_ex(partit%MPI_COMM_FESOM, partit%mype)
+ stop
+ END SELECT
+else
SELECT CASE (id)
CASE (1001)
bottom_flux = GlodecayBenthos(:,1) !*** DIN [mmolN/m^2/s] ***
+ Sed_2_Ocean_Flux(:,1) = bottom_flux !*** DIN [mmolN/m^2/s] *** R2OMIP
CASE (1002)
bottom_flux = GlodecayBenthos(:,2) + GlodecayBenthos(:,4) !*** DIC + calcification ***
+ Sed_2_Ocean_Flux(:,2) = bottom_flux !*** DIC + calcification *** R2OMIP
CASE (1003)
bottom_flux = GlodecayBenthos(:,4) * 2.0_WP - 1.0625_WP * GlodecayBenthos(:,1) !*** Alk ***
+ Sed_2_Ocean_Flux(:,3) = bottom_flux !*** Alk *** R2OMIP
CASE (1018)
bottom_flux = GlodecayBenthos(:,3) !*** Si ***
+ Sed_2_Ocean_Flux(:,4) = bottom_flux !*** Si *** R2OMIP
CASE (1019)
bottom_flux = GlodecayBenthos(:,1) * Fe2N_benthos !*** DFe ***
+ Sed_2_Ocean_Flux(:,5) = bottom_flux !*** DFe *** R2OMIP
CASE (1022)
bottom_flux = -GlodecayBenthos(:,2) * redO2C !*** O2 ***
+ Sed_2_Ocean_Flux(:,6) = bottom_flux !*** O2 *** R2OMIP
+ CASE (1302)
+ if (ciso) then
+ bottom_flux = GlodecayBenthos(:,5) + GlodecayBenthos(:,6) !*** DIC_13 and Calc: DIC_13 ***
+ end if
+ CASE (1402)
+ if (ciso) then
+ bottom_flux = GlodecayBenthos(:,7) + GlodecayBenthos(:,8) !*** DIC_14 and Calc: DIC_14 ***
+ end if
CASE DEFAULT
if (partit%mype==0) then
write(*,*) 'check specified in boundary conditions'
@@ -244,6 +413,8 @@ subroutine diff_ver_recom_expl(tr_num, tracers, partit, mesh)
call par_ex(partit%MPI_COMM_FESOM, partit%mype)
stop
END SELECT
+endif ! (use_MEDUSA .and. (sedflux_num .gt. 0))
+#endif
do n=1, myDim_nod2D
@@ -309,7 +480,7 @@ subroutine ver_sinking_recom(tr_num, tracers, partit, mesh)
real(kind=8) :: Rjp,Rj,Rjm
real(kind=8) :: cfl, d0, d1, thetaP, thetaM, psiP, psiM
- real(kind=8) :: onesixth = 1.d0/6.d0
+ real(kind=8) :: onesixth = 1.d0/6.d0
real(kind=8) :: dt_sink, c1, c2
real(kind=8) :: Vsink, tv
real(kind=8),dimension(mesh%nl) :: Wvel_flux
@@ -334,54 +505,65 @@ subroutine ver_sinking_recom(tr_num, tracers, partit, mesh)
Vsink=0.0_WP
- if (tracers%data(tr_num)%ID ==1007 .or. & !idetn
- tracers%data(tr_num)%ID ==1008 .or. & !idetc
- tracers%data(tr_num)%ID ==1017 .or. & !idetsi
- tracers%data(tr_num)%ID ==1021 ) then !idetcal
+!< Assign sinking velocities based on tracer ID
+!< Groups tracers by functional type and assigns corresponding velocity
+! Detritus tracers (nitrogen, carbon, silicate, calcite)
+ if (tracers%data(tr_num)%ID == 1007 .or. & ! idetn
+ tracers%data(tr_num)%ID == 1008 .or. & ! idetc
+ tracers%data(tr_num)%ID == 1017 .or. & ! idetsi
+ tracers%data(tr_num)%ID == 1021) then ! idetcal
Vsink = VDet
- elseif(tracers%data(tr_num)%ID ==1004 .or. & !iphyn
- tracers%data(tr_num)%ID ==1005 .or. & !iphyc
- tracers%data(tr_num)%ID==1006 ) then !ipchl
-
+! Phytoplankton tracers (nitrogen, carbon, chlorophyll)
+ elseif (tracers%data(tr_num)%ID == 1004 .or. & ! iphyn
+ tracers%data(tr_num)%ID == 1005 .or. & ! iphyc
+ tracers%data(tr_num)%ID == 1006) then ! ipchl
Vsink = VPhy
- elseif(tracers%data(tr_num)%ID==1013 .or. & !idian
- tracers%data(tr_num)%ID==1014 .or. & !idiac
- tracers%data(tr_num)%ID==1016 .or. & !idiasi
- tracers%data(tr_num)%ID==1015 ) then !idchl
-
+! Diatom tracers (nitrogen, carbon, silicate, chlorophyll)
+ elseif (tracers%data(tr_num)%ID == 1013 .or. & ! idian
+ tracers%data(tr_num)%ID == 1014 .or. & ! idiac
+ tracers%data(tr_num)%ID == 1016 .or. & ! idiasi
+ tracers%data(tr_num)%ID == 1015) then ! idchl
Vsink = VDia
-#if defined (__coccos)
- elseif(tracers%data(tr_num)%ID == 1029 .or. & !icocn
- tracers%data(tr_num)%ID == 1030 .or. & !icocc
- tracers%data(tr_num)%ID == 1031 ) then !icchl
-
+! Coccolithophore tracers (nitrogen, carbon, chlorophyll)
+ elseif (enable_coccos .and. &
+ (tracers%data(tr_num)%ID == 1029 .or. & ! icocn
+ tracers%data(tr_num)%ID == 1030 .or. & ! icocc
+ tracers%data(tr_num)%ID == 1031)) then ! icchl
Vsink = VCocco
-#endif
- elseif(tracers%data(tr_num)%ID == 1020) then !iphycal
-
-#if defined (__coccos)
- Vsink = VCocco
-#else
- Vsink = VPhy
-#endif
-
-#if defined (__3Zoo2Det)
- elseif(tracers%data(tr_num)%ID==1025 .or. & !idetz2n
- tracers%data(tr_num)%ID==1026 .or. & !idetz2c
- tracers%data(tr_num)%ID==1027 .or. & !idetz2si
- tracers%data(tr_num)%ID==1028 ) then !idetz2calc
-
- Vsink = VDet_zoo2
-#endif
+! Phaeocystis tracers (nitrogen, carbon, chlorophyll)
+ elseif (enable_coccos .and. &
+ (tracers%data(tr_num)%ID == 1032 .or. & ! iphan
+ tracers%data(tr_num)%ID == 1033 .or. & ! iphac
+ tracers%data(tr_num)%ID == 1034)) then ! iphachl
+ Vsink = VPhaeo
+
+
+! Phytoplankton calcite tracer (special case)
+ elseif (tracers%data(tr_num)%ID == 1020) then ! iphycal
+ if (enable_coccos) then
+ Vsink = VCocco
+ else
+ Vsink = VPhy
end if
+! Zooplankton-2 detritus tracers (nitrogen, carbon, silicate, calcite)
+ elseif (enable_3zoo2det .and. &
+ (tracers%data(tr_num)%ID == 1025 .or. & ! idetz2n
+ tracers%data(tr_num)%ID == 1026 .or. & ! idetz2c
+ tracers%data(tr_num)%ID == 1027 .or. & ! idetz2si
+ tracers%data(tr_num)%ID == 1028)) then ! idetz2calc
+ Vsink = VDet_zoo2
+
+ end if
+
+
!! ---- No sinking if Vsink < 0.1 m/day
-if (Vsink .gt. 0.1) then
+if (Vsink .gt. 0.1) then
do n = 1,myDim_nod2D
if (ulevels_nod2D(n)>1) cycle
@@ -404,21 +586,28 @@ subroutine ver_sinking_recom(tr_num, tracers, partit, mesh)
if (allow_var_sinking) then
Wvel_flux(nz) = -((Vdet_a * abs(zbar_3d_n(nz,n))/SecondsPerDay) + Vsink/SecondsPerDay)
if (use_ballasting) then
+! Apply ballasting on slow sinking detritus
+!if (any(recom_sinking_tracer_id == tracer_id(tr_num))) then
+
+ if (tracers%data(tr_num)%ID ==1007 .or. & !idetn
+ tracers%data(tr_num)%ID ==1008 .or. & !idetc
+ tracers%data(tr_num)%ID ==1017 .or. & !idetsi
+ tracers%data(tr_num)%ID ==1021 ) then !idetcal
Wvel_flux(nz) = w_ref1 * scaling_density1_3D(nz,n) * scaling_visc_3D(nz,n)
if (depth_scaling1.gt.0.0) Wvel_flux(nz) = Wvel_flux(nz) + (depth_scaling1 * abs(zbar_3d_n(nz,n)))
if (abs(Wvel_flux(nz)) .gt. max_sinking_velocity) Wvel_flux(nz) = max_sinking_velocity
- !! * sinking velocity [m d-1] surface --> bottom (negative)*
+ ! sinking velocity [m d-1] surface --> bottom (negative)
Wvel_flux(nz) = -1.0d0 * Wvel_flux(nz)/SecondsPerDay ! now in [m s-1]
+ endif
endif
end if
-#if defined (__3Zoo2Det)
-
- !! ---- We assume *constant* sinking for second detritus
- if(tracers%data(tr_num)%ID ==1025 .or. & !idetz2n
+ !! ---- We assume constant sinking for second detritus
+ if(enable_3zoo2det .and. &
+ tracers%data(tr_num)%ID ==1025 .or. & !idetz2n
tracers%data(tr_num)%ID ==1026 .or. & !idetz2c
tracers%data(tr_num)%ID ==1027 .or. & !idetz2si
tracers%data(tr_num)%ID ==1028 ) then !idetz2calc
@@ -432,12 +621,17 @@ subroutine ver_sinking_recom(tr_num, tracers, partit, mesh)
if (abs(Wvel_flux(nz)) .gt. max_sinking_velocity) Wvel_flux(nz) = max_sinking_velocity
- !! * sinking velocity [m d-1] surface --> bottom (negative) *
+ ! sinking velocity [m d-1] surface --> bottom (negative)
Wvel_flux(nz) = -1.0d0 * Wvel_flux(nz)/SecondsPerDay ! now in [m s-1]
end if
endif
-#endif
+
+ if (tracers%data(tr_num)%ID == 1021) Sinkvel1_tr(nz,n,tr_num) = Wvel_flux(nz) !-1.0d0/SecondsPerDay !idetcal
+ if (enable_3zoo2det .and. &
+ tracers%data(tr_num)%ID == 1028) Sinkvel2_tr(nz,n,tr_num) = Wvel_flux(nz) !idetz2calc
+
+
end do
dt_sink = dt
@@ -477,7 +671,7 @@ subroutine ver_sinking_recom(tr_num, tracers, partit, mesh)
(1.d0-cfl)/(1.d-20-cfl)*thetaM))
tv= (0.5 * wPs * (trarr(nz,n) + psiM * Rj)+ &
- 0.5 * wM * (trarr(max(nzmin,nz-1),n) + psiP * Rj))
+ 0.5 * wM * (trarr(max(nzmin,nz-1),n) + psiP * Rj))
vd_flux(nz)= - tv*area(nz,n)
end do
end if ! 3rd Order DST Sceheme with flux limiting
@@ -496,7 +690,7 @@ subroutine ver_sinking_recom(tr_num, tracers, partit, mesh)
do nz=nzmin+1,nzmax !nlevels_nod2D_minimum-1
! tv = trarr(nz,n) ! simple scheme - test1
-! tv = 0.5_WP*(trarr(nz-1,n)+trarr(nz,n)) ! consider both layers - test2
+! tv = 0.5_WP*(trarr(nz-1,n)+trarr(nz,n)) ! consider both layers - test2
! tv = tv*Wvel_flux(nz) ! Wvel_flux is negative
tv = - 0.5* & ! - test3
(trarr(nz-1,n)*(Wvel_flux(nz)-abs(Wvel_flux(nz))) + &
@@ -525,9 +719,9 @@ subroutine ballast(tr_num, tracers, partit, mesh)
use recom_config
use recom_glovar
- USE o_PARAM
- USE o_ARRAYS
- USE g_CONFIG
+ use o_PARAM
+ use o_ARRAYS
+ use g_CONFIG
use g_forcing_arrays
use g_comm_auto
use g_clock
@@ -561,6 +755,9 @@ subroutine ballast(tr_num, tracers, partit, mesh)
! b) sea water viscosity, c) depth (currently for small detritus only), and d) a constant reference sinking speed
! -----
+! check oce_ale_tracer.F90
+! call get_seawater_viscosity(mesh) ! seawater_visc_3D
+! call get_particle_density(mesh) ! rho_particle = density of particle class 1 and 2
!___________________________________________________________________________
! loop over local nodes
do row=1,myDim_nod2D
@@ -588,21 +785,19 @@ subroutine ballast(tr_num, tracers, partit, mesh)
scaling_density1_3D(k,row)=1.0
scaling_density2_3D(k,row)=1.0
- if (use_density_scaling) then
- if (tracers%data(tr_num)%ID ==1008)then !idetc
- if (tracers%data(tr_num)%values(k,row)>0.001) then ! only apply ballasting above a certain biomass (OG Todo: remove)
- scaling_density1_3D(k,row) = (rho_particle1(k,row)-rho_seawater(1))/(rho_ref_part-rho_ref_water)
- endif
- endif
-#if defined (__3Zoo2Det)
-
- if (tracers%data(tr_num)%ID ==1026)then ! idetz2c
- if (tracers%data(tr_num)%values(k,row)>0.001) then ! only apply ballasting above a certain biomass (OG Todo: remove)
- scaling_density2_3D(k,row) = (rho_particle2(k,row)-rho_seawater(1))/(rho_ref_part-rho_ref_water)
- endif
- endif
-#endif
- endif
+ if (use_density_scaling) then
+ !if (tracers%data(tr_num)%ID ==1008)then !idetc
+ !if (tracers%data(tr_num)%values(k,row)>0.001) then ! only apply ballasting above a certain biomass (OG Todo: remove)
+ scaling_density1_3D(k,row) = (rho_particle1(k,row)-rho_seawater(1))/(rho_ref_part-rho_ref_water)
+ !endif
+ !endif
+ !if (enable_3zoo2det .and. &
+ !tracers%data(tr_num)%ID ==1026)then ! idetz2c
+ !if (tracers%data(tr_num)%values(k,row)>0.001) then ! only apply ballasting above a certain biomass (OG Todo: remove)
+ scaling_density2_3D(k,row) = (rho_particle2(k,row)-rho_seawater(1))/(rho_ref_part-rho_ref_water)
+ !endif
+ !endif
+ endif
scaling_visc_3D(k,row)=1.0
@@ -622,9 +817,11 @@ subroutine ballast(tr_num, tracers, partit, mesh)
! in the unlikely (if possible at all...) case that rho_particle(k)-rho_seawater(1)<0, prevent the scaling factor from being negative
if (any(scaling_density1_3D(:,:) <= tiny)) scaling_density1_3D(:,:) = 1.0_WP ! tiny = 2.23D-16
-#if defined (__3Zoo2Det)
- if (any(scaling_density2_3D(:,:) <= tiny)) scaling_density2_3D(:,:) = 1.0_WP ! tiny = 2.23D-16
-#endif
+
+ if (enable_3zoo2det) then
+ if (any(scaling_density2_3D(:,:) <= tiny)) scaling_density2_3D(:,:) = 1.0_WP ! tiny = 2.23D-16
+ endif
+
end subroutine ballast
!-------------------------------------------------------------------------------
! Subroutine calculate density of particle
@@ -678,6 +875,7 @@ subroutine get_particle_density(tracers, partit, mesh)
b4 = 0.0
aux = 0.0
+! Below guarantees non-negative tracer field
do tr_num=1,num_tracers
if (tracers%data(tr_num)%ID==1008) b1 = max(tiny,tracers%data(tr_num)%values(:,:)) !idetc ! [mmol m-3] detritus carbon
if (tracers%data(tr_num)%ID==1007) b2 = max(tiny,tracers%data(tr_num)%values(:,:)) !idetn ! [mmol m-3] detritus nitrogen
@@ -696,7 +894,7 @@ subroutine get_particle_density(tracers, partit, mesh)
rho_particle1(nzmin:nzmax,row) = rho_CaCO3*a4(nzmin:nzmax,row) + rho_opal*a3(nzmin:nzmax,row) + rho_POC*a1(nzmin:nzmax,row) + rho_PON*a2(nzmin:nzmax,row)
end do
-#if defined (__3Zoo2Det)
+ if (enable_3zoo2det) then
rho_particle2 = 0.0
b1 = 0.0
b2 = 0.0
@@ -721,7 +919,7 @@ subroutine get_particle_density(tracers, partit, mesh)
a4(nzmin:nzmax,row) = b4(nzmin:nzmax,row)/aux(nzmin:nzmax,row)
rho_particle2(nzmin:nzmax,row) = rho_CaCO3*a4(nzmin:nzmax,row) + rho_opal*a3(nzmin:nzmax,row) + rho_POC*a1(nzmin:nzmax,row) + rho_PON*a2(nzmin:nzmax,row)
end do
-#endif
+ endif
end subroutine get_particle_density
!-------------------------------------------------------------------------------
@@ -734,16 +932,15 @@ end subroutine get_particle_density
subroutine get_seawater_viscosity(tr_num, tracers, partit, mesh)
+ use recom_config
+ use recom_glovar
use MOD_MESH
use MOD_PARTIT
use MOD_PARSUP
use MOD_TRACER
-
- use recom_config
- use recom_glovar
- USE o_PARAM
- USE o_ARRAYS
- USE g_CONFIG
+ use o_PARAM
+ use o_ARRAYS
+ use g_CONFIG
use g_forcing_arrays
use g_comm_auto
use g_clock
diff --git a/src/int_recom/recom_sms.F90 b/src/int_recom/recom_sms.F90
index 044d59c1e..84d5a0e54 100644
--- a/src/int_recom/recom_sms.F90
+++ b/src/int_recom/recom_sms.F90
@@ -40,8 +40,9 @@ subroutine REcoM_sms(n,Nn,state,thick,recipthick,SurfSR,sms,Temp, Sali_depth &
type(t_ice) , intent(inout), target :: ice
integer, intent(in) :: Nn !< Total number of nodes in the vertical
+ integer :: nzmax, nzmin, k_bottom, nlevels_nod2D_minimum !R2OMIP (OmegaC)
real(kind=8),dimension(mesh%nl-1,bgc_num),intent(inout) :: state !< ChlA conc in phytoplankton [mg/m3]
- !! should be in instead of inout
+ !! should be in instead of inout
real(kind=8),dimension(mesh%nl-1) :: thick !< [m] Vertical distance between two nodes = Thickness
real(kind=8),dimension(mesh%nl-1) :: recipthick !< [1/m] reciprocal of thick
@@ -85,261 +86,1417 @@ subroutine REcoM_sms(n,Nn,state,thick,recipthick,SurfSR,sms,Temp, Sali_depth &
real(kind=8), intent(in) :: Latd(1) ! latitude in degree
real(kind=8), intent(in) :: Lond(1) ! longitude in degree
real(kind=8) :: mocsy_step_per_day
- real(kind=8) :: &
- DIN, & !< Dissolved Inorganic Nitrogen [mmol/m3]
- DIC, & !< Dissolved Inorganic Carbon [mmol/m3]
- Alk, & !< Total Alkalinity [mmol/m3]
- PhyN, & !< Intracellular conc of Nitrogen in small phytoplankton [mmol/m3]
- PhyC, & !< Intracellular conc of Carbon in small phytoplankton [mmol/m3]
- PhyChl, & !< Current intracellular ChlA conc. [mg/m3]
- DetN, & !< Conc of N in Detritus [mmol/m3]
- DetC, & !< Conc of C in Detritus [mmol/m3]
- HetN, & !< Conc of N in heterotrophs [mmol/m3]
- HetC, & !< Conc of C in heterotrophs [mmol/m3]
- DON, & !< Dissolved organic N in the water [mmol/m3]
- EOC, & !< Extracellular Organic C conc [mmol/m3]
- DiaN, &
- DiaC, &
- DiaChl, &
- DiaSi, &
- DetSi, &
-#if defined (__coccos)
- CoccoN, &
- CoccoC, &
- CoccoChl,&
-#endif
- Si, &
- Fe, &
- PhyCalc, &
- DetCalc, &
-#if defined (__3Zoo2Det)
- Zoo2N, &
- Zoo2C, &
- DetZ2N, &
- DetZ2C, &
- DetZ2Si, &
- DetZ2Calc,&
- MicZooN, & ! 3Zoo
- MicZooC, & ! 3Zoo
-#endif
- FreeFe, &
- O2
+
+! --- Biogeochemical state variables ---
+ real(kind=8) :: &
+ DIN, & ! [mmol/m3] Dissolved inorganic nitrogen
+ DIC, & ! [mmol/m3] Dissolved inorganic carbon
+ Alk, & ! [mmol/m3] Total alkalinity
+ PhyN, & ! [mmol/m3] Phytoplankton nitrogen (small)
+ PhyC, & ! [mmol/m3] Phytoplankton carbon (small)
+ PhyChl, & ! [mg/m3] Phytoplankton chlorophyll
+ DetN, & ! [mmol/m3] Detrital nitrogen
+ DetC, & ! [mmol/m3] Detrital carbon
+ HetN, & ! [mmol/m3] Heterotroph nitrogen
+ HetC, & ! [mmol/m3] Heterotroph carbon
+ DON, & ! [mmol/m3] Dissolved organic nitrogen
+ EOC, & ! [mmol/m3] Extracellular organic carbon
+ DOCt, & ! [mmol/m3] terrestrial DOC ! R2OMIP
+ DiaN, & ! [mmol/m3] Diatom nitrogen
+ DiaC, & ! [mmol/m3] Diatom carbon
+ DiaChl, & ! [mg/m3] Diatom chlorophyll
+ DiaSi, & ! [mmol/m3] Diatom silicate
+ DetSi, & ! [mmol/m3] Detrital silicate
+ Si, & ! [mmol/m3] Dissolved silicate
+ Fe, & ! [mmol/m3] Dissolved iron
+ PhyCalc, & ! [mmol/m3] Phytoplankton calcite
+ DetCalc, & ! [mmol/m3] Detrital calcite
+ FreeFe, & ! [mmol/m3] Free iron
+ O2 ! [mmol/m3] Dissolved oxygen
+
+! Coccolithophore variables (conditionally used based on namelist)
+real(kind=8) :: &
+ CoccoN, & ! [mmol/m3] Coccolithophore nitrogen
+ CoccoC, & ! [mmol/m3] Coccolithophore carbon
+ CoccoChl, & ! [mg/m3] Coccolithophore chlorophyll
+ PhaeoN, & ! [mmol/m3] Phaeocystis nitrogen
+ PhaeoC, & ! [mmol/m3] Phaeocystis carbon
+ PhaeoChl ! [mg/m3] Phaeocystis chlorophyll
+
+! Extended zooplankton variables (conditionally used based on namelist)
+real(kind=8) :: &
+ Zoo2N, & ! [mmol/m3] Zooplankton type 2 nitrogen
+ Zoo2C, & ! [mmol/m3] Zooplankton type 2 carbon
+ DetZ2N, & ! [mmol/m3] Zooplankton detritus nitrogen
+ DetZ2C, & ! [mmol/m3] Zooplankton detritus carbon
+ DetZ2Si, & ! [mmol/m3] Zooplankton detritus silicate
+ DetZ2Calc, & ! [mmol/m3] Zooplankton detritus calcite
+ MicZooN, & ! [mmol/m3] Microzooplankton nitrogen
+ MicZooC ! [mmol/m3] Microzooplankton carbon
#include "../associate_part_def.h"
#include "../associate_mesh_def.h"
#include "../associate_part_ass.h"
#include "../associate_mesh_ass.h"
- sms = zero ! double precision
- tiny_N = tiny_chl/chl2N_max !< 0.00001/ 3.15d0 Chl2N_max [mg CHL/mmol N] Maximum CHL a : N ratio = 0.3 gCHL gN^-1
- tiny_N_d = tiny_chl/chl2N_max_d !< 0.00001/ 4.2d0
+ ! ===========================================================================
+ ! VARIABLE DECLARATIONS AND INITIALIZATION
+ ! ===========================================================================
+
+ !===============================================================================
+ ! INITIALIZATION AND SETUP
+ !===============================================================================
+ ! Initializes arrays, calculates minimum thresholds, and sets up time stepping.
+ !
+ ! Variables:
+ ! sms : Source-minus-sink array for tracer updates [mmol m-3 day-1]
+ ! zero : Double precision zero (0.0d0)
+ ! tiny : Very small positive number (numerical stability)
+ ! tiny_chl : Minimum chlorophyll concentration [mgChl m-3]
+ !
+ ! Source-Minus-Sink (SMS) Array:
+ ! - Accumulates all biogeochemical fluxes
+ ! - Dimension: (vertical_levels, number_of_tracers)
+ ! - Updated throughout biological calculations
+ ! - Applied to state variables at end of time step
+ ! - Units: concentration per day [mmol m-3 day-1]
+ !-------------------------------------------------------------------------------
+
+ ! Initialize source-minus-sink array
+ ! Sets all biogeochemical fluxes to zero at start of time step
+ sms = zero
+
+ !===============================================================================
+ ! MINIMUM THRESHOLD VALUES
+ !===============================================================================
+ ! Calculates minimum allowable concentrations for all biological state variables.
+ ! Prevents division by zero and ensures numerical stability.
+ !
+ ! Threshold Calculation Strategy:
+ ! - Based on physiological maximum ratios
+ ! - Works backward from minimum chlorophyll
+ ! - Ensures stoichiometric consistency
+ ! - Species-specific values
+ !
+ ! Rationale for Minimum Thresholds:
+ ! - Division by zero prevention in quota calculations
+ ! - Numerical stability in resource limitation terms
+ ! - Prevents spurious negative values
+ ! - Represents detection limits or "ghost populations"
+ !
+ ! Typical Minimum Values:
+ ! - Chlorophyll: ~0.001-0.01 mgChl m-3
+ ! - Nitrogen: ~0.001-0.01 mmolN m-3
+ ! - Carbon: ~0.01-0.1 mmolC m-3
+ !-------------------------------------------------------------------------------
+
+ !-------------------------------------------------------------------------------
+ ! Small Phytoplankton Thresholds
+ !-------------------------------------------------------------------------------
+ ! Variables:
+ ! tiny_N : Minimum small phyto nitrogen [mmolN m-3]
+ ! tiny_C : Minimum small phyto carbon [mmolC m-3]
+ ! tiny_chl : Minimum chlorophyll (set externally) [mgChl m-3]
+ ! chl2N_max : Maximum Chlorophyll:Nitrogen ratio [mgChl mmolN-1]
+ ! NCmax : Maximum Nitrogen:Carbon quota [mmolN mmolC-1]
+ !
+ ! Calculation Logic:
+ ! 1. Start with minimum observable Chl (tiny_chl)
+ ! 2. Calculate minimum N using maximum Chl:N ratio
+ ! 3. Calculate minimum C using maximum N:C quota
+ !
+ ! Typical Values:
+ ! chl2N_max = 3.15 mgChl/mmolN (high Chl per N, low light acclimation)
+ ! NCmax = 0.2 mmolN/mmolC (luxury N consumption maximum)
+
+ ! Minimum nitrogen based on minimum chlorophyll and maximum Chl:N ratio
+ tiny_N = tiny_chl / chl2N_max
+
+ ! Minimum carbon based on minimum nitrogen and maximum N:C quota
+ tiny_C = tiny_N / NCmax
+
+ !-------------------------------------------------------------------------------
+ ! Diatom Thresholds
+ !-------------------------------------------------------------------------------
+ ! Variables:
+ ! tiny_N_d : Minimum diatom nitrogen [mmolN m-3]
+ ! tiny_C_d : Minimum diatom carbon [mmolC m-3]
+ ! tiny_Si : Minimum diatom silicate [mmolSi m-3]
+ ! chl2N_max_d : Maximum diatom Chl:N ratio [mgChl mmolN-1]
+ ! NCmax_d : Maximum diatom N:C quota [mmolN mmolC-1]
+ ! SiCmax : Maximum diatom Si:C quota [mmolSi mmolC-1]
+ !
+ ! Typical Values:
+ ! chl2N_max_d = 4.2 mgChl/mmolN (diatoms can have higher Chl:N)
+ ! NCmax_d = 0.2 mmolN/mmolC
+ ! SiCmax = 0.8 mmolSi/mmolC (heavily silicified frustules)
+ !
+ ! Silicon Requirement:
+ ! - Unique to diatoms (frustule formation)
+ ! - Calculated from minimum carbon and maximum Si:C ratio
+
+ ! Minimum diatom nitrogen
+ tiny_N_d = tiny_chl / chl2N_max_d
+
+ ! Minimum diatom carbon
+ tiny_C_d = tiny_N_d / NCmax_d
+
+ ! Minimum silicate (based on diatom carbon and maximum Si:C quota)
+ tiny_Si = tiny_C_d / SiCmax
+
+ !-------------------------------------------------------------------------------
+ ! Coccolithophore and Phaeocystis Thresholds (Optional)
+ !-------------------------------------------------------------------------------
+ ! Only calculated when 4-plankton functional type model is enabled
+
+ if (enable_coccos) then
+
+ ! Coccolithophore thresholds
+ ! Variables:
+ ! tiny_N_c : Minimum cocco nitrogen [mmolN m-3]
+ ! tiny_C_c : Minimum cocco carbon [mmolC m-3]
+ ! chl2N_max_c : Maximum cocco Chl:N ratio [mgChl mmolN-1]
+ ! NCmax_c : Maximum cocco N:C quota [mmolN mmolC-1]
+
+ tiny_N_c = tiny_chl / chl2N_max_c
+ tiny_C_c = tiny_N_c / NCmax_c
+
+ ! Phaeocystis thresholds
+ ! Variables:
+ ! tiny_N_p : Minimum Phaeo nitrogen [mmolN m-3]
+ ! tiny_C_p : Minimum Phaeo carbon [mmolC m-3]
+ ! chl2N_max_p : Maximum Phaeo Chl:N ratio [mgChl mmolN-1]
+ ! NCmax_p : Maximum Phaeo N:C quota [mmolN mmolC-1]
+
+ tiny_N_p = tiny_chl / chl2N_max_p
+ tiny_C_p = tiny_N_p / NCmax_p
- tiny_C = tiny_N /NCmax !< NCmax = 0.2d0 [mmol N/mmol C] Maximum cell quota of nitrogen (N:C)
- tiny_C_d = tiny_N_d/NCmax_d !< NCmax_d = 0.2d0
+ endif
- tiny_Si = tiny_C_d/SiCmax !< SiCmax = 0.8d0
+ ! Reciprocal of heterotroph respiration rate
+ ! Used in Redfield-based respiration calculations
+ ! Variable:
+ ! recip_res_het : Reciprocal respiration parameter [day]
+ ! res_het : Heterotroph respiration rate [day-1]
+ ! Typical value: res_het = 0.01 day-1 (combined respiration + mortality)
+ recip_res_het = 1.d0 / res_het
+
+ ! Atmospheric pressure conversion for carbonate chemistry
+ ! MOCSY requires pressure in atmospheres
+ ! Variables:
+ ! Patm_depth : Atmospheric pressure [atm]
+ ! Loc_slp : Local sea level pressure [Pa]
+ ! Pa2atm : Pascal to atmosphere conversion factor [Pa atm-1]
+ Patm_depth = Loc_slp / Pa2atm
+
+ !===============================================================================
+ ! TIME STEPPING SETUP
+ !===============================================================================
+ ! Converts time steps and sets up sub-cycling for biogeochemistry.
+ !
+ ! Time Step Hierarchy:
+ ! 1. FESOM physics time step (dt) [seconds]
+ ! 2. Daily time step (dt_d) [days]
+ ! 3. REcoM biogeochemistry sub-step (dt_b) [days]
+ !
+ ! Sub-Cycling Rationale:
+ ! - Physics: Slow (hours to days)
+ ! - Fast biology: Minutes to hours (phytoplankton growth, grazing)
+ ! - Allows finer temporal resolution for biological processes
+ ! - Improves numerical stability for stiff biological systems
+ !
+ ! Variables:
+ ! rTref : Reciprocal reference temperature [K-1]
+ ! recom_Tref : Reference temperature (typically 288.15 K = 15degC) [K]
+ ! dt : FESOM physics time step [seconds]
+ ! dt_d : Physics time step in days [days]
+ ! dt_b : REcoM biogeochemistry sub-time step [days]
+ ! SecondsPerDay : Conversion factor (86400) [s day-1]
+ ! biostep : Number of biogeochemistry steps per physics step [-]
+ !
+ ! Typical Configuration:
+ ! dt = 3600 s (1 hour physics step)
+ ! biostep = 4 (15-minute biogeochemistry steps)
+ ! dt_b = 0.25/24 = 0.0104 days
+ !-------------------------------------------------------------------------------
+
+ ! Convert FESOM physics time step to days
+ dt_d = dt / SecondsPerDay
+
+ ! Calculate biogeochemistry sub-time step
+ ! Divides physics step into smaller biogeochemical steps
+ dt_b = dt_d / real(biostep)
+
+ ! Reciprocal reference temperature for Arrhenius calculations
+ ! Reference: 288.15 K (15degC) used in temperature dependence functions
+ rTref = real(one) / recom_Tref
+
+ !===============================================================================
+ ! MAIN TIME INTEGRATION LOOP
+ !===============================================================================
+ ! Iterates through biogeochemical sub-time steps within each physics time step.
+ ! Allows fine temporal resolution for fast biological processes.
+ !
+ ! Loop Structure:
+ ! - Outer loop: Biogeochemistry sub-steps (biostep iterations)
+ ! - Inner loop: Vertical layers (surface to bottom)
+ !
+ ! Variables:
+ ! step : Current biogeochemistry sub-step counter [-]
+ ! biostep : Total number of sub-steps per physics step [-]
+ ! kdzUpper : Cumulative light attenuation from surface [dimensionless]
+ ! sms : Source-minus-sink flux array [mmol m-3 day-1]
+ ! tiny : Threshold for negligible fluxes [mmol m-3 day-1]
+ !
+ ! Numerical Cleanup:
+ ! - Removes negligible SMS values before applying
+ ! - Prevents accumulation of numerical noise
+ ! - Improves computational efficiency
+ !-------------------------------------------------------------------------------
+
+ do step = one, biostep
+
+ ! Reset upper light attenuation (top of the cell) at start of each sub-step
+ ! Light attenuation integrates downward through water column
+ kdzUpper = 0.d0
+
+ ! Clean up negligible SMS values to prevent numerical issues
+ ! Sets very small fluxes to exactly zero
+ if (any(abs(sms(:, :)) <= tiny)) sms(:, :) = zero
+
+ !===========================================================================
+ ! VERTICAL LOOP THROUGH WATER COLUMN
+ !===========================================================================
+ ! Processes each vertical layer from surface to bottom.
+ ! Updates state variables and enforces constraints.
+ !
+ ! Variables:
+ ! k : Current vertical level index [-]
+ ! nn : Number of vertical levels in water column [-]
+ !
+ ! Note: Alternative loop configurations commented out:
+ ! - nzmin, nzmax: Min/max active levels (for dry cells)
+ ! - myDim_nod2D: Horizontal dimension (for 3D unstructured grids)
+ !---------------------------------------------------------------------------
+
+ do k = one, nn
+ ! Alternative loop structures (commented out):
+ ! do n = 1, myDim_nod2D
+ ! Nn = nlevels_nod2D(n) - 1
+ ! nzmin = ulevels_nod2D(row)
+ ! nzmax = nlevels_nod2D(row)
+
+ !-----------------------------------------------------------------------
+ ! DISSOLVED INORGANIC NUTRIENTS
+ !-----------------------------------------------------------------------
+ ! Update nutrient concentrations: state(previous) + SMS(fluxes)
+ ! Enforce minimum values for numerical stability
+ !
+ ! Variables:
+ ! DIN : Dissolved inorganic nitrogen (NO3- + NH4+) [mmolN m-3]
+ ! Si : Dissolved silicate (Si(OH)4) [mmolSi m-3]
+ ! Fe : Dissolved iron (bioavailable Fe) [mmolFe m-3]
+ !
+ ! max() function ensures non-negative concentrations
+ !-----------------------------------------------------------------------
+
+ DIN = max(tiny, state(k, idin) + sms(k, idin))
+ Si = max(tiny, state(k, isi) + sms(k, isi))
+ Fe = max(tiny, state(k, ife) + sms(k, ife))
+
+ !-----------------------------------------------------------------------
+ ! CARBON SYSTEM VARIABLES
+ !-----------------------------------------------------------------------
+ ! Variables:
+ ! DIC : Dissolved inorganic carbon (CO2 + HCO3- + CO3--) [mmolC m-3]
+ ! ALK : Total alkalinity [meq m-3]
+ ! O2 : Dissolved oxygen [mmolO2 m-3]
+ !-----------------------------------------------------------------------
+
+ DIC = max(tiny, state(k, idic) + sms(k, idic))
+ ALK = max(tiny, state(k, ialk) + sms(k, ialk))
+ O2 = max(tiny, state(k, ioxy) + sms(k, ioxy))
+
+ !-----------------------------------------------------------------------
+ ! DISSOLVED ORGANIC MATTER
+ !-----------------------------------------------------------------------
+ ! Variables:
+ ! DON : Dissolved organic nitrogen (labile + semi-labile) [mmolN m-3]
+ ! EOC : Dissolved organic carbon (labile + semi-labile) [mmolC m-3]
+ !
+ ! Note: EOC naming convention (Enhanced Organic Carbon) is historical
+ !-----------------------------------------------------------------------
+
+ DON = max(tiny, state(k, idon) + sms(k, idon))
+ EOC = max(tiny, state(k, idoc) + sms(k, idoc))
+
+ if (useRivers) then
+ DOCt= max(tiny, state(k,idoct) + sms(k, idoct)) ! R2OMIP
+ end if
+ !-----------------------------------------------------------------------
+ ! SMALL PHYTOPLANKTON
+ !-----------------------------------------------------------------------
+ ! General phytoplankton functional type
+ ! Variables:
+ ! PhyN : Small phyto nitrogen [mmolN m-3]
+ ! PhyC : Small phyto carbon [mmolC m-3]
+ ! PhyChl : Small phyto chlorophyll [mgChl m-3]
+ ! PhyCalc : Small phyto calcite (if calcifying) [mmolC m-3]
+ !-----------------------------------------------------------------------
+
+ PhyN = max(tiny_N, state(k, iphyn) + sms(k, iphyn))
+ PhyC = max(tiny_C, state(k, iphyc) + sms(k, iphyc))
+ PhyChl = max(tiny_chl, state(k, ipchl) + sms(k, ipchl))
+ PhyCalc = max(tiny, state(k, iphycal) + sms(k, iphycal))
+
+ !-----------------------------------------------------------------------
+ ! DIATOMS (SILICIFYING PHYTOPLANKTON)
+ !-----------------------------------------------------------------------
+ ! Large phytoplankton with silica frustules
+ ! Variables:
+ ! DiaN : Diatom nitrogen [mmolN m-3]
+ ! DiaC : Diatom carbon [mmolC m-3]
+ ! DiaChl : Diatom chlorophyll [mgChl m-3]
+ ! DiaSi : Diatom silicate (frustule) [mmolSi m-3]
+ !-----------------------------------------------------------------------
+
+ DiaN = max(tiny_N_d, state(k, idian) + sms(k, idian))
+ DiaC = max(tiny_C_d, state(k, idiac) + sms(k, idiac))
+ DiaChl = max(tiny_chl, state(k, idchl) + sms(k, idchl))
+ DiaSi = max(tiny_si, state(k, idiasi) + sms(k, idiasi))
+
+ if (enable_coccos) then
+
+ !-------------------------------------------------------------------
+ ! COCCOLITHOPHORES (CALCIFYING PHYTOPLANKTON)
+ !-------------------------------------------------------------------
+ ! Variables:
+ ! CoccoN : Cocco nitrogen [mmolN m-3]
+ ! CoccoC : Cocco carbon [mmolC m-3]
+ ! CoccoChl : Cocco chlorophyll [mgChl m-3]
+ !-------------------------------------------------------------------
+
+ CoccoN = max(tiny_N_c, state(k, icocn) + sms(k, icocn))
+ CoccoC = max(tiny_C_c, state(k, icocc) + sms(k, icocc))
+ CoccoChl = max(tiny_chl, state(k, icchl) + sms(k, icchl))
+
+ !-------------------------------------------------------------------
+ ! PHAEOCYSTIS (COLONIAL PHYTOPLANKTON)
+ !-------------------------------------------------------------------
+ ! Variables:
+ ! PhaeoN : Phaeo nitrogen [mmolN m-3]
+ ! PhaeoC : Phaeo carbon [mmolC m-3]
+ ! PhaeoChl : Phaeo chlorophyll [mgChl m-3]
+ !-------------------------------------------------------------------
+
+ PhaeoN = max(tiny_N_p, state(k, iphan) + sms(k, iphan))
+ PhaeoC = max(tiny_C_p, state(k, iphac) + sms(k, iphac))
+ PhaeoChl = max(tiny_chl, state(k, iphachl) + sms(k, iphachl))
-#if defined (__coccos)
- tiny_N_c = tiny_chl/chl2N_max_c
- tiny_C_c = tiny_N_c/NCmax_c
-#endif
+ end if
- recip_res_het = 1.d0/res_het !< res_het = 0.01d0 [1/day] Respiration by heterotrophs and mortality (loss to detritus)
+ !-----------------------------------------------------------------------
+ ! HETEROTROPHS (ZOOPLANKTON)
+ !-----------------------------------------------------------------------
+ ! Primary grazers (mesozooplankton)
+ ! Variables:
+ ! HetN : Mesozooplankton nitrogen [mmolN m-3]
+ ! HetC : Mesozooplankton carbon [mmolC m-3]
+ !-----------------------------------------------------------------------
+
+ HetN = max(tiny, state(k, ihetn) + sms(k, ihetn))
+ HetC = max(tiny, state(k, ihetc) + sms(k, ihetc))
+
+ if (enable_3zoo2det) then
+
+ !-------------------------------------------------------------------
+ ! ADDITIONAL ZOOPLANKTON (3-ZOOPLANKTON MODEL)
+ !-------------------------------------------------------------------
+ ! Macrozooplankton (e.g., krill)
+ ! Variables:
+ ! Zoo2N : Macrozooplankton nitrogen [mmolN m-3]
+ ! Zoo2C : Macrozooplankton carbon [mmolC m-3]
+ Zoo2N = max(tiny, state(k, izoo2n) + sms(k, izoo2n))
+ Zoo2C = max(tiny, state(k, izoo2c) + sms(k, izoo2c))
+
+ ! Microzooplankton (e.g., ciliates, heterotrophic dinoflagellates)
+ ! Variables:
+ ! MicZooN : Microzooplankton nitrogen [mmolN m-3]
+ ! MicZooC : Microzooplankton carbon [mmolC m-3]
+ MicZooN = max(tiny, state(k, imiczoon) + sms(k, imiczoon))
+ MicZooC = max(tiny, state(k, imiczooc) + sms(k, imiczooc))
- Patm_depth = Loc_slp/Pa2atm ! MOCSY convert from Pa to atm.
+ end if
-!-------------------------------------------------------------------------------
-!> REcoM time steps [day]
-!-------------------------------------------------------------------------------
+ !-----------------------------------------------------------------------
+ ! DETRITUS (DEAD ORGANIC MATTER)
+ !-----------------------------------------------------------------------
+ ! Slow-sinking detritus pools
+ ! Variables:
+ ! DetN : Detrital nitrogen [mmolN m-3]
+ ! DetC : Detrital carbon [mmolC m-3]
+ ! DetSi : Detrital silicate [mmolSi m-3]
+ ! DetCalc : Detrital calcite [mmolC m-3]
+ !-----------------------------------------------------------------------
+
+ DetN = max(tiny, state(k, idetn) + sms(k, idetn))
+ DetC = max(tiny, state(k, idetc) + sms(k, idetc))
+ DetSi = max(tiny, state(k, idetsi) + sms(k, idetsi))
+ DetCalc = max(tiny, state(k, idetcal) + sms(k, idetcal))
+
+ if (enable_3zoo2det) then
+
+ !-------------------------------------------------------------------
+ ! FAST-SINKING DETRITUS (FECAL PELLETS)
+ !-------------------------------------------------------------------
+ ! Large, rapidly sinking particles
+ ! Variables:
+ ! DetZ2N : Fast detritus nitrogen [mmolN m-3]
+ ! DetZ2C : Fast detritus carbon [mmolC m-3]
+ ! DetZ2Si : Fast detritus silicate [mmolSi m-3]
+ ! DetZ2Calc : Fast detritus calcite [mmolC m-3]
+ !-------------------------------------------------------------------
+
+ DetZ2N = max(tiny, state(k, idetz2n) + sms(k, idetz2n))
+ DetZ2C = max(tiny, state(k, idetz2c) + sms(k, idetz2c))
+ DetZ2Si = max(tiny, state(k, idetz2si) + sms(k, idetz2si))
+ DetZ2Calc = max(tiny, state(k, idetz2calc) + sms(k, idetz2calc))
- rTref = real(one)/recom_Tref
-
- dt_d = dt/SecondsPerDay !< Size of FESOM time step [day]
- dt_b = dt_d/real(biostep) !< Size of REcoM time step [day]
+ end if
-!-------------------------------------------------------------------------------
-!Main time loop starts
- do step = one,biostep
+ !-----------------------------------------------------------------------
+ ! FREE IRON INITIALIZATION
+ !-----------------------------------------------------------------------
+ ! Free iron will be calculated later from total iron budget
+ ! Accounts for scavenging, complexation, and biological uptake
+ !-----------------------------------------------------------------------
- kdzUpper = 0.d0 !< Upper light attenuation of top cell is set to zero
+ FreeFe = zero
- if (any(abs(sms(:,:)) <= tiny)) sms(:,:) = zero ! tiny = 2.23D-16
+ !=======================================================================
+ ! PHYSICAL ENVIRONMENT CONSTRAINTS FOR CARBONATE CHEMISTRY
+ !=======================================================================
+ ! Validates and constrains physical parameters for MOCSY carbonate
+ ! system calculations. Ensures inputs are within valid ranges.
+ !
+ ! MOCSY Valid Ranges (Lueker K1/K2 formulation):
+ ! Temperature: 2-35degC
+ ! Salinity: 19-43 psu
+ !
+ ! Rationale for Constraints:
+ ! - Equilibrium constants are empirical fits
+ ! - Extrapolation outside valid range introduces errors
+ ! - Numerical instability at extreme values
+ ! - Ice formation creates low-salinity issues
+ !-----------------------------------------------------------------------
+
+ !-----------------------------------------------------------------------
+ ! Temperature Constraints
+ !-----------------------------------------------------------------------
+ ! Variables:
+ ! REcoM_T_depth : Constrained temperature for MOCSY [degC]
+ ! Temp(k) : Actual temperature at depth k [degC]
+ !
+ ! Constraints:
+ ! Minimum: 2degC (prevents extrapolation below calibration range)
+ ! Maximum: 40degC (safety limit, ocean rarely exceeds 35degC)
+ !
+ ! Note: K1/K2 Lueker formulation valid for 2-35degC
+ !-----------------------------------------------------------------------
+
+ REcoM_T_depth = max(2.d0, Temp(k)) ! Apply minimum
+ REcoM_T_depth = min(REcoM_T_depth, 40.d0) ! Apply maximum
+
+ !-----------------------------------------------------------------------
+ ! Salinity Constraints
+ !-----------------------------------------------------------------------
+ ! Variables:
+ ! REcoM_S_depth : Constrained salinity for MOCSY [psu]
+ ! Sali_depth(k) : Actual salinity at depth k [psu]
+ !
+ ! Constraints:
+ ! Minimum: 21 psu (increased from 19 to avoid numerical issues)
+ ! Maximum: 43 psu (upper limit of calibration range)
+ !
+ ! Problematic Conditions:
+ ! - Salinity 19-21 psu with ice concentration > 97%
+ ! - Causes numerical instability in MOCSY
+ ! - Conservative constraint (21 psu minimum) prevents issues
+ !
+ ! Note: Brackish water and ice-covered regions require special care
+ !-----------------------------------------------------------------------
+
+ REcoM_S_depth = max(21.d0, Sali_depth(k)) ! Apply minimum
+ REcoM_S_depth = min(REcoM_S_depth, 43.d0) ! Apply maximum
+
+ !-----------------------------------------------------------------------
+ ! Unit Conversions for MOCSY
+ !-----------------------------------------------------------------------
+ ! MOCSY requires concentrations in mol/m3 (not mmol/m3)
+ ! Conversion factor: 1e-3 (mmol -> mol)
+ !
+ ! Variables (output):
+ ! REcoM_DIC_depth : DIC for MOCSY [mol m-3]
+ ! REcoM_Alk_depth : Alkalinity for MOCSY [mol m-3]
+ ! REcoM_Si_depth : Silicate for MOCSY [mol m-3]
+ ! REcoM_Phos_depth : Phosphate for MOCSY [mol m-3]
+ !
+ ! Sources:
+ ! state(k, idic) + sms(k, idic) : DIC [mmol m-3]
+ ! state(k, ialk) + sms(k, ialk) : Alkalinity [mmol m-3]
+ ! state(k, isi) + sms(k, isi) : Silicate [mmol m-3]
+ ! state(k, idin) + sms(k, idin) : DIN -> Phosphate via Redfield
+ !-----------------------------------------------------------------------
+
+ ! Dissolved inorganic carbon [mol m-3]
+ REcoM_DIC_depth = max(tiny * 1e-3, state(k, idic) * 1e-3 + sms(k, idic) * 1e-3)
+
+ ! Total alkalinity [mol m-3]
+ REcoM_Alk_depth = max(tiny * 1e-3, state(k, ialk) * 1e-3 + sms(k, ialk) * 1e-3)
+
+ ! Silicate [mol m-3]
+ REcoM_Si_depth = max(tiny * 1e-3, state(k, isi) * 1e-3 + sms(k, isi) * 1e-3)
+
+ ! Phosphate [mol m-3]
+ ! Calculated from nitrogen using Redfield ratio (N:P = 16:1)
+ ! Model tracks nitrogen but MOCSY needs phosphate
+ REcoM_Phos_depth = max(tiny * 1e-3, state(k, idin) * 1e-3 + sms(k, idin) * 1e-3) / 16.d0
+
+ ! ===================================================================
+ ! CELLULAR QUOTAS AND RATIOS CALCULATIONS
+ ! ===================================================================
+
+ !===============================================================================
+ ! Small Phytoplankton Quotas
+ !===============================================================================
+ ! Calculates stoichiometric ratios for the small phytoplankton functional type.
+ ! Represents diverse group of small flagellates and picophytoplankton.
+ !
+ ! Variables:
+ ! quota : Nitrogen:Carbon quota [mmolN mmolC-1]
+ ! recipquota : Carbon:Nitrogen ratio [mmolC mmolN-1]
+ ! Chl2C : Chlorophyll:Carbon ratio [mgChl mmolC-1]
+ ! Chl2N : Chlorophyll:Nitrogen ratio [mgChl mmolN-1]
+ ! CHL2C_plast : Plastidic Chlorophyll:Carbon ratio [mgChl mmolC-1]
+ ! PhyN : Small phytoplankton nitrogen [mmolN m-3]
+ ! PhyC : Small phytoplankton carbon [mmolC m-3]
+ ! PhyChl : Small phytoplankton chlorophyll [mgChl m-3]
+ ! NCmin : Minimum N:C quota (subsistence quota) [mmolN mmolC-1]
+ !
+ ! Quota Interpretation:
+ ! - High quota (N:C > 0.15): Nutrient replete, luxury consumption
+ ! - Medium quota (N:C ≈ 0.10): Balanced growth
+ ! - Low quota (N:C < 0.06): Severely N-limited, near subsistence
+ ! - Minimum quota (NCmin ≈ 0.04): Zero growth threshold
+ !
+ ! Plastidic Chlorophyll Concept:
+ ! - Total Chl includes storage and structural chlorophyll
+ ! - Plastidic Chl represents functional photosynthetic apparatus
+ ! - Correction factor: quota/(quota - NCmin)
+ ! - Higher correction when quota approaches minimum (more Chl in chloroplasts)
+ !-------------------------------------------------------------------------------
+
+ ! Nitrogen:Carbon quota (cellular N:C ratio)
+ ! Controls growth rate via Droop limitation
+ quota = PhyN / PhyC
+
+ ! Carbon:Nitrogen ratio (reciprocal)
+ ! Used for converting N-based fluxes to carbon
+ recipquota = real(one) / quota
+
+ ! Chlorophyll:Carbon ratio
+ ! Reflects photoacclimation state (higher in low light)
+ Chl2C = PhyChl / PhyC
+
+ ! Chlorophyll:Nitrogen ratio
+ ! Links photosynthetic machinery to nitrogen investment
+ Chl2N = PhyChl / PhyN
+
+ ! Plastidic Chlorophyll:Carbon ratio
+ ! Estimates chlorophyll in active photosynthetic apparatus
+ ! Correction accounts for non-photosynthetic N (structural proteins, storage)
+ ! Formula: Chl2C x (quota / (quota - NCmin))
+ ! As quota -> NCmin, more N is in photosynthetic machinery
+ CHL2C_plast = Chl2C * (quota / (quota - NCmin))
+
+ !===============================================================================
+ ! Diatom Quotas
+ !===============================================================================
+ ! Calculates stoichiometric ratios for diatoms (large phytoplankton with
+ ! silica frustules). Includes unique silicon quotas.
+ !
+ ! Variables:
+ ! quota_dia : Diatom N:C quota [mmolN mmolC-1]
+ ! recipQuota_dia : Diatom C:N ratio [mmolC mmolN-1]
+ ! Chl2C_dia : Diatom Chl:C ratio [mgChl mmolC-1]
+ ! Chl2N_dia : Diatom Chl:N ratio [mgChl mmolN-1]
+ ! CHL2C_plast_dia : Diatom plastidic Chl:C ratio [mgChl mmolC-1]
+ ! qSiC : Diatom Si:C quota [mmolSi mmolC-1]
+ ! qSiN : Diatom Si:N quota [mmolSi mmolN-1]
+ ! DiaN : Diatom nitrogen [mmolN m-3]
+ ! DiaC : Diatom carbon [mmolC m-3]
+ ! DiaChl : Diatom chlorophyll [mgChl m-3]
+ ! DiaSi : Diatom silicon [mmolSi m-3]
+ ! NCmin_d : Minimum diatom N:C quota [mmolN mmolC-1]
+ !
+ ! Silicon Quota Significance:
+ ! - Required for frustule (shell) formation
+ ! - Typical Si:C ≈ 0.13 (Brzezinski 1985)
+ ! - Low Si:C -> thin frustules, increased sinking mortality
+ ! - High Si:C -> thick frustules, enhanced sinking
+ ! - Si limitation can occur even when N is abundant
+ !
+ ! Diatom-Specific Features:
+ ! - Generally lower Chl:C than small phytoplankton (package effect)
+ ! - Higher maximum growth rates when nutrient replete
+ ! - Bloom-forming under high-nutrient conditions
+ !-------------------------------------------------------------------------------
+
+ ! Nitrogen:Carbon quota
+ quota_dia = DiaN / DiaC
+
+ ! Carbon:Nitrogen ratio (reciprocal)
+ recipQuota_dia = real(one) / quota_dia
+
+ ! Chlorophyll:Carbon ratio
+ ! Generally lower than small phytoplankton due to large cell size (package effect)
+ Chl2C_dia = DiaChl / DiaC
+
+ ! Chlorophyll:Nitrogen ratio
+ Chl2N_dia = DiaChl / DiaN
+
+ ! Plastidic Chlorophyll:Carbon ratio
+ ! Corrected for non-photosynthetic nitrogen allocation
+ CHL2C_plast_dia = Chl2C_dia * (quota_dia / (quota_dia - NCmin_d))
+
+ ! Silicon:Carbon quota
+ ! Critical for frustule formation and diatom physiology
+ ! Low Si:C indicates silicon limitation
+ qSiC = DiaSi / DiaC
+
+ ! Silicon:Nitrogen quota
+ ! Alternative measure of silicon status relative to cellular nitrogen
+ qSiN = DiaSi / DiaN
+
+ !===============================================================================
+ ! Additional Phytoplankton Quotas (OPTIONAL)
+ !===============================================================================
+ ! Calculates quotas for coccolithophores and Phaeocystis when enabled.
+ ! These groups have distinct biogeochemical roles.
+ !
+ ! Coccolithophores:
+ ! - Calcifying phytoplankton (produce CaCO3 plates)
+ ! - Warm-water adapted
+ ! - Important for carbonate counter-pump
+ !
+ ! Phaeocystis:
+ ! - Colonial phytoplankton (can form large blooms)
+ ! - Produces mucilaginous matrix
+ ! - Cold-water species (polar and temperate)
+ ! - High aggregation potential
+ !-------------------------------------------------------------------------------
+
+ if (enable_coccos) then
+
+ !===========================================================================
+ ! Coccolithophore Quotas
+ !===========================================================================
+ ! Calcifying phytoplankton with calcium carbonate plates (coccoliths)
+ !
+ ! Variables:
+ ! quota_cocco : Cocco N:C quota [mmolN mmolC-1]
+ ! recipQuota_cocco : Cocco C:N ratio [mmolC mmolN-1]
+ ! Chl2C_cocco : Cocco Chl:C ratio [mgChl mmolC-1]
+ ! Chl2N_cocco : Cocco Chl:N ratio [mgChl mmolN-1]
+ ! CHL2C_plast_cocco : Cocco plastidic Chl:C ratio [mgChl mmolC-1]
+ ! CoccoN : Coccolithophore nitrogen [mmolN m-3]
+ ! CoccoC : Coccolithophore carbon [mmolC m-3]
+ ! CoccoChl : Coccolithophore chlorophyll [mgChl m-3]
+ ! NCmin_c : Minimum cocco N:C quota [mmolN mmolC-1]
+ !
+ ! Note: Additional calcite quotas (CaCO3:C) calculated in calcification module
+ !---------------------------------------------------------------------------
+
+ ! Nitrogen:Carbon quota
+ quota_cocco = CoccoN / CoccoC
+
+ ! Carbon:Nitrogen ratio
+ recipQuota_cocco = real(one) / quota_cocco
+
+ ! Chlorophyll:Carbon ratio
+ Chl2C_cocco = CoccoChl / CoccoC
+
+ ! Chlorophyll:Nitrogen ratio
+ Chl2N_cocco = CoccoChl / CoccoN
+
+ ! Plastidic Chlorophyll:Carbon ratio
+ CHL2C_plast_cocco = Chl2C_cocco * (quota_cocco / (quota_cocco - NCmin_c))
+
+ !===========================================================================
+ ! Phaeocystis Quotas
+ !===========================================================================
+ ! Colonial phytoplankton that forms large blooms in cold waters
+ !
+ ! Variables:
+ ! quota_phaeo : Phaeo N:C quota [mmolN mmolC-1]
+ ! recipQuota_phaeo : Phaeo C:N ratio [mmolC mmolN-1]
+ ! Chl2C_phaeo : Phaeo Chl:C ratio [mgChl mmolC-1]
+ ! Chl2N_phaeo : Phaeo Chl:N ratio [mgChl mmolN-1]
+ ! CHL2C_plast_phaeo : Phaeo plastidic Chl:C ratio [mgChl mmolC-1]
+ ! PhaeoN : Phaeocystis nitrogen [mmolN m-3]
+ ! PhaeoC : Phaeocystis carbon [mmolC m-3]
+ ! PhaeoChl : Phaeocystis chlorophyll [mgChl m-3]
+ ! NCmin_p : Minimum Phaeo N:C quota [mmolN mmolC-1]
+ !
+ ! Ecological Notes:
+ ! - Forms colonial mucilaginous matrix (contributes to DOM)
+ ! - Can dominate Arctic/Antarctic spring blooms
+ ! - Enhanced aggregation and export potential
+ !---------------------------------------------------------------------------
+
+ ! Nitrogen:Carbon quota
+ quota_phaeo = PhaeoN / PhaeoC
+
+ ! Carbon:Nitrogen ratio
+ recipQuota_phaeo = real(one) / quota_phaeo
+
+ ! Chlorophyll:Carbon ratio
+ Chl2C_phaeo = PhaeoChl / PhaeoC
+
+ ! Chlorophyll:Nitrogen ratio
+ Chl2N_phaeo = PhaeoChl / PhaeoN
+
+ ! Plastidic Chlorophyll:Carbon ratio
+ CHL2C_plast_phaeo = Chl2C_phaeo * (quota_phaeo / (quota_phaeo - NCmin_p))
-!-------------------------------------------------------------------------------
-! Main vertical loop starts
- do k = one,Nn ! nzmin, nzmax
-! do n=1, myDim_nod2D!+eDim_nod2D
-! Nn=nlevels_nod2D(n)-1 !nzmax
-! nzmin = ulevels_nod2D(row)
-! nzmax = nlevels_nod2D(row)
- DIN = max(tiny,state(k,idin) + sms(k,idin )) !< Avoids division by zero
- DIC = max(tiny,state(k,idic) + sms(k,idic )) !! and updates Conc between
- ALK = max(tiny,state(k,ialk) + sms(k,ialk )) !! local steps in REcoM when
- PhyN = max(tiny_N,state(k,iphyn) + sms(k,iphyn )) !! biostep > 1
- PhyC = max(tiny_C,state(k,iphyc) + sms(k,iphyc ))
- PhyChl = max(tiny_chl,state(k,ipchl) + sms(k,ipchl ))
- DetN = max(tiny,state(k,idetn) + sms(k,idetn ))
- DetC = max(tiny,state(k,idetc) + sms(k,idetc ))
- HetN = max(tiny,state(k,ihetn) + sms(k,ihetn ))
- HetC = max(tiny,state(k,ihetc) + sms(k,ihetc ))
-#if defined (__3Zoo2Det)
- Zoo2N = max(tiny,state(k,izoo2n) + sms(k,izoo2n))
- Zoo2C = max(tiny,state(k,izoo2c) + sms(k,izoo2c))
- DetZ2N = max(tiny,state(k,idetz2n) + sms(k,idetz2n))
- DetZ2C = max(tiny,state(k,idetz2c) + sms(k,idetz2c))
- DetZ2Si = max(tiny,state(k,idetz2si) + sms(k,idetz2si))
- DetZ2Calc = max(tiny,state(k,idetz2calc) + sms(k,idetz2calc))
- MicZooN = max(tiny,state(k,imiczoon) + sms(k,imiczoon))
- MicZooC = max(tiny,state(k,imiczooc) + sms(k,imiczooc))
-#endif
- DON = max(tiny,state(k,idon) + sms(k,idon ))
- EOC = max(tiny,state(k,idoc) + sms(k,idoc ))
- DiaN = max(tiny_N_d,state(k,idian) + sms(k,idian ))
- DiaC = max(tiny_C_d,state(k,idiac) + sms(k,idiac ))
- DiaChl = max(tiny_chl,state(k,idchl) + sms(k,idchl ))
- DiaSi = max(tiny_si,state(k,idiasi) + sms(k,idiasi))
- DetSi = max(tiny,state(k,idetsi) + sms(k,idetsi))
- Si = max(tiny,state(k,isi) + sms(k,isi ))
-#if defined (__coccos)
- CoccoN = max(tiny_N_c,state(k,icocn) + sms(k,icocn ))
- CoccoC = max(tiny_C_c,state(k,icocc) + sms(k,icocc ))
- CoccoChl = max(tiny_chl,state(k,icchl) + sms(k,icchl ))
-#endif
- Fe = max(tiny,state(k,ife) + sms(k,ife ))
- O2 = max(tiny,state(k,ioxy) + sms(k,ioxy))
- FreeFe = zero
+ end if
-! For Mocsy
- REcoM_T_depth = max(2.d0, Temp(k)) ! minimum set to 2 degC: K1/K2 Lueker valid between 2degC-35degC and 19-43psu
- REcoM_T_depth = min(REcoM_T_depth, 40.d0) ! maximum set to 40 degC: K1/K2 Lueker valid between 2degC-35degC and 19-43psu
- REcoM_S_depth = max(21.d0, Sali_depth(k)) ! minimum set to 21: K1/K2 Lueker valid between 2degC-35degC and 19-43psu, else causes trouble in regions with S between 19 and 21 and ice conc above 97%
- REcoM_S_depth = min(REcoM_S_depth, 43.d0) ! maximum set to 43: K1/K2 Lueker valid between 2degC-35degC and 19-43psu, else causes trouble
- REcoM_DIC_depth = max(tiny*1e-3,state(k,idic)*1e-3 + sms(k,idic )*1e-3)
- REcoM_Alk_depth = max(tiny*1e-3,state(k,ialk)*1e-3 + sms(k,ialk )*1e-3)
- REcoM_Si_depth = max(tiny*1e-3,state(k,isi)*1e-3 + sms(k,isi )*1e-3)
-
- REcoM_Phos_depth = max(tiny*1e-3,state(k,idin)*1e-3 + sms(k,idin )*1e-3) /16 ! convert N to P with Redfield [mol/m3]
-
- PhyCalc = max(tiny,state(k,iphycal) + sms(k,iphycal))
- DetCalc = max(tiny,state(k,idetcal) + sms(k,idetcal))
-
-!!------------------------------------------------------------------------------
-!< Quotas
- ! *** Small phytoplankton
- quota = PhyN / PhyC ! include variability of the N: C ratio, cellular chemical composition
- recipquota = real(one) / quota
- Chl2C = PhyChl / PhyC ! Chl a:phytoplankton carbon ratio, cellular chemical composition [gCHL gC^-1]
- Chl2N = PhyChl / PhyN ! Chl a:phytoplankton nitrogen ratio, cellular chemical composition [gCHL gN^-1]
- CHL2C_plast = Chl2C * (quota/(quota - NCmin))
-
- ! *** Diatoms
- quota_dia = DiaN / DiaC
- recipQuota_dia = real(one)/quota_dia
- Chl2C_dia = DiaChl / DiaC
- Chl2N_dia = DiaChl / DiaN
- CHL2C_plast_dia = Chl2C_dia * (quota_dia/(quota_dia - NCmin_d))
- qSiC = DiaSi / DiaC
- qSiN = DiaSi / DiaN
-
-#if defined (__coccos)
- quota_cocco = CoccoN / CoccoC
- recipQuota_cocco = real(one)/quota_cocco
- Chl2C_cocco = CoccoChl / CoccoC
- Chl2N_cocco = CoccoChl / CoccoN
- CHL2C_plast_cocco = Chl2C_cocco * (quota_cocco/(quota_cocco - NCmin_c))
-#endif
- recipQZoo = HetC / HetN
- recip_hetN_plus = 1.d0 / (HetN + tiny_het) ! MB's addition for more stable zoo respiration
- if (Grazing_detritus) recipDet = DetC / DetN
-#if defined (__3Zoo2Det)
- recipQZoo2 = Zoo2C / Zoo2N
- recipQZoo3 = MicZooC / MicZooN
- if (Grazing_detritus) recipDet2 = DetZ2C / DetZ2N
-#endif
+ !===============================================================================
+ ! Zooplankton and Detritus Quotas
+ !===============================================================================
+ ! Calculates carbon:nitrogen ratios for consumers and detrital pools.
+ ! These ratios are more constrained than phytoplankton (less variable).
+ !
+ ! Zooplankton C:N ratios:
+ ! - Typically near Redfield ratio (C:N ≈ 6.6)
+ ! - Less variable than phytoplankton (homeostatic regulation)
+ ! - Important for grazer nutrition and trophic transfer efficiency
+ !
+ ! Detritus C:N ratios:
+ ! - Reflects source material composition
+ ! - Can increase with depth (preferential N remineralization)
+ ! - Affects remineralization stoichiometry
+ !
+ ! Variables:
+ ! recipQZoo : Mesozooplankton C:N ratio [mmolC mmolN-1]
+ ! recipQZoo2 : Macrozooplankton C:N ratio [mmolC mmolN-1]
+ ! recipQZoo3 : Microzooplankton C:N ratio [mmolC mmolN-1]
+ ! recipDet : Slow-sinking detritus C:N ratio [mmolC mmolN-1]
+ ! recipDet2 : Fast-sinking detritus C:N ratio [mmolC mmolN-1]
+ ! recip_hetN_plus : Stable divisor for respiration calculations [mmolN-1 m3]
+ ! HetC, HetN : Mesozooplankton carbon and nitrogen [mmol m-3]
+ ! Zoo2C, Zoo2N : Macrozooplankton carbon and nitrogen [mmol m-3]
+ ! MicZooC, MicZooN: Microzooplankton carbon and nitrogen [mmol m-3]
+ ! DetC, DetN : Detritus carbon and nitrogen [mmol m-3]
+ ! DetZ2C, DetZ2N : Fast-sinking detritus carbon and nitrogen [mmol m-3]
+ ! tiny_het : Small number to prevent division by zero [mmolN m-3]
+ !-------------------------------------------------------------------------------
+
+ !-------------------------------------------------------------------------------
+ ! Mesozooplankton (Primary Heterotroph) Quotas
+ !-------------------------------------------------------------------------------
+ ! Primary grazer consuming phytoplankton and microzooplankton
+
+ ! Carbon:Nitrogen ratio
+ ! Used for converting nitrogen-based grazing to carbon fluxes
+ recipQZoo = HetC / HetN
+
+ ! Stable reciprocal for respiration calculations
+ ! Prevents division by zero when zooplankton biomass is very low
+ ! Used in Redfield-based respiration formulation
+ recip_hetN_plus = 1.d0 / (HetN + tiny_het)
+
+ !-------------------------------------------------------------------------------
+ ! Detritus Quotas
+ !-------------------------------------------------------------------------------
+ ! Organic matter pools with variable C:N ratios
-!-------------------------------------------------------------------------------
-!> Temperature dependence of rates
-!-------------------------------------------------------------------------------
-!< Schourup 2013 Eq. A54
-!< Temperature dependence of metabolic rate, fT, dimensionless
-!< Ae: Slope of the linear region of the Arrhenius plot
-!< rTloc: Inverse of local temperature in [1/Kelvin]
-!< rTref=288.15 (15 degC): Reference temperature for Arrhenius equation [1/Kelvin]
-!< See Figure A1
-!< Other functions can be used for temperature dependency (Eppley 1972; Li 1980; Ahlgren 1987)
-
- rTloc = real(one)/(Temp(k) + C2K)
- arrFunc = exp(-Ae * ( rTloc - rTref))
-#if defined (__coccos)
- CoccoTFunc = max(0.1419d0 * Temp(k)**0.8151d0,tiny) ! Function from Fielding 2013; is based on observational GR, but range fits best to ours
-#endif
-
-#if defined (__3Zoo2Det)
- arrFuncZoo2 = exp(t1_zoo2/t2_zoo2 - t1_zoo2*rTloc)/(1 + exp(t3_zoo2/t4_zoo2 - t3_zoo2*rTloc)) ! 2Zoo
- q10_mes = 1.0242**(Temp(k)) ! 3Zoo
- q10_mic = 1.04**(Temp(k)) ! 3Zoo
- q10_mes_res = 1.0887**(Temp(k)) ! 3Zoo
- q10_mic_res = 1.0897**(Temp(k)) ! 3Zoo
-#endif
-
-!< Silicate temperature dependence
-! reminSiT = min(1.32e16 * exp(-11200.d0 * rTloc),reminSi) !! arrFunc control, reminSi=0.02d0 ! Kamatani (1982)
-! reminSiT = reminSi
- reminSiT = max(0.023d0 * 2.6d0**((Temp(k)-10.)/10.),reminSi)
+ if (Grazing_detritus) then
+ ! Slow-sinking detritus C:N ratio
+ ! Source: Unassimilated food, mortality, aggregation
+ ! Generally close to Redfield but can be elevated
+ recipDet = DetC / DetN
+ endif
-!-------------------------------------------------------------------------------
-!> O2 dependence of rates
-!-------------------------------------------------------------------------------
-!! O2 dependency of organic matter remineralization
-!! O2Func [0.0, 1.0]
-!! k_o2_remin = 15.d0 mmol m-3; Table 1 in Cram 2018 cites
-!! DeVries & Weber 2017 for a range of 0-30 mmol m-3
-
- O2Func = 1.d0 ! in this case, remin. rates only depend on temperature
- if (O2dep_remin) O2Func = O2/(k_o2_remin + O2) ! O2remin
-
-!< *** Light ***
-!< *************
-!! Has to be calculated here already to use the 1%PAR depth.
- if (k==1) then
- PARave = max(tiny,SurfSR)
- PAR(k) = PARave
-
- chl_upper = (PhyChl + DiaChl)
-#if defined (__coccos)
- chl_upper = chl_upper + CoccoChl
-#endif
- else
- chl_lower = PhyChl + DiaChl
-#if defined (__coccos)
- chl_lower = chl_lower + CoccoChl
-#endif
- Chlave = (chl_upper+chl_lower)*0.5
-
- kappa = k_w + a_chl * (Chlave)
- kappastar = kappa / cosAI(n)
- kdzLower = kdzUpper + kappastar * thick(k-1)
- Lowerlight = SurfSR * exp(-kdzLower)
- Lowerlight = max(tiny,Lowerlight)
- PARave = Lowerlight
- PAR(k) = PARave
- chl_upper = chl_lower
- kdzUpper = kdzLower
- end if
+ if (enable_3zoo2det) then
-!-------------------------------------------------------------------------------
-! Depth component of Mocsy (see http://ocmip5.ipsl.jussieu.fr/mocsy/pyth.html)
-!-------------------------------------------------------------------------------
+ !---------------------------------------------------------------------------
+ ! Additional Zooplankton Quotas (3-Zooplankton Model)
+ !---------------------------------------------------------------------------
+
+ ! Macrozooplankton (e.g., krill) C:N ratio
+ ! Larger organisms with potentially different stoichiometry
+ recipQZoo2 = Zoo2C / Zoo2N
+
+ ! Microzooplankton (e.g., ciliates, heterotrophic dinoflagellates) C:N ratio
+ ! Smallest heterotrophs, link to microbial loop
+ recipQZoo3 = MicZooC / MicZooN
+
+ if (Grazing_detritus) then
+ !-----------------------------------------------------------------------
+ ! Fast-Sinking Detritus (Fecal Pellets)
+ !-----------------------------------------------------------------------
+ ! Large, rapidly sinking particles
+ ! Source: Zooplankton fecal pellets, large aggregates
+ ! Important for biological pump and carbon export
-! Calculate the carbonate system for the very first time step of the first year of the run
- !if (mocsy_restart==.false. .and. recom_istep==1) then ! r_restart is defined in gen_modules_clock in fesom_cpl.
+ recipDet2 = DetZ2C / DetZ2N
+ endif
+
+ endif
+
+ ! ===================================================================
+ ! CARBON ISOTOPE TRACERS (if enabled)
+ ! ===================================================================
+
+ if (ciso) then
+ ! 13C isotope tracers
+ DIC_13 = max(tiny, state(k, idic_13) + sms(k, idic_13))
+ PhyC_13 = max(tiny_C, state(k, iphyc_13) + sms(k, iphyc_13))
+ DetC_13 = max(tiny, state(k, idetc_13) + sms(k, idetc_13))
+ HetC_13 = max(tiny, state(k, ihetc_13) + sms(k, ihetc_13))
+ EOC_13 = max(tiny, state(k, idoc_13) + sms(k, idoc_13))
+ DiaC_13 = max(tiny_C, state(k, idiac_13) + sms(k, idiac_13))
+ PhyCalc_13 = max(tiny, state(k, iphycal_13) + sms(k, iphycal_13))
+ DetCalc_13 = max(tiny, state(k, idetcal_13) + sms(k, idetcal_13))
+
+ ! 13C calcite dissolution with fractionation
+ calc_diss_13 = alpha_dcal_13 * calc_diss
+
+ ! 13C quotas
+ quota_13 = PhyN / PhyC_13
+ recipQuota_13 = real(one) / quota_13
+ quota_dia_13 = DiaN / DiaC_13
+ recipQuota_dia_13 = real(one) / quota_dia_13
+ recipQZoo_13 = HetC_13 / HetN
+
+ ! 14C radiocarbon tracers (if enabled)
+ if (ciso_14) then
+ DIC_14 = max(tiny, state(k,idic_14) + sms(k, idic_14))
+
+ if (ciso_organic_14) then
+ PhyC_14 = max(tiny_C, state(k,iphyc_14) + sms(k, iphyc_14))
+ DetC_14 = max(tiny, state(k,idetc_14) + sms(k, idetc_14))
+ HetC_14 = max(tiny, state(k,ihetc_14) + sms(k, ihetc_14))
+ EOC_14 = max(tiny, state(k,idoc_14) + sms(k, idoc_14))
+ DiaC_14 = max(tiny_C, state(k,idiac_14) + sms(k, idiac_14))
+ PhyCalc_14 = max(tiny, state(k,iphycal_14) + sms(k, iphycal_14))
+ DetCalc_14 = max(tiny, state(k,idetcal_14) + sms(k, idetcal_14))
+
+ calc_diss_14 = alpha_dcal_14 * calc_diss
+
+ quota_14 = PhyN / PhyC_14
+ recipQuota_14 = real(one) / quota_14
+ quota_dia_14 = DiaN / DiaC_14
+ recipQuota_dia_14 = real(one) / quota_dia_14
+ recipQZoo_14 = HetC_14 / HetN
+ end if ! ciso_organic_14
+ end if ! ciso_14
+ end if ! ciso
+
+ !===============================================================================
+ ! TEMPERATURE DEPENDENCE OF METABOLIC RATES
+ !===============================================================================
+ ! Calculates how temperature affects biological rates using multiple
+ ! formulations appropriate for different organism groups.
+ !
+ ! General Principle:
+ ! - Metabolic rates increase exponentially with temperature (Q10 rule)
+ ! - Different organisms have different thermal optima and tolerances
+ ! - Cold-adapted vs warm-adapted species
+ !
+ ! Variables (Arrhenius):
+ ! rTloc : Inverse of local absolute temperature [K-1]
+ ! arrFunc : Arrhenius temperature function [-]
+ ! Temp(k) : Temperature at depth k [degC]
+ ! C2K : Celsius to Kelvin conversion (273.15) [K]
+ ! Ae : Activation energy parameter [K]
+ ! rTref : Inverse reference temperature (1/288.15 K at 15degC) [K-1]
+ !
+ ! Alternative Formulations (commented in code):
+ ! - Eppley (1972): Log-linear for phytoplankton
+ ! - Li (1980): Parabolic curve
+ ! - Ahlgren (1987): Optimum curve
+ !-------------------------------------------------------------------------------
+
+ !-------------------------------------------------------------------------------
+ ! Standard Arrhenius Function
+ !-------------------------------------------------------------------------------
+ ! General metabolic rate temperature dependence (Schourup 2013, Eq. A54)
+ ! Exponential increase with temperature (no upper thermal limit)
+ !
+ ! Equation:
+ ! f(T) = exp(-Ae × (1/T - 1/Tref))
+ !
+ ! Where:
+ ! - Ae: Slope of Arrhenius plot (activation energy/gas constant)
+ ! - Tref: Reference temperature (typically 15degC = 288.15 K)
+ ! - T: Absolute temperature [K]
+ !
+ ! Used for: Most metabolic processes without strong thermal limits
+ ! (e.g., remineralization, basal metabolism)
+
+ ! Calculate inverse absolute temperature
+ rTloc = real(one) / (Temp(k) + C2K)
+
+ ! Calculate Arrhenius function
+ arrFunc = exp(-Ae * (rTloc - rTref))
+
+ !-------------------------------------------------------------------------------
+ ! Phytoplankton-Specific Temperature Functions
+ !-------------------------------------------------------------------------------
+ ! Species-specific exponential and optimum-curve temperature responses
+ ! Tuned for 4-plankton functional type version (small phyto, diatoms, coccos, Phaeocystis)
+ !
+ ! Note: New functions require calibration if adapted to 2-plankton version
+ !-------------------------------------------------------------------------------
+
+ ! Old coccolithophore temperature function (commented out):
+ ! Power law form from Fielding (2013) based on observational growth rates
+ ! if (enable_coccos) then
+ ! CoccoTFunc = max(0.1419d0 * Temp(k)**0.8151d0, tiny)
+ ! endif
+
+ if (enable_coccos) then
+
+ !---------------------------------------------------------------------------
+ ! Small Phytoplankton
+ !---------------------------------------------------------------------------
+ ! Exponential temperature response: f(T) = exp(a + b×T)
+ ! Represents diverse group with broad thermal tolerance
+ ! Monotonic increase with temperature (no upper limit in this formulation)
+
+ Temp_phyto = exp(ord_phy + expon_phy * Temp(k))
+ VTTemp_phyto(k) = Temp_phyto ! Store for diagnostics
+
+ !---------------------------------------------------------------------------
+ ! Diatoms
+ !---------------------------------------------------------------------------
+ ! Large phytoplankton with silica frustules
+ ! Exponential form with different parameters than small phyto
+ ! Generally favored by cooler, nutrient-rich conditions
+
+ Temp_diatoms = exp(ord_d + expon_d * Temp(k))
+ VTTemp_diatoms(k) = Temp_diatoms ! Store for diagnostics
+
+ !---------------------------------------------------------------------------
+ ! Coccolithophores
+ !---------------------------------------------------------------------------
+ ! Calcifying phytoplankton with minimum temperature threshold
+ ! Cold-intolerant: minimal growth below 5degC
+ ! Exponential increase above threshold temperature
+ !
+ ! Ecological rationale: Coccos typically dominate in warm, stratified waters
+
+ if (Temp(k) < 5.0) then
+ ! Below threshold: minimal metabolic activity
+ Temp_cocco = tiny
+ else
+ ! Above threshold: exponential response
+ Temp_cocco = exp(ord_cocco + expon_cocco * Temp(k))
+ Temp_cocco = max(Temp_cocco, tiny) ! Ensure positive values
+ end if
+ VTTemp_cocco(k) = Temp_cocco ! Store for diagnostics
+
+ !---------------------------------------------------------------------------
+ ! Phaeocystis
+ !---------------------------------------------------------------------------
+ ! Colonial phytoplankton with bell-shaped temperature response
+ ! Blanchard function from Grimaud et al. (2017)
+ ! Has optimal temperature with decline at high and low temperatures
+ !
+ ! Equation: f(T) = uopt × ((Tmax-T)/(Tmax-Topt))^β × exp(-β×(Topt-T)/(Tmax-Topt))
+ !
+ ! Where:
+ ! - uopt: Maximum growth rate at optimal temperature [day-1]
+ ! - Topt: Optimal temperature [degC]
+ ! - Tmax: Maximum temperature (growth = 0) [degC]
+ ! - β: Shape parameter (steepness of curve) [-]
+ !
+ ! Ecological rationale: Phaeocystis blooms occur at specific temperature ranges
+ ! (typically cold-temperate waters, 0-10degC)
+
+ Temp_phaeo = uopt_phaeo * ((Tmax_phaeo - Temp(k)) / (Tmax_phaeo - Topt_phaeo))**beta_phaeo &
+ * exp(-beta_phaeo * (Topt_phaeo - Temp(k)) / (Tmax_phaeo - Topt_phaeo))
+ Temp_phaeo = max(Temp_phaeo, tiny) ! Ensure positive values
+ VTTemp_phaeo(k) = Temp_phaeo ! Store for diagnostics
+
+ endif
+
+ !-------------------------------------------------------------------------------
+ ! Zooplankton Temperature Dependencies
+ !-------------------------------------------------------------------------------
+ ! Temperature functions for different zooplankton types with thermal limits
+ ! Q10 formulations: exponential increase with ~doubling per 10degC
+
+ if (enable_3zoo2det) then
+
+ !---------------------------------------------------------------------------
+ ! Macrozooplankton (Krill) Temperature Function
+ !---------------------------------------------------------------------------
+ ! Sigmoid function with upper thermal limit
+ ! Accounts for thermal stress at high temperatures
+ !
+ ! Equation: f(T) = exp(t1/t2 - t1/T) / (1 + exp(t3/t4 - t3/T))
+ !
+ ! Numerator: Exponential increase with temperature
+ ! Denominator: Sigmoid decline at high temperatures (thermal stress)
+ !
+ ! Ecological rationale: Macrozooplankton have defined thermal niches
+ ! (e.g., Antarctic krill prefer cold water, decline above ~4degC)
+
+ arrFuncZoo2 = exp(t1_zoo2 / t2_zoo2 - t1_zoo2 * rTloc) / &
+ (1.0 + exp(t3_zoo2 / t4_zoo2 - t3_zoo2 * rTloc))
+
+ !---------------------------------------------------------------------------
+ ! Q10 Temperature Coefficients
+ !---------------------------------------------------------------------------
+ ! Q10 formulation: rate = Q10^(T/10)
+ ! Simple exponential increase with temperature
+ !
+ ! Q10 values:
+ ! - ~1.02-1.04: Moderate temperature sensitivity (typical for metabolism)
+ ! - ~1.09: Higher sensitivity (respiration processes)
+ !
+ ! Ecological interpretation:
+ ! - Smaller organisms (microzooplankton) often have higher Q10
+ ! - Respiration Q10 > growth Q10 (maintenance costs increase faster)
+
+ q10_mes = 1.0242**(Temp(k)) ! Mesozooplankton metabolism
+ q10_mic = 1.04**(Temp(k)) ! Microzooplankton metabolism
+ q10_mes_res = 1.0887**(Temp(k)) ! Mesozooplankton respiration
+ q10_mic_res = 1.0897**(Temp(k)) ! Microzooplankton respiration
+
+ endif
+
+ !-------------------------------------------------------------------------------
+ ! Silicate Dissolution Temperature Dependence
+ !-------------------------------------------------------------------------------
+ ! Temperature effect on biogenic silica (diatom frustule) dissolution
+ ! Higher temperatures accelerate chemical dissolution kinetics
+ !
+ ! Variables:
+ ! reminSiT : Temperature-dependent Si dissolution rate [day-1]
+ ! reminSi : Minimum dissolution rate [day-1]
+ !
+ ! Exponential formulation: 2.6× increase per 10degC
+ ! Reference temperature: 10degC
+ !
+
+ reminSiT = max(0.023d0 * 2.6d0**((Temp(k) - 10.0) / 10.0), reminSi)
+
+ ! Alternative Kamatani (1982) function (commented out):
+ ! reminSiT = min(1.32e16 * exp(-11200.d0 * rTloc), reminSi)
+
+ !===============================================================================
+ ! 2. OXYGEN DEPENDENCE OF REMINERALIZATION
+ !===============================================================================
+ ! Calculates oxygen limitation effects on aerobic organic matter decomposition.
+ ! Important for oxygen minimum zones (OMZs) and suboxic/anoxic environments.
+ !
+ ! Variables:
+ ! O2Func : Oxygen limitation factor [0-1, 0=anoxic, 1=oxic]
+ ! O2 : Dissolved oxygen concentration [mmolO2 m-3]
+ ! k_o2_remin : Half-saturation for O2-limited remineralization [mmolO2 m-3]
+ ! O2dep_remin : Flag to enable O2-dependent remineralization [logical]
+ !
+ ! Michaelis-Menten Formulation:
+ ! f(O2) = O2 / (k_O2 + O2)
+ !
+ ! Parameter Value:
+ ! k_o2_remin = 15 mmolO2 m-3 (half-saturation constant)
+ ! Range: 0-30 mmolO2 m-3 based on DeVries & Weber (2017), cited in Cram (2018)
+ !
+ ! Ecological/Biogeochemical Significance:
+ ! - Aerobic respiration dominates in oxic waters (O2 > 30 mmol m-3)
+ ! - Suboxic/anoxic metabolism (denitrification, sulfate reduction) in OMZs
+ ! - Reduced remineralization efficiency in low-O2 environments
+ ! - Important for nutrient cycling and carbon export in OMZs
+ !
+ ! Note: When O2 < 0.1 mmol m-3, consider switching to anaerobic pathways
+ ! (not implemented in this version)
+ !-------------------------------------------------------------------------------
+
+ ! Default: no oxygen limitation (fully oxic conditions)
+ O2Func = 1.d0
+
+ if (O2dep_remin) then
+ ! Enable oxygen-dependent remineralization
+ ! Michaelis-Menten type limitation
+ ! Becomes significant when O2 < ~30 mmol m-3
+ O2Func = O2 / (k_o2_remin + O2)
+ endif
+
+ !===============================================================================
+ ! LIGHT AVAILABILITY CALCULATION
+ !===============================================================================
+ ! Calculates photosynthetically available radiation (PAR) through the water
+ ! column using Beer-Lambert law with chlorophyll-based attenuation.
+ !
+ ! Light Attenuation Components:
+ ! 1. Water attenuation (k_w): Clear water absorption and scattering
+ ! 2. Chlorophyll attenuation (a_chl): Phytoplankton self-shading
+ !
+ ! Variables:
+ ! PARave : Average PAR at depth k [W m-2]
+ ! PAR(k) : Stored PAR for layer k [W m-2]
+ ! SurfSR : Surface solar radiation [W m-2]
+ ! chl_upper : Chlorophyll at upper layer boundary [mgChl m-3]
+ ! chl_lower : Chlorophyll at lower layer boundary [mgChl m-3]
+ ! Chlave : Average chlorophyll in layer [mgChl m-3]
+ ! kappa : Total attenuation coefficient [m-1]
+ ! kappastar : Angle-corrected attenuation coefficient [m-1]
+ ! k_w : Water attenuation coefficient [m-1]
+ ! a_chl : Chlorophyll-specific attenuation [(m2 mgChl-1)]
+ ! cosAI(n) : Cosine of solar zenith angle [-]
+ ! thick(k) : Layer thickness [m]
+ ! kdzLower : Cumulative optical depth [dimensionless]
+ ! kdzUpper : Cumulative optical depth at upper boundary [dimensionless]
+ !
+ ! Beer-Lambert Law:
+ ! I(z) = I0 × exp(-κ×z)
+ ! where κ = k_w + a_chl×[Chl]
+ !
+ ! Self-Shading Effect:
+ ! - High chlorophyll reduces light penetration
+ ! - Limits bloom depth and total biomass
+ ! - Creates trade-off between cell density and light availability
+ !
+ ! Ecological Significance:
+ ! - Defines euphotic zone depth (1% surface light)
+ ! - Controls vertical distribution of primary production
+ ! - Self-shading is key negative feedback on bloom magnitude
+ !-------------------------------------------------------------------------------
+
+ if (k == 1) then
+
+ !===========================================================================
+ ! SURFACE LAYER INITIALIZATION
+ !===========================================================================
+ ! Surface layer receives full incident solar radiation
+ ! Initialize chlorophyll and optical depth for subsurface calculations
+ !---------------------------------------------------------------------------
+
+ ! Surface PAR equals incident solar radiation
+ PARave = max(tiny, SurfSR)
+ PAR(k) = PARave
+
+ ! Initialize surface chlorophyll for attenuation calculation
+ ! Sum all phytoplankton functional types
+ chl_upper = (PhyChl + DiaChl) ! Base groups (always present)
+
+ if (enable_coccos) then
+ ! Add coccolithophores and Phaeocystis if enabled
+ chl_upper = chl_upper + CoccoChl + PhaeoChl
+ endif
+ else
+
+ !===========================================================================
+ ! SUBSURFACE LIGHT ATTENUATION
+ !===========================================================================
+ ! Calculate light penetration through water column using Beer-Lambert law
+ ! with chlorophyll-based self-shading
+ !---------------------------------------------------------------------------
+
+ !---------------------------------------------------------------------------
+ ! Calculate Current Layer Chlorophyll
+ !---------------------------------------------------------------------------
+
+ chl_lower = PhyChl + DiaChl
+
+ if (enable_coccos) then
+ chl_lower = chl_lower + CoccoChl + PhaeoChl
+ endif
+
+ ! Average chlorophyll between layer boundaries
+ ! Assumes linear interpolation within layer
+ Chlave = (chl_upper + chl_lower) * 0.5
+
+ !---------------------------------------------------------------------------
+ ! Calculate Attenuation Coefficient
+ !---------------------------------------------------------------------------
+
+ ! Total attenuation coefficient
+ ! k_w: Clear water absorption (~0.04 m-1 in ocean)
+ ! a_chl: Chlorophyll-specific attenuation (~0.03-0.05 m2 mgChl-1)
+ kappa = k_w + a_chl * Chlave
+
+ ! Correct for solar zenith angle (path length through water)
+ ! Lower sun angle -> longer path -> more attenuation
+ kappastar = kappa / cosAI(n)
+
+ ! Cumulative optical depth (dimensionless)
+ ! Integrates attenuation over depth
+ kdzLower = kdzUpper + kappastar * thick(k - 1)
+
+ !---------------------------------------------------------------------------
+ ! Calculate Light at Layer
+ !---------------------------------------------------------------------------
+
+ ! Beer-Lambert law: exponential decay with optical depth
+ Lowerlight = SurfSR * exp(-kdzLower)
+ Lowerlight = max(tiny, Lowerlight) ! Ensure positive value
+
+ ! Store PAR for this layer
+ PARave = Lowerlight
+ PAR(k) = PARave
+
+ ! Update variables for next layer
+ chl_upper = chl_lower ! Current lower becomes next upper
+ kdzUpper = kdzLower ! Current cumulative depth for next layer
+
+ end if
+
+ !===============================================================================
+ ! MARINE CARBONATE SYSTEM CALCULATIONS (MOCSY)
+ !===============================================================================
+ ! Calculates complete marine carbonate chemistry using the MOCSY package
+ ! (Marine Ocean Carbon System Solver).
+ !
+ ! This module calculates:
+ ! 1. Carbonate system speciation (CO2, HCO3-, CO3--)
+ ! 2. pH and partial pressure of CO2 (pCO2)
+ ! 3. Carbonate saturation states (Omega for calcite and aragonite)
+ ! 4. Solubility products and seawater properties
+ !
+ ! Key Features:
+ ! - Adaptive update frequency (depth-dependent)
+ ! - Euphotic zone: Weekly updates (high biological activity)
+ ! - Deep waters: Monthly updates (slower changes)
+ ! - Complete thermodynamic consistency
+ ! - Pressure correction for depth
+ !
+ ! MOCSY Package:
+ ! - Developed for OCMIP5 project
+ ! - Solves carbonate system from two known parameters
+ ! - Accounts for temperature, salinity, pressure effects
+ ! - Multiple equilibrium constant formulations available
+ !
+ ! Update Strategy:
+ ! - Initialize on first time step (mstep = 1)
+ ! - Euphotic zone (PAR > 1% surface): 7-day updates
+ ! - Deep waters (PAR < 1% surface): 30-day updates
+ ! - Rationale: Biological activity drives rapid changes near surface
+ !
+ ! Input Parameters:
+ ! - Temperature, Salinity (from physical model)
+ ! - DIC, Alkalinity (from biogeochemical tracers)
+ ! - Silicate, Phosphate (affects equilibrium constants)
+ ! - Atmospheric pressure, Latitude (for gas exchange)
+ !
+ ! Output Variables:
+ ! - pH, pCO2, fCO2 (CO2 partial and fugacity)
+ ! - CO2, HCO3-, CO3-- (carbonate species concentrations)
+ ! - OmegaC, OmegaA (calcite and aragonite saturation)
+ ! - Solubility products, seawater density
+ !
+ ! Ecological/Biogeochemical Significance:
+ ! - Controls CO2 uptake/release (air-sea exchange)
+ ! - Regulates calcification and dissolution rates
+ ! - Affects phytoplankton carbon acquisition
+ ! - Critical for ocean acidification studies
+ !
+ ! References:
+ ! - MOCSY: http://ocmip5.ipsl.jussieu.fr/mocsy/
+ ! - Orr & Epitalon (2015) - MOCSY 2.0 user guide
+ !===============================================================================
+
+ !===============================================================================
+ ! PREPARATION AND INITIALIZATION
+ !===============================================================================
+ ! Prepares input data and initializes carbonate system on first time step.
+ !
+ ! Variables:
+ ! dpos(1) : Depth for pressure calculations [m, positive down]
+ ! zF(k) : Model depth coordinate [m, negative down]
+ ! mstep : Model time step counter [-]
+ ! k : Vertical layer index [-]
+ !
+ ! Input Arrays for MOCSY:
+ ! REcoM_T_depth : Temperature [degC, potential temperature]
+ ! REcoM_S_depth : Salinity [psu, practical salinity]
+ ! REcoM_Alk_depth : Total alkalinity [mol m-3]
+ ! REcoM_DIC_depth : Dissolved inorganic carbon [mol m-3]
+ ! REcoM_Si_depth : Silicate concentration [mol m-3]
+ ! REcoM_Phos_depth : Phosphate concentration [mol m-3]
+ ! Patm_depth : Atmospheric pressure [atm]
+ ! Latd : Latitude [degrees]
+ ! Nmocsy : Number of points (1 for single depth)
+ !
+ ! Note: Depth convention conversion required (model uses negative depths)
+ !-------------------------------------------------------------------------------
+
+ ! Convert model depth coordinate to positive depth for MOCSY
+ ! Model convention: zF(k) is negative (e.g., -100 m)
+ ! MOCSY convention: depth is positive (e.g., 100 m)
dpos(1) = -zF(k)
- if (mstep==1) then
- call vars_sprac(ph_depth, pco2_depth, fco2_depth, co2_depth, hco3_depth, co3_depth, OmegaA_depth, OmegaC_depth, kspc_depth, BetaD_depth, &
- rhoSW_depth, p_depth, tempis_depth, &
- REcoM_T_depth, REcoM_S_depth, REcoM_Alk_depth, REcoM_DIC_depth, REcoM_Si_depth, REcoM_Phos_depth, Patm_depth, dpos, Latd, Nmocsy, &
- optCON='mol/m3', optT='Tpot ', optP='m ', optB='u74', optK1K2='l ', optKf='dg', optGAS='Pinsitu', optS='Sprc')
+
+ !===============================================================================
+ ! INITIAL CARBONATE SYSTEM CALCULATION
+ !===============================================================================
+ ! Calculates complete carbonate system on first model time step.
+ ! Provides initial conditions for all carbonate chemistry variables.
+ !
+ ! Output Variables (from MOCSY):
+ ! ph_depth(1) : pH on total scale [-]
+ ! pco2_depth(1) : Partial pressure of CO2 [μatm]
+ ! fco2_depth(1) : Fugacity of CO2 [μatm]
+ ! co2_depth(1) : Dissolved CO2 concentration [mol m-3]
+ ! hco3_depth(1) : Bicarbonate concentration [mol m-3]
+ ! co3_depth(1) : Carbonate ion concentration [mol m-3]
+ ! OmegaA_depth(1) : Aragonite saturation state [-]
+ ! OmegaC_depth(1) : Calcite saturation state [-]
+ ! kspc_depth(1) : Calcite solubility product [mol2 kg-2]
+ ! BetaD_depth(1) : Revelle factor (buffer capacity) [-]
+ ! rhoSW_depth(1) : Seawater density [kg m-3]
+ ! p_depth(1) : Pressure [bar]
+ ! tempis_depth(1) : In situ temperature [degC]
+ !
+ ! Water Column Storage:
+ ! CO2_watercolumn(k) : Stored CO2 for biological calculations [mol m-3]
+ ! pH_watercolumn(k) : Stored pH [-]
+ ! pCO2_watercolumn(k) : Stored pCO2 [μatm]
+ ! HCO3_watercolumn(k) : Stored bicarbonate [mol m-3]
+ ! CO3_watercolumn(k) : Stored carbonate [mol m-3]
+ ! OmegaC_watercolumn(k) : Stored calcite saturation [-]
+ ! kspc_watercolumn(k) : Stored solubility product [mol2 kg-2]
+ ! rhoSW_watercolumn(k) : Stored seawater density [kg m-3]
+ !
+ ! MOCSY Options:
+ ! optCON='mol/m3' : Concentration units (mol/m3)
+ ! optT='Tpot ' : Temperature is potential temperature
+ ! optP='m ' : Pressure given as depth in meters
+ ! optB='u74' : Boron:Salinity ratio from Uppström (1974)
+ ! optK1K2='l ' : Carbonic acid constants from Lueker et al. (2000)
+ ! optKf='dg' : HF constant from Dickson & Goyet (1994)
+ ! optGAS='Pinsitu' : Pressure is in situ (accounts for depth)
+ ! optS='Sprc' : Salinity on practical scale
+ !-------------------------------------------------------------------------------
+
+ if (mstep == 1) then
+
+ ! Call MOCSY to solve carbonate system
+ ! Uses DIC and Alkalinity as input pair (most common in ocean models)
+ call vars_sprac(ph_depth, pco2_depth, fco2_depth, co2_depth, hco3_depth, co3_depth, &
+ OmegaA_depth, OmegaC_depth, kspc_depth, BetaD_depth, &
+ rhoSW_depth, p_depth, tempis_depth, &
+ REcoM_T_depth, REcoM_S_depth, REcoM_Alk_depth, REcoM_DIC_depth, &
+ REcoM_Si_depth, REcoM_Phos_depth, Patm_depth, dpos, Latd, Nmocsy, &
+ optCON='mol/m3', optT='Tpot ', optP='m ', optB='u74', &
+ optK1K2='l ', optKf='dg', optGAS='Pinsitu', optS='Sprc')
+
+ ! Store results in water column arrays for use in biogeochemical calculations
CO2_watercolumn(k) = co2_depth(1)
pH_watercolumn(k) = ph_depth(1)
pCO2_watercolumn(k) = pco2_depth(1)
@@ -348,18 +1505,72 @@ subroutine REcoM_sms(n,Nn,state,thick,recipthick,SurfSR,sms,Temp, Sali_depth &
OmegaC_watercolumn(k) = OmegaC_depth(1)
kspc_watercolumn(k) = kspc_depth(1)
rhoSW_watercolumn(k) = rhoSW_depth(1)
- endif
-
-!! Calculate carbonate system every 7 days for depths < 1%PAR, and every 30 days for the depths below.
- mocsy_step_per_day = 1/dt_b ! NEW ms: time steps per day in recom -> is that correct? Not necessary to define in namelist?
- logfile_outfreq_7 = mocsy_step_per_day*7
- logfile_outfreq_30 = mocsy_step_per_day*30
-
- if (PARave > 0.01*SurfSR .and. mod(mstep,logfile_outfreq_7)==0) then
- call vars_sprac(ph_depth, pco2_depth, fco2_depth, co2_depth, hco3_depth, co3_depth, OmegaA_depth, OmegaC_depth, kspc_depth, BetaD_depth, &
- rhoSW_depth, p_depth, tempis_depth, &
- REcoM_T_depth, REcoM_S_depth, REcoM_Alk_depth, REcoM_DIC_depth, REcoM_Si_depth, REcoM_Phos_depth, Patm_depth, dpos, Latd, Nmocsy, &
- optCON='mol/m3', optT='Tpot ', optP='m ', optB='u74', optK1K2='l ', optKf='dg', optGAS='Pinsitu', optS='Sprc')
+
+ endif
+
+ !===============================================================================
+ ! ADAPTIVE CARBONATE SYSTEM UPDATE FREQUENCY
+ !===============================================================================
+ ! Determines how often to recalculate carbonate system based on depth.
+ ! More frequent updates where biological activity drives rapid changes.
+ !
+ ! Variables:
+ ! mocsy_step_per_day : Number of model time steps per day [-]
+ ! dt_b : Model time step [days]
+ ! logfile_outfreq_7 : Number of steps in 7 days [-]
+ ! logfile_outfreq_30 : Number of steps in 30 days [-]
+ ! PARave : Average photosynthetically active radiation [W m-2]
+ ! SurfSR : Surface solar radiation [W m-2]
+ !
+ ! Update Strategy:
+ ! - Euphotic zone (PAR > 1% surface): 7-day updates
+ ! * High photosynthesis rates alter DIC and pH rapidly
+ ! * Important for accurate phytoplankton CO2 responses
+ ! - Deep waters (PAR < 1% surface): 30-day updates
+ ! * Slower changes dominated by remineralization and mixing
+ ! * Reduces computational cost while maintaining accuracy
+ !
+ ! Computational Cost Considerations:
+ ! - Carbonate system solving is computationally expensive
+ ! - Adaptive frequency balances accuracy and performance
+ ! - Typical speedup: 4× faster than daily updates everywhere
+ !-------------------------------------------------------------------------------
+
+ ! Calculate update frequencies based on model time step
+ mocsy_step_per_day = 1.0 / dt_b
+ logfile_outfreq_7 = mocsy_step_per_day * 7.0 ! Steps in 7 days
+ logfile_outfreq_30 = mocsy_step_per_day * 30.0 ! Steps in 30 days
+
+ !===============================================================================
+ ! EUPHOTIC ZONE UPDATES (WEEKLY)
+ !===============================================================================
+ ! Frequent updates in sunlit surface waters where biological activity is high.
+ ! Euphotic zone defined as PAR > 1% of surface irradiance.
+ !
+ ! Biological Drivers:
+ ! - Photosynthesis removes DIC, increases pH
+ ! - Respiration/remineralization adds DIC, decreases pH
+ ! - Calcification removes alkalinity
+ ! - Rapid daily and seasonal cycles
+ !
+ ! Why 7-day updates?
+ ! - Captures weekly-scale biological dynamics
+ ! - Adequate for phytoplankton bloom progression
+ ! - Reasonable computational cost
+ !-------------------------------------------------------------------------------
+
+ if (PARave > 0.01 * SurfSR .and. mod(mstep, logfile_outfreq_7) == 0) then
+
+ ! Weekly updates in euphotic zone (high biological activity)
+ call vars_sprac(ph_depth, pco2_depth, fco2_depth, co2_depth, hco3_depth, co3_depth, &
+ OmegaA_depth, OmegaC_depth, kspc_depth, BetaD_depth, &
+ rhoSW_depth, p_depth, tempis_depth, &
+ REcoM_T_depth, REcoM_S_depth, REcoM_Alk_depth, REcoM_DIC_depth, &
+ REcoM_Si_depth, REcoM_Phos_depth, Patm_depth, dpos, Latd, Nmocsy, &
+ optCON='mol/m3', optT='Tpot ', optP='m ', optB='u74', &
+ optK1K2='l ', optKf='dg', optGAS='Pinsitu', optS='Sprc')
+
+ ! Update water column arrays with new carbonate chemistry
CO2_watercolumn(k) = co2_depth(1)
pH_watercolumn(k) = ph_depth(1)
pCO2_watercolumn(k) = pco2_depth(1)
@@ -369,11 +1580,39 @@ subroutine REcoM_sms(n,Nn,state,thick,recipthick,SurfSR,sms,Temp, Sali_depth &
kspc_watercolumn(k) = kspc_depth(1)
rhoSW_watercolumn(k) = rhoSW_depth(1)
- elseif (PARave < 0.01*SurfSR .and. mod(mstep,logfile_outfreq_30)==0) then
- call vars_sprac(ph_depth, pco2_depth, fco2_depth, co2_depth, hco3_depth, co3_depth, OmegaA_depth, OmegaC_depth, kspc_depth, BetaD_depth, &
- rhoSW_depth, p_depth, tempis_depth, &
- REcoM_T_depth, REcoM_S_depth, REcoM_Alk_depth, REcoM_DIC_depth, REcoM_Si_depth, REcoM_Phos_depth, Patm_depth, dpos, Latd, Nmocsy, &
- optCON='mol/m3', optT='Tpot ', optP='m ', optB='u74', optK1K2='l ', optKf='dg', optGAS='Pinsitu', optS='Sprc')
+ !===============================================================================
+ ! DEEP WATER UPDATES (MONTHLY)
+ !===============================================================================
+ ! Less frequent updates in dark deep waters where changes are slower.
+ ! Deep waters defined as PAR < 1% of surface irradiance.
+ !
+ ! Physical/Chemical Drivers:
+ ! - Slow remineralization of sinking organic matter
+ ! - Calcite dissolution (below saturation horizon)
+ ! - Mixing and advection
+ ! - No photosynthesis to drive rapid changes
+ !
+ ! Why 30-day updates?
+ ! - Changes occur on monthly to seasonal timescales
+ ! - Dominated by physical transport and slow remineralization
+ ! - Significant computational savings with minimal accuracy loss
+ !
+ ! Note: Below permanent pycnocline, even longer update intervals
+ ! could be justified (e.g., seasonal)
+ !-------------------------------------------------------------------------------
+
+ elseif (PARave < 0.01 * SurfSR .and. mod(mstep, logfile_outfreq_30) == 0) then
+
+ ! Monthly updates in deep waters (low biological activity)
+ call vars_sprac(ph_depth, pco2_depth, fco2_depth, co2_depth, hco3_depth, co3_depth, &
+ OmegaA_depth, OmegaC_depth, kspc_depth, BetaD_depth, &
+ rhoSW_depth, p_depth, tempis_depth, &
+ REcoM_T_depth, REcoM_S_depth, REcoM_Alk_depth, REcoM_DIC_depth, &
+ REcoM_Si_depth, REcoM_Phos_depth, Patm_depth, dpos, Latd, Nmocsy, &
+ optCON='mol/m3', optT='Tpot ', optP='m ', optB='u74', &
+ optK1K2='l ', optKf='dg', optGAS='Pinsitu', optS='Sprc')
+
+ ! Update water column arrays with new carbonate chemistry
CO2_watercolumn(k) = co2_depth(1)
pH_watercolumn(k) = ph_depth(1)
pCO2_watercolumn(k) = pco2_depth(1)
@@ -382,741 +1621,2408 @@ subroutine REcoM_sms(n,Nn,state,thick,recipthick,SurfSR,sms,Temp, Sali_depth &
OmegaC_watercolumn(k) = OmegaC_depth(1)
kspc_watercolumn(k) = kspc_depth(1)
rhoSW_watercolumn(k) = rhoSW_depth(1)
+
endif
-!-------------------------------------------------------------------------------
-! CO2 dependence of rates ! NEW CO2
-!-------------------------------------------------------------------------------
-! Convert pH to proton concentration
- h_depth(1) = 10.**(-ph_depth(1))
-! Conversion factor Cunits not needed for [H], because in model and function derived from pH and therefore in [mol/L]
+ if (NitrogenSS) then
+ ! This part has been developpes for R2OMIP for calculating bottom ocean OmegaC
+ nzmax=nlevels_nod2D(n)-1
+ nzmin=ulevels_nod2D(n)
+ k_bottom=nod_in_elem2D_num(n)
+
+ ! Screening minimum depth in neigbouring nodes around node n
+ nlevels_nod2D_minimum=minval(nlevels(nod_in_elem2D(1:k_bottom, n))-1)
+
+ if (k >= nlevels_nod2D_minimum .and. k < nzmax) then
+ OmegaC_bottom(n) = (OmegaC_depth(1) * (area(k,n)-area(k+1,n)) / area(k,n))
+
+ else if (k == nzmax) then
+ OmegaC_bottom(n) = (OmegaC_depth(1) * (area(k+1,n) / area(k,n)))
+ else
+ OmegaC_bottom(n) = 0.0_WP
+ end if
+ endif
+
+ !===============================================================================
+ ! CO2 EFFECTS AND CALCITE DISSOLUTION
+ !===============================================================================
+ ! Simulates ocean acidification impacts on phytoplankton growth and calcium
+ ! carbonate dissolution in the water column.
+ !
+ ! This module calculates:
+ ! 1. CO2/pH effects on phytoplankton photosynthesis (species-specific)
+ ! 2. Calcite dissolution rates (saturation-state or depth-dependent)
+ !
+ ! Key Features:
+ ! - Multi-component CO2 response (HCO3- benefit, CO2 toxicity, pH stress)
+ ! - Species-specific sensitivities to ocean acidification
+ ! - Two dissolution mechanisms (thermodynamic vs empirical)
+ ! - Velocity-dependent dissolution for sinking particles
+ !
+ ! CO2 Response Function:
+ ! f(CO2) = a×[HCO3-]/(b+[HCO3-]) - exp(-c×[CO2]) - d×[H+]
+ !
+ ! Three competing effects:
+ ! 1. HCO3- availability (substrate for carbon fixation) - POSITIVE
+ ! 2. High CO2 concentration (toxicity/stress) - NEGATIVE
+ ! 3. Low pH (proton stress on enzymes) - NEGATIVE
+ !
+ ! Phytoplankton Groups:
+ ! - Small phytoplankton: Moderate sensitivity
+ ! - Diatoms: Generally tolerant
+ ! - Coccolithophores: High sensitivity (calcifying organisms)
+ ! - Phaeocystis: Variable sensitivity
+ !
+ ! Dissolution Mechanisms:
+ ! A) Saturation-state dependent (OmegaC_diss = TRUE)
+ ! - Thermodynamically based on carbonate saturation
+ ! - Aumont et al. (2015) parameterization
+ ! B) Depth-dependent (OmegaC_diss = FALSE)
+ ! - Empirical dissolution rates scaled by sinking velocity
+ !
+ ! Ecological/Biogeochemical Significance:
+ ! - Ocean acidification reduces calcification and alters competitive balance
+ ! - Dissolution releases CO2 and alkalinity back to seawater
+ ! - Critical for understanding climate change impacts on marine ecosystems
+ !
+ ! References:
+ ! - Aumont et al. (2015) - Saturation-state dependent dissolution
+ ! - Schourup-Kristensen et al. (2013) - REcoM model description
+ !===============================================================================
+
+ !===============================================================================
+ ! CO2 EFFECTS ON PHYTOPLANKTON GROWTH
+ !===============================================================================
+ ! Calculates how ocean acidification (elevated CO2, reduced pH) affects
+ ! phytoplankton photosynthesis rates through a complex response function.
+ !
+ ! Response Function Components:
+ ! 1. Michaelis-Menten HCO3- uptake (carbonate benefit)
+ ! 2. Exponential CO2 inhibition (high CO2 toxicity)
+ ! 3. Linear H+ inhibition (pH stress on cellular processes)
+ !
+ ! Variables (Small Phytoplankton):
+ ! PhyCO2 : CO2 effect modifier for small phyto [0-3]
+ ! a_co2_phy : HCO3- uptake parameter [-]
+ ! b_co2_phy : HCO3- half-saturation [mmolC m-3]
+ ! c_co2_phy : CO2 inhibition coefficient [m3 mmolC-1]
+ ! d_co2_phy : H+ stress coefficient [L mol-1]
+ ! HCO3_watercolumn(k) : Bicarbonate concentration [mmolC m-3]
+ ! CO2_watercolumn(k) : Dissolved CO2 concentration [mmolC m-3]
+ ! pH_watercolumn(k) : Water column pH [-]
+ ! Cunits : Concentration units conversion factor [-]
+ ! h_depth(1) : Proton concentration at surface [mol L-1]
+ ! VTPhyCO2(k) : Diagnostic output for CO2 effect [-]
+ !
+ ! Constraints:
+ ! - Upper limit: 3× enhancement (April 2022 modification)
+ ! - Lower limit: 0 (no negative values, July 2022 modification)
+ !
+ ! Note: Similar calculations for diatoms, coccolithophores, and Phaeocystis
+ ! with species-specific parameters reflecting different sensitivities
+ !-------------------------------------------------------------------------------
+
+ ! Convert pH to proton concentration for calculations
+ ! pH = -log10[H+], therefore [H+] = 10^(-pH)
+ h_depth(1) = 10.d0**(-ph_depth(1))
+
+ ! Note: Cunits conversion not needed for [H+] because pH is already in mol/L
+
+ !-------------------------------------------------------------------------------
+ ! Small Phytoplankton CO2 Response
+ !-------------------------------------------------------------------------------
+ ! Moderate sensitivity to ocean acidification
+ ! Represents diverse group with varied carbon acquisition strategies
-! Small phytoplankton
PhyCO2 = a_co2_phy * HCO3_watercolumn(k) * Cunits / (b_co2_phy + HCO3_watercolumn(k) * Cunits) &
- - exp(-c_co2_phy * CO2_watercolumn(k) * Cunits) - d_co2_phy * 10.**(-pH_watercolumn(k))
- PhyCO2 = min(PhyCO2,3.d0) ! April 2022: limitation to 3
- PhyCO2 = max(0.d0,PhyCO2) ! July 2022: limitation to zero
+ - exp(-c_co2_phy * CO2_watercolumn(k) * Cunits) &
+ - d_co2_phy * 10.d0**(-pH_watercolumn(k))
+
+ ! Apply empirical constraints based on observations
+ PhyCO2 = min(PhyCO2, 3.d0) ! Upper limit: maximum 3x enhancement
+ PhyCO2 = max(0.d0, PhyCO2) ! Lower limit: prevent negative growth response
+
+ ! Store for diagnostics and output
+ VTPhyCO2(k) = PhyCO2
+
+ !-------------------------------------------------------------------------------
+ ! Diatoms CO2 Response
+ !-------------------------------------------------------------------------------
+ ! Generally tolerant to elevated CO2
+ ! Efficient carbon concentrating mechanisms (CCMs)
-! Diatoms
DiaCO2 = a_co2_dia * HCO3_watercolumn(k) * Cunits / (b_co2_dia + HCO3_watercolumn(k) * Cunits) &
- - exp(-c_co2_dia * CO2_watercolumn(k) * Cunits) - d_co2_dia * 10.**(-pH_watercolumn(k))
- DiaCO2 = min(DiaCO2,3.d0) ! April 2022: limitation to 3
- DiaCO2 = max(0.d0,DiaCO2) ! July 2022: limitation to zero
-
-#if defined (__coccos)
-! Coccolithophores
- CoccoCO2 = a_co2_cocco * HCO3_watercolumn(k) * Cunits / (b_co2_cocco + HCO3_watercolumn(k) * Cunits) &
- - exp(-c_co2_cocco * CO2_watercolumn(k) * Cunits) - d_co2_cocco * 10.**(-pH_watercolumn(k))
- CoccoCO2 = min(CoccoCO2,3.d0) ! April 2022: limitation to 3
- CoccoCO2 = max(0.d0,CoccoCO2) ! July 2022: limitation to zero
-#endif
-
-
-!------------------------------------------------------------------------------
-! Calcite dissolution dependent on OmegaC ! DISS
-!------------------------------------------------------------------------------
- Sink_Vel = Vdet_a* abs(zF(k)) + Vdet
-
- if (OmegaC_diss) then ! Calcdiss dependent on carbonate saturation
- Ca = (0.02128d0/40.078d0) * Sali_depth(k)/1.80655d0 ! Calcium ion concentration [mol/kg], function from varsolver.f90
- CO3_sat = (kspc_watercolumn(k) / Ca) * rhoSW_watercolumn(k) ! Saturated carbonate ion concentration, converted to [mol/m3]
- calc_diss = calc_diss_omegac * max(zero,(1-(CO3_watercolumn(k)/CO3_sat)))**(calc_diss_exp) ! Dissolution rate scaled by carbonate ratio, after Aumont et al. 2015
-#if defined (__3Zoo2Det)
- calc_diss2 = calc_diss
-#endif
- calc_diss_ben = calc_diss
- else ! Calcdiss dependent on depth
-
- calc_diss = calc_diss_rate * Sink_Vel/20.d0 ! Dissolution rate of CaCO3 scaled by the sinking velocity at the current depth
-#if defined (__3Zoo2Det)
-! calc_diss2 = calc_diss_rate2 ! Dissolution rate of CaCO3 scaled by the sinking velocity at the current depth seczoo
- calc_diss2 = calc_diss_rate2* Sink_Vel/20.d0
-#endif
- calc_diss_ben = calc_diss_rate * Sink_Vel/20.d0 ! DISS added the variable calc_diss_ben to keep the calcite dissolution in the benthos with the old formulation
+ - exp(-c_co2_dia * CO2_watercolumn(k) * Cunits) &
+ - d_co2_dia * 10.d0**(-pH_watercolumn(k))
+
+ ! Apply constraints
+ DiaCO2 = min(DiaCO2, 3.d0) ! Upper limit: 3x enhancement
+ DiaCO2 = max(0.d0, DiaCO2) ! Lower limit: no negative effect
+
+ ! Store for diagnostics
+ VTDiaCO2(k) = DiaCO2
+
+ if (enable_coccos) then
+
+ !---------------------------------------------------------------------------
+ ! Coccolithophores CO2 Response
+ !---------------------------------------------------------------------------
+ ! Calcifying phytoplankton - highly sensitive to ocean acidification
+ ! Both photosynthesis and calcification affected by carbonate chemistry
+ ! May be disadvantaged under future high-CO2 conditions
+
+ CoccoCO2 = a_co2_cocco * HCO3_watercolumn(k) * Cunits / (b_co2_cocco + HCO3_watercolumn(k) * Cunits) &
+ - exp(-c_co2_cocco * CO2_watercolumn(k) * Cunits) &
+ - d_co2_cocco * 10.d0**(-pH_watercolumn(k))
+
+ ! Apply constraints
+ CoccoCO2 = min(CoccoCO2, 3.d0) ! Upper limit: 3x enhancement
+ CoccoCO2 = max(0.d0, CoccoCO2) ! Lower limit: no negative effect
+
+ ! Store for diagnostics
+ VTCoccoCO2(k) = CoccoCO2
+
+ !---------------------------------------------------------------------------
+ ! Phaeocystis CO2 Response
+ !---------------------------------------------------------------------------
+ ! Colonial phytoplankton with variable CO2 sensitivity
+ ! Response may depend on bloom stage and environmental conditions
+
+ PhaeoCO2 = a_co2_phaeo * HCO3_watercolumn(k) * Cunits / (b_co2_phaeo + HCO3_watercolumn(k) * Cunits) &
+ - exp(-c_co2_phaeo * CO2_watercolumn(k) * Cunits) &
+ - d_co2_phaeo * 10.d0**(-pH_watercolumn(k))
+
+ ! Apply constraints
+ PhaeoCO2 = min(PhaeoCO2, 3.d0) ! Upper limit: 3× enhancement
+ PhaeoCO2 = max(0.d0, PhaeoCO2) ! Lower limit: no negative effect
+
+ ! Store for diagnostics
+ VTPhaeoCO2(k) = PhaeoCO2
+
endif
-!-------------------------------------------------------------------------------
-!> Photosynthesis section, light parameters and rates
-!-------------------------------------------------------------------------------
-!< Schourup 2013 Appendix A6.2
-!< Intracellular regulation of C uptake
-!< qlimitFac, qlimitFacTmp: Factor that regulates photosynthesis
-!< NMinSlope: 50.d0
-!< NCmin: 0.04d0
-!< quota: PhyN/PhyC
-!< qlimitFac [0.0, 1.0]
-!< if quota < NCmin qlimitFac=0
-!< if quota > ≈ 9 * NCmin qlimitFac=1
-!< P_cm: 3.0d0 [1/day], Rate of C-specific photosynthesis
-
-!< pMax = The carbon-specific, light-saturated rate of photosynthesis [day^-1]
-!< Nutrient limited environment
-!< Small pyhtoplankton is limited by iron and nitrogen
-!< Diatoms are additionally limited by silicon
-
-!< *** Small phytoplankton ***
-!< ***************************
- qlimitFac = recom_limiter(NMinSlope, NCmin, quota) ! Eqn A55
- feLimitFac = Fe/(k_Fe + Fe) ! Use Michaelis–Menten kinetics
- qlimitFac = min(qlimitFac, feLimitFac) ! Liebig law of the minimum
- pMax = P_cm * qlimitFac * arrFunc ! Maximum value of C-specific rate of photosynthesis
-
-!< *** Diatoms ***
-!< ***************
- qlimitFac = recom_limiter(NMinSlope, NCmin_d, quota_dia)
+
+ !===============================================================================
+ ! CALCITE DISSOLUTION
+ !===============================================================================
+ ! Calculates dissolution rates of calcium carbonate (CaCO3) in seawater.
+ ! Dissolution depends on carbonate saturation state or depth (two modes).
+ !
+ ! Carbonate Saturation State (Omega):
+ ! Ω = [CO3²⁻] / [CO3²⁻]sat
+ ! - Ω > 1: Supersaturated (favors precipitation, slow dissolution)
+ ! - Ω < 1: Undersaturated (favors dissolution)
+ !
+ ! Variables (Saturation-dependent mode):
+ ! calc_diss : Primary detritus dissolution rate [day-1]
+ ! calc_diss2 : Secondary detritus dissolution rate [day-1]
+ ! calc_diss_ben : Benthic dissolution rate [day-1]
+ ! calc_diss_omegac : Base dissolution rate coefficient [day-1]
+ ! calc_diss_exp : Dissolution order exponent [-]
+ ! Ca : Calcium ion concentration [mol kg-1]
+ ! CO3_sat : Saturated carbonate concentration [mol m-3]
+ ! CO3_watercolumn(k) : Actual carbonate concentration [mol m-3]
+ ! kspc_watercolumn(k) : Solubility product for calcite [mol2 kg-2]
+ ! rhoSW_watercolumn(k): Seawater density [kg m-3]
+ ! Sali_depth(k) : Salinity [psu]
+ !
+ ! Variables (Depth-dependent mode):
+ ! calc_diss_rate : Primary dissolution rate constant [day-1]
+ ! calc_diss_rate2 : Secondary dissolution rate constant [day-1]
+ ! Sink_Vel : Particle sinking velocity [m day-1]
+ ! Vdet_a : Depth-dependent sinking coefficient [day-1]
+ ! Vdet : Base sinking velocity [m day-1]
+ ! zF(k) : Depth at layer k [m]
+ !
+ ! Note: Dissolution releases CO2 and alkalinity, affecting carbonate chemistry
+ !-------------------------------------------------------------------------------
+
+ !-------------------------------------------------------------------------------
+ ! Calculate Sinking Velocity
+ !-------------------------------------------------------------------------------
+ ! Sinking velocity increases with depth (particle compaction, reduced drag)
+
+ Sink_Vel = Vdet_a * abs(zF(k)) + Vdet
+
+ if (OmegaC_diss) then
+
+ !===========================================================================
+ ! SATURATION-STATE DEPENDENT DISSOLUTION
+ !===========================================================================
+ ! Thermodynamically-based dissolution using carbonate saturation state
+ ! Based on Aumont et al. (2015) parameterization
+ !---------------------------------------------------------------------------
+
+ !---------------------------------------------------------------------------
+ ! Calculate Calcium Ion Concentration
+ !---------------------------------------------------------------------------
+ ! Conservative element: scales linearly with salinity
+ ! Reference: 0.02128 mol/kg at salinity 35 psu
+
+ Ca = (0.02128d0 / 40.078d0) * Sali_depth(k) / 1.80655d0
+
+ !---------------------------------------------------------------------------
+ ! Calculate Saturated Carbonate Ion Concentration
+ !---------------------------------------------------------------------------
+ ! [CO3²⁻]sat = Ksp / [Ca²+]
+ ! Where Ksp is the solubility product for calcite
+ ! Convert from mol/kg to mol/m3 using seawater density
+
+ CO3_sat = (kspc_watercolumn(k) / Ca) * rhoSW_watercolumn(k)
+
+ !---------------------------------------------------------------------------
+ ! Calculate Dissolution Rate
+ !---------------------------------------------------------------------------
+ ! Dissolution increases with undersaturation (Ω < 1)
+ ! Power law relationship: rate ∝ (1 - Ω)^n
+ ! Exponent (n) typically 1-4 depending on calcite form
+
+ calc_diss = calc_diss_omegac * max(zero, (1.0 - (CO3_watercolumn(k) / CO3_sat)))**(calc_diss_exp)
+
+ ! Apply same dissolution rate to all detritus types
+ ! Assumes similar calcite characteristics regardless of source
+ if (enable_3zoo2det) then
+ calc_diss2 = calc_diss ! Fast-sinking detritus
+ endif
+ calc_diss_ben = calc_diss ! Benthic detritus
+
+ else
+
+ !===========================================================================
+ ! DEPTH-DEPENDENT DISSOLUTION
+ !===========================================================================
+ ! Empirical dissolution rates scaled by sinking velocity
+ ! Simpler approach when carbonate chemistry is not fully resolved
+ !---------------------------------------------------------------------------
+
+ !---------------------------------------------------------------------------
+ ! Primary Detritus Dissolution
+ !---------------------------------------------------------------------------
+ ! Dissolution rate scales with sinking velocity
+ ! Faster sinking -> less time for dissolution per unit depth
+ ! Reference velocity: 20 m/day
+
+ calc_diss = calc_diss_rate * Sink_Vel / 20.d0
+
+ if (enable_3zoo2det) then
+ !-----------------------------------------------------------------------
+ ! Secondary Detritus Dissolution (Fast-sinking)
+ !-----------------------------------------------------------------------
+ ! May have different dissolution characteristics than primary detritus
+ ! (e.g., more compact, different organic coating)
+
+ calc_diss2 = calc_diss_rate2 * Sink_Vel / 20.d0
+ endif
+
+ !---------------------------------------------------------------------------
+ ! Benthic Dissolution
+ !---------------------------------------------------------------------------
+ ! Calcite reaching the sediment interface
+ ! Uses same rate as primary detritus
+
+ calc_diss_ben = calc_diss_rate * Sink_Vel / 20.d0
+
+ endif
+
+ !===============================================================================
+ ! PHOTOSYNTHESIS LIMITATION FACTORS
+ !===============================================================================
+ ! Calculates how nutrients, iron, and temperature limit maximum photosynthesis
+ ! rates using intracellular quota-based regulation (Droop model).
+ !
+ ! Limitation Approach:
+ ! - Intracellular regulation through N:C, Si:C quotas
+ ! - Michaelis-Menten iron limitation
+ ! - Liebig's law: most limiting factor controls growth
+ !
+ ! Variables (Small Phytoplankton):
+ ! qlimitFac : Combined nutrient limitation factor [0-1, 0=limited, 1=replete]
+ ! feLimitFac : Iron limitation factor [0-1]
+ ! quota : Phytoplankton N:C ratio [mmolN mmolC-1]
+ ! NCmin : Minimum N:C ratio (subsistence quota) [mmolN mmolC-1]
+ ! NMinSlope : Steepness of limitation curve [-]
+ ! Fe : Dissolved iron concentration [mmolFe m-3]
+ ! k_Fe : Half-saturation for Fe uptake [mmolFe m-3]
+ ! pMax : Maximum photosynthesis rate [day-1]
+ ! P_cm : Maximum rate constant [day-1]
+ ! Temp_phyto : Temperature function for small phyto [-]
+ ! arrFunc : Arrhenius temperature function [-]
+ !
+ ! recom_limiter Function:
+ ! Returns limitation factor based on quota:
+ ! - Returns ~0 when quota near minimum (severely limited)
+ ! - Returns ~1 when quota is high (nutrient replete)
+ ! - Smooth transition controlled by slope parameter
+ !
+ ! Note: Similar calculations for diatoms, coccolithophores, and Phaeocystis
+ ! with species-specific parameters and additional Si limitation for diatoms
+ !-------------------------------------------------------------------------------
+
+ !-------------------------------------------------------------------------------
+ ! Small Phytoplankton
+ !-------------------------------------------------------------------------------
+ ! Limited by nitrogen and iron
+ ! Represents small flagellates, small cyanobacteria, etc.
+
+ ! Nitrogen limitation based on intracellular N:C quota
+ qlimitFac = recom_limiter(NMinSlope, NCmin, quota)
+
+ ! Iron limitation using Michaelis-Menten kinetics
+ ! Iron is often the limiting micronutrient in HNLC regions
+ feLimitFac = Fe / (k_Fe + Fe)
+
+ ! Apply Liebig's law: most limiting nutrient controls photosynthesis
+ qlimitFac = min(qlimitFac, feLimitFac)
+
+ ! Track limitation
+ VTqlimitFac_phyto(k) = qlimitFac
+
+ ! Calculate maximum photosynthesis rate with temperature correction
+ if (enable_coccos) then
+ ! Use species-specific temperature function (when cocco module active)
+ pMax = qlimitFac * Temp_phyto
+ else
+ ! Use standard Arrhenius temperature function
+ pMax = P_cm * qlimitFac * arrFunc
+ endif
+
+ !-------------------------------------------------------------------------------
+ ! Diatoms
+ !-------------------------------------------------------------------------------
+ ! Limited by nitrogen, silicon, and iron
+ ! Large phytoplankton with silica frustules (shells)
+
+ ! Nitrogen limitation
+ qlimitFac = recom_limiter(NMinSlope, NCmin_d, quota_dia)
+
+ ! Silicon limitation (unique to diatoms)
+ ! Required for frustule formation - critical for diatom growth
qlimitFacTmp = recom_limiter(SiMinSlope, SiCmin, qSiC)
- qlimitFac = min(qLimitFac, qlimitFacTmp)
- feLimitFac = Fe/(k_Fe_d + Fe)
- qlimitFac = min(qlimitFac, feLimitFac)
- pMax_dia = P_cm_d * qlimitFac * arrFunc
-
-!< *** Coccolithophores ***
-!< ************************
-#if defined (__coccos)
- qlimitFac = recom_limiter(NMinSlope, NCmin_c, quota_cocco)
- feLimitFac = Fe/(k_Fe_c + Fe)
- qlimitFac = min(qlimitFac, feLimitFac)
- pMax_cocco = P_cm_c * qlimitFac * CoccoTFunc ! Here the T dependency is changed
-#endif
-!-------------------------------------------------------------------------------
-!< *** Small phytoplankton photosynthesis rate ***
-!< ***********************************************
- if (pMax .lt. tiny .OR. PARave /= PARave .OR. CHL2C /= CHL2C) then ! OG in case of only respiration, i.e. darkness??
+ qlimitFac = min(qlimitFac, qlimitFacTmp)
+
+ ! Iron limitation
+ feLimitFac = Fe / (k_Fe_d + Fe)
+ qlimitFac = min(qlimitFac, feLimitFac)
+
+ ! Track limitation
+ VTqlimitFac_diatoms(k) = qlimitFac
+
+ ! Calculate maximum photosynthesis rate
+ if (enable_coccos) then
+ pMax_dia = qlimitFac * Temp_diatoms
+ else
+ pMax_dia = P_cm_d * qlimitFac * arrFunc
+ endif
+
+ !-------------------------------------------------------------------------------
+ ! Coccolithophores (Optional)
+ !-------------------------------------------------------------------------------
+ ! Limited by nitrogen and iron
+ ! Calcifying phytoplankton that produce calcite plates
+
+ if (enable_coccos) then
+
+ ! Nitrogen limitation
+ qlimitFac = recom_limiter(NMinSlope, NCmin_c, quota_cocco)
+
+ ! Iron limitation
+ feLimitFac = Fe / (k_Fe_c + Fe)
+ qlimitFac = min(qlimitFac, feLimitFac)
+
+ ! Track limitation
+ VTqlimitFac_cocco(k) = qlimitFac
+
+ ! Calculate maximum photosynthesis rate
+ pMax_cocco = qlimitFac * Temp_cocco
+
+ !---------------------------------------------------------------------------
+ ! Phaeocystis (Optional)
+ !---------------------------------------------------------------------------
+ ! Limited by nitrogen and iron
+ ! Colonial phytoplankton that can form large blooms
+
+ ! Nitrogen limitation
+ qlimitFac = recom_limiter(NMinSlope, NCmin_p, quota_phaeo)
+
+ ! Iron limitation
+ feLimitFac = Fe / (k_Fe_p + Fe)
+ qlimitFac = min(qlimitFac, feLimitFac)
+
+ ! Track limitation
+ VTqlimitFac_phaeo(k) = qlimitFac
+
+ ! Calculate maximum photosynthesis rate
+ pMax_phaeo = qlimitFac * Temp_phaeo
+
+ endif
+
+ !===============================================================================
+ ! LIGHT-DEPENDENT PHOTOSYNTHESIS RATE CALCULATIONS
+ !===============================================================================
+ ! Calculates actual photosynthesis rates using photosynthesis-irradiance (P-I)
+ ! curves. Uses exponential saturation model (no photoinhibition).
+ !
+ ! P-I Curve Model:
+ ! P = Pmax × (1 - exp(-α × Chl:C × PAR / Pmax))
+ !
+ ! Where:
+ ! P : Actual photosynthesis rate [day-1]
+ ! Pmax : Maximum rate (nutrient and temperature limited) [day-1]
+ ! α : Initial slope of P-I curve (photosynthetic efficiency) [-]
+ ! Chl:C : Chlorophyll to carbon ratio [mgChl mmolC-1]
+ ! PAR : Photosynthetically active radiation [W m-2]
+ !
+ ! Variables (Small Phytoplankton):
+ ! Cphot : Carbon-specific photosynthesis rate [day-1]
+ ! PARave : Average PAR in mixed layer [W m-2]
+ ! alfa : Initial slope parameter [-]
+ ! Chl2C : Chlorophyll:Carbon ratio [mgChl mmolC-1]
+ ! PhyCO2 : CO2 limitation factor [0-1]
+ ! VTCphotLigLim_phyto : Light limitation factor for diagnostics [0-1]
+ ! VTCphot_phyto : Final photosynthesis rate for diagnostics [day-1]
+ !
+ ! Safety Checks:
+ ! - Check for darkness (pMax < tiny)
+ ! - Check for NaN values (PARave /= PARave)
+ ! - Check for valid Chl:C ratios
+ !
+ ! Note: Similar calculations for all phytoplankton types
+ !-------------------------------------------------------------------------------
+
+ !-------------------------------------------------------------------------------
+ ! Small Phytoplankton Photosynthesis
+ !-------------------------------------------------------------------------------
+
+ if (pMax < tiny .OR. PARave /= PARave .OR. CHL2C /= CHL2C) then
+ ! No photosynthesis in darkness or under invalid conditions
Cphot = zero
else
- Cphot = pMax*(real(one) - exp(-alfa * Chl2C * PARave / pMax))
- if (CO2lim) Cphot = Cphot * PhyCO2 ! Added the CO2 dependence
- end if
- if (Cphot .lt. tiny) Cphot = zero
+ ! Calculate photosynthesis using exponential P-I curve
+ ! Model saturates at high light (no photoinhibition)
+ Cphot = pMax * (1.0d0 - exp(-alfa * Chl2C * PARave / pMax))
+
+ ! Store light limitation factor for diagnostics
+ ! Ratio of actual to maximum rate indicates light limitation severity
+ VTCphotLigLim_phyto(k) = Cphot / pMax
+
+ ! Apply CO2 limitation if ocean acidification sensitivity is enabled
+ if (CO2lim) Cphot = Cphot * PhyCO2
+ endif
+
+ ! Ensure non-negative values (numerical safety)
+ if (Cphot < tiny) Cphot = zero
+
+ ! Store final photosynthesis rate for diagnostics and output
+ VTCphot_phyto(k) = Cphot
-!< *** Diatom photosynthesis rate ***
-!< **********************************
- if ( pMax_dia .lt. tiny .OR. PARave /= PARave .OR. CHL2C_dia /= CHL2C_dia) then
+ !-------------------------------------------------------------------------------
+ ! Diatom Photosynthesis
+ !-------------------------------------------------------------------------------
+
+ if (pMax_dia < tiny .OR. PARave /= PARave .OR. CHL2C_dia /= CHL2C_dia) then
Cphot_dia = zero
else
- Cphot_dia = pMax_dia * (real(one) - exp(-alfa_d * Chl2C_dia * PARave / pMax_dia))
- if (CO2lim) Cphot_dia = Cphot_dia * DiaCO2 ! Added the CO2 dependence
- end if
- if (Cphot_dia .lt. tiny) Cphot_dia = zero
-
-!< *** Coccolithophore photosynthesis rate ***
-!< *******************************************
-#if defined (__coccos)
- if ( pMax_cocco .lt. tiny .OR. Parave /= Parave .OR. CHL2C_cocco /= CHL2C_cocco) then
- Cphot_cocco = zero
- else
- Cphot_cocco = pMax_cocco * (real(one) - exp( -alfa_c * Chl2C_cocco * PARave / pMax_cocco))
- if (CO2lim) Cphot_cocco = Cphot_cocco * CoccoCO2 ! Added the CO2 dependence
- end if
- if (Cphot_cocco .lt. tiny) Cphot_cocco = zero
-#endif
-!-------------------------------------------------------------------------------
-!< chlorophyll degradation
-!-------------------------------------------------------------------------------
- KOchl = deg_Chl
- KOchl_dia = deg_Chl_d
-#if defined (__coccos)
- KOchl_cocco = deg_Chl_c
-#endif
-
+ ! Diatom P-I curve with species-specific parameters
+ Cphot_dia = pMax_dia * (1.0 - exp(-alfa_d * Chl2C_dia * PARave / pMax_dia))
+
+ ! Store light limitation diagnostic
+ VTCphotLigLim_diatoms(k) = Cphot_dia / pMax_dia
+
+ ! Apply CO2 limitation
+ if (CO2lim) Cphot_dia = Cphot_dia * DiaCO2
+ endif
+
+ if (Cphot_dia < tiny) Cphot_dia = zero
+ VTCphot_diatoms(k) = Cphot_dia
+
+ !-------------------------------------------------------------------------------
+ ! Coccolithophore Photosynthesis (Optional)
+ !-------------------------------------------------------------------------------
+
+ if (enable_coccos) then
+
+ if (pMax_cocco < tiny .OR. PARave /= PARave .OR. CHL2C_cocco /= CHL2C_cocco) then
+ Cphot_cocco = zero
+ else
+ ! Coccolithophore P-I curve
+ Cphot_cocco = pMax_cocco * (1.0 - exp(-alfa_c * Chl2C_cocco * PARave / pMax_cocco))
+
+ ! Store light limitation diagnostic
+ VTCphotLigLim_cocco(k) = Cphot_cocco / pMax_cocco
+
+ ! Apply CO2 limitation
+ if (CO2lim) Cphot_cocco = Cphot_cocco * CoccoCO2
+ endif
+
+ if (Cphot_cocco < tiny) Cphot_cocco = zero
+ VTCphot_cocco(k) = Cphot_cocco
+
+ !---------------------------------------------------------------------------
+ ! Phaeocystis Photosynthesis (Optional)
+ !---------------------------------------------------------------------------
+
+ if (pMax_phaeo < tiny .OR. PARave /= PARave .OR. CHL2C_phaeo /= CHL2C_phaeo) then
+ Cphot_phaeo = zero
+ else
+ ! Phaeocystis P-I curve
+ Cphot_phaeo = pMax_phaeo * (1.0 - exp(-alfa_p * Chl2C_phaeo * PARave / pMax_phaeo))
+
+ ! Store light limitation diagnostic
+ VTCphotLigLim_phaeo(k) = Cphot_phaeo / pMax_phaeo
+
+ ! Apply CO2 limitation
+ if (CO2lim) Cphot_phaeo = Cphot_phaeo * PhaeoCO2
+ endif
+
+ if (Cphot_phaeo < tiny) Cphot_phaeo = zero
+ VTCphot_phaeo(k) = Cphot_phaeo
+
+ endif
+
+ !===============================================================================
+ ! CHLOROPHYLL DEGRADATION
+ !===============================================================================
+ ! Calculates chlorophyll degradation rates with optional photodamage effects.
+ ! Chlorophyll degrades due to senescence and light-induced damage.
+ !
+ ! Two Modes:
+ ! A) Base degradation: Constant rate (use_photodamage = FALSE)
+ ! B) Photodamage-dependent: Light-dependent rate (use_photodamage = TRUE)
+ !
+ ! Variables:
+ ! KOchl : Chlorophyll degradation rate for small phyto [day-1]
+ ! KOchl_dia : Chlorophyll degradation rate for diatoms [day-1]
+ ! KOchl_cocco : Chlorophyll degradation rate for coccos [day-1]
+ ! KOchl_phaeo : Chlorophyll degradation rate for Phaeocystis [day-1]
+ ! deg_Chl : Base degradation rate constant [day-1]
+ ! CHL2C_plast : Chlorophyll:Carbon ratio in plastids [mgChl mmolC-1]
+ ! alfa : P-I curve initial slope [-]
+ ! PARave : Average PAR [W m-2]
+ ! pMax : Maximum photosynthesis rate [day-1]
+ !
+ ! Photodamage Model:
+ ! - High light damages photosystem II and degrades chlorophyll
+ ! - Uses same exponential form as P-I curve (saturating damage)
+ ! - Minimum degradation rate (10% of base) in darkness
+ ! - No upper cap (commented out safety constraint)
+ !
+ ! Note: Photodamage increases chlorophyll turnover at high light
+ ! This helps prevent photoinhibition and photooxidative stress
+ !-------------------------------------------------------------------------------
+
+ !-------------------------------------------------------------------------------
+ ! Set Base Chlorophyll Degradation Rates
+ !-------------------------------------------------------------------------------
+ ! Constant degradation rates independent of light (senescence)
+
+ KOchl = deg_Chl ! Small phytoplankton
+ KOchl_dia = deg_Chl_d ! Diatoms
+
+ if (enable_coccos) then
+ KOchl_cocco = deg_Chl_c ! Coccolithophores
+ KOchl_phaeo = deg_Chl_p ! Phaeocystis
+ endif
+
if (use_photodamage) then
-!< add a minimum value for photodamage
-!< *** Phytoplankton Chla loss ***
-!< *******************************
- if (pMax .lt. tiny .OR. PARave /= PARave .OR. CHL2C_plast /= CHL2C_plast) then
- KOchl = deg_Chl*0.1d0
+
+ !===========================================================================
+ ! PHOTODAMAGE-DEPENDENT DEGRADATION
+ !===========================================================================
+ ! Light-dependent chlorophyll degradation using saturation model
+ ! Higher light intensity increases chlorophyll turnover
+ !---------------------------------------------------------------------------
+
+ !---------------------------------------------------------------------------
+ ! Small Phytoplankton Chlorophyll Loss
+ !---------------------------------------------------------------------------
+
+ if (pMax < tiny .OR. PARave /= PARave .OR. CHL2C_plast /= CHL2C_plast) then
+ ! Minimum degradation in darkness (10% of base rate)
+ KOchl = deg_Chl * 0.1d0
else
- KOchl = deg_Chl*(real(one) - exp(-alfa * CHL2C_plast * PARave / pMax))
- KOchl = max((deg_Chl*0.1d0), KOchl)
+ ! Saturation model: degradation increases with light
+ ! Uses same exponential form as P-I curve
+ KOchl = deg_Chl * (real(one) - exp(-alfa * CHL2C_plast * PARave / pMax))
+
+ !< Alternative linear model (commented out):
+ !< Degradation directly proportional to light intensity
+ !KOchl = deg_Chl * CHL2C_plast * PARave
+
+ ! Ensure minimum degradation rate (10% of base)
+ KOchl = max((deg_Chl * 0.1d0), KOchl)
+
+ !< Safety constraint (commented out):
+ !< Caps maximum degradation at 0.3 day-1
+ !KOchl = min(KOchl, 0.3d0)
end if
-!< *** Diatoms Chla loss ***
-!< *************************
- if (pMax_dia .lt. tiny .OR. PARave /= PARave .OR. CHL2C_plast_dia /= CHL2C_plast_dia) then
- KOchl_dia = deg_Chl_d*0.1d0
+
+ !---------------------------------------------------------------------------
+ ! Diatom Chlorophyll Loss
+ !---------------------------------------------------------------------------
+
+ if (pMax_dia < tiny .OR. PARave /= PARave .OR. CHL2C_plast_dia /= CHL2C_plast_dia) then
+ KOchl_dia = deg_Chl_d * 0.1d0
else
- KOchl_dia = deg_Chl_d * (real(one) - exp(-alfa_d * CHL2C_plast_dia * PARave / pMax_dia ))
- KOchl_dia = max((deg_Chl_d*0.1d0), KOchl_dia)
- end if
-!< *** Coccolithophores chla loss ***
-!< **********************************
-#if defined (__coccos)
- if (pMax_cocco .lt. tiny .OR. PARave /= Parave .OR. CHL2C_plast_cocco /= CHL2C_plast_cocco) then
- KOchl_cocco = deg_Chl_c*0.1d0
- else
- KOchl_cocco = deg_Chl_c * (real(one) - exp( -alfa_c * CHL2C_plast_cocco * PARave / pMax_cocco ))
- KOchl_cocco = max((deg_Chl_c*0.1d0), KOchl_cocco)
- end if
-#endif
- if (KOchl /= KOchl) then
- print*,' KOchl is ', KOchl
- print*,' deg_Chl is ', deg_Chl
- print*,' alfa is ', alfa
- print*,' CHL2C is ', CHL2C_plast
- print*,' PARave is ', PARave
- print*,' pMax is ', pMax
- stop
+ ! Diatom-specific photodamage model
+ KOchl_dia = deg_Chl_d * (real(one) - exp(-alfa_d * CHL2C_plast_dia * PARave / pMax_dia))
+
+ !KOchl_dia = deg_Chl_d * CHL2C_plast_dia * PARave
+
+ KOchl_dia = max((deg_Chl_d * 0.1d0), KOchl_dia)
+ !KOchl_dia = min(KOchl_dia, 0.3d0)
end if
- if (KOchl_dia /= KOchl_dia) then
- print*,' KOchl_dia is ', KOchl_dia
- print*,' deg_Chl_d is ', deg_Chl_d
- print*,' alfa_d is ', alfa_d
- print*,' CHL2C_d is ', CHL2C_plast_dia
- print*,' PARave is ', PARave
- print*,' pMax_d is ', pMax_dia
+
+ if (enable_coccos) then
+
+ !-----------------------------------------------------------------------
+ ! Coccolithophore Chlorophyll Loss
+ !-----------------------------------------------------------------------
+
+ if (pMax_cocco < tiny .OR. PARave /= PARave .OR. CHL2C_plast_cocco /= CHL2C_plast_cocco) then
+ KOchl_cocco = deg_Chl_c * 0.1d0
+ else
+ ! Coccolithophore-specific photodamage model
+ KOchl_cocco = deg_Chl_c * (real(one) - exp(-alfa_c * CHL2C_plast_cocco * PARave / pMax_cocco))
+
+ !KOchl_cocco = deg_Chl_c * CHL2C_plast_cocco * PARave
+
+ KOchl_cocco = max((deg_Chl_c * 0.1d0), KOchl_cocco)
+ !KOchl_cocco = min(KOchl_cocco, 0.3d0)
+ end if
+
+ !-----------------------------------------------------------------------
+ ! Phaeocystis Chlorophyll Loss
+ !-----------------------------------------------------------------------
+
+ if (pMax_phaeo < tiny .OR. PARave /= PARave .OR. CHL2C_plast_phaeo /= CHL2C_plast_phaeo) then
+ KOchl_phaeo = deg_Chl_p * 0.1d0
+ else
+ ! Phaeocystis-specific photodamage model
+ KOchl_phaeo = deg_Chl_p * (real(one) - exp(-alfa_p * CHL2C_plast_phaeo * PARave / pMax_phaeo))
+
+ !KOchl_phaeo = deg_Chl_p * CHL2C_plast_phaeo * PARave
+
+ KOchl_phaeo = max((deg_Chl_p * 0.1d0), KOchl_phaeo)
+ !KOchl_phaeo = min(KOchl_phaeo, 0.3d0)
+ end if
+
+ endif ! enable_coccos
+
+ endif ! use_photodamage
+
+ !---------------------------------------------------------------------------
+ ! ERROR CHECKING AND DEBUGGING
+ ! Check for NaN values in chlorophyll degradation rates
+ !---------------------------------------------------------------------------
+
+ ! Small phytoplankton
+ if (KOchl /= KOchl) then
+ print*, 'ERROR: KOchl is NaN'
+ print*, ' deg_Chl =', deg_Chl
+ print*, ' alfa =', alfa
+ print*, ' CHL2C_plast =', CHL2C_plast
+ print*, ' PARave =', PARave
+ print*, ' pMax =', pMax
+ stop
+ end if
+
+ ! Diatoms
+ if (KOchl_dia /= KOchl_dia) then
+ print*, 'ERROR: KOchl_dia is NaN'
+ print*, ' deg_Chl_d =', deg_Chl_d
+ print*, ' alfa_d =', alfa_d
+ print*, ' CHL2C_plast_dia =', CHL2C_plast_dia
+ print*, ' PARave =', PARave
+ print*, ' pMax_dia =', pMax_dia
+ stop
+ end if
+
+ ! Additional species (if enabled)
+ if (enable_coccos) then
+ if (KOchl_cocco /= KOchl_cocco) then
+ print*, 'ERROR: KOchl_cocco is NaN'
+ print*, ' deg_Chl_c =', deg_Chl_c
+ print*, ' alfa_c =', alfa_c
+ print*, ' CHL2C_plast_cocco =', CHL2C_plast_cocco
+ print*, ' PARave =', PARave
+ print*, ' pMax_cocco =', pMax_cocco
stop
end if
-#if defined (__coccos)
- if (KOchl_cocco /= KOchl_cocco) then
- print*,' KOchl_cocco is ', KOchl_cocco
- print*,' deg_Chl_c is ', deg_Chl_c
- print*,' alfa_c is ', alfa_c
- print*,' CHL2C_c is ', CHL2C_plast_cocco
- print*,' PARave is ', PARave
- print*,' pMax_c is ', pMax_cocco
+
+ if (KOchl_phaeo /= KOchl_phaeo) then
+ print*, 'ERROR: KOchl_phaeo is NaN'
+ print*, ' deg_Chl_p =', deg_Chl_p
+ print*, ' alfa_p =', alfa_p
+ print*, ' CHL2C_plast_phaeo =', CHL2C_plast_phaeo
+ print*, ' PARave =', PARave
+ print*, ' pMax_phaeo =', pMax_phaeo
stop
- end if
-#endif
- end if ! photodamage
-
-!-------------------------------------------------------------------------------
-!> Assimilation section
-!-------------------------------------------------------------------------------
+ end if
+ endif
-!< Nitrogen and silicon part
-!< Compute assimilation from Geider et al 1998
-!< V_cm: Scaling factor for C-specific N uptake, dimensionless
-!< NCmax: Maximum cell quota of nitrogen (N:C) [mmol N/mmol C]
-!< NMaxSlope: Max slope for limiting function
-!< NCuptakeRatio: Maximum uptake ratio N:C [mmol N mmol C−1]
-!< SiCUptakeRatio: Maximum uptake ratio Si : C [mmol Si mmol C−1 ]
-!< The N:C ratio is taken into account, as a
-!! too high ratio indicates that the intracellular
-!! concentration of energy rich carbon molecules becomes too low to
-!! use energy on silicon uptake.
-
- V_cm = V_cm_fact
- limitFacN = recom_limiter(NMaxSlope, quota, NCmax)
- N_assim = V_cm * pMax * NCuptakeRatio & ! [mmol N / (mmol C * day)]
- * limitFacN * (DIN/(DIN + k_din)) ! Michaelis–Menten kinetics
-
- V_cm = V_cm_fact_d
- limitFacN_dia = recom_limiter(NMaxSlope, quota_dia, NCmax_d)
- N_assim_dia = V_cm * pMax_dia * NCUptakeRatio_d &
- * limitFacN_dia * DIN/(DIN + k_din_d)
-
-#if defined (__coccos)
- V_cm = V_cm_fact_c
+ !===============================================================================
+ ! PHYTOPLANKTON ASSIMILATION SECTION
+ !===============================================================================
+ ! Computes nutrient uptake, chlorophyll synthesis, and respiration rates
+ ! for multiple phytoplankton functional types following Geider et al. 1998
+ !===============================================================================
+
+ !===============================================================================
+ ! NITROGEN ASSIMILATION
+ !===============================================================================
+ ! Calculates nitrogen uptake rates for all phytoplankton groups based on
+ ! nutrient availability, cell quota status, and maximum uptake capacity
+ !
+ ! Key Parameters:
+ ! V_cm_fact : Scaling factor for C-specific N uptake [-]
+ ! NCmax : Maximum cell quota of nitrogen (N:C) [mmolN mmolC-1]
+ ! NMaxSlope : Maximum slope for quota limiting function [-]
+ ! NCuptakeRatio : Maximum uptake ratio N:C [mmolN mmolC-1]
+ ! k_din : Half-saturation constant for DIN uptake [mmolN m-3]
+ ! pMax : Maximum photosynthesis rate [day-1]
+ !
+ ! Note: Cell quota limiting function prevents luxury N uptake when internal
+ ! N:C ratio approaches maximum capacity
+ !-------------------------------------------------------------------------------
+
+ ! --- Small phytoplankton Nitrogen Uptake ---
+ V_cm = V_cm_fact
+ limitFacN = recom_limiter(NMaxSlope, quota, NCmax)
+ N_assim = V_cm * pMax * NCuptakeRatio * limitFacN * (DIN/(DIN + k_din))
+
+ ! --- Diatom Nitrogen Uptake ---
+ V_cm = V_cm_fact_d
+ limitFacN_dia = recom_limiter(NMaxSlope, quota_dia, NCmax_d)
+ N_assim_dia = V_cm * pMax_dia * NCUptakeRatio_d * limitFacN_dia * DIN/(DIN + k_din_d)
+
+ ! --- Optional Coccolithophore and Phaeocystis Groups ---
+ if (enable_coccos) then
+ ! Coccolithophore nitrogen uptake
+ V_cm = V_cm_fact_c
limitFacN_cocco = recom_limiter(NMaxSlope, quota_cocco, NCmax_c)
- N_assim_cocco = V_cm * pMax_cocco * NCUptakeRatio_c &
- * limitFacN_cocco * DIN/(DIN + k_din_c)
-#endif
+ N_assim_cocco = V_cm * pMax_cocco * NCUptakeRatio_c * limitFacN_cocco * &
+ DIN/(DIN + k_din_c)
+
+ ! Phaeocystis nitrogen uptake
+ V_cm = V_cm_fact_p
+ limitFacN_phaeo = recom_limiter(NMaxSlope, quota_phaeo, NCmax_p)
+ N_assim_phaeo = V_cm * pMax_phaeo * NCUptakeRatio_p * limitFacN_phaeo * &
+ DIN/(DIN + k_din_p)
+ endif
- limitFacSi = recom_limiter(SiMaxSlope, qSiC, SiCmax) &
- * limitFacN_dia
- Si_assim = V_cm_fact_d * P_cm_d * arrFunc * SiCUptakeRatio &
- * limitFacSi * Si/(Si + k_si)
+ !===============================================================================
+ ! SILICON ASSIMILATION (DIATOMS ONLY)
+ !===============================================================================
+ ! Calculates silicate uptake for diatom frustule formation
+ !
+ ! Key Parameters:
+ ! SiCUptakeRatio : Maximum uptake ratio Si:C [mmolSi mmolC-1]
+ ! SiCmax : Maximum cell quota of silicon (Si:C) [mmolSi mmolC-1]
+ ! SiMaxSlope : Maximum slope for Si quota limiting function [-]
+ ! k_si : Half-saturation constant for Si uptake [mmolSi m-3]
+ ! P_cm_d : Maximum photosynthesis rate for diatoms [day-1]
+ !
+ ! Note: Silicon uptake is coupled to nitrogen status - high N:C ratios indicate
+ ! low intracellular energy reserves, limiting energy-intensive Si uptake
+ !-------------------------------------------------------------------------------
+
+ limitFacSi = recom_limiter(SiMaxSlope, qSiC, SiCmax) * limitFacN_dia
+
+ if (.NOT. enable_coccos) then
+ ! Standard silicon assimilation formulation
+ Si_assim = V_cm_fact_d * P_cm_d * arrFunc * SiCUptakeRatio * limitFacSi * &
+ Si/(Si + k_si)
+ else
+ ! Alternative formulation with temperature dependence
+ Si_assim = V_cm_fact_d * Temp_diatoms * SiCUptakeRatio * limitFacSi * &
+ Si/(Si + k_si)
+ VTSi_assimDia(k) = Si_assim
+ endif
-!-------------------------------------------------------------------------------
-!< *** Iron chemistry ***
-!< **********************
-! select the method to calculate freeFe
- freeFe = iron_chemistry(Fe,totalligand,ligandStabConst)
-!-------------------------------------------------------------------------------
-!< *** Chlorophyll synthesis ***
-!< *****************************
+ !===============================================================================
+ ! 3. IRON CHEMISTRY
+ !===============================================================================
+ ! Computes free (bioavailable) iron concentration from total dissolved iron
+ ! accounting for complexation with organic ligands
+ !
+ ! Variables:
+ ! Fe : Total dissolved iron [µmol m-3]
+ ! totalligand : Total organic ligand concentration [µmol m-3]
+ ! ligandStabConst : Conditional stability constant [M-1]
+ ! freeFe : Free (inorganic) iron concentration [µmol m-3]
+ !-------------------------------------------------------------------------------
+
+ freeFe = iron_chemistry(Fe, totalligand, ligandStabConst)
+
+ !===============================================================================
+ ! 4. CHLOROPHYLL SYNTHESIS
+ !===============================================================================
+ ! Calculates chlorophyll production coupled to nitrogen assimilation
+ ! following photoacclimation theory (Geider et al. 1998)
+ !
+ ! Key Parameters:
+ ! Chl2N_max : Maximum Chl:N ratio [mg Chl mmolN-1]
+ ! Chl2C : Chlorophyll to carbon ratio [mg Chl mmolC-1]
+ ! alfa : Initial slope of P-I curve [mmolC (mg Chl)-1 m2 µmol-1 day-1]
+ ! Cphot : Carbon-specific photosynthesis rate [day-1]
+ ! PARave : Depth-averaged photosynthetically available radiation [µmol m-2 s-1]
+ !
+ ! Note: Chlorophyll synthesis is down-regulated when light is sufficient,
+ ! preventing over-investment in light-harvesting machinery
+ !-------------------------------------------------------------------------------
+
+ ! --- Small phytoplankton Chlorophyll Synthesis ---
+ chlSynth = zero
+ if (PARave >= tiny .AND. PARave == PARave) then
+ chlSynth = N_assim * Chl2N_max * &
+ min(real(one), Cphot/(alfa * Chl2C * PARave))
+ endif
-!< Coupled to N uptake
-!< Converted to chlorophyll units with a maximum Chl:N ratio, Chl2N_max
-!< Chl2N_max: Maximum Chl:N ratio for phytoplankton [mg Chl mmol N−1 ]
+ ! --- Diatom Chlorophyll Synthesis ---
+ ChlSynth_dia = zero
+ if (PARave >= tiny .AND. PARave == PARave) then
+ ChlSynth_dia = N_assim_dia * Chl2N_max_d * &
+ min(real(one), Cphot_dia / (alfa_d * Chl2C_dia * PARave))
+ end if
- chlSynth = zero
- if (PARave .ge. tiny .AND. PARave .eq. PARave) then
- chlSynth = N_assim * Chl2N_max &
- * min(real(one),Cphot/(alfa * Chl2C * PARave))
- end if
- ChlSynth_dia = zero
- if (PARave .ge. tiny .AND. PARave .eq. PARave) then
- ChlSynth_dia = N_assim_dia * Chl2N_max_d &
- * min(real(one),Cphot_dia /(alfa_d * Chl2C_dia * PARave))
- end if
+ ! --- Optional Coccolithophore and Phaeocystis Chlorophyll Synthesis ---
+ if (enable_coccos) then
+ ! Coccolithophore chlorophyll synthesis
ChlSynth_cocco = zero
-#if defined (__coccos)
- if (PARave .ge. tiny .AND. PARave .eq. PARave) then
- ChlSynth_cocco = N_assim_cocco * Chl2N_max_c &
- * min(real(one),Cphot_cocco /(alfa_c * Chl2C_cocco * PARave))
- end if
-#endif
-!-------------------------------------------------------------------------------
-!< *** Phytoplankton respiraion rate ***
-!< *************************************
+ if (PARave >= tiny .AND. PARave == PARave) then
+ ChlSynth_cocco = N_assim_cocco * Chl2N_max_c * &
+ min(real(one), Cphot_cocco / (alfa_c * Chl2C_cocco * PARave))
+ end if
-!< res_phy: Maintenance respiration rate constant [day−1 ]
-!< biosynth: The cost of biosynthesis of N [mmol C mmol N−1 ]
+ ! Phaeocystis chlorophyll synthesis
+ ChlSynth_phaeo = zero
+ if (PARave >= tiny .AND. PARave == PARave) then
+ ChlSynth_phaeo = N_assim_phaeo * Chl2N_max_p * &
+ min(real(one), Cphot_phaeo/(alfa_p * Chl2C_phaeo * PARave))
+ end if
+ endif
- phyRespRate = res_phy * limitFacN + biosynth * N_assim
- phyRespRate_dia = res_phy_d * limitFacN_dia + biosynth * N_assim_dia + biosynthSi * Si_assim
-#if defined (__coccos)
+ !===============================================================================
+ ! 5. PHYTOPLANKTON RESPIRATION RATES
+ !===============================================================================
+ ! Computes carbon loss through maintenance respiration and biosynthetic costs
+ !
+ ! Key Parameters:
+ ! res_phy : Maintenance respiration rate constant [day-1]
+ ! biosynth : Biosynthetic cost of nitrogen assimilation [mmolC mmolN-1]
+ ! biosynthSi : Biosynthetic cost of silicon assimilation [mmolC mmolSi-1]
+ !
+ ! Components:
+ ! 1. Maintenance respiration: Quota-dependent baseline metabolic cost
+ ! 2. Biosynthetic costs: Additional respiration for nutrient assimilation
+ !
+ ! Equation: R = res_phy * limitFacN + biosynth * N_assim + biosynthSi * Si_assim
+ !-------------------------------------------------------------------------------
+
+ ! --- Small phytoplankton Respiration ---
+ phyRespRate = res_phy * limitFacN + biosynth * N_assim
+
+ ! --- Diatom Respiration (includes silicon biosynthesis cost) ---
+ phyRespRate_dia = res_phy_d * limitFacN_dia + biosynth * N_assim_dia + &
+ biosynthSi * Si_assim
+
+ ! --- Optional Coccolithophore and Phaeocystis Respiration ---
+ if (enable_coccos) then
phyRespRate_cocco = res_phy_c * limitFacN_cocco + biosynth * N_assim_cocco
-#endif
+ phyRespRate_phaeo = res_phy_p * limitFacN_phaeo + biosynth * N_assim_phaeo
+ endif
-!-------------------------------------------------------------------------------
-! Mesozooplankton
-!-------------------------------------------------------------------------------
-!< Grazing on small phytoplankton, diatoms, coccolithophore (optional),
-!< microzooplankton (optional), slow- and fast-sinking detritus
-
-!< *** Food availability ***
-!< *************************
-!< pzPhy: Maximum nanophytoplankton preference
-!< pzDia: Maximum diatom preference
-!< pzCocco: Maximum coccolithophore preference
-!< pzDet: Maximum slow-sinking detritus prefence by first zooplankton
-!< pzDetZ2: Maximum fast-sinking detritus preference by first zooplankton
-!< pzMicZoo: Maximum microzooplankton preference by first zooplankton
-
- if (REcoM_Grazing_Variable_Preference) then ! CHECK ONUR
- aux = pzPhy*PhyN + pzDia*DiaN
- if (Grazing_detritus) aux = aux + PzDet*DetN
-#if defined (__3Zoo2Det)
- if (Grazing_detritus) aux = aux + pzDetZ2*DetZ2N ! 2Det
- aux = aux + pzMicZoo*MicZooN ! 3Zoo
-#endif
-#if defined (__coccos)
- aux = aux + pzCocco*CoccoN
-#endif
-! ******************************************************************************
- varpzPhy = (pzPhy*PhyN)/aux
- varpzDia = (pzDia*DiaN)/aux
- if (Grazing_detritus) varpzDet = (pzDet*DetN)/aux
-#if defined (__3Zoo2Det)
- if (Grazing_detritus) varpzDetZ2 = (pzDetZ2*DetZ2N)/aux ! 2Det
- varpzMicZoo = (pzMicZoo*MicZooN)/aux ! 3Zoo
-#endif
-#if defined (__coccos)
- varpzCocco = (pzCocco*CoccoN)/aux
-#endif
-! ******************************************************************************
- fDiaN = varpzDia * DiaN
- fPhyN = varpzPhy * PhyN
- if (Grazing_detritus) fDetN = varpzDet * DetN
-#if defined (__3Zoo2Det)
- if (Grazing_detritus) fDetZ2N = varpzDetZ2 * DetZ2N ! 2Det
- fMicZooN = varpzMicZoo * MicZooN ! 3Zoo
-#endif
-#if defined (__coccos)
- fCoccoN = varpzCocco * CoccoN
-#endif
- else ! REcoM_Grazing_Variable_Preference = .false.
- fPhyN = pzPhy * PhyN
- fDiaN = pzDia * DiaN
- if (Grazing_detritus) fDetN = pzDet * DetN
-#if defined (__3Zoo2Det)
- if (Grazing_detritus) fDetZ2N = pzDetZ2 * DetZ2N ! 2Det
- fMicZooN = pzMicZoo * MicZooN ! 3Zoo
-#endif
-#if defined (__coccos)
- fCoccoN = pzCocco * CoccoN
-#endif
- end if ! REcoM_Grazing_Variable_Preference
+ !===============================================================================
+ ! MESOZOOPLANKTON GRAZING
+ !===============================================================================
+ ! Simulates mesozooplankton grazing on multiple prey types using a Holling
+ ! Type III functional response with food-dependent preferences and efficiency.
+ !
+ ! This module calculates:
+ ! 1. Food availability and grazing preferences (fixed or variable)
+ ! 2. Total grazing flux with Holling Type III response
+ ! 3. Distribution of grazing among prey types
+ ! 4. Food-dependent grazing efficiency
+ ! 5. Carbon flux from grazed prey to mesozooplankton
+ !
+ ! Key Features:
+ ! - Variable or fixed prey preferences
+ ! - Optional prey types (coccolithophores, microzooplankton, detritus)
+ ! - Temperature-dependent grazing rate (Q10 or Arrhenius)
+ ! - Food-dependent assimilation efficiency
+ !
+ ! References:
+ ! - Schourup-Kristensen et al. (2013) - REcoM model description
+ !===============================================================================
+
+ !===============================================================================
+ ! 1. FOOD AVAILABILITY AND GRAZING PREFERENCES
+ !===============================================================================
+ ! Calculates which prey types are available and their relative preferences.
+ ! Two modes:
+ ! - Variable preferences: Adjust based on relative prey abundance
+ ! - Fixed preferences: Use constant maximum preference values
+ !
+ ! Variables:
+ ! pzPhy, pzDia : Max preference for small phyto and diatoms [-]
+ ! pzCocco, pzPhaeo: Max preference for coccoliths and Phaeocystis [-]
+ ! pzDet, pzDetZ2 : Max preference for slow/fast sinking detritus [-]
+ ! pzMicZoo : Max preference for microzooplankton [-]
+ ! PhyN, DiaN : Small phytoplankton and diatom nitrogen [mmolN m-3]
+ ! CoccoN, PhaeoN : Coccolithophore and Phaeocystis nitrogen [mmolN m-3]
+ ! DetN, DetZ2N : Slow and fast sinking detritus nitrogen [mmolN m-3]
+ ! MicZooN : Microzooplankton nitrogen [mmolN m-3]
+ ! varpz* : Variable preferences (calculated from availability) [-]
+ ! f*N : Available food pools (preference × concentration) [mmolN m-3]
+ ! aux : Total weighted food availability [mmolN m-3]
+ !
+ ! Logic:
+ ! IF variable preferences: varpz_i = (pz_i × prey_i) / Σ(pz_j × prey_j)
+ ! ELSE: Use fixed maximum preferences (pz_i)
+ ! Food pools: f_i = preference_i × prey_i
+ !-------------------------------------------------------------------------------
+
+ if (REcoM_Grazing_Variable_Preference) then
+ !---------------------------------------------------------------------------
+ ! VARIABLE PREFERENCE MODE
+ ! Preferences scale with relative abundance of each prey type
+ !---------------------------------------------------------------------------
+
+ ! Calculate total weighted food availability (denominator)
+ aux = pzPhy * PhyN + pzDia * DiaN
-!< *** Grazing fluxes ***
-!< **********************
- food = fPhyN + fDiaN
- if (Grazing_detritus) food = food + fDetN
-#if defined (__3Zoo2Det)
- if (Grazing_detritus) food = food + fDetZ2N
- food = food + fMicZooN ! 3Zoo
-#endif
-#if defined (__coccos)
- food = food + fCoccoN
-#endif
-! ******************************************************************************
- foodsq = food**2
- grazingFlux = (Graz_max * foodsq)/(epsilonr + foodsq) * HetN * arrFunc
-#if defined (__3Zoo2Det)
- grazingFlux = (Graz_max * foodsq)/(epsilonr + foodsq) * HetN * q10_mes
-#endif
- grazingFlux_phy = grazingFlux * fphyN / food
- grazingFlux_Dia = grazingFlux * fDiaN / food
- if (Grazing_detritus) grazingFlux_Det = grazingFlux * fDetN / food
-#if defined (__3Zoo2Det)
- if (Grazing_detritus) grazingFlux_DetZ2 = grazingFlux * fDetZ2N / food
- grazingFlux_miczoo = grazingFlux * fMicZooN / food ! 3Zoo
-#endif
-#if defined (__coccos)
- grazingFlux_Cocco = grazingFlux * fCoccoN / food
-#endif
-
-!< *** Grazing efficiency ***
-!< **************************
- grazEff = gfin + 1/(0.2*food + 2)
-
- grazingFluxcarbon_mes = (grazingFlux_phy * recipQuota * grazEff) &
- + (grazingFlux_Dia * recipQuota_Dia * grazEff)
-
- if (Grazing_detritus) grazingFluxcarbon_mes = grazingFluxcarbon_mes &
- + (grazingFlux_Det * recipDet * grazEff)
-#if defined (__3Zoo2Det)
- if (Grazing_detritus) grazingFluxcarbon_mes = grazingFluxcarbon_mes &
- + (grazingFlux_DetZ2 * recipDet2 * grazEff)
- grazingFluxcarbon_mes = grazingFluxcarbon_mes &
- + (grazingFlux_miczoo * recipQZoo3 * grazEff) ! 3Zoo
-#endif
-#if defined (__coccos)
- grazingFluxcarbon_mes = grazingFluxcarbon_mes &
- + (grazingFlux_Cocco * recipQuota_Cocco * grazEff)
-#endif
+ if (Grazing_detritus) then
+ aux = aux + pzDet * DetN
+ endif
-!-------------------------------------------------------------------------------
-! Second Zooplankton
-!-------------------------------------------------------------------------------
-!< Grazing on small phytoplankton, diatoms, coccolithophore (optional),
-!< heterotrophs, slow- and fast-sinking detritus
-
-!< *** Food availability ***
-!< *************************
-!< pzPhy2: Maximum nanophytoplankton preference
-!< pzDia2: Maximum diatom preference
-!< pzCocco2: Maximum coccolithophore preference
-!< pzDet2: Maximum slow-sinking detritus prefence
-!< pzDetZ22: Maximum fast-sinking detritus preference
-!< pzHet: Maximum mesozooplankton preference
-!< pzMicZoo2: Maximum microzooplankton preference
-
-#if defined (__3Zoo2Det)
- if (REcoM_Grazing_Variable_Preference) then
- aux = pzPhy2 * PhyN + PzDia2 * DiaN + pzHet * HetN
- if (Grazing_detritus) aux = aux + pzDet2 * DetN + pzDetZ22 * DetZ2N
- aux = aux + pzMicZoo2 * MicZooN ! 3Zoo
-#if defined (__coccos)
- aux = aux + pzCocco2 * CoccoN
-#endif
-! ******************************************************************************
- varpzPhy2 = (pzPhy2 * PhyN)/aux
- varpzDia2 = (pzDia2 * DiaN)/aux
- varpzMicZoo2 = (pzMicZoo2 * MicZooN)/aux ! 3Zoo
-
-#if defined (__coccos)
- varpzCocco2 = (pzCocco2 * CoccoN)/aux
-#endif
- varpzHet = (pzHet * HetN)/aux
- if (Grazing_detritus) then
- varpzDet2 = (pzDet2 * DetN)/aux
- varpzDetZ22 = (pzDetZ22 * DetZ2N)/aux
- end if
-! ******************************************************************************
- fDiaN2 = varpzDia2 * DiaN
- fPhyN2 = varpzPhy2 * PhyN
- fMicZooN2 = varpzMicZoo2 * MicZooN ! 3Zoo
-#if defined (__coccos)
- fCoccoN2 = varpzCocco2 * CoccoN
-#endif
- fHetN = varpzHet * HetN
- if (Grazing_detritus) then
- fDetN2 = varpzDet2 * DetN
- fDetZ2N2 = varpzDetZ22 * DetZ2N
- end if
- else ! REcoM_Grazing_Variable_Preference = .false.
-
- fDiaN2 = pzDia2 * DiaN
- fPhyN2 = pzPhy2 * PhyN
- fMicZooN2 = pzMicZoo2 * MicZooN ! 3Zoo
-#if defined (__coccos)
- fCoccoN2 = pzCocco2 * CoccoN
-#endif
- fHetN = pzHet * HetN
- if (Grazing_detritus) then
- fDetN2 = pzDet2 * DetN
- fDetZ2N2 = pzDetZ22 * DetZ2N
- end if
- end if ! REcoM_Grazing_Variable_Preference
+ if (enable_3zoo2det) then
+ if (Grazing_detritus) aux = aux + pzDetZ2 * DetZ2N ! Fast-sinking detritus
+ aux = aux + pzMicZoo * MicZooN ! Microzooplankton
+ endif
-!< *** Grazing fluxes ***
-!< **********************
- food2 = fPhyN2 + fDiaN2 + fHetN
- if (Grazing_detritus) food2 = food2 + fDetN2 + fDetZ2N2
- food2 = food2 + fMicZooN2 ! 3Zoo
-#if defined (__coccos)
- food2 = food2 + fCoccoN2
-#endif
-! ******************************************************************************
- foodsq2 = food2**2
- grazingFlux2 = (Graz_max2 * foodsq2)/(epsilon2 + foodsq2) * Zoo2N * arrFuncZoo2
+ if (enable_coccos) then
+ aux = aux + pzCocco * CoccoN + pzPhaeo * PhaeoN
+ endif
- grazingFlux_phy2 = (grazingFlux2 * fphyN2)/food2
- grazingFlux_Dia2 = (grazingFlux2 * fDiaN2)/food2
- grazingFlux_miczoo2 = (grazingFlux2 * fMicZooN2)/food2 ! 3Zoo
+ ! Calculate variable preferences (normalized by total availability)
+ varpzPhy = (pzPhy * PhyN) / aux
+ varpzDia = (pzDia * DiaN) / aux
-#if defined (__coccos)
- grazingFlux_Cocco2 = (grazingFlux2 * fCoccoN2)/food2
-#endif
- grazingFlux_het2 = (grazingFlux2 * fHetN)/food2
if (Grazing_detritus) then
- grazingFlux_Det2 = (grazingFlux2 * fDetN2)/food2
- grazingFlux_DetZ22 = (grazingFlux2 * fDetZ2N2)/food2
- end if
+ varpzDet = (pzDet * DetN) / aux
+ endif
+
+ if (enable_3zoo2det) then
+ if (Grazing_detritus) varpzDetZ2 = (pzDetZ2 * DetZ2N) / aux
+ varpzMicZoo = (pzMicZoo * MicZooN) / aux
+ endif
+
+ if (enable_coccos) then
+ varpzCocco = (pzCocco * CoccoN) / aux
+ varpzPhaeo = (pzPhaeo * PhaeoN) / aux
+ endif
+
+ ! Calculate available food pools (preference × concentration)
+ fPhyN = varpzPhy * PhyN
+ fDiaN = varpzDia * DiaN
- grazingFluxcarbonzoo2 = (grazingFlux_phy2 * recipQuota * grazEff2) &
- + (grazingFlux_Dia2 * recipQuota_Dia * grazEff2) &
- + (grazingFlux_het2 * recipQZoo * grazEff2)
if (Grazing_detritus) then
- grazingFluxcarbonzoo2 = grazingFluxcarbonzoo2 + &
- + (grazingFlux_Det2 * recipDet * grazEff2) &
- + (grazingFlux_DetZ22 * recipDet2 * grazEff2)
- end if
- grazingFluxcarbonzoo2 = grazingFluxcarbonzoo2 + &
- + (grazingFlux_miczoo2 * recipQZoo3 * grazEff2) ! 3Zoo
-#if defined (__coccos)
- grazingFluxcarbonzoo2 = grazingFluxcarbonzoo2 + &
- + (grazingFlux_Cocco2 * recipQuota_Cocco * grazEff2)
-#endif
+ fDetN = varpzDet * DetN
+ endif
-!-------------------------------------------------------------------------------
-! Third Zooplankton (Microzooplankton)
-!-------------------------------------------------------------------------------
-!< Grazing on small phytoplankton, diatoms and coccolithophore (optional)
+ if (enable_3zoo2det) then
+ if (Grazing_detritus) fDetZ2N = varpzDetZ2 * DetZ2N
+ fMicZooN = varpzMicZoo * MicZooN
+ endif
-!< *** Food availability ***
-!< *************************
-!< pzPhy3: Maximum nanophytoplankton preference
-!< pzDia3: Maximum diatom preference
-!< pzCocco3: Maximum coccolithophore preference
+ if (enable_coccos) then
+ fCoccoN = varpzCocco * CoccoN
+ fPhaeoN = varpzPhaeo * PhaeoN
+ endif
- if (REcoM_Grazing_Variable_Preference) then
- aux = pzPhy3 * PhyN + pzDia3 * DiaN
-#if defined (__coccos)
- aux = aux + pzCocco3 * CoccoN
-#endif
-! ******************************************************************************
- varpzPhy3 = (pzPhy3 * PhyN)/aux
- varpzDia3 = (pzDia3 * DiaN)/aux
-#if defined (__coccos)
- varpzCocco3 = (pzCocco3 * CoccoN)/aux
-#endif
-! ******************************************************************************
- fPhyN3 = varpzPhy3 * PhyN
- fDiaN3 = varpzDia3 * DiaN
-#if defined (__coccos)
- fCoccoN3 = varpzCocco3 * CoccoN
-#endif
- else ! REcoM_Grazing_Variable_Preference = .false.
-
- fPhyN3 = pzPhy3 * PhyN
- fDiaN3 = pzDia3 * DiaN
-#if defined (__coccos)
- fCoccoN3 = pzCocco3 * CoccoN
-#endif
- endif !REcoM_Grazing_Variable_Preference
-
-!< *** Grazing fluxes ***
-!< **********************
- food3 = fPhyN3 + fDiaN3
-#if defined (__coccos)
- food3 = food3 + fCoccoN3
-#endif
-! ******************************************************************************
- foodsq3 = food3**2
- grazingFlux3 = (Graz_max3 * foodsq3)/(epsilon3 + foodsq3) * MicZooN * q10_mic
- grazingFlux_phy3 = (grazingFlux3 * fphyN3)/food3
- grazingFlux_Dia3 = (grazingFlux3 * fDiaN3)/food3
-#if defined (__coccos)
- grazingFlux_Cocco3 = (grazingFlux3 * fCoccoN3)/food3
-#endif
-#endif
+ else
+ !---------------------------------------------------------------------------
+ ! FIXED PREFERENCE MODE
+ ! Use constant maximum preference values
+ !---------------------------------------------------------------------------
-!-------------------------------------------------------------------------------
-!< Heterotrophic respiration is assumed to drive zooplankton back to
-!< Redfield C:N if their C:N becomes higher than Redfield
-!< res_het: Timescale for zooplankton respiration [day−1 ]
-
- if (het_resp_noredfield) then
-#if defined (__3Zoo2Det)
- HetRespFlux = res_het * q10_mes_res * HetC ! 3Zoo
-#else
- HetRespFlux = res_het * arrFunc * HetC ! tau * f_T [HetC]
-#endif
- else
- HetRespFlux = recip_res_het * arrFunc * (hetC * recip_hetN_plus - redfield) * HetC
- HetRespFlux = max(zero, HetRespFlux) !!!!!!!! CHECK Judith Valid for het_resp_noredfield case as well ???????? Then move it below
+ fPhyN = pzPhy * PhyN
+ fDiaN = pzDia * DiaN
+
+ if (Grazing_detritus) then
+ fDetN = pzDet * DetN
endif
+ if (enable_3zoo2det) then
+ if (Grazing_detritus) fDetZ2N = pzDetZ2 * DetZ2N
+ fMicZooN = pzMicZoo * MicZooN
+ endif
-!-------------------------------------------------------------------------------
-!< Zooplanton mortality (Quadratic)
+ if (enable_coccos) then
+ fCoccoN = pzCocco * CoccoN
+ fPhaeoN = pzPhaeo * PhaeoN
+ endif
- hetLossFlux = loss_het * HetN * HetN
+ endif ! REcoM_Grazing_Variable_Preference
+
+ !===============================================================================
+ ! 2. TOTAL GRAZING FLUX (HOLLING TYPE III)
+ !===============================================================================
+ ! Calculates total grazing rate using a sigmoidal (Type III) functional response.
+ ! This creates a threshold effect where grazing accelerates at higher food levels.
+ !
+ ! Variables:
+ ! food : Total available food [mmolN m-3]
+ ! foodsq : Squared food concentration [mmolN2 m-6]
+ ! grazingFlux : Total N grazing rate [mmolN m-3 day-1]
+ ! Graz_max : Maximum specific grazing rate [day-1]
+ ! epsilonr : Half-saturation constant squared [mmolN2 m-6]
+ ! HetN : Mesozooplankton nitrogen concentration [mmolN m-3]
+ ! q10_mes : Q10 temperature function for mesozooplankton [-]
+ ! arrFunc : Arrhenius temperature function [-]
+ !
+ ! Equation: Holling Type III
+ ! grazingFlux = (Graz_max × food²) / (epsilonr + food²) × HetN × T_func
+ !
+ ! Note: Uses Q10 when 3-zoo/2-detritus enabled, otherwise uses Arrhenius
+ !-------------------------------------------------------------------------------
+
+ ! Sum all available food pools
+ food = fPhyN + fDiaN
-#if defined (__3Zoo2Det)
-!-------------------------------------------------------------------------------
-!< Second zooplankton respiration
+ if (Grazing_detritus) then
+ food = food + fDetN
+ endif
- call krill_resp(n, partit, mesh)
+ if (enable_3zoo2det) then
+ if (Grazing_detritus) food = food + fDetZ2N
+ food = food + fMicZooN
+ endif
- if((grazingFluxcarbonzoo2/Zoo2C) <= 0.1)then
- res_zoo2_f = 0.1*(grazingFluxcarbonzoo2/Zoo2C*100)
- else
- res_zoo2_f = 1.
- end if
- recip_res_zoo22 = res_zoo2*(1.+ res_zoo2_f + res_zoo2_a)
- Zoo2RespFlux = recip_res_zoo22 * Zoo2C
-!-------------------------------------------------------------------------------
-!< Second zooplankton mortality (Quadratic)
+ if (enable_coccos) then
+ food = food + fCoccoN + fPhaeoN
+ endif
- Zoo2LossFlux = loss_zoo2 * zoo2N * zoo2N
+ ! Calculate grazing flux with Holling Type III functional response
+ foodsq = food**2
-!-------------------------------------------------------------------------------
-!< Second zooplankton fecal pellets
+ if (enable_3zoo2det) then
+ grazingFlux = (Graz_max * foodsq) / (epsilonr + foodsq) * HetN * q10_mes
+ else
+ grazingFlux = (Graz_max * foodsq) / (epsilonr + foodsq) * HetN * arrFunc
+ endif
- Zoo2fecalloss_n = fecal_rate_n * grazingFlux2
- Zoo2fecalloss_c = fecal_rate_c * grazingFluxcarbonzoo2
+ !===============================================================================
+ ! 3. GRAZING FLUX DISTRIBUTION
+ !===============================================================================
+ ! Partitions total grazing among prey types proportional to their availability.
+ !
+ ! Variables:
+ ! grazingFlux_phy : Grazing on small phytoplankton [mmolN m-3 day-1]
+ ! grazingFlux_Dia : Grazing on diatoms [mmolN m-3 day-1]
+ ! grazingFlux_Det : Grazing on slow-sinking detritus [mmolN m-3 day-1]
+ ! grazingFlux_DetZ2 : Grazing on fast-sinking detritus [mmolN m-3 day-1]
+ ! grazingFlux_miczoo : Grazing on microzooplankton [mmolN m-3 day-1]
+ ! grazingFlux_Cocco : Grazing on coccolithophores [mmolN m-3 day-1]
+ ! grazingFlux_Phaeo : Grazing on Phaeocystis [mmolN m-3 day-1]
+ !
+ ! Equation for each prey type i:
+ ! grazingFlux_i = grazingFlux × (f_i / total_food)
+ !-------------------------------------------------------------------------------
+
+ grazingFlux_phy = grazingFlux * fPhyN / food
+ grazingFlux_Dia = grazingFlux * fDiaN / food
-!-------------------------------------------------------------------------------
-!< Mesozooplankton fecal pellets
+ if (Grazing_detritus) then
+ grazingFlux_Det = grazingFlux * fDetN / food
+ endif
- mesfecalloss_n = fecal_rate_n_mes * grazingFlux
- mesfecalloss_c = fecal_rate_c_mes * grazingFluxcarbon_mes
+ if (enable_3zoo2det) then
+ if (Grazing_detritus) grazingFlux_DetZ2 = grazingFlux * fDetZ2N / food
+ grazingFlux_miczoo = grazingFlux * fMicZooN / food
+ endif
-!-------------------------------------------------------------------------------
-! Third zooplankton, microzooplankton, respiration ! 3Zoo
+ if (enable_coccos) then
+ grazingFlux_Cocco = grazingFlux * fCoccoN / food
+ grazingFlux_Phaeo = grazingFlux * fPhaeoN / food
+ endif
- MicZooRespFlux = res_miczoo * q10_mic_res * MicZooC
-!-------------------------------------------------------------------------------
-! Third zooplankton, microzooplankton, mortality (Quadratic) ! 3Zoo
+ !===============================================================================
+ ! 4. GRAZING EFFICIENCY AND CARBON FLUX
+ !===============================================================================
+ ! Calculates food-dependent assimilation efficiency and converts grazed nitrogen
+ ! to carbon flux using prey-specific C:N ratios.
+ !
+ ! Variables:
+ ! grazEff : Grazing/assimilation efficiency [-]
+ ! gfin : Baseline grazing efficiency [-]
+ ! grazingFluxcarbon_mes : Total carbon flux to mesozooplankton [mmolC m-3 day-1]
+ ! recipQuota : Small phytoplankton C:N ratio [mmolC mmolN-1]
+ ! recipQuota_Dia : Diatom C:N ratio [mmolC mmolN-1]
+ ! recipQuota_Cocco : Coccolithophore C:N ratio [mmolC mmolN-1]
+ ! recipQuota_phaeo : Phaeocystis C:N ratio [mmolC mmolN-1]
+ ! recipDet, recipDet2 : Detritus C:N ratios [mmolC mmolN-1]
+ ! recipQZoo3 : Microzooplankton C:N ratio [mmolC mmolN-1]
+ !
+ ! Grazing Efficiency Equation:
+ ! grazEff = gfin + 1/(0.2×food + 2)
+ ! Higher food -> higher efficiency (asymptotes to gfin + 0.5)
+ !
+ ! Carbon Flux Equation:
+ ! C_flux = Σ(grazingFlux_i × C:N_ratio_i × grazEff)
+ !-------------------------------------------------------------------------------
+
+ ! Calculate food-dependent grazing efficiency
+ ! Increases with food availability, representing improved assimilation at higher rations
+ grazEff = gfin + 1.0 / (0.2 * food + 2.0)
+
+ ! Convert grazed nitrogen to carbon flux using prey C:N ratios
+ grazingFluxcarbon_mes = (grazingFlux_phy * recipQuota * grazEff) + &
+ (grazingFlux_Dia * recipQuota_Dia * grazEff)
- MicZooLossFlux = loss_miczoo * MicZooN * MicZooN
-#endif
+ if (Grazing_detritus) then
+ grazingFluxcarbon_mes = grazingFluxcarbon_mes + &
+ (grazingFlux_Det * recipDet * grazEff)
+ endif
-!-------------------------------------------------------------------------------
-! Phytoplankton and detritus aggregation
-!-------------------------------------------------------------------------------
- if (diatom_mucus) then
- qlimitFac = recom_limiter(NMinSlope, NCmin_d, quota_dia)
- qlimitFacTmp = recom_limiter(SiMinSlope, SiCmin, qSiC)
- qlimitFac = min(qLimitFac, qlimitFacTmp)
- feLimitFac= Fe/(k_Fe_d + Fe)
- qlimitFac = min(qlimitFac, feLimitFac)
- aggregationrate = agg_PP * (1 - qlimitFac) * DiaN
- else
- aggregationrate = agg_PP * DiaN
+ if (enable_3zoo2det) then
+ if (Grazing_detritus) then
+ grazingFluxcarbon_mes = grazingFluxcarbon_mes + &
+ (grazingFlux_DetZ2 * recipDet2 * grazEff)
endif
-
- aggregationrate = aggregationrate + agg_PD * DetN + agg_PP * PhyN
-
-#if defined (__3Zoo2Det)
- aggregationrate = aggregationrate + agg_PD * DetZ2N ! 2Det
-#endif
-#if defined (__coccos)
- aggregationrate = aggregationrate + agg_PP * CoccoN
-#endif
-
-!-------------------------------------------------------------------------------
-! Calcification
-!-------------------------------------------------------------------------------
-! Terms required for the formation and dissolution of CaCO3
-! Without this, calcification is performed by a fraction of small phytoplankton
+ grazingFluxcarbon_mes = grazingFluxcarbon_mes + &
+ (grazingFlux_miczoo * recipQZoo3 * grazEff)
+ endif
+
+ if (enable_coccos) then
+ grazingFluxcarbon_mes = grazingFluxcarbon_mes + &
+ (grazingFlux_Cocco * recipQuota_Cocco * grazEff) + &
+ (grazingFlux_Phaeo * recipQuota_phaeo * grazEff)
+ endif
+
+ !===============================================================================
+ ! MACROZOOPLANKTON GRAZING
+ !===============================================================================
+ ! Simulates macrozooplankton (second zooplankton) grazing on multiple prey types
+ ! using a Holling Type II functional response with food-dependent preferences.
+ !
+ ! This module calculates:
+ ! 1. Food availability and grazing preferences (fixed or variable)
+ ! 2. Total grazing flux with Holling Type II response
+ ! 3. Distribution of grazing among prey types
+ ! 4. Carbon assimilation from grazed prey using C:N ratios
+ !
+ ! Key Features:
+ ! - Carnivorous feeding: grazes on mesozooplankton and microzooplankton
+ ! - Herbivorous feeding: grazes on phytoplankton, diatoms, coccolithophores
+ ! - Detritivorous feeding: optional grazing on slow/fast-sinking detritus
+ ! - Variable or fixed prey preferences
+ ! - Temperature-dependent grazing rate (Arrhenius)
+ ! - Constant assimilation efficiency (grazEff2)
+ !
+ ! Prey Types:
+ ! - Primary: Mesozooplankton, microzooplankton, small phyto, diatoms
+ ! - Optional: Coccolithophores, Phaeocystis, slow/fast-sinking detritus
+ !
+ ! References:
+ ! - Schourup-Kristensen et al. (2013) - REcoM model description
+ !===============================================================================
+
+ if (enable_3zoo2det) then
+
+ !===========================================================================
+ ! 1. FOOD AVAILABILITY AND GRAZING PREFERENCES
+ !===========================================================================
+ ! Calculates which prey types are available and their relative preferences.
+ ! Two modes:
+ ! - Variable preferences: Adjust based on relative prey abundance
+ ! - Fixed preferences: Use constant maximum preference values
+ !
+ ! Variables:
+ ! pzPhy2, pzDia2 : Max preference for small phyto and diatoms [-]
+ ! pzCocco2, pzPhaeo2: Max preference for coccoliths and Phaeocystis [-]
+ ! pzHet : Max preference for mesozooplankton [-]
+ ! pzMicZoo2 : Max preference for microzooplankton [-]
+ ! pzDet2, pzDetZ22 : Max preference for slow/fast sinking detritus [-]
+ ! PhyN, DiaN : Small phytoplankton and diatom nitrogen [mmolN m-3]
+ ! CoccoN, PhaeoN : Coccolithophore and Phaeocystis nitrogen [mmolN m-3]
+ ! HetN : Mesozooplankton nitrogen [mmolN m-3]
+ ! MicZooN : Microzooplankton nitrogen [mmolN m-3]
+ ! DetN, DetZ2N : Slow and fast sinking detritus nitrogen [mmolN m-3]
+ ! varpz*2, varpzHet: Variable preferences (calculated from availability) [-]
+ ! f*N2, fHetN : Available food pools (preference × concentration) [mmolN m-3]
+ ! aux : Total weighted food availability [mmolN m-3]
+ !
+ ! Logic:
+ ! IF variable preferences: varpz_i = (pz_i × prey_i) / Σ(pz_j × prey_j)
+ ! ELSE: Use fixed maximum preferences (pz_i)
+ ! Food pools: f_i = preference_i × prey_i
+ !---------------------------------------------------------------------------
+
+ if (REcoM_Grazing_Variable_Preference) then
+ !-----------------------------------------------------------------------
+ ! VARIABLE PREFERENCE MODE
+ ! Preferences scale with relative abundance of each prey type
+ !-----------------------------------------------------------------------
+
+ ! Calculate total weighted food availability (denominator)
+ ! Core prey: phytoplankton, diatoms, meso- and microzooplankton
+ aux = pzPhy2 * PhyN + pzDia2 * DiaN + pzHet * HetN + pzMicZoo2 * MicZooN
+
+ ! Add detritus pools if detrital grazing is enabled
+ if (Grazing_detritus) then
+ aux = aux + pzDet2 * DetN + pzDetZ22 * DetZ2N
+ endif
+
+ ! Add coccolithophores and Phaeocystis if enabled
+ if (enable_coccos) then
+ aux = aux + pzCocco2 * CoccoN + pzPhaeo2 * PhaeoN
+ endif
+
+ ! Calculate variable preferences (normalized by total availability)
+ ! Each preference = (max_pref × prey_conc) / total_weighted_food
+ varpzPhy2 = (pzPhy2 * PhyN) / aux
+ varpzDia2 = (pzDia2 * DiaN) / aux
+ varpzMicZoo2 = (pzMicZoo2 * MicZooN) / aux
+ varpzHet = (pzHet * HetN) / aux
+
+ if (enable_coccos) then
+ varpzCocco2 = (pzCocco2 * CoccoN) / aux
+ varpzPhaeo2 = (pzPhaeo2 * PhaeoN) / aux
+ endif
+
+ if (Grazing_detritus) then
+ varpzDet2 = (pzDet2 * DetN) / aux
+ varpzDetZ22 = (pzDetZ22 * DetZ2N) / aux
+ end if
+
+ ! Calculate available food pools (preference × concentration)
+ fPhyN2 = varpzPhy2 * PhyN
+ fDiaN2 = varpzDia2 * DiaN
+ fMicZooN2 = varpzMicZoo2 * MicZooN
+ fHetN = varpzHet * HetN
+
+ if (enable_coccos) then
+ fCoccoN2 = varpzCocco2 * CoccoN
+ fPhaeoN2 = varpzPhaeo2 * PhaeoN
+ endif
+
+ if (Grazing_detritus) then
+ fDetN2 = varpzDet2 * DetN
+ fDetZ2N2 = varpzDetZ22 * DetZ2N
+ end if
-#if defined (__coccos)
- if (Temp(k) < 10.6) then ! (PICPOC definition after Krumhardt et al. 2017, 2019; Temp(k) because we need degC here)
- PICPOCtemp = 0.104d0 * Temp(k) - 0.108d0
else
- PICPOCtemp = 1.0d0
- end if
- PICPOCtemp = max(tiny,PICPOCtemp)
-
- PICPOCCO2 = a_co2_calc * HCO3_watercolumn(k) * Cunits / (b_co2_calc + HCO3_watercolumn(k) * Cunits) - exp(-c_co2_calc * CO2_watercolumn(k) * Cunits) - d_co2_calc * 10.**(-pH_watercolumn(k))
- PICPOCCO2 = min(PICPOCCO2,3.d0) ! April 2022: limitation to 3
- PICPOCCO2 = max(0.d0,PICPOCCO2) ! July 2022: limitation to zero
-
- PICPOCN = -0.31 * (DIN/(DIN + k_din_c)) + 1.31
- PICPOCN = max(tiny,PICPOCN)
-
- calcification = 1.d0 * Cphot_cocco * CoccoC * PICPOCtemp * PICPOCN
- if (CO2lim) calcification = calcification * PICPOCCO2
-
-#else
-!< calc_prod_ratio: Calcite production ratio, dimensionless
- calcification = calc_prod_ratio * Cphot * PhyC ! Z in equations
-#endif
-
- calc_loss_agg = aggregationrate * PhyCalc
-
-#if defined (__coccos)
-!< *** Coccolithophores ***
-!< ************************
- aux = recipQuota_Cocco/(CoccoC + tiny) * PhyCalc
- calc_loss_gra = grazingFlux_Cocco * aux
-#if defined (__3Zoo2Det)
- calc_loss_gra2 = grazingFlux_Cocco2 * aux
- calc_loss_gra3 = grazingFlux_Cocco3 * aux ! 3Zoo
-#endif
-
-#else
-!< *** Small phytoplankton ***
-!< ***************************
- aux = recipQuota/(PhyC + tiny) * PhyCalc
- calc_loss_gra = grazingFlux_phy * aux
-#if defined (__3Zoo2Det)
- calc_loss_gra2 = grazingFlux_phy2 * aux
- calc_loss_gra3 = grazingFlux_phy3 * aux ! 3Zoo
-#endif
-#endif
-!-------------------------------------------------------------------------------
-! Sources minus sinks (SMS)
-!-------------------------------------------------------------------------------
+ !-----------------------------------------------------------------------
+ ! FIXED PREFERENCE MODE
+ ! Use constant maximum preference values
+ !-----------------------------------------------------------------------
+
+ fPhyN2 = pzPhy2 * PhyN
+ fDiaN2 = pzDia2 * DiaN
+ fMicZooN2 = pzMicZoo2 * MicZooN
+ fHetN = pzHet * HetN
-!< *** DIN ***
-!< ***********
-
-!< N_assim: N assimilation rate for nanophytoplankton [mmolN mmolC-1 day-1]
-!< PhyC: Intracellular carbon concentration in nanophytoplankton [mmolC m-3]
-!< N_assim_Dia: N assimilation rate for diatoms [mmolN mmolC-1 day-1]
-!< DiaC: Intracellular carbon concentration in diatoms [mmolC m-3]
-!< N_assim_Cocco: N assimilation rate for coccolithophore [mmolN mmolC-1 day-1]
-!< CoccoC: Intracellular carbon concentration in coccolithophore [mmolC m-3]
-!< rho_N*arrFunc: Remineralization rate and temperature dependency which is calculated with arrFunc [day^-1]
-!< O2Func: O2 dependency of organic matter remineralization
-!< DON: Extracellular dissolved organic nitrogen [mmolN m-3]
-!< dt_b: REcoM time step [day]
-
-!! Schourup 2013 Eq. A2
-
- sms(k,idin) = ( &
- - N_assim * PhyC & ! --> N assimilation Nanophytoplankton, [mmol N/(mmol C * day)] C specific N utilization rate
- - N_assim_Dia * DiaC & ! --> N assimilation Diatoms
-#if defined (__coccos)
- - N_assim_Cocco * CoccoC & ! --> N assimilation Coccolithophore
-#endif
- + rho_N * arrFunc * O2Func * DON & ! --> DON remineralization, temperature dependent [day^-1 * mmol/m3] ! O2remin
- ) * dt_b + sms(k,idin)
-
-!< *** DIC ***
-!< ***********
-
-!< rho_C1: Temperature dependent C degradation of extracellular organic C (EOC) [day^-1]
-
- sms(k,idic) = ( &
- - Cphot * PhyC & ! --> Small pyhtoplankton photosynthesis
- + phyRespRate * PhyC & ! --> Small pyhtoplankton respiration
- - Cphot_Dia * DiaC & ! --> Diatom photosynthesis
- + phyRespRate_Dia * DiaC & ! --> Diatom respiration
-#if defined (__coccos)
- - Cphot_Cocco * CoccoC & ! --> Coccolithophore photosynthesis
- + phyRespRate_Cocco * CoccoC & ! --> Coccolithophore respiration
-#endif
- + rho_C1 * arrFunc * O2Func * EOC & ! --> Remineralization of DOC ! NEW O2remin
- + HetRespFlux & ! --> Mesozooplankton respiration
-#if defined (__3Zoo2Det)
- + Zoo2RespFlux & ! --> Macrozooplankton respiration
- + MicZooRespFlux & ! --> Microzooplankton respiration
-#endif
- + calc_diss * DetCalc & ! --> Calcite dissolution from slow-sinking detritus
- + calc_loss_gra * calc_diss_guts & ! --> Additional dissolution in mesozooplankton guts
-#if defined (__3Zoo2Det)
- + calc_loss_gra2 * calc_diss_guts & ! --> Additional dissolution in macrozooplankton guts
- + calc_loss_gra3 * calc_diss_guts & ! --> Additional dissolution in microzooplankton guts
- + calc_diss2 * DetZ2Calc & ! --> Calcite dissolution from fast-sinking detritus
-#endif
- - calcification & ! --> Calcification
- ) * dt_b + sms(k,idic)
+ if (enable_coccos) then
+ fCoccoN2 = pzCocco2 * CoccoN
+ fPhaeoN2 = pzPhaeo2 * PhaeoN
+ endif
+
+ if (Grazing_detritus) then
+ fDetN2 = pzDet2 * DetN
+ fDetZ2N2 = pzDetZ22 * DetZ2N
+ end if
+
+ end if ! REcoM_Grazing_Variable_Preference
+
+ !===========================================================================
+ ! 2. TOTAL GRAZING FLUX (HOLLING TYPE II)
+ !===========================================================================
+ ! Calculates total grazing rate using a hyperbolic (Type II) functional
+ ! response. This creates saturating grazing at high food concentrations.
+ !
+ ! Variables:
+ ! food2 : Total available food [mmolN m-3]
+ ! foodsq2 : Squared food concentration [mmolN2 m-6]
+ ! grazingFlux2 : Total N grazing rate [mmolN m-3 day-1]
+ ! Graz_max2 : Maximum specific grazing rate [day-1]
+ ! epsilon2 : Half-saturation constant squared [mmolN2 m-6]
+ ! Zoo2N : Macrozooplankton nitrogen concentration [mmolN m-3]
+ ! arrFuncZoo2 : Arrhenius temperature function for macrozooplankton [-]
+ !
+ ! Equation: Holling Type II
+ ! grazingFlux2 = (Graz_max2 × food²) / (epsilon2 + food²) × Zoo2N × T_func
+ !
+ ! Note: Uses Arrhenius temperature dependency (arrFuncZoo2)
+ !---------------------------------------------------------------------------
+
+ ! Sum all available food pools
+ food2 = fPhyN2 + fDiaN2 + fHetN + fMicZooN2
+
+ if (Grazing_detritus) then
+ food2 = food2 + fDetN2 + fDetZ2N2
+ endif
+
+ if (enable_coccos) then
+ food2 = food2 + fCoccoN2 + fPhaeoN2
+ endif
+
+ ! Calculate grazing flux with Holling Type II functional response
+ ! Type II uses squared food (similar to Type III but with different parameters)
+ foodsq2 = food2**2
+ grazingFlux2 = (Graz_max2 * foodsq2) / (epsilon2 + foodsq2) * Zoo2N * arrFuncZoo2
+
+ !===========================================================================
+ ! 3. GRAZING FLUX DISTRIBUTION
+ !===========================================================================
+ ! Partitions total grazing among prey types proportional to their availability.
+ !
+ ! Variables:
+ ! grazingFlux_phy2 : Grazing on small phytoplankton [mmolN m-3 day-1]
+ ! grazingFlux_Dia2 : Grazing on diatoms [mmolN m-3 day-1]
+ ! grazingFlux_miczoo2 : Grazing on microzooplankton [mmolN m-3 day-1]
+ ! grazingFlux_het2 : Grazing on mesozooplankton [mmolN m-3 day-1]
+ ! grazingFlux_Cocco2 : Grazing on coccolithophores [mmolN m-3 day-1]
+ ! grazingFlux_Phaeo2 : Grazing on Phaeocystis [mmolN m-3 day-1]
+ ! grazingFlux_Det2 : Grazing on slow-sinking detritus [mmolN m-3 day-1]
+ ! grazingFlux_DetZ22 : Grazing on fast-sinking detritus [mmolN m-3 day-1]
+ !
+ ! Equation for each prey type i:
+ ! grazingFlux_i = grazingFlux2 × (f_i / total_food)
+ !---------------------------------------------------------------------------
+
+ ! Distribute total grazing among prey types proportionally
+ grazingFlux_phy2 = (grazingFlux2 * fPhyN2) / food2
+ grazingFlux_Dia2 = (grazingFlux2 * fDiaN2) / food2
+ grazingFlux_miczoo2 = (grazingFlux2 * fMicZooN2) / food2
+ grazingFlux_het2 = (grazingFlux2 * fHetN) / food2
+
+ if (enable_coccos) then
+ grazingFlux_Cocco2 = (grazingFlux2 * fCoccoN2) / food2
+ grazingFlux_Phaeo2 = (grazingFlux2 * fPhaeoN2) / food2
+ endif
+
+ if (Grazing_detritus) then
+ grazingFlux_Det2 = (grazingFlux2 * fDetN2) / food2
+ grazingFlux_DetZ22 = (grazingFlux2 * fDetZ2N2) / food2
+ end if
+
+ !===========================================================================
+ ! 4. CARBON ASSIMILATION
+ !===========================================================================
+ ! Converts grazed nitrogen to assimilated carbon flux using prey-specific
+ ! C:N ratios and constant grazing efficiency.
+ !
+ ! Variables:
+ ! grazingFluxcarbonzoo2 : Total carbon flux to macrozooplankton [mmolC m-3 day-1]
+ ! grazEff2 : Macrozooplankton grazing efficiency (constant) [-]
+ ! recipQuota : Small phytoplankton C:N ratio [mmolC mmolN-1]
+ ! recipQuota_Dia : Diatom C:N ratio [mmolC mmolN-1]
+ ! recipQuota_Cocco : Coccolithophore C:N ratio [mmolC mmolN-1]
+ ! recipQuota_Phaeo : Phaeocystis C:N ratio [mmolC mmolN-1]
+ ! recipQZoo : Mesozooplankton C:N ratio [mmolC mmolN-1]
+ ! recipQZoo3 : Microzooplankton C:N ratio [mmolC mmolN-1]
+ ! recipDet, recipDet2 : Detritus C:N ratios [mmolC mmolN-1]
+ !
+ ! Carbon Flux Equation:
+ ! C_flux = Σ(grazingFlux_i × C:N_ratio_i × grazEff2)
+ !
+ ! Note: Unlike mesozooplankton, macrozooplankton uses constant efficiency
+ ! (grazEff2) rather than food-dependent efficiency
+ !---------------------------------------------------------------------------
+
+ ! Convert grazed nitrogen to carbon flux using prey C:N ratios
+ ! Start with core prey types (always present)
+ grazingFluxcarbonzoo2 = (grazingFlux_phy2 * recipQuota * grazEff2) + &
+ (grazingFlux_Dia2 * recipQuota_Dia * grazEff2) + &
+ (grazingFlux_het2 * recipQZoo * grazEff2) + &
+ (grazingFlux_miczoo2 * recipQZoo3 * grazEff2)
+
+ ! Add detritus contribution if detrital grazing is enabled
+ if (Grazing_detritus) then
+ grazingFluxcarbonzoo2 = grazingFluxcarbonzoo2 + &
+ (grazingFlux_Det2 * recipDet * grazEff2) + &
+ (grazingFlux_DetZ22 * recipDet2 * grazEff2)
+ end if
+
+ ! Add coccolithophore and Phaeocystis contribution if enabled
+ if (enable_coccos) then
+ grazingFluxcarbonzoo2 = grazingFluxcarbonzoo2 + &
+ (grazingFlux_Cocco2 * recipQuota_Cocco * grazEff2) + &
+ (grazingFlux_Phaeo2 * recipQuota_Phaeo * grazEff2)
+ endif
+
+ endif ! enable_3zoo2det
+
+ !===============================================================================
+ ! MICROZOOPLANKTON GRAZING
+ !===============================================================================
+ ! Simulates microzooplankton (third zooplankton) grazing on phytoplankton prey
+ ! using a Holling Type II functional response with food-dependent preferences.
+ !
+ ! This module calculates:
+ ! 1. Food availability and grazing preferences (fixed or variable)
+ ! 2. Total grazing flux with Holling Type II response
+ ! 3. Distribution of grazing among prey types
+ ! 4. Carbon assimilation from grazed prey (calculated elsewhere)
+ !
+ ! Key Features:
+ ! - Strictly herbivorous: only grazes on phytoplankton groups
+ ! - No carnivory: does not graze on other zooplankton
+ ! - No detritivory: does not graze on detritus
+ ! - Variable or fixed prey preferences
+ ! - Temperature-dependent grazing rate (Q10)
+ ! - Smallest zooplankton size class (fastest response to phytoplankton)
+ !
+ ! Prey Types:
+ ! - Primary: Small phytoplankton, diatoms
+ ! - Optional: Coccolithophores, Phaeocystis
+ !
+ ! Ecological Role:
+ ! - Links small phytoplankton to higher trophic levels
+ ! - Prey for mesozooplankton and macrozooplankton
+ ! - Rapid response to phytoplankton blooms
+ !
+ ! References:
+ ! - Schourup-Kristensen et al. (2013) - REcoM model description
+ !===============================================================================
+
+ if (enable_3zoo2det) then
+
+ !===========================================================================
+ ! 1. FOOD AVAILABILITY AND GRAZING PREFERENCES
+ !===========================================================================
+ ! Calculates which phytoplankton prey types are available and their
+ ! relative preferences.
+ ! Two modes:
+ ! - Variable preferences: Adjust based on relative prey abundance
+ ! - Fixed preferences: Use constant maximum preference values
+ !
+ ! Variables:
+ ! pzPhy3, pzDia3 : Max preference for small phyto and diatoms [-]
+ ! pzCocco3, pzPhaeo3 : Max preference for coccoliths and Phaeocystis [-]
+ ! PhyN, DiaN : Small phytoplankton and diatom nitrogen [mmolN m-3]
+ ! CoccoN, PhaeoN : Coccolithophore and Phaeocystis nitrogen [mmolN m-3]
+ ! varpzPhy3, varpzDia3: Variable preferences (calculated from availability) [-]
+ ! varpzCocco3, varpzPhaeo3: Variable preferences for coccos/phaeo [-]
+ ! fPhyN3, fDiaN3 : Available food pools (preference × concentration) [mmolN m-3]
+ ! fCoccoN3, fPhaeoN3 : Available coccolithophore/Phaeocystis pools [mmolN m-3]
+ ! aux : Total weighted food availability [mmolN m-3]
+ !
+ ! Logic:
+ ! IF variable preferences: varpz_i = (pz_i × prey_i) / Σ(pz_j × prey_j)
+ ! ELSE: Use fixed maximum preferences (pz_i)
+ ! Food pools: f_i = preference_i × prey_i
+ !
+ ! Note: Microzooplankton have simpler feeding than meso/macrozooplankton
+ ! - No carnivory (no zooplankton prey)
+ ! - No detritivory (no detritus grazing)
+ !---------------------------------------------------------------------------
+
+ if (REcoM_Grazing_Variable_Preference) then
+ !-----------------------------------------------------------------------
+ ! VARIABLE PREFERENCE MODE
+ ! Preferences scale with relative abundance of each phytoplankton type
+ !-----------------------------------------------------------------------
+
+ ! Calculate total weighted food availability (denominator)
+ ! Core phytoplankton prey: small phytoplankton and diatoms
+ aux = pzPhy3 * PhyN + pzDia3 * DiaN
+
+ ! Add coccolithophores and Phaeocystis if enabled
+ if (enable_coccos) then
+ aux = aux + pzCocco3 * CoccoN + pzPhaeo3 * PhaeoN
+ endif
+
+ ! Calculate variable preferences (normalized by total availability)
+ ! Each preference = (max_pref × prey_conc) / total_weighted_food
+ varpzPhy3 = (pzPhy3 * PhyN) / aux
+ varpzDia3 = (pzDia3 * DiaN) / aux
+
+ if (enable_coccos) then
+ varpzCocco3 = (pzCocco3 * CoccoN) / aux
+ varpzPhaeo3 = (pzPhaeo3 * PhaeoN) / aux
+ endif
+
+ ! Calculate available food pools (preference × concentration)
+ fPhyN3 = varpzPhy3 * PhyN
+ fDiaN3 = varpzDia3 * DiaN
+
+ if (enable_coccos) then
+ fCoccoN3 = varpzCocco3 * CoccoN
+ fPhaeoN3 = varpzPhaeo3 * PhaeoN
+ endif
+
+ else
+ !-----------------------------------------------------------------------
+ ! FIXED PREFERENCE MODE
+ ! Use constant maximum preference values
+ !-----------------------------------------------------------------------
+
+ fPhyN3 = pzPhy3 * PhyN
+ fDiaN3 = pzDia3 * DiaN
+
+ if (enable_coccos) then
+ fCoccoN3 = pzCocco3 * CoccoN
+ fPhaeoN3 = pzPhaeo3 * PhaeoN
+ endif
+
+ endif ! REcoM_Grazing_Variable_Preference
+
+ !===========================================================================
+ ! 2. TOTAL GRAZING FLUX (HOLLING TYPE II)
+ !===========================================================================
+ ! Calculates total grazing rate using a hyperbolic (Type II) functional
+ ! response. This creates saturating grazing at high phytoplankton
+ ! concentrations.
+ !
+ ! Variables:
+ ! food3 : Total available phytoplankton food [mmolN m-3]
+ ! foodsq3 : Squared food concentration [mmolN2 m-6]
+ ! grazingFlux3 : Total N grazing rate [mmolN m-3 day-1]
+ ! Graz_max3 : Maximum specific grazing rate [day-1]
+ ! epsilon3 : Half-saturation constant squared [mmolN2 m-6]
+ ! MicZooN : Microzooplankton nitrogen concentration [mmolN m-3]
+ ! q10_mic : Q10 temperature function for microzooplankton [-]
+ !
+ ! Equation: Holling Type II
+ ! grazingFlux3 = (Graz_max3 × food³) / (epsilon3 + food²) × MicZooN × T_func
+ !
+ ! Note: Uses Q10 temperature dependency (q10_mic) for rapid metabolic response
+ ! Smaller organisms typically have higher Q10 sensitivity
+ !---------------------------------------------------------------------------
+
+ ! Sum all available phytoplankton food pools
+ food3 = fPhyN3 + fDiaN3
+
+ if (enable_coccos) then
+ food3 = food3 + fCoccoN3 + fPhaeoN3
+ endif
+
+ ! Calculate grazing flux with Holling Type II functional response
+ ! Type II creates hyperbolic saturation: grazing rate increases rapidly
+ ! at low food, then saturates at high food concentrations
+ foodsq3 = food3**2
+ grazingFlux3 = (Graz_max3 * foodsq3) / (epsilon3 + foodsq3) * MicZooN * q10_mic
+
+ !===========================================================================
+ ! 3. GRAZING FLUX DISTRIBUTION
+ !===========================================================================
+ ! Partitions total grazing among phytoplankton prey types proportional
+ ! to their availability.
+ !
+ ! Variables:
+ ! grazingFlux_phy3 : Grazing on small phytoplankton [mmolN m-3 day-1]
+ ! grazingFlux_Dia3 : Grazing on diatoms [mmolN m-3 day-1]
+ ! grazingFlux_Cocco3 : Grazing on coccolithophores [mmolN m-3 day-1]
+ ! grazingFlux_Phaeo3 : Grazing on Phaeocystis [mmolN m-3 day-1]
+ !
+ ! Equation for each prey type i:
+ ! grazingFlux_i = grazingFlux3 × (f_i / total_food)
+ !
+ ! Note: This proportional distribution ensures conservation of mass
+ ! The sum of all distributed fluxes equals the total grazing flux
+ !---------------------------------------------------------------------------
+
+ ! Distribute total grazing among phytoplankton prey types proportionally
+ grazingFlux_phy3 = (grazingFlux3 * fPhyN3) / food3
+ grazingFlux_Dia3 = (grazingFlux3 * fDiaN3) / food3
+
+ if (enable_coccos) then
+ grazingFlux_Cocco3 = (grazingFlux3 * fCoccoN3) / food3
+ grazingFlux_Phaeo3 = (grazingFlux3 * fPhaeoN3) / food3
+ endif
+
+ !===========================================================================
+ ! 4. CARBON ASSIMILATION
+ !===========================================================================
+ ! Carbon flux calculation for microzooplankton is handled elsewhere in the
+ ! model code using the nitrogen grazing fluxes calculated above and
+ ! prey-specific C:N ratios.
+ !
+ ! The carbon assimilation follows the general pattern:
+ ! C_flux = Σ(grazingFlux_i × C:N_ratio_i × grazEff3)
+ !
+ ! Where:
+ ! grazEff3 = Microzooplankton grazing efficiency (constant) [-]
+ ! C:N ratios for each phytoplankton prey type [mmolC mmolN-1]
+ !
+ ! This calculation is performed in the carbon balance section of the model
+ ! to maintain consistency with other carbon flux calculations.
+ !===========================================================================
+
+ endif ! enable_3zoo2det
+
+ !===============================================================================
+ ! MESOZOOPLANKTON RESPIRATION
+ !===============================================================================
+ ! Calculates mesozooplankton carbon respiration using either simple temperature-
+ ! dependent respiration or Redfield-based respiration that accounts for C:N
+ ! stoichiometry deviations.
+ !
+ ! Two respiration modes:
+ ! A) Simple mode: Constant specific rate with temperature correction
+ ! B) Redfield mode: Respirate excess carbon above Redfield C:N ratio
+ !
+ ! Variables:
+ ! HetRespFlux : Mesozooplankton respiration rate [mmolC m-3 day-1]
+ ! res_het : Baseline respiration rate constant [day-1]
+ ! HetC : Mesozooplankton carbon concentration [mmolC m-3]
+ ! HetN : Mesozooplankton nitrogen concentration [mmolN m-3]
+ ! q10_mes_res : Q10 temperature function for meso respiration [-]
+ ! arrFunc : Arrhenius temperature function [-]
+ ! recip_hetN_plus : Reciprocal of (HetN + small number) [mmolN-1 m3]
+ ! redfield : Redfield C:N ratio (106:16 ≈ 6.625) [mmolC mmolN-1]
+ ! recip_res_het : Reciprocal respiration parameter [day-1]
+ !
+ ! Logic:
+ ! IF simple mode: RespFlux = res_het × T_func × HetC
+ ! ELSE Redfield mode: RespFlux = recip_res_het × T_func × (C:N - Redfield) × HetC
+ ! Redfield mode respirates excess carbon when C:N > Redfield ratio
+ !
+ ! Note: Redfield-based respiration maintains stoichiometric homeostasis
+ !-------------------------------------------------------------------------------
+
+ if (het_resp_noredfield) then
+ !---------------------------------------------------------------------------
+ ! SIMPLE RESPIRATION MODE
+ ! Constant specific rate with temperature dependency
+ !---------------------------------------------------------------------------
+
+ if (enable_3zoo2det) then
+ ! Use Q10 temperature function (exponential temperature sensitivity)
+ HetRespFlux = res_het * q10_mes_res * HetC
+ else
+ ! Use Arrhenius temperature function
+ HetRespFlux = res_het * arrFunc * HetC
+ endif
+
+ else
+ !---------------------------------------------------------------------------
+ ! REDFIELD-BASED RESPIRATION MODE
+ ! Respirate excess carbon above Redfield C:N ratio
+ !---------------------------------------------------------------------------
+
+ ! Calculate respiration based on deviation from Redfield ratio
+ ! When C:N > Redfield, organism has excess carbon that must be respired
+ ! This maintains stoichiometric balance in the organism
+ HetRespFlux = recip_res_het * arrFunc * (HetC * recip_hetN_plus - redfield) * HetC
+
+ ! Ensure non-negative flux (no respiration when C:N ≤ Redfield)
+ HetRespFlux = max(zero, HetRespFlux)
+
+ endif
+
+ !===============================================================================
+ ! CARBON ISOTOPE TRACKING (OPTIONAL)
+ !===============================================================================
+ ! Tracks respiration fluxes of carbon isotopes (13C and 14C) for paleoclimate
+ ! and carbon cycle studies.
+ !
+ ! Variables:
+ ! HetRespFlux_13 : 13C respiration flux [mmol13C m-3 day-1]
+ ! HetRespFlux_14 : 14C respiration flux [mmol14C m-3 day-1]
+ ! HetC_13 : Mesozooplankton 13C concentration [mmol13C m-3]
+ ! HetC_14 : Mesozooplankton 14C concentration [mmol14C m-3]
+ ! HetC : Total mesozooplankton carbon [mmolC m-3]
+ ! ciso : Flag for 13C isotope tracking [logical]
+ ! ciso_14 : Flag for 14C isotope tracking [logical]
+ ! ciso_organic_14 : Flag for 14C in organic matter [logical]
+ !
+ ! Equation:
+ ! IsotopeFlux = TotalFlux × (Isotope_C / Total_C)
+ ! Assumes isotope ratios are conserved during respiration
+ !-------------------------------------------------------------------------------
+
+ if (ciso) then
+ ! Track 13C respiration proportional to 13C:12C ratio in biomass
+ HetRespFlux_13 = HetRespFlux * HetC_13 / HetC
+
+ if (ciso_14 .and. ciso_organic_14) then
+ ! Track 14C respiration (for radiocarbon dating applications)
+ ! Used to study carbon residence times and ocean circulation
+ HetRespFlux_14 = HetRespFlux * HetC_14 / HetC
+ end if
+ end if
+
+ !===============================================================================
+ ! MESOZOOPLANKTON MORTALITY
+ !===============================================================================
+ ! Calculates density-dependent mortality using quadratic formulation.
+ ! Higher densities lead to disproportionately higher mortality.
+ !
+ ! Variables:
+ ! hetLossFlux : Mesozooplankton mortality flux [mmolN m-3 day-1]
+ ! loss_het : Mortality rate constant [day-1 (mmolN m-3)-1]
+ ! HetN : Mesozooplankton nitrogen concentration [mmolN m-3]
+ !
+ ! Equation: Quadratic Mortality
+ ! Mortality = loss_het × HetN²
+ !
+ ! Ecological Rationale:
+ ! - Linear term represents background mortality (disease, senescence)
+ ! - Quadratic term represents density-dependent processes:
+ ! * Increased predation pressure at high densities
+ ! * Disease transmission (increases with encounter rate)
+ ! * Intraspecific competition for resources
+ !
+ ! Note: Mortality products go to detritus pool (recycling pathway)
+ !-------------------------------------------------------------------------------
+
+ hetLossFlux = loss_het * HetN * HetN
+
+ if (enable_3zoo2det) then
+
+ !===========================================================================
+ ! MACROZOOPLANKTON RESPIRATION (KRILL)
+ !===========================================================================
+ ! Calculates macrozooplankton respiration with feeding-dependent stress
+ ! response. Poor feeding conditions increase metabolic costs.
+ !
+ ! Variables:
+ ! Zoo2RespFlux : Macrozooplankton respiration [mmolC m-3 day-1]
+ ! res_zoo2 : Baseline respiration rate [day-1]
+ ! res_zoo2_f : Feeding success modifier [-]
+ ! res_zoo2_a : Additional respiration factor [-]
+ ! recip_res_zoo22 : Combined respiration coefficient [day-1]
+ ! Zoo2C : Macrozooplankton carbon concentration [mmolC m-3]
+ ! grazingFluxcarbonzoo2: Carbon ingestion rate [mmolC m-3 day-1]
+ !
+ ! Feeding Success Response:
+ ! - IF specific ingestion < 0.1 day-1: Stress response activated
+ ! * Increases metabolic costs (searching, maintenance)
+ ! * res_zoo2_f scales linearly with feeding rate
+ ! - ELSE: Normal feeding conditions (res_zoo2_f = 1.0)
+ !
+ ! Total Respiration:
+ ! RespFlux = res_zoo2 × (1 + res_zoo2_f + res_zoo2_a) × Zoo2C
+ !
+ ! Note: Calls external subroutine krill_resp() for detailed metabolism
+ !---------------------------------------------------------------------------
+
+ ! Call detailed krill respiration subroutine
+ ! Handles additional physiological processes (e.g., molting, reproduction)
+ call krill_resp(n, partit, mesh)
+
+ ! Calculate feeding success modifier
+ ! Low feeding rates trigger stress response with elevated respiration
+ if ((grazingFluxcarbonzoo2 / Zoo2C) <= 0.1) then
+ ! Stress response: metabolic costs increase linearly with feeding deficit
+ ! Factor of 0.1 converts to percentage basis
+ res_zoo2_f = 0.1 * (grazingFluxcarbonzoo2 / Zoo2C * 100.0)
+ else
+ ! Normal feeding: no additional metabolic stress
+ res_zoo2_f = 1.0
+ end if
+
+ ! Calculate combined respiration coefficient
+ ! Includes baseline + feeding stress + additional factors
+ recip_res_zoo22 = res_zoo2 * (1.0 + res_zoo2_f + res_zoo2_a)
+
+ ! Calculate total respiration flux
+ Zoo2RespFlux = recip_res_zoo22 * Zoo2C
+
+ !===========================================================================
+ ! MACROZOOPLANKTON MORTALITY
+ !===========================================================================
+ ! Quadratic density-dependent mortality for macrozooplankton.
+ !
+ ! Variables:
+ ! Zoo2LossFlux : Macrozooplankton mortality flux [mmolN m-3 day-1]
+ ! loss_zoo2 : Mortality rate constant [day-1 (mmolN m-3)-1]
+ ! zoo2N : Macrozooplankton nitrogen concentration [mmolN m-3]
+ !
+ ! Equation: Quadratic Mortality
+ ! Mortality = loss_zoo2 × zoo2N²
+ !---------------------------------------------------------------------------
+
+ Zoo2LossFlux = loss_zoo2 * zoo2N * zoo2N
+
+ !===========================================================================
+ ! MICROZOOPLANKTON RESPIRATION AND MORTALITY
+ !===========================================================================
+ ! Calculates microzooplankton respiration and mortality.
+ ! Simpler than macro/mesozooplankton (no feeding-dependent stress).
+ !
+ ! Variables:
+ ! MicZooRespFlux : Microzooplankton respiration [mmolC m-3 day-1]
+ ! MicZooLossFlux : Microzooplankton mortality [mmolN m-3 day-1]
+ ! res_miczoo : Respiration rate constant [day-1]
+ ! loss_miczoo : Mortality rate constant [day-1 (mmolN m-3)-1]
+ ! q10_mic_res : Q10 temperature function for micro respiration [-]
+ ! MicZooC : Microzooplankton carbon concentration [mmolC m-3]
+ ! MicZooN : Microzooplankton nitrogen concentration [mmolN m-3]
+ !
+ ! Respiration Equation:
+ ! RespFlux = res_miczoo × q10_mic_res × MicZooC
+ !
+ ! Mortality Equation:
+ ! Mortality = loss_miczoo × MicZooN²
+ !---------------------------------------------------------------------------
+
+ ! Temperature-dependent respiration (Q10 formulation)
+ ! Smaller organisms typically have higher temperature sensitivity
+ MicZooRespFlux = res_miczoo * q10_mic_res * MicZooC
+
+ ! Quadratic density-dependent mortality
+ MicZooLossFlux = loss_miczoo * MicZooN * MicZooN
+
+ endif ! enable_3zoo2det
+
+ !===============================================================================
+ ! FECAL PELLET PRODUCTION
+ !===============================================================================
+ ! Calculates fecal pellet production from mesozooplankton and macrozooplankton.
+ ! Fecal pellets are key to the biological carbon pump due to fast sinking.
+ !
+ ! Fecal pellets represent:
+ ! - Undigested/unassimilated food material
+ ! - Packaged waste with high sinking velocity (100-1000 m/day)
+ ! - Major pathway for carbon export to deep ocean
+ ! - Important food source for deep-sea organisms
+ !
+ ! Variables:
+ ! Zoo2fecalloss_n : Macrozooplankton fecal N [mmolN m-3 day-1]
+ ! Zoo2fecalloss_c : Macrozooplankton fecal C [mmolC m-3 day-1]
+ ! mesfecalloss_n : Mesozooplankton fecal N [mmolN m-3 day-1]
+ ! mesfecalloss_c : Mesozooplankton fecal C [mmolC m-3 day-1]
+ ! fecal_rate_n : Fecal production rate for N [fraction of ingestion]
+ ! fecal_rate_c : Fecal production rate for C [fraction of ingestion]
+ ! fecal_rate_n_mes : Mesozooplankton N fecal rate [-]
+ ! fecal_rate_c_mes : Mesozooplankton C fecal rate [-]
+ ! grazingFlux2 : Macrozooplankton N ingestion [mmolN m-3 day-1]
+ ! grazingFlux : Mesozooplankton N ingestion [mmolN m-3 day-1]
+ ! grazingFluxcarbonzoo2 : Macro C ingestion [mmolC m-3 day-1]
+ ! grazingFluxcarbon_mes : Meso C ingestion [mmolC m-3 day-1]
+ !
+ ! Equation:
+ ! Fecal_flux = fecal_rate × ingestion_flux
+ ! Fecal rate typically 10-30% of ingestion (remainder is assimilated)
+ !
+ ! Note: Fecal C:N ratio may differ from prey due to selective digestion
+ !-------------------------------------------------------------------------------
+
+ if (enable_3zoo2det) then
+
+ !---------------------------------------------------------------------------
+ ! Macrozooplankton Fecal Pellet Production
+ !---------------------------------------------------------------------------
+ ! Larger zooplankton produce larger, faster-sinking fecal pellets
+
+ Zoo2fecalloss_n = fecal_rate_n * grazingFlux2 ! Nitrogen
+ Zoo2fecalloss_c = fecal_rate_c * grazingFluxcarbonzoo2 ! Carbon
+
+ !---------------------------------------------------------------------------
+ ! Mesozooplankton Fecal Pellet Production
+ !---------------------------------------------------------------------------
+ ! Smaller fecal pellets than macrozooplankton but still fast-sinking
+
+ mesfecalloss_n = fecal_rate_n_mes * grazingFlux ! Nitrogen
+ mesfecalloss_c = fecal_rate_c_mes * grazingFluxcarbon_mes ! Carbon
+
+ endif ! enable_3zoo2det
+
+ !===============================================================================
+ ! PHYTOPLANKTON AND DETRITUS AGGREGATION
+ !===============================================================================
+ ! Calculates particle aggregation that forms larger, faster-sinking particles.
+ ! Critical process for biological carbon pump and export production.
+ !
+ ! Aggregation mechanisms:
+ ! - Particle collision and sticking (Brownian motion, shear, settling)
+ ! - Diatom mucus production enhances aggregation (nutrient stress response)
+ ! - Transparent exopolymer particles (TEP) glue particles together
+ !
+ ! Variables:
+ ! aggregationrate : Total particle aggregation rate [mmolN m-3 day-1]
+ ! agg_PP : Phytoplankton-phytoplankton aggregation rate [day-1]
+ ! agg_PD : Phytoplankton-detritus aggregation rate [day-1]
+ ! PhyN, DiaN : Phytoplankton nitrogen concentrations [mmolN m-3]
+ ! CoccoN, PhaeoN : Coccolithophore and Phaeocystis N [mmolN m-3]
+ ! DetN, DetZ2N : Slow and fast-sinking detritus N [mmolN m-3]
+ ! qlimitFac : Nutrient limitation factor (0=replete, 1=limited) [-]
+ ! feLimitFac : Iron limitation factor [-]
+ ! quota_dia : Diatom N:C quota [mmolN mmolC-1]
+ ! qSiC : Diatom Si:C quota [mmolSi mmolC-1]
+ !
+ ! Note: Aggregation products enter fast-sinking detritus pool (DetZ2N)
+ !-------------------------------------------------------------------------------
+
+ !---------------------------------------------------------------------------
+ ! Diatom Mucus-Enhanced Aggregation (Optional)
+ !---------------------------------------------------------------------------
+ ! Nutrient limitation triggers diatom mucus production, enhancing aggregation
+ ! and forming large, rapidly-sinking marine snow aggregates.
+
+ if (diatom_mucus) then
+
+ !-----------------------------------------------------------------------
+ ! Calculate nutrient limitation factors
+ !-----------------------------------------------------------------------
+
+ ! Nitrogen limitation factor
+ ! Uses limiter function: returns 0 when quota is high (replete)
+ ! returns 1 when quota is low (limited)
+ qlimitFac = recom_limiter(NMinSlope, NCmin_d, quota_dia)
+
+ ! Silicon limitation factor
+ ! Diatoms require silica for frustule (shell) formation
+ qlimitFacTmp = recom_limiter(SiMinSlope, SiCmin, qSiC)
+ qlimitFac = min(qlimitFac, qlimitFacTmp) ! Most limiting nutrient
+
+ ! Iron limitation factor
+ ! Iron is essential for photosynthesis and often limiting in ocean
+ feLimitFac = Fe / (k_Fe_d + Fe)
+ qlimitFac = min(qlimitFac, feLimitFac) ! Most limiting of all nutrients
+
+ ! Calculate mucus-enhanced aggregation rate
+ ! Aggregation increases with nutrient stress (high limitation factor)
+ ! Factor (1 - qlimitFac): 0 when replete, 1 when severely limited
+ aggregationrate = agg_PP * (1.0 - qlimitFac) * DiaN
+
+ else
+
+ !-----------------------------------------------------------------------
+ ! Simple aggregation without nutrient limitation effect
+ !-----------------------------------------------------------------------
+ aggregationrate = agg_PP * DiaN
+
+ endif
+
+ !---------------------------------------------------------------------------
+ ! Total Aggregation Rate
+ !---------------------------------------------------------------------------
+ ! Sum contributions from all particle types
+ ! Each particle type can aggregate with itself and other particles
+
+ ! Add small phytoplankton and detritus aggregation
+ aggregationrate = aggregationrate + agg_PD * DetN + agg_PP * PhyN
+
+ if (enable_3zoo2det) then
+ ! Add fast-sinking detritus aggregation
+ aggregationrate = aggregationrate + agg_PD * DetZ2N
+ endif
+
+ if (enable_coccos) then
+ ! Add coccolithophore and Phaeocystis aggregation
+ ! These can form large blooms with high aggregation potential
+ aggregationrate = aggregationrate + agg_PP * CoccoN + agg_PP * PhaeoN
+ endif
+
+ !===============================================================================
+ ! MARINE CALCIFICATION
+ !===============================================================================
+ ! Simulates the formation and dissolution of calcium carbonate (CaCO3) in
+ ! marine environments, primarily through phytoplankton calcification.
+ !
+ ! This module calculates:
+ ! 1. Calcification rates (organism-specific or general)
+ ! 2. Environmental controls on calcification (temperature, CO2, nutrients)
+ ! 3. Loss processes (grazing, aggregation)
+ ! 4. Carbon isotope fractionation (13C, 14C - optional)
+ !
+ ! Key Features:
+ ! - Explicit coccolithophore calcification (temperature, CO2, nutrient effects)
+ ! - General small phytoplankton calcification (simplified)
+ ! - Ocean acidification sensitivity (CO2/carbonate chemistry effects)
+ ! - PIC:POC ratio variability (environmental controls on calcite production)
+ ! - Isotope fractionation during calcification
+ !
+ ! Calcification Scenarios:
+ ! A) enable_coccos = TRUE: Explicit coccolithophore model
+ ! - Temperature-dependent PIC:POC ratios (Krumhardt et al. 2017, 2019)
+ ! - CO2/carbonate chemistry effects (ocean acidification)
+ ! - Nitrogen limitation effects
+ ! B) enable_coccos = FALSE: General small phytoplankton
+ ! - Fixed fraction of photosynthesis goes to calcification
+ !
+ ! Ecological/Biogeochemical Significance:
+ ! - Produces ballast that increases particle sinking (biological pump)
+ ! - Releases CO2 during calcification (carbonate counter-pump)
+ ! - Major component of ocean alkalinity cycle
+ ! - Sensitive to ocean acidification (climate change impact)
+ !
+ ! References:
+ ! - Krumhardt et al. (2017, 2019) - Coccolithophore parameterization
+ ! - Gürses et al. (2023) - REcoM2 model description
+ !===============================================================================
+
+ !===============================================================================
+ ! CALCIFICATION RATE CALCULATION
+ !===============================================================================
+ ! Calculates the rate at which calcium carbonate (CaCO3) is formed by marine
+ ! organisms, with environmental modulation of the PIC:POC ratio.
+ !
+ ! PIC = Particulate Inorganic Carbon (CaCO3)
+ ! POC = Particulate Organic Carbon (photosynthetic biomass)
+ !
+ ! Variables (Coccolithophore mode):
+ ! calcification : CaCO3 formation rate [mmolC m-3 day-1]
+ ! Cphot_cocco : Coccolithophore C-specific photosynthesis [day-1]
+ ! CoccoC : Coccolithophore carbon concentration [mmolC m-3]
+ ! PICPOCtemp : Temperature modifier for PIC:POC ratio [-]
+ ! PICPOCCO2 : CO2/carbonate chemistry modifier for PIC:POC [-]
+ ! PICPOCN : Nitrogen limitation modifier for PIC:POC [-]
+ ! Temp(k) : Temperature at depth k [degC]
+ ! HCO3_watercolumn: Bicarbonate concentration [mmolC m-3]
+ ! CO2_watercolumn : Dissolved CO2 concentration [mmolC m-3]
+ ! pH_watercolumn : Water column pH [-]
+ ! DIN : Dissolved inorganic nitrogen [mmolN m-3]
+ ! k_din_c : Half-saturation for DIN effect on calcification [mmolN m-3]
+ ! a,b,c,d_co2_calc: CO2 effect parameters [-]
+ ! Cunits : Conversion factor for units [-]
+ !
+ ! Variables (General phytoplankton mode):
+ ! calc_prod_ratio : Fixed calcification:photosynthesis ratio [-]
+ ! Cphot : Small phytoplankton photosynthesis rate [day-1]
+ ! PhyC : Small phytoplankton carbon [mmolC m-3]
+ !-------------------------------------------------------------------------------
+
+ if (enable_coccos) then
+
+ !===========================================================================
+ ! COCCOLITHOPHORE-SPECIFIC CALCIFICATION
+ !===========================================================================
+ ! Coccolithophores are marine phytoplankton that produce calcite plates
+ ! (coccoliths) as an external protective covering.
+ !
+ ! Environmental Controls:
+ ! - Temperature: Optimum calcification at warm temperatures (>10.6degC)
+ ! - CO2: Ocean acidification reduces calcification efficiency
+ ! - Nitrogen: High nutrient availability reduces PIC:POC ratio
+ !---------------------------------------------------------------------------
+
+ !---------------------------------------------------------------------------
+ ! Temperature Effect on PIC:POC Ratio
+ !---------------------------------------------------------------------------
+ ! Based on Krumhardt et al. (2017, 2019) parameterization
+ ! Warmer temperatures favor higher calcification efficiency
+
+ if (Temp(k) < 10.6) then
+ ! Linear relationship for temperatures below 10.6degC
+ ! Calcification efficiency increases with temperature
+ PICPOCtemp = 0.104d0 * Temp(k) - 0.108d0
+ else
+ ! Maximum efficiency at temperatures ≥ 10.6degC
+ ! Represents optimal conditions for coccolith formation
+ PICPOCtemp = 1.0d0
+ end if
+
+ ! Prevent negative values (can occur at very low temperatures)
+ PICPOCtemp = max(tiny, PICPOCtemp)
+
+ !---------------------------------------------------------------------------
+ ! CO2/Carbonate Chemistry Effect on PIC:POC Ratio
+ !---------------------------------------------------------------------------
+ ! Complex function representing ocean acidification impacts
+ ! Three components:
+ ! 1. HCO3- availability (substrate for calcification)
+ ! 2. High CO2 inhibition (ocean acidification stress)
+ ! 3. Low pH inhibition (direct pH stress on calcification)
+
+ PICPOCCO2 = a_co2_calc * HCO3_watercolumn(k) * Cunits / (b_co2_calc + HCO3_watercolumn(k) * Cunits) &
+ - exp(-c_co2_calc * CO2_watercolumn(k) * Cunits) &
+ - d_co2_calc * 10.d0**(-pH_watercolumn(k))
+
+ ! Apply empirical constraints to CO2 effect
+ PICPOCCO2 = min(PICPOCCO2, 3.d0) ! Upper limit (April 2022 modification)
+ PICPOCCO2 = max(0.d0, PICPOCCO2) ! Lower limit (July 2022 modification)
+
+ !---------------------------------------------------------------------------
+ ! Nitrogen Limitation Effect on PIC:POC Ratio
+ !---------------------------------------------------------------------------
+ ! Higher DIN availability reduces calcification efficiency
+ ! Ecological rationale: Under nutrient replete conditions, organisms
+ ! allocate resources preferentially to organic carbon (growth) rather
+ ! than calcite plates (protection)
+
+ PICPOCN = -0.31 * (DIN / (DIN + k_din_c)) + 1.31
+ PICPOCN = max(tiny, PICPOCN) ! Prevent negative values
+
+ !---------------------------------------------------------------------------
+ ! Calculate Final Coccolithophore Calcification Rate
+ !---------------------------------------------------------------------------
+ ! Combine photosynthesis rate with all environmental modifiers
+ ! Base rate × Temperature effect × Nutrient effect
+
+ calcification = 1.d0 * Cphot_cocco * CoccoC * PICPOCtemp * PICPOCN
+
+ ! Apply CO2 limitation if ocean acidification sensitivity is enabled
+ if (CO2lim) then
+ calcification = calcification * PICPOCCO2
+ end if
+
+ else
+
+ !===========================================================================
+ ! GENERAL SMALL PHYTOPLANKTON CALCIFICATION
+ !===========================================================================
+ ! Simplified approach: calcification as a fixed fraction of photosynthesis
+ ! Used when coccolithophores are not explicitly represented
+ ! Represents calcification by other small calcifying organisms
+ !---------------------------------------------------------------------------
+
+ calcification = calc_prod_ratio * Cphot * PhyC
+
+ endif
+
+ !===============================================================================
+ ! CALCIFICATION LOSS PROCESSES
+ !===============================================================================
+ ! Calculates removal of calcified material through grazing and aggregation.
+ ! These processes transfer CaCO3 to zooplankton or sinking particles.
+ !
+ ! Variables:
+ ! calc_loss_agg : CaCO3 loss through aggregation [mmolC m-3 day-1]
+ ! calc_loss_gra : CaCO3 loss to primary grazer [mmolC m-3 day-1]
+ ! calc_loss_gra2 : CaCO3 loss to secondary grazer [mmolC m-3 day-1]
+ ! calc_loss_gra3 : CaCO3 loss to tertiary grazer [mmolC m-3 day-1]
+ ! PhyCalc : Phytoplankton calcite content [mmolC m-3]
+ ! aggregationrate : Particle aggregation rate [mmolN m-3 day-1]
+ ! recipQuota : Small phytoplankton C:N ratio [mmolC mmolN-1]
+ ! recipQuota_Cocco: Coccolithophore C:N ratio [mmolC mmolN-1]
+ ! grazingFlux_* : Grazing rates on different prey [mmolN m-3 day-1]
+ ! aux : Auxiliary conversion factor [mmolC mmolN-1]
+ !
+ ! Note: CaCO3 in grazed material can dissolve in zooplankton guts or
+ ! provide ballast for fecal pellets (enhancing sinking)
+ !-------------------------------------------------------------------------------
+
+ !-------------------------------------------------------------------------------
+ ! Aggregation Loss
+ !-------------------------------------------------------------------------------
+ ! CaCO3 is incorporated into aggregates (marine snow) that sink rapidly
+ ! Provides ballast effect: increases particle density and sinking velocity
+
+ calc_loss_agg = aggregationrate * PhyCalc
+
+ if (enable_coccos) then
+
+ !---------------------------------------------------------------------------
+ ! Coccolithophore Grazing Losses
+ !---------------------------------------------------------------------------
+ ! Calculate CaCO3 consumed by grazers feeding on coccolithophores
+ ! Requires conversion from nitrogen-based grazing to carbon flux
+
+ ! Calculate auxiliary conversion factor (CaCO3:N ratio in coccolithophores)
+ aux = recipQuota_Cocco / (CoccoC + tiny) * PhyCalc
+
+ ! Primary grazer (mesozooplankton) consumption
+ calc_loss_gra = grazingFlux_Cocco * aux
+
+ if (enable_3zoo2det) then
+ ! Secondary grazer (macrozooplankton) consumption
+ calc_loss_gra2 = grazingFlux_Cocco2 * aux
+
+ ! Tertiary grazer (microzooplankton) consumption
+ calc_loss_gra3 = grazingFlux_Cocco3 * aux
+ endif
+
+ else
+
+ !---------------------------------------------------------------------------
+ ! Small Phytoplankton Grazing Losses
+ !---------------------------------------------------------------------------
+ ! Calculate CaCO3 consumed by grazers feeding on calcifying small phytoplankton
+
+ ! Calculate auxiliary conversion factor (CaCO3:N ratio in small phytoplankton)
+ aux = recipQuota / (PhyC + tiny) * PhyCalc
+
+ ! Primary grazer (mesozooplankton) consumption
+ calc_loss_gra = grazingFlux_phy * aux
+
+ if (enable_3zoo2det) then
+ ! Secondary grazer (macrozooplankton) consumption
+ calc_loss_gra2 = grazingFlux_phy2 * aux
+
+ ! Tertiary grazer (microzooplankton) consumption
+ calc_loss_gra3 = grazingFlux_phy3 * aux
+ endif
+
+ endif
+
+ !===============================================================================
+ ! CARBON ISOTOPE FRACTIONATION
+ !===============================================================================
+ ! Handles carbon-13 and carbon-14 isotope fractionation during calcification
+ ! and loss processes. Used for paleoclimate reconstructions and carbon cycle
+ ! studies.
+ !
+ ! Isotope Fractionation:
+ ! - Light isotopes (12C) are preferentially incorporated during calcification
+ ! - Fractionation factors (alpha) quantify this discrimination
+ ! - Different fractionation for 13C and 14C
+ !
+ ! Variables:
+ ! calcification_13 : 13C calcification rate [mmol13C m-3 day-1]
+ ! calcification_14 : 14C calcification rate [mmol14C m-3 day-1]
+ ! alpha_calc_13 : 13C fractionation factor during calcification [-]
+ ! alpha_calc_14 : 14C fractionation factor during calcification [-]
+ ! calc_loss_agg_13/14 : Isotope losses through aggregation [mmol m-3 day-1]
+ ! calc_loss_gra_13/14 : Isotope losses through grazing [mmol m-3 day-1]
+ ! PhyCalc_13/14 : Phytoplankton calcite isotope content [mmol m-3]
+ ! PhyC_13/14 : Phytoplankton organic carbon isotopes [mmol m-3]
+ ! recipQuota_13/14 : Isotope-specific C:N ratios [mmol mmol-1]
+ !
+ ! Applications:
+ ! - 13C: Paleoclimate proxies, carbon source tracing
+ ! - 14C: Radiocarbon dating, carbon residence times
+ !
+ ! Note: Only executed if carbon isotope tracking is enabled (ciso = TRUE)
+ !-------------------------------------------------------------------------------
+
+ if (ciso) then
+
+ !===========================================================================
+ ! Carbon-13 Isotope Calculations
+ !===========================================================================
+ ! Track 13C through calcification and loss processes
+ !---------------------------------------------------------------------------
+
+ ! Calcification with isotopic fractionation
+ ! Alpha factor < 1 means light isotope (12C) is preferentially incorporated
+ calcification_13 = calcification * alpha_calc_13
+
+ ! Isotopic losses through aggregation
+ ! Assumes no fractionation during physical aggregation process
+ calc_loss_agg_13 = aggregationRate * PhyCalc_13
+
+ ! Isotopic losses through grazing
+ ! Requires isotope-specific conversion factor
+ calc_loss_gra_13 = grazingFlux_phy * recipQuota_13 / (PhyC_13 + tiny) * PhyCalc_13
+
+ if (ciso_14 .and. ciso_organic_14) then
+
+ !=======================================================================
+ ! Carbon-14 Isotope Calculations
+ !=======================================================================
+ ! Track radiocarbon (14C) through calcification and loss processes
+ ! Used for determining carbon residence times and age dating
+ !-----------------------------------------------------------------------
+
+ ! Calcification with 14C fractionation
+ ! 14C fractionation is approximately twice that of 13C
+ calcification_14 = calc_prod_ratio * Cphot * PhyC_14 * alpha_calc_14
+
+ ! 14C losses through aggregation
+ calc_loss_agg_14 = aggregationRate * PhyCalc_14
+
+ ! 14C losses through grazing
+ calc_loss_gra_14 = grazingFlux_phy * recipQuota_14 / (PhyC_14 + tiny) * PhyCalc_14
+
+ end if ! ciso_14 .and. ciso_organic_14
+
+ end if ! ciso
+
+ !===============================================================================
+ ! 1. DISSOLVED INORGANIC NITROGEN (DIN)
+ !===============================================================================
+ ! Represents the pool of bioavailable nitrogen (nitrate + ammonium)
+ !
+ ! Variables:
+ ! N_assim : N assimilation rate for small phytoplankton [mmolN mmolC-1 day-1]
+ ! N_assim_Dia : N assimilation rate for diatoms [mmolN mmolC-1 day-1]
+ ! N_assim_Cocco : N assimilation rate for coccolithophore [mmolN mmolC-1 day-1]
+ ! N_assim_Phaeo : N assimilation rate for Phaeocystis [mmolN mmolC-1 day-1]
+ ! PhyC, DiaC : Intracellular carbon concentration [mmolC m-3]
+ ! CoccoC, PhaeoC : Intracellular carbon concentration [mmolC m-3]
+ ! rho_N : Remineralization rate constant [day-1]
+ ! arrFunc : Arrhenius temperature dependency function [-]
+ ! O2Func : O2 dependency of organic matter remineralization [-]
+ ! DON : Dissolved organic nitrogen [mmolN m-3]
+ ! dt_b : REcoM time step [day]
+ !
+ ! Equation Reference: Schourup-Kristensen 2013, Eq. A2
+
+ sms(k,idin) = ( &
+ !---------------------------------------------------------------------------
+ ! SINKS: Nitrogen Uptake (decreases DIN)
+ !---------------------------------------------------------------------------
+ ! Phytoplankton assimilation of NO3- and NH4+
+ - N_assim * PhyC & ! Small phytoplankton
+ - N_assim_Dia * DiaC & ! Diatoms
+ - N_assim_Cocco * CoccoC * is_coccos & ! Coccolithophores
+ - N_assim_Phaeo * PhaeoC * is_coccos & ! Phaeocystis
+ !---------------------------------------------------------------------------
+ ! SOURCES: Remineralization (increases DIN)
+ !---------------------------------------------------------------------------
+ ! DON remineralization releases bioavailable nitrogen
+ + rho_N * arrFunc * O2Func * DON & ! Temperature and O2 dependent
+ ) * dt_b + sms(k,idin)
+
+ !===============================================================================
+ ! 2. DISSOLVED INORGANIC CARBON (DIC)
+ !===============================================================================
+ ! Represents the pool of inorganic carbon (CO2 + HCO3- + CO3-2)
+ !
+ ! Variables:
+ ! Cphot : Small phytoplankton photosynthesis rate [day-1]
+ ! Cphot_Dia : Diatom photosynthesis rate [day-1]
+ ! Cphot_Cocco : Coccolithophore photosynthesis rate [day-1]
+ ! Cphot_Phaeo : Phaeocystis photosynthesis rate [day-1]
+ ! phyRespRate : Small phytoplankton respiration rate [day-1]
+ ! phyRespRate_Dia : Diatom respiration rate [day-1]
+ ! phyRespRate_Cocco : Coccolithophore respiration rate [day-1]
+ ! phyRespRate_Phaeo : Phaeocystis respiration rate [day-1]
+ ! rho_C1 : Temperature-dependent DOC degradation rate [day-1]
+ ! EOC : Extracellular organic carbon [mmolC m-3]
+ ! HetRespFlux : Mesozooplankton respiration flux [mmolC m-3 day-1]
+ ! Zoo2RespFlux : Macrozooplankton respiration flux [mmolC m-3 day-1]
+ ! MicZooRespFlux : Microzooplankton respiration flux [mmolC m-3 day-1]
+ ! calc_diss : Slow-sinking calcite dissolution rate [day-1]
+ ! calc_diss2 : Fast-sinking calcite dissolution rate [day-1]
+ ! DetCalc : Slow-sinking calcite detritus pool [mmolC m-3]
+ ! DetZ2Calc : Fast-sinking calcite detritus pool [mmolC m-3]
+ ! calc_loss_gra : Calcite loss via mesozooplankton grazing [mmolC m-3 day-1]
+ ! calc_loss_gra2 : Calcite loss via macrozooplankton grazing [mmolC m-3 day-1]
+ ! calc_loss_gra3 : Calcite loss via microzooplankton grazing [mmolC m-3 day-1]
+ ! calc_diss_guts : Calcite dissolution rate in zooplankton guts [-]
+ ! calcification : Rate of CaCO3 formation [mmolC m-3 day-1]
+
+ sms(k,idic) = ( &
+ !---------------------------------------------------------------------------
+ ! SINKS: Carbon Fixation (decreases DIC)
+ !---------------------------------------------------------------------------
+ ! Photosynthetic uptake of CO2 by phytoplankton
+ - Cphot * PhyC & ! Small phytoplankton
+ - Cphot_Dia * DiaC & ! Diatoms
+ - Cphot_Cocco * CoccoC * is_coccos & ! Coccolithophores
+ - Cphot_Phaeo * PhaeoC * is_coccos & ! Phaeocystis
+ !---------------------------------------------------------------------------
+ ! SINKS: Calcification (decreases DIC)
+ !---------------------------------------------------------------------------
+ ! CaCO3 formation: Ca2+ + CO3-2 -> CaCO3
+ - calcification &
+ !---------------------------------------------------------------------------
+ ! SOURCES: Phytoplankton Respiration (increases DIC)
+ !---------------------------------------------------------------------------
+ ! Release of CO2 through autotrophic respiration
+ + phyRespRate * PhyC & ! Small phytoplankton
+ + phyRespRate_Dia * DiaC & ! Diatoms
+ + phyRespRate_Cocco * CoccoC * is_coccos & ! Coccolithophores
+ + phyRespRate_Phaeo * PhaeoC * is_coccos & ! Phaeocystis
+ !---------------------------------------------------------------------------
+ ! SOURCES: DOC Remineralization (increases DIC)
+ !---------------------------------------------------------------------------
+ ! Microbial degradation of dissolved organic carbon
+ + rho_C1 * arrFunc * O2Func * EOC & ! Temperature and O2 dependent
+ + rho_C1t * DOCt * is_riverinput & ! --> Remineralization of terrestrial DOC ! R2OMIP
+ !---------------------------------------------------------------------------
+ ! SOURCES: Zooplankton Respiration (increases DIC)
+ !---------------------------------------------------------------------------
+ ! Release of CO2 through heterotrophic respiration
+ + HetRespFlux & ! Mesozooplankton
+ + Zoo2RespFlux * is_3zoo2det & ! Macrozooplankton
+ + MicZooRespFlux * is_3zoo2det & ! Microzooplankton
+ !---------------------------------------------------------------------------
+ ! SOURCES: Calcite Dissolution (increases DIC)
+ !---------------------------------------------------------------------------
+ ! Reaction: CaCO3 + CO2 + H2O -> Ca2+ + 2HCO3-
+ + calc_diss * DetCalc & ! Slow-sinking calcite
+ + calc_loss_gra * calc_diss_guts & ! Mesozooplankton gut
+ + calc_loss_gra2 * calc_diss_guts * is_3zoo2det & ! Macrozooplankton gut
+ + calc_loss_gra3 * calc_diss_guts * is_3zoo2det & ! Microzooplankton gut
+ + calc_diss2 * DetZ2Calc * is_3zoo2det & ! Fast-sinking calcite
+ ) * dt_b + sms(k,idic)
! if((Latd(1)<-45.0) .and. ((state(k,idic)+sms(k,idic))>2500)) then
! !co2flux(1)=0.0
@@ -1135,1048 +4041,3515 @@ subroutine REcoM_sms(n,Nn,state,thick,recipthick,SurfSR,sms,Temp, Sali_depth &
! stop
! endif
-!< *** Alk ***
-!< ***********
-
-!< Alkalinity (Assumes that N:P follows a constant Redfield ratio
-!< N_assimC: 1.0625 = 1/16 + 1
-
- sms(k,ialk) = ( &
- + 1.0625 * N_assim * PhyC &
- + 1.0625 * N_assim_Dia * DiaC &
-#if defined (__coccos)
- + 1.0625 * N_assim_Cocco * CoccoC &
-#endif
- - 1.0625 * rho_N * arrFunc * O2Func * DON & ! O2remin
- + 2.d0 * calc_diss * DetCalc &
- + 2.d0 * calc_loss_gra * calc_diss_guts &
-#if defined (__3Zoo2Det)
- + 2.d0 * calc_loss_gra2 * calc_diss_guts &
- + 2.d0 * calc_loss_gra3 * calc_diss_guts & ! 3Zoo
- + 2.d0 * calc_diss2 * DetZ2Calc &
-#endif
- - 2.d0 * calcification &
- ) * dt_b + sms(k,ialk)
-!< *** Small Phytoplankton ***
-!< ***************************
-
-!____________________________________________________________
-!< Small phytoplankton N
-
-!< lossN: Phytoplankton loss of organic N compounds [day^-1]
-
- sms(k,iphyn) = ( &
- + N_assim * PhyC & ! --> N assimilation
- - lossN * limitFacN * PhyN & ! --> DON excretion
- - aggregationRate * PhyN & ! --> Aggregation loss
- - grazingFlux_phy & ! --> Grazing loss
-#if defined (__3Zoo2Det)
- - grazingFlux_phy2 &
- - grazingFlux_phy3 & ! 3Zoo
-#endif
- ) * dt_b + sms(k,iphyn)
-!____________________________________________________________
-!< Small phytoplankton C
-
-!< lossC: Phytoplankton loss of carbon [day^-1]
-!< When N : C ratio becomes too high, excretion of DOC is downregulated
-!< by the limiter function limitFacN
-!< aggregationRate transfers C to the detritus pool
-
- sms(k,iphyc) = ( &
- + Cphot * PhyC & ! --> Photosynthesis ---->/
- - lossC * limitFacN * PhyC & ! --> Excretion of DOC / Net photosynthesis
- - phyRespRate * PhyC & ! --> Respiration ----->/
- - aggregationRate * PhyC & ! --> Aggregation loss
- - grazingFlux_phy * recipQuota & ! --> Grazing loss
-#if defined (__3Zoo2Det)
- - grazingFlux_phy2 * recipQuota &
- - grazingFlux_phy3 * recipQuota & ! 3Zoo
-#endif
- ) * dt_b + sms(k,iphyc)
-!____________________________________________________________
-! Phytoplankton ChlA
-
-!< Chl2N: Conversion factor from mmolN to mgChla
-!< Chl2N = PhyChl/PhyN
-
- sms(k,ipchl) = ( &
- + chlSynth * PhyC & ! --> Chl-a synthesis
- - KOchl * PhyChl & ! --> Degradation loss
- - aggregationRate * PhyChl & ! --> Aggregation loss
- - grazingFlux_phy * Chl2N & ! --> Grazing loss
-#if defined (__3Zoo2Det)
- - grazingFlux_phy2 * Chl2N &
- - grazingFlux_phy3 * Chl2N & ! 3Zoo
-#endif
- ) * dt_b + sms(k,ipchl)
-
-!< *** Slow-sinking Detritus ***
-!< *****************************
-
-!____________________________________________________________
-! Detritus N
- if (Grazing_detritus) then
-#if defined (__3Zoo2Det)
- sms(k,idetn) = ( &
- + grazingFlux_phy3 &
- - grazingFlux_phy3 * grazEff3 &
- + grazingFlux_dia3 &
- - grazingFlux_dia3 * grazEff3 &
-#if defined (__coccos)
- + grazingFlux_Cocco3 &
- - grazingFlux_Cocco3 * grazEff3 &
- + aggregationRate * CoccoN &
-#endif
- - grazingFlux_Det * grazEff &
- - grazingFlux_Det2 * grazEff2 & ! --> okay, grazing of second zoo on first detritus
- + aggregationRate * PhyN &
- + aggregationRate * DiaN &
- + miczooLossFlux &
- - reminN * arrFunc * O2Func * DetN & ! O2remin
- ) * dt_b + sms(k,idetn)
-#else
- sms(k,idetn) = ( &
- + grazingFlux_phy &
- - grazingFlux_phy * grazEff &
- + grazingFlux_dia &
- - grazingFlux_dia * grazEff &
-#if defined (__coccos)
- + grazingFlux_Cocco &
- - grazingFlux_Cocco * grazEff &
- + aggregationRate * CoccoN &
-#endif
- - grazingFlux_Det * grazEff & ! Sloppy feeding is thought because of grazing flux multiplied with grazeff
- - grazingFlux_Det2 * grazEff2 & !!!!!!!!!!CHECK
- + aggregationRate * PhyN &
- + aggregationRate * DiaN &
- + hetLossFlux &
- - reminN * arrFunc * O2Func * DetN & ! O2remin
- ) * dt_b + sms(k,idetn)
-#endif
- else
-#if defined (__3Zoo2Det)
- sms(k,idetn) = ( &
- + grazingFlux_phy3 &
- + grazingFlux_dia3 &
-#if defined (__coccos)
- + grazingFlux_Cocco3 &
- + aggregationRate * CoccoN &
-#endif
- - grazingFlux * grazEff3 &
- + aggregationRate * PhyN &
- + aggregationRate * DiaN &
- + miczooLossFlux &
- - reminN * arrFunc * O2Func * DetN & ! O2remin
- ) * dt_b + sms(k,idetn)
-#else
- sms(k,idetn) = ( &
- + grazingFlux_phy &
- + grazingFlux_dia &
-#if defined (__coccos)
- + grazingFlux_Cocco &
- + aggregationRate * CoccoN &
-#endif
- - grazingFlux * grazEff &
- + aggregationRate * PhyN &
- + aggregationRate * DiaN &
- + hetLossFlux &
- - reminN * arrFunc * O2Func * DetN & ! O2remin
- ) * dt_b + sms(k,idetn)
-#endif
- end if
-
-!____________________________________________________________
-! Detritus C
- if (Grazing_detritus) then
-#if defined (__3Zoo2Det)
- sms(k,idetc) = ( &
- + grazingFlux_phy3 * recipQuota &
- - grazingFlux_phy3 * recipQuota * grazEff3 &
- + grazingFlux_Dia3 * recipQuota_Dia &
- - grazingFlux_Dia3 * recipQuota_Dia * grazEff3 &
-#if defined (__coccos)
- + grazingFlux_Cocco3 * recipQuota_Cocco &
- - grazingFlux_Cocco3 * recipQuota_Cocco * grazEff3 &
- + aggregationRate * CoccoC &
-#endif
- - grazingFlux_Det * recipDet * grazEff &
- - grazingFlux_Det2 * recipDet2 * grazEff2 &
- + aggregationRate * PhyC &
- + aggregationRate * DiaC &
- + miczooLossFlux * recipQZoo3 &
- - reminC * arrFunc * O2Func * DetC & ! O2remin
- ) * dt_b + sms(k,idetc)
-#else
- sms(k,idetc) = ( &
- + grazingFlux_phy * recipQuota &
- - grazingFlux_phy * recipQuota * grazEff &
- + grazingFlux_Dia * recipQuota_Dia &
- - grazingFlux_Dia * recipQuota_Dia * grazEff &
-#if defined (__coccos)
- + grazingFlux_Cocco * recipQuota_Cocco &
- - grazingFlux_Cocco * recipQuota_Cocco * grazEff &
- + aggregationRate * CoccoC &
-#endif
- - grazingFlux_Det * recipDet * grazEff &
- - grazingFlux_Det2 * recipDet2 * grazEff & !!!!!! CHECK
- + aggregationRate * phyC &
- + aggregationRate * DiaC &
- + hetLossFlux * recipQZoo &
- - reminC * arrFunc * O2Func * DetC & ! O2remin
- ) * dt_b + sms(k,idetc)
-#endif
- else
-#if defined (__3Zoo2Det)
- sms(k,idetc) = ( &
- + grazingFlux_phy3 * recipQuota &
- - grazingFlux_phy3 * recipQuota * grazEff3 &
- + grazingFlux_Dia3 * recipQuota_Dia &
- - grazingFlux_Dia3 * recipQuota_Dia * grazEff3 &
-#if defined (__coccos)
- + grazingFlux_Cocco3 * recipQuota_Cocco &
- - grazingFlux_Cocco3 * recipQuota_Cocco * grazEff3 &
- + aggregationRate * CoccoC &
-#endif
- + aggregationRate * PhyC &
- + aggregationRate * DiaC &
- + miczooLossFlux * recipQZoo3 &
- - reminC * arrFunc * O2Func * DetC & ! O2remin
- ) * dt_b + sms(k,idetc)
-#else
- sms(k,idetc) = ( &
- + grazingFlux_phy * recipQuota &
- - grazingFlux_phy * recipQuota * grazEff &
- + grazingFlux_Dia * recipQuota_Dia &
- - grazingFlux_Dia * recipQuota_Dia * grazEff &
-#if defined (__coccos)
- + grazingFlux_Cocco * recipQuota_Cocco &
- - grazingFlux_Cocco * recipQuota_Cocco * grazEff &
- + aggregationRate * CoccoC &
-#endif
- + aggregationRate * phyC &
- + aggregationRate * DiaC &
- + hetLossFlux * recipQZoo &
- - reminC * arrFunc * O2Func * DetC & ! O2remin
- ) * dt_b + sms(k,idetc)
-#endif
- end if
-
-!< *** Mesozooplankton ***
-!< ***********************
-
-!____________________________________________________________
-!< Heterotrophic N
- sms(k,ihetn) = ( &
- + grazingFlux * grazEff & ! --> Grazing on phytoplankton -> okay, because of recipQuota
-#if defined (__3Zoo2Det)
- - grazingFlux_het2 &
- - Mesfecalloss_n & ! 3Zoo
-#endif
- - hetLossFlux & ! --> Mortality
- - lossN_z * HetN & ! --> Excretion of DON
- ) * dt_b + sms(k,ihetn)
-!____________________________________________________________
-!< Heterotrophic C
+ !===============================================================================
+ ! 3. ALKALINITY (Alk)
+ !===============================================================================
+ ! Total alkalinity affects ocean pH and CO2 uptake capacity
+ ! Assumes constant Redfield N:P ratio
+ !
+ ! Key coefficient: 1.0625 = (1/16) + 1
+ ! - Represents the change in alkalinity per mole of nitrogen
+ ! - Includes both nitrate reduction (+ charge) and phosphate uptake
+
+ sms(k,ialk) = ( &
+ !---------------------------------------------------------------------------
+ ! SOURCES: Nutrient Uptake (increases alkalinity)
+ !---------------------------------------------------------------------------
+ ! Phytoplankton uptake of NO3- increases alkalinity
+ + 1.0625 * N_assim * PhyC & ! Small phytoplankton
+ + 1.0625 * N_assim_Dia * DiaC & ! Diatoms
+ + 1.0625 * N_assim_Cocco * CoccoC * is_coccos & ! Coccolithophores
+ + 1.0625 * N_assim_Phaeo * PhaeoC * is_coccos & ! Phaeocystis
+
+ !---------------------------------------------------------------------------
+ ! SINKS: Remineralization (decreases alkalinity)
+ !---------------------------------------------------------------------------
+ ! DON remineralization releases H+ and decreases alkalinity
+ - 1.0625 * rho_N * arrFunc * O2Func * DON &
+ !---------------------------------------------------------------------------
+ ! SOURCES: Calcite Dissolution (increases alkalinity)
+ !---------------------------------------------------------------------------
+ ! Reaction: CaCO3 + CO2 + H2O -> Ca2+ + 2HCO3-
+ ! Increases alkalinity by 2 equivalents per mole CaCO3
+ + 2.d0 * calc_diss * DetCalc & ! Slow-sinking calcite
+ + 2.d0 * calc_loss_gra * calc_diss_guts & ! Mesozooplankton gut
+ + 2.d0 * calc_loss_gra2 * calc_diss_guts * is_3zoo2det & ! Macrozooplankton gut
+ + 2.d0 * calc_loss_gra3 * calc_diss_guts * is_3zoo2det & ! Microzooplankton gut
+ + 2.d0 * calc_diss2 * DetZ2Calc * is_3zoo2det & ! Fast-sinking calcite
+
+ !---------------------------------------------------------------------------
+ ! SINKS: Calcification (decreases alkalinity)
+ !---------------------------------------------------------------------------
+ ! CaCO3 formation removes 2 equivalents of alkalinity
+ - 2.d0 * calcification &
+ ) * dt_b + sms(k,ialk)
+
+ !===============================================================================
+ ! SMALL PHYTOPLANKTON NITROGEN (PhyN)
+ !===============================================================================
+ ! Tracks the nitrogen content of small phytoplankton
+ !
+ ! Variables:
+ ! N_assim : N assimilation rate [day-1]
+ ! lossN : N loss rate [day-1]
+ ! limitFacN : Limiter function for N:C ratio regulation [-]
+ ! aggregationRate : Aggregation to detritus [day-1]
+ ! grazingFlux_phy : Mesozooplankton grazing [mmolN m-3 day-1]
+ ! grazingFlux_phy2 : Macrozooplankton grazing [mmolN m-3 day-1]
+ ! grazingFlux_phy3 : Microzooplankton grazing [mmolN m-3 day-1]
+
+ sms(k,iphyn) = ( &
+ !---------------------------------------------------------------------------
+ ! SOURCES: Nitrogen Assimilation
+ !---------------------------------------------------------------------------
+ + N_assim * PhyC &
+ !---------------------------------------------------------------------------
+ ! SINKS: Losses
+ !---------------------------------------------------------------------------
+ - lossN * limitFacN * PhyN & ! DON excretion (N:C regulated)
+ - aggregationRate * PhyN & ! Aggregation to detritus
+ - grazingFlux_phy & ! Mesozooplankton
+ - grazingFlux_phy2 * is_3zoo2det & ! Macrozooplankton
+ - grazingFlux_phy3 * is_3zoo2det & ! Microzooplankton
+ ) * dt_b + sms(k,iphyn)
+
+ !===============================================================================
+ ! 5. SMALL PHYTOPLANKTON CARBON (PhyC)
+ !===============================================================================
+ ! Tracks the carbon content of small phytoplankton.
+ !
+ ! Variables:
+ ! Cphot : Gross photosynthesis rate [day-1]
+ ! phyRespRate : Autotrophic respiration rate [day-1]
+ ! lossC : C loss rate [day-1]
+ ! recipQuota : Reciprocal of N:C quota (for N->C conversion) [-]
+ !
+ ! Note: DOC excretion is downregulated by limitFacN when N:C ratio is too high
+
+ sms(k,iphyc) = ( &
+ !---------------------------------------------------------------------------
+ ! SOURCES: Net Photosynthesis
+ !---------------------------------------------------------------------------
+ + Cphot * PhyC & ! Gross photosynthesis
+ - phyRespRate * PhyC & ! Autotrophic respiration
+ !---------------------------------------------------------------------------
+ ! SINKS: Losses
+ !---------------------------------------------------------------------------
+ - lossC * limitFacN * PhyC & ! DOC excretion (regulated)
+ - aggregationRate * PhyC & ! Aggregation to detritus
+ - grazingFlux_phy * recipQuota & ! Mesozooplankton (N->C)
+ - grazingFlux_phy2 * recipQuota * is_3zoo2det & ! Macrozooplankton
+ - grazingFlux_phy3 * recipQuota * is_3zoo2det & ! Microzooplankton
+ ) * dt_b + sms(k,iphyc)
+
+ !===============================================================================
+ ! 6. PHYTOPLANKTON CHLOROPHYLL-A (PhyChl)
+ !===============================================================================
+ ! Tracks chlorophyll-a content for light harvesting and photoacclimation
+ !
+ ! Variables:
+ ! chlSynth : Chlorophyll synthesis rate [mgChl mmolC-1 day-1]
+ ! KOchl : Chlorophyll degradation rate constant [day-1]
+ ! Chl2N : Chl:N ratio = PhyChl/PhyN [mgChl mmolN-1]
+
+ sms(k,ipchl) = ( &
+ !---------------------------------------------------------------------------
+ ! SOURCES: Chlorophyll Synthesis
+ !---------------------------------------------------------------------------
+ + chlSynth * PhyC & ! Photoacclimation
+ !---------------------------------------------------------------------------
+ ! SINKS: Degradation and Losses
+ !---------------------------------------------------------------------------
+
+ - KOchl * PhyChl & ! Natural degradation
+ - aggregationRate * PhyChl & ! Aggregation to detritus
+ - grazingFlux_phy * Chl2N & ! Mesozooplankton
+ - grazingFlux_phy2 * Chl2N * is_3zoo2det & ! Macrozooplankton
+ - grazingFlux_phy3 * Chl2N * is_3zoo2det & ! Microzooplankton
+ ) * dt_b + sms(k,ipchl)
+
+ !===============================================================================
+ ! 7. DETRITUS NITROGEN (DetN)
+ !===============================================================================
+ ! Tracks nitrogen content in slow-sinking organic particles.
+ !
+ ! Key Concepts:
+ ! - Sloppy Feeding: Not all grazed material is assimilated
+ ! Net detritus = Total grazing × (1 - grazing efficiency)
+ ! - Four Configurations: Based on Grazing_detritus and enable_3zoo2det flags
+ !
+ ! Variables:
+ ! grazEff, grazEff2, grazEff3 : Grazing efficiency (assimilation) [-]
+ ! aggregationRate : Aggregation rate [day-1]
+ ! hetLossFlux, miczooLossFlux : Zooplankton mortality [mmolN m-3 day-1]
+ ! reminN : Remineralization rate [day-1]
+ ! arrFunc : Arrhenius temperature function [-]
+ ! O2Func : Oxygen limitation function [-]
+ ! grazingFlux_phy3, grazingFlux_dia3 : Grazing by microzooplankton [mmolN m-3 day-1]
+ ! grazingFlux_phy, grazingFlux_dia : Grazing by mesozooplankton [mmolN m-3 day-1]
+ ! DetN : Detrital nitrogen concentration [mmolN m-3]
+ ! dt_b : Time step [day]
+ !-------------------------------------------------------------------------------
+
+ !-------------------------------------------------------------------------------
+ ! Configuration 1: WITH Detritus Grazing + 3 Zooplankton Types
+ !-------------------------------------------------------------------------------
+
if (Grazing_detritus) then
- sms(k,ihetc) = ( &
- + grazingFlux_phy * recipQuota * grazEff & ! --> Grazing on small phytoplankton
- + grazingFlux_Dia * recipQuota_Dia * grazEff & ! --> Grazing on diatom
-#if defined (__coccos)
- + grazingFlux_Cocco * recipQuota_Cocco * grazEff &
-#endif
-#if defined (__3Zoo2Det)
- + grazingFlux_miczoo * recipQZoo3 * grazEff & ! 3Zoo
- + grazingFlux_DetZ2 * recipDet2 * grazEff &
- - grazingFlux_het2 * recipQZoo &
- - Mesfecalloss_c & ! 3Zoo
-#endif
- + grazingFlux_Det * recipDet * grazEff & ! --> Grazing on detritus
- - hetLossFlux * recipQZoo & ! --> Mortality loss
- - lossC_z * HetC & ! --> Excretion loss
- - hetRespFlux & ! --> REspiration loss
- ) * dt_b + sms(k,ihetc)
+ if (enable_3zoo2det) then
+ sms(k,idetn) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Sloppy Feeding by Microzooplankton
+ !-----------------------------------------------------------------------
+ ! Net flux = Total grazing - Assimilated portion
+ + grazingFlux_phy3 - grazingFlux_phy3 * grazEff3 & ! Small phytoplankton
+ + grazingFlux_dia3 - grazingFlux_dia3 * grazEff3 & ! Diatoms
+ + (grazingFlux_Cocco3 - grazingFlux_Cocco3 * grazEff3) * is_coccos & ! Coccolithophores
+ + (grazingFlux_Phaeo3 - grazingFlux_Phaeo3 * grazEff3) * is_coccos & ! Phaeocystis
+ !-----------------------------------------------------------------------
+ ! SOURCES: Phytoplankton Aggregation
+ !-----------------------------------------------------------------------
+ + aggregationRate * PhyN &
+ + aggregationRate * DiaN &
+ + aggregationRate * CoccoN * is_coccos &
+ + aggregationRate * PhaeoN * is_coccos &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Zooplankton Mortality
+ !-----------------------------------------------------------------------
+ + miczooLossFlux &
+ !-----------------------------------------------------------------------
+ ! SINKS: Detritus Consumption
+ !-----------------------------------------------------------------------
+ - grazingFlux_Det * grazEff & ! Mesozooplankton
+ - grazingFlux_Det2 * grazEff2 & ! Macrozooplankton
+ !-----------------------------------------------------------------------
+ ! SINKS: Remineralization
+ !-----------------------------------------------------------------------
+ - reminN * arrFunc * O2Func * DetN & ! Bacterial decomposition
+ ) * dt_b + sms(k,idetn)
+ !-------------------------------------------------------------------------------
+ ! Configuration 2: WITH Detritus Grazing + 2 Zooplankton Types (Standard)
+ !-------------------------------------------------------------------------------
+ else
+ sms(k,idetn) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Sloppy Feeding by Mesozooplankton
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy - grazingFlux_phy * grazEff & ! Small phytoplankton
+ + grazingFlux_dia - grazingFlux_dia * grazEff & ! Diatoms
+ + (grazingFlux_Cocco - grazingFlux_Cocco * grazEff) * is_coccos & ! Coccolithophores
+ + (grazingFlux_Phaeo - grazingFlux_Phaeo * grazEff) * is_coccos & ! Phaeocystis
+ !-----------------------------------------------------------------------
+ ! SOURCES: Phytoplankton Aggregation
+ !-----------------------------------------------------------------------
+ + aggregationRate * PhyN &
+ + aggregationRate * DiaN &
+ + aggregationRate * CoccoN * is_coccos &
+ + aggregationRate * PhaeoN * is_coccos &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Zooplankton Mortality
+ !-----------------------------------------------------------------------
+ + hetLossFlux &
+ !-----------------------------------------------------------------------
+ ! SINKS: Detritus Consumption
+ !-----------------------------------------------------------------------
+ - grazingFlux_Det * grazEff & ! Mesozooplankton
+ - grazingFlux_Det2 * grazEff2 & ! Macrozooplankton
+ !-----------------------------------------------------------------------
+ ! SINKS: Remineralization
+ !-----------------------------------------------------------------------
+ - reminN * arrFunc * O2Func * DetN &
+ ) * dt_b + sms(k,idetn)
+ endif
+ !-------------------------------------------------------------------------------
+ ! Configuration 3: WITHOUT Detritus Grazing + 3 Zooplankton Types
+ !-------------------------------------------------------------------------------
else
- sms(k,ihetc) = ( &
- + grazingFlux_phy * recipQuota * grazEff &
- + grazingFlux_Dia * recipQuota_Dia * grazEff &
-#if defined (__coccos)
- + grazingFlux_Cocco * recipQuota_Cocco * grazEff &
-#endif
-#if defined (__3Zoo2Det)
- + grazingFlux_miczoo * recipQZoo3 * grazEff & ! 3Zoo
- - grazingFlux_het2 * recipQZoo &
- - Mesfecalloss_c & ! 3Zoo
-#endif
- - hetLossFlux * recipQZoo &
- - lossC_z * HetC &
- - hetRespFlux &
- ) * dt_b + sms(k,ihetc)
- endif
-
-!< *** Macrozooplankton ***
-!< ************************
-
-#if defined (__3Zoo2Det)
-!____________________________________________________________
-!< Second Zooplankton N
- sms(k,izoo2n) = ( &
- + grazingFlux2 * grazEff2 &
- - Zoo2LossFlux &
- - lossN_z2 * Zoo2N &
- - Zoo2fecalloss_n &
- ) * dt_b + sms(k,izoo2n)
-
-!____________________________________________________________
-!< Second Zooplankton C
- if (Grazing_detritus) then
-
- sms(k,izoo2c) = ( &
- + grazingFlux_phy2 * recipQuota * grazEff2 &
- + grazingFlux_Dia2 * recipQuota_Dia * grazEff2 &
-#if defined (__coccos)
- + grazingFlux_Cocco2 * recipQuota_Cocco * grazEff2 &
-#endif
- + grazingFlux_het2 * recipQZoo * grazEff2 &
- + grazingFlux_miczoo2* recipQZoo3 * grazEff2 & ! 3Zoo
- + grazingFlux_Det2 * recipDet * grazEff2 &
- + grazingFlux_DetZ22 * recipDet2 * grazEff2 &
- - zoo2LossFlux * recipQZoo2 &
- - lossC_z2 * Zoo2C &
- - Zoo2RespFlux &
- - Zoo2fecalloss_c &
- ) * dt_b + sms(k,izoo2c)
- else
- sms(k,izoo2c) = ( &
- + grazingFlux_phy2 * recipQuota * grazEff2 &
- + grazingFlux_Dia2 * recipQuota_Dia * grazEff2 &
-#if defined (__coccos)
- + grazingFlux_Cocco2 * recipQuota_Cocco * grazEff2 &
-#endif
- + grazingFlux_het2 * recipQZoo * grazEff2 &
- + grazingFlux_miczoo2* recipQZoo3 * grazEff2 & ! 3Zoo
- - zoo2LossFlux * recipQZoo2 &
- - lossC_z2 * Zoo2C &
- - Zoo2RespFlux &
- - Zoo2fecalloss_c &
- ) * dt_b + sms(k,izoo2c)
- end if
-
-!< *** Microzooplankton ***
-!< ************************
-
-!____________________________________________________________
-!< Third Zooplankton N
- sms(k,imiczoon) = ( &
- + grazingFlux3 * grazEff3 &
- - grazingFlux_miczoo &
- - grazingFlux_miczoo2 &
- - MicZooLossFlux &
- - lossN_z3 * MicZooN &
- ) * dt_b + sms(k,imiczoon)
-
-!____________________________________________________________
-!< Third Zooplankton C
- sms(k,imiczooc) = ( &
- + grazingFlux_phy3 * recipQuota * grazEff3 &
- + grazingFlux_Dia3 * recipQuota_Dia * grazEff3 &
-#if defined (__coccos)
- + grazingFlux_Cocco3 * recipQuota_Cocco * grazEff3 &
-#endif
- - MicZooLossFlux * recipQZoo3 &
- - grazingFlux_miczoo * recipQZoo3 &
- - grazingFlux_miczoo2 * recipQZoo3 &
- - lossC_z3 * MicZooC &
- - MicZooRespFlux &
- ) * dt_b + sms(k,imiczooc)
-
-!< *** Fast-sinking Detritus ***
-!< *****************************
-
-!____________________________________________________________
-!< Second Zooplankton Detritus N
- if (Grazing_detritus) then
- sms(k,idetz2n) = ( &
- + grazingFlux_phy2 &
- - grazingFlux_phy2 * grazEff2 &
- + grazingFlux_dia2 &
- - grazingFlux_dia2 * grazEff2 &
-#if defined (__coccos)
- + grazingFlux_Cocco &
- - grazingFlux_Cocco * grazEff &
- + grazingFlux_Cocco2 &
- - grazingFlux_Cocco2 * grazEff2 &
-#endif
- + grazingFlux_het2 &
- - grazingFlux_het2 * grazEff2 &
- + grazingFlux_miczoo2 &
- - grazingFlux_miczoo2 * grazEff2 &
- + grazingFlux_phy &
- - grazingFlux_phy * grazEff &
- + grazingFlux_dia &
- - grazingFlux_dia * grazEff &
- + grazingFlux_miczoo &
- - grazingFlux_miczoo * grazEff &
- - grazingFlux_DetZ2 * grazEff &
- - grazingFlux_DetZ22 * grazEff2 &
- + Zoo2LossFlux &
- + hetLossFlux &
- + Zoo2fecalloss_n &
- + Mesfecalloss_n &
- - reminN * arrFunc * O2Func * DetZ2N & ! O2remin
- ) * dt_b + sms(k,idetz2n)
- else
- sms(k,idetz2n) = ( &
- + grazingFlux_phy2 &
- + grazingFlux_dia2 &
-#if defined (__coccos)
- + grazingFlux_Cocco &
- + grazingFlux_Cocco2 &
-#endif
- + grazingFlux_het2 &
- + grazingFlux_miczoo2 &
- - grazingFlux2 * grazEff2 &
- + grazingFlux_phy &
- + grazingFlux_dia &
- + grazingFlux_miczoo &
- - grazingFlux * grazEff &
- + Zoo2LossFlux &
- + hetLossFlux &
- + Zoo2fecalloss_n &
- + Mesfecalloss_n &
- - reminN * arrFunc * O2Func * DetZ2N & ! O2remin
- ) * dt_b + sms(k,idetz2n)
- end if
-
-!____________________________________________________________
-!< Second Zooplankton Detritus C
- if (Grazing_detritus) then
- sms(k,idetz2c) = ( &
- + grazingFlux_phy2 * recipQuota &
- - grazingFlux_phy2 * recipQuota * grazEff2 &
- + grazingFlux_Dia2 * recipQuota_Dia &
- - grazingFlux_Dia2 * recipQuota_Dia * grazEff2 &
-#if defined (__coccos)
- + grazingFlux_Cocco * recipQuota_Cocco &
- - grazingFlux_Cocco * recipQuota_Cocco * grazEff &
- + grazingFlux_Cocco2 * recipQuota_Cocco &
- - grazingFlux_Cocco2 * recipQuota_Cocco * grazEff2 &
-#endif
- + grazingFlux_het2 * recipQZoo &
- - grazingFlux_het2 * recipQZoo * grazEff2 &
- + grazingFlux_miczoo2 * recipQZoo3 &
- - grazingFlux_miczoo2 * recipQZoo3 * grazEff2 &
- + grazingFlux_phy * recipQuota &
- - grazingFlux_phy * recipQuota * grazEff &
- + grazingFlux_Dia * recipQuota_Dia &
- - grazingFlux_Dia * recipQuota_Dia * grazEff &
- + grazingFlux_miczoo * recipQZoo3 &
- - grazingFlux_miczoo * recipQZoo3 * grazEff &
- - grazingFlux_DetZ2 * recipDet2 * grazEff &
- - grazingFlux_DetZ22 * recipDet2 * grazEff2 &
- + Zoo2LossFlux * recipQZoo2 &
- + hetLossFlux * recipQZoo &
- + Zoo2fecalloss_c &
- + Mesfecalloss_c &
- - reminC * arrFunc * O2Func * DetZ2C & ! O2remin
- ) * dt_b + sms(k,idetz2c)
- else
- sms(k,idetz2c) = ( &
- + grazingFlux_phy2 * recipQuota &
- - grazingFlux_phy2 * recipQuota * grazEff2 &
- + grazingFlux_Dia2 * recipQuota_Dia &
- - grazingFlux_Dia2 * recipQuota_Dia * grazEff2 &
-#if defined (__coccos)
- + grazingFlux_Cocco * recipQuota_Cocco &
- - grazingFlux_Cocco * recipQuota_Cocco * grazEff &
- + grazingFlux_Cocco2 * recipQuota_Cocco &
- - grazingFlux_Cocco2 * recipQuota_Cocco * grazEff2 &
-#endif
- + grazingFlux_het2 * recipQZoo &
- - grazingFlux_het2 * recipQZoo * grazEff2 &
- + grazingFlux_miczoo2 * recipQZoo3 &
- - grazingFlux_miczoo2 * recipQZoo3 * grazEff2 &
- + grazingFlux_phy * recipQuota &
- - grazingFlux_phy * recipQuota * grazEff &
- + grazingFlux_Dia * recipQuota_Dia &
- - grazingFlux_Dia * recipQuota_Dia * grazEff &
- + grazingFlux_miczoo * recipQZoo3 &
- - grazingFlux_miczoo * recipQZoo3 * grazEff &
- + Zoo2LossFlux * recipQZoo2 &
- + hetLossFlux * recipQZoo &
- + Zoo2fecalloss_c &
- + Mesfecalloss_c &
- - reminC * arrFunc * O2Func * DetZ2C & ! O2remin
- ) * dt_b + sms(k,idetz2c)
- end if
-
-!____________________________________________________________
-!< Second Zooplankton Detritus Si
- sms(k,idetz2si) = ( &
- + grazingFlux_dia2 * qSiN & ! --> qSin convert N to Si
- + grazingFlux_dia * qSiN &
- - reminSiT * DetZ2Si &
- ) * dt_b + sms(k,idetz2si)
-
-!____________________________________________________________
-!< Second Zooplankton Detritus calcite
- sms(k,idetz2calc) = ( &
- + calc_loss_gra2 &
- - calc_loss_gra2 * calc_diss_guts &
- + calc_loss_gra &
- - calc_loss_gra * calc_diss_guts &
- - calc_diss2 * DetZ2Calc &
- ) * dt_b + sms(k,idetz2calc)
-#endif
-
-!< *** DOM ***
-!< ***********
-
-!____________________________________________________________
-!< DON (Extracellular organic N)
-
- sms(k,idon) = ( &
- + lossN * limitFacN * phyN &
- + lossN_d * limitFacN_Dia * DiaN &
-#if defined (__coccos)
- + lossN_c * limitFacN_Cocco * CoccoN &
-#endif
- + reminN * arrFunc * O2Func * DetN &
- + lossN_z * HetN &
-#if defined (__3Zoo2Det)
- + reminN * arrFunc * O2Func * DetZ2N &
- + lossN_z2 * Zoo2N &
- + lossN_z3 * MicZooN & ! 3Zoo
-#endif
- - rho_N * arrFunc * O2Func * DON & ! O2remin
- ) * dt_b + sms(k,idon)
-
-!____________________________________________________________
-!< EOC
-
- sms(k,idoc) = ( &
- + lossC * limitFacN * phyC &
- + lossC_d * limitFacN_dia * DiaC &
-#if defined (__coccos)
- + lossC_c * limitFacN_cocco * CoccoC &
-#endif
- + reminC * arrFunc * O2Func * DetC &
- + lossC_z * HetC &
-#if defined (__3Zoo2Det)
- + reminC * arrFunc * O2Func * DetZ2C &
- + lossC_z2 * Zoo2C &
- + lossC_z3 * MicZooC & ! 3Zoo
-#endif
- - rho_c1 * arrFunc * O2Func * EOC & ! O2remin
- ) * dt_b + sms(k,idoc)
-
-!< *** Diatoms ***
-!< ***************
-
-!____________________________________________________________
-!< Diatom N
-
-!< lossN: Diatom loss of organic N compounds [day^-1]
-!< When N : C ratio becomes too high, excretion of DON is downregulated
-!< by the limiter function limitFacN_dia
-!< aggregationRate transfers N to the detritus pool
-
- sms(k,idian) = ( &
- + N_assim_dia * DiaC & ! --> N assimilation
- - lossN_d * limitFacN_dia * DiaN & ! --> DON excretion
- - aggregationRate * DiaN & ! --> Aggregation loss
- - grazingFlux_Dia & ! --> Grazing loss
-#if defined (__3Zoo2Det)
- - grazingFlux_Dia2 &
- - grazingFlux_Dia3 & ! 3Zoo
-#endif
- ) * dt_b + sms(k,idian)
-
-!____________________________________________________________
-!< Diatom C
-
-!< lossC_d: Diatom loss of carbon [day^-1]
-!< When N : C ratio becomes too high, excretion of DOC is downregulated
-!< by the limiter function limitFacN_dia
-!< aggregationRate transfers C to the detritus pool
-
- sms(k,idiac) = ( &
- + Cphot_dia * DiaC & ! -- Photosynthesis ---->/
- - lossC_d * limitFacN_dia * DiaC & ! -- Excretion of DOC --/ Net Photosynthesis
- - phyRespRate_dia * DiaC & ! -- Respiration ----->/
- - aggregationRate * DiaC &
- - grazingFlux_dia * recipQuota_dia &
-#if defined (__3Zoo2Det)
- - grazingFlux_dia2 * recipQuota_dia &
- - grazingFlux_dia3 * recipQuota_dia & ! 3Zoo
-#endif
- ) * dt_b + sms(k,idiac)
-
-!____________________________________________________________
-!< Diatom Chl
-
- sms(k,idchl) = ( &
- + chlSynth_dia * DiaC & ! --> Chl a synthesis
- - KOchl_dia * DiaChl & ! --> Degradation loss
- - aggregationRate * DiaChl & ! --> Aggregation loss
- - grazingFlux_dia * Chl2N_dia & ! --> Grazing loss
-#if defined (__3Zoo2Det)
- - grazingFlux_dia2 * Chl2N_dia &
- - grazingFlux_dia3 * Chl2N_dia & ! 3Zoo
-#endif
- ) * dt_b + sms(k,idchl)
-
-!____________________________________________________________
-!< Diatom Si
-
-!< lossN_d: Diatom loss of organic nitrogen compunds [day^-1]
-!< When N : C ratio becomes too high, excretion is downregulated
-!< by the limiter function limitFacN_dia
-!< aggregationRate transfers Si to the detritus pool
-
- sms(k,idiasi) = ( &
- + Si_assim * DiaC & ! -- Diatom silicon assimilation
- - lossN_d * limitFacN_dia * DiaSi & ! -- Excretion to detritus
- - aggregationRate * DiaSi & ! -- Aggregation loss
- - grazingFlux_dia * qSiN & ! -- Grazing loss
-#if defined (__3Zoo2Det)
- - grazingFlux_dia2 * qSiN &
- - grazingFlux_dia3 * qSiN & ! 3Zoo
-#endif
- ) * dt_b + sms(k,idiasi)
-
-!< *** Coccolithophore ***
-!< ***********************
-
-#if defined (__coccos)
-!____________________________________________________________
-!< Coccolithophore N
- sms(k,icocn) = ( &
- + N_assim_cocco * CoccoC &
- - lossN_c * limitFacN_cocco * CoccoN &
- - aggregationRate * CoccoN &
- - grazingFlux_Cocco &
-#if defined (__3Zoo2Det)
- - grazingFlux_Cocco2 &
- - grazingFlux_Cocco3 & ! 3Zoo
-#endif
- ) * dt_b + sms(k,icocn)
-
-!____________________________________________________________
-!< Coccolithophore C
-
- sms(k,icocc) = ( &
- + Cphot_cocco * CoccoC &
- - lossC_c * limitFacN_cocco * CoccoC &
- - phyRespRate_cocco * CoccoC &
- - aggregationRate * CoccoC &
- - grazingFlux_cocco * recipQuota_cocco &
-#if defined (__3Zoo2Det)
- - grazingFlux_Cocco2 * recipQuota_cocco &
- - grazingFlux_Cocco3 * recipQuota_cocco & ! 3Zoo
-#endif
- ) * dt_b + sms(k,icocc)
-
- if(sms(k,icocc)>100) then
- print*,'ERROR: strange CoccoC !'
- print*,'k= ', k
- print*,'dt= ', dt
- print*,'dt_b= ', dt_b
- print*,'state(k,icocc): ', state(k,icocc)
- print*,'sms CoccoC: ', CoccoC
- print*,'sms CoccoN: ', CoccoN
- print*,'sms Cphot cocco: ', Cphot_cocco*CoccoC
- print*,'sms lossC_c: ', lossC_c
- print*,'sms limitFacN_cocco: ', limitFacN_cocco
- print*,'sms phyRespRate_cocco: ', phyRespRate_cocco
- print*,'sms grazingFlux_cocco: ', grazingFlux_cocco
- print*,'sms grazingFlux_cocco2: ', grazingFlux_Cocco2
- print*,'sms grazingFlux_cocco3: ', grazingFlux_Cocco3
- print*,'sms recipQuota_cocco: ', recipQuota_cocco
-
- print*,'sms recipQuota_cocco: ', recipQuota_cocco
- call par_ex(partit%MPI_COMM_FESOM, partit%mype)
- stop
- endif
-
-!____________________________________________________________
-!< Coccolithophore Chl
-
- sms(k,icchl) = ( &
- + ChlSynth_cocco * CoccoC &
- - KOchl_cocco * CoccoChl &
- - aggregationRate * CoccoChl &
- - grazingFlux_cocco * Chl2N_cocco &
-#if defined (__3Zoo2Det)
- - grazingFlux_Cocco2 * Chl2N_cocco &
- - grazingFlux_Cocco3 * Chl2N_cocco & ! 3Zoo
-#endif
- ) * dt_b + sms(k,icchl)
-#endif
-
-!< *** Silicate ***
-!< ****************
-
-!____________________________________________________________
-!< Detritus Si
-#if defined (__3Zoo2Det)
- sms(k,idetsi) = ( &
- + aggregationRate * DiaSi &
- + lossN_d * limitFacN_dia * DiaSi &
- + grazingFlux_dia3 * qSiN &
- - reminSiT * DetSi &
- ) * dt_b + sms(k,idetsi)
-#else
- sms(k,idetsi) = ( &
- + aggregationRate * DiaSi &
- + lossN_d * limitFacN_dia * DiaSi &
- + grazingFlux_dia * qSiN &
- - reminSiT * DetSi &
- ) * dt_b + sms(k,idetsi)
-#endif
-!____________________________________________________________
-!< DSi, Silicate
-
-!< DiaC: Intracellular carbon concentration in diatoms [mmolC m-3]
-!< DetSi: Detritus silicon concentration [mmolSi m-3]
-!< Si_assim: Si assimilation rate for diatoms [mmolSi mmolC-1 day-1]
-!< reminSiT: Remineralization rate of silicon, temperature dependency [day-1]
-!< dt_b: REcoM time step [day]
-
-!! Schourup 2013 Eq. A3
-
- sms(k,isi) = ( &
- - Si_assim * DiaC & ! --> Si assimilation of diatoms
- + reminSiT * DetSi & ! --> Remineralization of detritus, temperature dependent
-#if defined (__3Zoo2Det)
- + reminSiT * DetZ2Si &
-#endif
- ) * dt_b + sms(k,isi)
-!< *** Iron ***
-!< ************
-
-!____________________________________________________________
-!< Fe
-
-!< Fe2N: Intracellular Fe : N ratio [μmol Fe mmol N^-1] Fe2N = Fe2C * 6.625
-!< PhyC: Intracellular carbon concentration in nanophytoplankton [mmolCm^-3]
-!< Cphot: C-specific actual rate of photosynthesis for nanopyhtoplankton [day^-1]
-!< DiaC: Intracellular carbon concentration in diatoms [mmol C m^-3 ]
-!< Cphot_dia: C-specific actual rate of photosynthesis for diatom [day^-1]
-!< phyRespRate: Nanopyhtoplankton respiration rate [day^-1]
-!< phyRespRate_dia: Diatom respiration rate [day^-1]
-!< lossC: Nanopyhtoplankton excretion of organic C [day^-1]
-!< limitFacN: limiting factor
-!< lossC_d: Diatom excretion of organic C [day^-1]
-!< limitFacN_dia: limiting factor
-!< detC: Detritus carbon concentration [mmol C m^-3]
-!< reminC: Temperature dependent remineralisation rate of detritus [day^-1]
-!< arrFunc: Arrhenius function
-!< hetC: Zooplankton carbon concentration [mmol C m^-3 ]
-!< lossC_z: Zooplankton excretion of organic C [day^-1 ]
-!< hetRespFlux: Zooplankton respiration rate [day^-1]
-!< kScavFe: Scavenging rate of iron [m3 mmol C^-1 day^-1]
-
- sms(k,ife) = ( Fe2N * ( &
- - N_assim * PhyC & ! --> N assimilation Nanophytoplankton, [mmol N/(mmol C * day)] C specific N utilization rate
- - N_assim_dia * DiaC & ! --> N assimilation Diatom
-#if defined (__coccos)
- - N_assim_cocco * CoccoC &
- + lossN_c * limitFacN_cocco * CoccoN &
-#endif
- + lossN * limitFacN * PhyN & ! --> Excretion from small pythoplankton
- + lossN_d * limitFacN_dia * DiaN & ! --> Excretion from diatom
- + reminN * arrFunc * O2Func * DetN & ! --> Remineralization of detritus ! NEW O2remin
- + lossN_z * HetN & ! --> Excretion from zooplankton
-#if defined (__3Zoo2Det)
- + reminN * arrFunc * O2Func * DetZ2N & ! O2remin
- + lossN_z2 * Zoo2N &
- + lossN_z3 * MicZooN & ! 3Zoo
-#endif
- ) &
- - kScavFe * DetC * FreeFe &
-#if defined (__3Zoo2Det)
- - kScavFe * DetZ2C * FreeFe &
-#endif
- ) * dt_b + sms(k,ife)
-
-!< *** Calcification ***
-!< *********************
-
-!____________________________________________________________
-!< Small phytoplankton calcite
-
-#if defined (__coccos)
- sms(k,iphycal) = ( &
- + calcification & ! --> Calcification
- - lossC_c * limitFacN_cocco * PhyCalc & ! --> Excretion loss
- - phyRespRate_cocco * PhyCalc & ! --> Respiration
- - calc_loss_agg & ! --> Aggregation loss
- - calc_loss_gra & ! --> Grazing loss
-#if defined (__3Zoo2Det)
- - calc_loss_gra2 &
- - calc_loss_gra3 & ! 3Zoo
-#endif
- ) * dt_b + sms(k,iphycal)
-#else
- sms(k,iphycal) = ( &
- + calcification & ! --> Calcification
- - lossC * limitFacN * PhyCalc & ! --> Excretion loss
- - phyRespRate * PhyCalc & ! --> Respiration
- - calc_loss_agg & ! --> Aggregation loss
- - calc_loss_gra & ! --> Grazing loss
-#if defined (__3Zoo2Det)
- - calc_loss_gra2 &
- - calc_loss_gra3 & ! 3Zoo
-#endif
- ) * dt_b + sms(k,iphycal)
-#endif
-
-!____________________________________________________________
-! Detritus calcite
-#if defined (__coccos)
-
-#if defined (__3Zoo2Det)
- sms(k,idetcal) = ( &
- + lossC_c * limitFacN_cocco * PhyCalc &
- + phyRespRate_cocco * PhyCalc &
- + calc_loss_agg &
- + calc_loss_gra3 &
- - calc_loss_gra3 * calc_diss_guts &
- - calc_diss * DetCalc &
- ) * dt_b + sms(k,idetcal)
-
-#else
- sms(k,idetcal) = ( &
- + lossC_c * limitFacN_cocco * PhyCalc &
- + phyRespRate_cocco * PhyCalc &
- + calc_loss_agg &
- + calc_loss_gra &
- - calc_loss_gra * calc_diss_guts &
- - calc_diss * DetCalc &
- ) * dt_b + sms(k,idetcal)
-
-#endif
-
-#else
-
-#if defined (__3Zoo2Det)
- sms(k,idetcal) = ( &
- + lossC * limitFacN * PhyCalc &
- + phyRespRate * PhyCalc &
- + calc_loss_agg &
- + calc_loss_gra3 &
- - calc_loss_gra3 * calc_diss_guts &
- - calc_diss * DetCalc &
- ) * dt_b + sms(k,idetcal)
-#else
- sms(k,idetcal) = ( &
- + lossC * limitFacN * PhyCalc &
- + phyRespRate * PhyCalc &
- + calc_loss_agg &
- + calc_loss_gra &
- - calc_loss_gra * calc_diss_guts &
- - calc_diss * DetCalc &
- ) * dt_b + sms(k,idetcal)
-#endif
-#endif
-
-!____________________________________________________________
-! Oxygen
-
- sms(k,ioxy) = ( &
- + Cphot * phyC &
- - phyRespRate * phyC &
- + Cphot_dia * diaC &
- - phyRespRate_dia * diaC &
-#if defined (__coccos)
- + Cphot_cocco * CoccoC &
- - phyRespRate_cocco * CoccoC &
-#endif
- - rho_C1 * arrFunc * O2Func * EOC & ! O2remin
- - hetRespFlux &
-#if defined (__3Zoo2Det)
- - Zoo2RespFlux &
- - MicZooRespFlux & ! 3Zoo
-#endif
- ) * redO2C * dt_b + sms(k,ioxy)
-!
-!-------------------------------------------------------------------------------
-! Diagnostics: Averaged rates
-
- recipbiostep = 1.d0/real(biostep)
-if (Diags) then
-!*** Net primary production [mmol C /(m3 * day)]
- vertNPPn(k) = vertNPPn(k) + ( &
- + Cphot * PhyC &
- - PhyRespRate * PhyC &
- ) * recipbiostep
-
- vertNPPd(k) = vertNPPd(k) + ( &
- + Cphot_dia * DiaC &
- - PhyRespRate_dia * DiaC &
- ) * recipbiostep
+ if (enable_3zoo2det) then
+ sms(k,idetn) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Direct Transfer from Grazing
+ !-----------------------------------------------------------------------
+ ! All grazed material enters detritus (no detritus grazing)
+ + grazingFlux_phy3 & ! Microzooplankton->small phyto !OG added
+ + grazingFlux_dia3 & ! Microzooplankton->diatoms
+ + grazingFlux_Cocco3 * is_coccos & ! Microzooplankton->coccoliths
+ + grazingFlux_Phaeo3 * is_coccos & ! Microzooplankton->Phaeocystis
+ !-----------------------------------------------------------------------
+ ! SOURCES: Phytoplankton Aggregation
+ !-----------------------------------------------------------------------
+ + aggregationRate * PhyN &
+ + aggregationRate * DiaN &
+ + aggregationRate * CoccoN * is_coccos &
+ + aggregationRate * PhaeoN * is_coccos &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Zooplankton Mortality
+ !-----------------------------------------------------------------------
+ + miczooLossFlux &
+ !-----------------------------------------------------------------------
+ ! SINKS: Generic Zooplankton Consumption
+ !-----------------------------------------------------------------------
+ - grazingFlux * grazEff3 &
+ !-----------------------------------------------------------------------
+ ! SINKS: Remineralization
+ !-----------------------------------------------------------------------
+ - reminN * arrFunc * O2Func * DetN &
+ ) * dt_b + sms(k,idetn)
+
+ !-------------------------------------------------------------------------------
+ ! Configuration 4: WITHOUT Detritus Grazing + 2 Zooplankton Types
+ !-------------------------------------------------------------------------------
+ else
+ sms(k,idetn) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Direct Transfer from Grazing
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy & ! Mesozooplankton->small phyto
+ + grazingFlux_dia & ! Mesozooplankton->diatoms
+ + grazingFlux_Cocco * is_coccos & ! Mesozooplankton->coccoliths
+ + grazingFlux_Phaeo * is_coccos & ! Mesozooplankton->Phaeocystis
+ !-----------------------------------------------------------------------
+ ! SOURCES: Phytoplankton Aggregation
+ !-----------------------------------------------------------------------
+ + aggregationRate * PhyN &
+ + aggregationRate * DiaN &
+ + aggregationRate * CoccoN * is_coccos &
+ + aggregationRate * PhaeoN * is_coccos &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Zooplankton Mortality
+ !-----------------------------------------------------------------------
+ + hetLossFlux &
+ !-----------------------------------------------------------------------
+ ! SINKS: Generic Zooplankton Consumption
+ !-----------------------------------------------------------------------
+ - grazingFlux * grazEff &
+ !-----------------------------------------------------------------------
+ ! SINKS: Remineralization
+ !-----------------------------------------------------------------------
+ - reminN * arrFunc * O2Func * DetN &
+ ) * dt_b + sms(k,idetn)
+ endif
+ end if
+
+ !===============================================================================
+ ! 8. DETRITUS CARBON (DetC)
+ !===============================================================================
+ ! Tracks carbon content in slow-sinking organic particles
+ !
+ ! Key Concepts:
+ ! - Stoichiometric Conversion: N-based fluxes -> C-based fluxes
+ ! Uses reciprocal quotas (recipQuota = C:N ratio) for conversion
+ ! - Sloppy Feeding: Net detritus = Total grazing × (1 - efficiency)
+ !
+ ! Variables:
+ ! recipQuota, recipQuota_Dia, etc. : C:N quotas for phytoplankton [-]
+ ! recipDet, recipDet2 : C:N ratios in detritus [-]
+ ! recipQZoo, recipQZoo2, recipQZoo3: C:N ratios in zooplankton [-]
+ ! reminC : C remineralization rate [day-1]
+ !
+!===============================================================================
+! KEY CONCEPTS:
+!===============================================================================
+! 1. SLOPPY FEEDING: Not all grazed material is assimilated
+! - Net detritus production = Total grazing × (1 - grazing efficiency)
+! - Represents fecal pellets and inefficient consumption
+!
+! 2. STOICHIOMETRIC CONVERSION: N-based fluxes -> C-based fluxes
+! - recipQuota = C:N ratio of phytoplankton
+! - recipDet = C:N ratio of detritus
+! - recipQZoo = C:N ratio of zooplankton
+!
+! 3. FOOD WEB CONFIGURATIONS:
+! - Grazing_detritus ON: Zooplankton can feed on detritus (coprophagy)
+! - Grazing_detritus OFF: Detritus only forms from grazing/mortality
+! - enable_3zoo2det: Adds microzooplankton + fast-sinking detritus
+!
+! 4. REMINERALIZATION: Temperature and oxygen dependent
+! - arrFunc: Increases with temperature (Arrhenius kinetics)
+! - O2Func: Decreases under low oxygen (anaerobic conditions)
+!===============================================================================
+ !-------------------------------------------------------------------------------
+ ! Configuration 1: WITH Detritus Grazing + 3 Zooplankton Types
+ !-------------------------------------------------------------------------------
+ if (Grazing_detritus) then
+ if (enable_3zoo2det) then
+ sms(k,idetc) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Sloppy Feeding by Microzooplankton (C-basis)
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy3 * recipQuota * (1.d0 - grazEff3) & ! Small phyto
+ + grazingFlux_Dia3 * recipQuota_Dia * (1.d0 - grazEff3) & ! Diatoms
+ + grazingFlux_Cocco3 * recipQuota_Cocco * (1.d0 - grazEff3) * is_coccos & ! Coccoliths
+ + grazingFlux_Phaeo3 * recipQuota_Phaeo * (1.d0 - grazEff3) * is_coccos & ! Phaeocystis
+ !-----------------------------------------------------------------------
+ ! SOURCES: Phytoplankton Aggregation (C-basis)
+ !-----------------------------------------------------------------------
+ + aggregationRate * PhyC &
+ + aggregationRate * DiaC &
+ + aggregationRate * CoccoC * is_coccos &
+ + aggregationRate * PhaeoC * is_coccos &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Zooplankton Mortality (C-basis)
+ !-----------------------------------------------------------------------
+ + miczooLossFlux * recipQZoo3 & ! N->C conversion
+ !-----------------------------------------------------------------------
+ ! SINKS: Detritus Consumption (C-basis)
+ !-----------------------------------------------------------------------
+ - grazingFlux_Det * recipDet * grazEff & ! Mesozooplankton
+ - grazingFlux_Det2 * recipDet * grazEff2 & ! Macrozooplankton ! corrected recipDet2 -> recipDet
+ !-----------------------------------------------------------------------
+ ! SINKS: Remineralization
+ !-----------------------------------------------------------------------
+ - reminC * arrFunc * O2Func * DetC & ! Bacterial respiration
+ ) * dt_b + sms(k,idetc)
+
+ !-------------------------------------------------------------------------------
+ ! Configuration 2: WITH Detritus Grazing + 2 Zooplankton Types (Standard)
+ !-------------------------------------------------------------------------------
+ else
+ sms(k,idetc) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Sloppy Feeding by Mesozooplankton (C-basis)
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy * recipQuota * (1.d0 - grazEff) &
+ + grazingFlux_Dia * recipQuota_Dia * (1.d0 - grazEff) &
+ + grazingFlux_Cocco * recipQuota_Cocco * (1.d0 - grazEff) * is_coccos &
+ + grazingFlux_Phaeo * recipQuota_Phaeo * (1.d0 - grazEff) * is_coccos &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Phytoplankton Aggregation (C-basis)
+ !-----------------------------------------------------------------------
+ + aggregationRate * phyC &
+ + aggregationRate * DiaC &
+ + aggregationRate * CoccoC * is_coccos &
+ + aggregationRate * PhaeoC * is_coccos &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Zooplankton Mortality (C-basis)
+ !-----------------------------------------------------------------------
+ + hetLossFlux * recipQZoo &
+ !-----------------------------------------------------------------------
+ ! SINKS: Detritus Consumption (C-basis)
+ !-----------------------------------------------------------------------
+ - grazingFlux_Det * recipDet * grazEff &
+ ! - grazingFlux_Det2 * recipDet2 * grazEff & !!!!!! CHECK
+ !-----------------------------------------------------------------------
+ ! SINKS: Remineralization
+ !-----------------------------------------------------------------------
+ - reminC * arrFunc * O2Func * DetC &
+ ) * dt_b + sms(k,idetc)
-#if defined (__coccos)
- vertNPPc(k) = vertNPPc(k) + ( &
- + Cphot_cocco * CoccoC &
- - PhyRespRate_cocco * CoccoC &
- ) * recipbiostep
-#endif
+ endif
-!*** Gross primary production [mmol C /(m3 * day)]
- vertGPPn(k) = vertGPPn(k) + ( &
- + Cphot * PhyC &
- ) * recipbiostep
+ !-------------------------------------------------------------------------------
+ ! Configuration 3: WITHOUT Detritus Grazing + 3 Zooplankton Types
+ !-------------------------------------------------------------------------------
+ else
+ if (enable_3zoo2det) then
+ sms(k,idetc) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Sloppy Feeding by Microzooplankton (C-basis)
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy3 * recipQuota * (1.d0 - grazEff3) &
+ + grazingFlux_Dia3 * recipQuota_Dia * (1.d0 - grazEff3) &
+ + grazingFlux_Cocco3 * recipQuota_Cocco * (1.d0 - grazEff3) * is_coccos &
+ + grazingFlux_Phaeo3 * recipQuota_Phaeo * (1.d0 - grazEff3) * is_coccos &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Phytoplankton Aggregation (C-basis)
+ !-----------------------------------------------------------------------
+ + aggregationRate * PhyC &
+ + aggregationRate * DiaC &
+ + aggregationRate * CoccoC * is_coccos &
+ + aggregationRate * PhaeoC * is_coccos &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Zooplankton Mortality (C-basis)
+ !-----------------------------------------------------------------------
+ + miczooLossFlux * recipQZoo3 &
+ !-----------------------------------------------------------------------
+ ! SINKS: Remineralization
+ !-----------------------------------------------------------------------
+ - reminC * arrFunc * O2Func * DetC &
+ ) * dt_b + sms(k,idetc)
+
+ !-------------------------------------------------------------------------------
+ ! Configuration 4: WITHOUT Detritus Grazing + 2 Zooplankton Types
+ !-------------------------------------------------------------------------------
+ else
+ sms(k,idetc) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Sloppy Feeding by Mesozooplankton (C-basis)
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy * recipQuota * (1.d0 - grazEff) &
+ + grazingFlux_Dia * recipQuota_Dia * (1.d0 - grazEff) &
+ + grazingFlux_Cocco * recipQuota_Cocco * (1.d0 - grazEff) * is_coccos &
+ + grazingFlux_Phaeo * recipQuota_Phaeo * (1.d0 - grazEff) * is_coccos &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Phytoplankton Aggregation (C-basis)
+ !-----------------------------------------------------------------------
+ + aggregationRate * phyC &
+ + aggregationRate * DiaC &
+ + aggregationRate * CoccoC * is_coccos &
+ + aggregationRate * PhaeoC * is_coccos &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Zooplankton Mortality (C-basis)
+ !-----------------------------------------------------------------------
+ + hetLossFlux * recipQZoo &
+ !-----------------------------------------------------------------------
+ ! SINKS: Remineralization
+ !-----------------------------------------------------------------------
+ - reminC * arrFunc * O2Func * DetC &
+ ) * dt_b + sms(k,idetc)
- vertGPPd(k) = vertGPPd(k) + ( &
- + Cphot_dia * DiaC &
- ) * recipbiostep
+ endif
+ end if
+
+ !===============================================================================
+ ! 9. MESOZOOPLANKTON NITROGEN (HetN)
+ !===============================================================================
+ ! Primary herbivorous/omnivorous grazers that feed on phytoplankton and
+ ! smaller prey items.
+ !
+ ! Variables:
+ ! grazingFlux : Total N grazing rate [mmolN m-3 day-1]
+ ! grazEff : Grazing/assimilation efficiency [-]
+ ! grazingFlux_het2 : Predation by macrozooplankton [mmolN m-3 day-1]
+ ! Mesfecalloss_n : Fecal pellet production [mmolN m-3 day-1]
+ ! hetLossFlux : Mortality flux [mmolN m-3 day-1]
+ ! lossN_z : DON excretion rate [day-1]
+ !-------------------------------------------------------------------------------
+
+ sms(k,ihetn) = ( &
+ !---------------------------------------------------------------------------
+ ! SOURCES: Grazing
+ !---------------------------------------------------------------------------
+ + grazingFlux * grazEff & ! Assimilated N
+ !---------------------------------------------------------------------------
+ ! SINKS: Predation, Mortality, Excretion
+ !---------------------------------------------------------------------------
+ - grazingFlux_het2 * is_3zoo2det & ! Predation by macrozooplankton
+ - Mesfecalloss_n * is_3zoo2det & ! Fecal pellets
+ - hetLossFlux & ! Mortality
+ - lossN_z * HetN & ! DON excretion
+ ) * dt_b + sms(k,ihetn)
+
+ !===============================================================================
+ ! 10. MESOZOOPLANKTON CARBON (HetC)
+ !===============================================================================
+ ! Carbon budget uses reciprocal quotas (C:N ratios) to convert N-based
+ ! grazing rates to carbon equivalents.
+ !
+ ! Variables:
+ ! recipQuota, recipQuota_Dia, etc. : C:N ratios of prey items [-]
+ ! recipDet, recipDet2 : C:N ratios of detritus [-]
+ ! recipQZoo, recipQZoo3 : C:N ratios of zooplankton [-]
+ ! hetRespFlux : Respiration to CO2 [mmolC m-3 day-1]
+ ! lossC_z : DOC excretion rate [day-1]
+ !-------------------------------------------------------------------------------
+
+ !-------------------------------------------------------------------------------
+ ! Configuration: Mesozooplankton CAN Graze on Detritus
+ !-------------------------------------------------------------------------------
+ if (Grazing_detritus) then
+ sms(k,ihetc) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Grazing (C-basis)
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy * recipQuota * grazEff & ! Small phytoplankton
+ + grazingFlux_Dia * recipQuota_Dia * grazEff & ! Diatoms
+ + grazingFlux_Cocco * recipQuota_Cocco * grazEff * is_coccos & ! Coccolithophores
+ + grazingFlux_Phaeo * recipQuota_Phaeo * grazEff * is_coccos & ! Phaeocystis
+ + grazingFlux_miczoo * recipQZoo3 * grazEff * is_3zoo2det & ! Microzooplankton
+ + grazingFlux_DetZ2 * recipDet2 * grazEff * is_3zoo2det & ! Fast-sinking detritus
+ + grazingFlux_Det * recipDet * grazEff & ! Slow-sinking detritus
+ !-----------------------------------------------------------------------
+ ! SINKS: Predation, Mortality, Respiration, Excretion
+ !-----------------------------------------------------------------------
+ - grazingFlux_het2 * recipQZoo * is_3zoo2det & ! Predation
+ - Mesfecalloss_c * is_3zoo2det & ! Fecal pellets
+ - hetLossFlux * recipQZoo & ! Mortality
+ - lossC_z * HetC & ! DOC excretion
+ - hetRespFlux & ! Respiration to CO2
+ ) * dt_b + sms(k,ihetc)
+
+ !-------------------------------------------------------------------------------
+ ! Configuration: Mesozooplankton CANNOT Graze on Detritus
+ !-------------------------------------------------------------------------------
+ else
+ sms(k,ihetc) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Grazing (C-basis, herbivorous diet only)
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy * recipQuota * grazEff &
+ + grazingFlux_Dia * recipQuota_Dia * grazEff &
+ + grazingFlux_Cocco * recipQuota_Cocco * grazEff * is_coccos &
+ + grazingFlux_Phaeo * recipQuota_Phaeo * grazEff * is_coccos &
+ + grazingFlux_miczoo * recipQZoo3 * grazEff * is_3zoo2det &
+ !-----------------------------------------------------------------------
+ ! SINKS: Predation, Mortality, Respiration, Excretion
+ !-----------------------------------------------------------------------
+ - grazingFlux_het2 * recipQZoo * is_3zoo2det &
+ - Mesfecalloss_c * is_3zoo2det &
+ - hetLossFlux * recipQZoo &
+ - lossC_z * HetC &
+ - hetRespFlux &
+ ) * dt_b + sms(k,ihetc)
+ endif
-#if defined (__coccos)
- vertGPPc(k) = vertGPPc(k) + ( &
- + Cphot_cocco * CoccoC &
- ) * recipbiostep
-#endif
+ !===============================================================================
+ ! 11. MACROZOOPLANKTON NITROGEN (Zoo2N)
+ !===============================================================================
+ ! Larger predatory zooplankton that feed on mesozooplankton, microzooplankton,
+ ! and phytoplankton. Only active when enable_3zoo2det = .true.
+ !
+ ! Variables:
+ ! grazingFlux2 : Total N grazing rate [mmolN m-3 day-1]
+ ! grazEff2 : Grazing/assimilation efficiency [-]
+ ! Zoo2LossFlux : Mortality flux [mmolN m-3 day-1]
+ ! lossN_z2 : DON excretion rate [day-1]
+ ! Zoo2fecalloss_n : Fecal pellet production [mmolN m-3 day-1]
+ !-------------------------------------------------------------------------------
+
+ if (enable_3zoo2det) then
+ sms(k,izoo2n) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Grazing
+ !-----------------------------------------------------------------------
+ + grazingFlux2 * grazEff2 & ! Assimilated N
+ !-----------------------------------------------------------------------
+ ! SINKS: Mortality, Excretion, Fecal Pellets
+ !-----------------------------------------------------------------------
+ - Zoo2LossFlux & ! Mortality
+ - lossN_z2 * Zoo2N & ! DON excretion
+ - Zoo2fecalloss_n & ! Fecal pellets
+ ) * dt_b + sms(k,izoo2n)
+
+ !===============================================================================
+ ! 12. MACROZOOPLANKTON CARBON (Zoo2C)
+ !===============================================================================
+ ! Carbon budget for macrozooplankton with stoichiometric conversions.
+ !
+ ! Variables:
+ ! recipQuota, recipQuota_Dia, etc. : C:N ratios of prey [-]
+ ! recipDet, recipDet2 : C:N ratios of detritus [-]
+ ! recipQZoo, recipQZoo2, recipQZoo3: C:N ratios of zooplankton [-]
+ ! Zoo2RespFlux : Respiration to CO2 [mmolC m-3 day-1]
+ ! lossC_z2 : DOC excretion rate [day-1]
+ !-------------------------------------------------------------------------------
+
+ !---------------------------------------------------------------------------
+ ! Configuration: Macrozooplankton CAN Graze on Detritus
+ !---------------------------------------------------------------------------
-!*** Net N-assimilation [mmol N/(m3 * day)]
- vertNNAn(k) = vertNNAn(k) + ( &
- + N_assim * PhyC &
- - lossN * limitFacN * PhyN &
- ) * recipbiostep
+ if (Grazing_detritus) then
+ sms(k,izoo2c) = ( &
+ !-------------------------------------------------------------------
+ ! SOURCES: Grazing (C-basis)
+ !-------------------------------------------------------------------
+ + grazingFlux_phy2 * recipQuota * grazEff2 & ! Small phytoplankton
+ + grazingFlux_Dia2 * recipQuota_Dia * grazEff2 & ! Diatoms
+ + grazingFlux_Cocco2 * recipQuota_Cocco * grazEff2 * is_coccos & ! Coccolithophores
+ + grazingFlux_Phaeo2 * recipQuota_Phaeo * grazEff2 * is_coccos & ! Phaeocystis
+ + grazingFlux_het2 * recipQZoo * grazEff2 & ! Mesozooplankton (predation)
+ + grazingFlux_miczoo2* recipQZoo3 * grazEff2 & ! Microzooplankton
+ + grazingFlux_Det2 * recipDet * grazEff2 & ! Slow-sinking detritus
+ + grazingFlux_DetZ22 * recipDet2 * grazEff2 & ! Fast-sinking detritus
+ !-------------------------------------------------------------------
+ ! SINKS: Mortality, Respiration, Excretion, Fecal Pellets
+ !-------------------------------------------------------------------
+ - zoo2LossFlux * recipQZoo2 & ! Mortality
+ - lossC_z2 * Zoo2C & ! DOC excretion
+ - Zoo2RespFlux & ! Respiration to CO2
+ - Zoo2fecalloss_c & ! Fecal pellets
+ ) * dt_b + sms(k,izoo2c)
+
+ !---------------------------------------------------------------------------
+ ! Configuration: Macrozooplankton CANNOT Graze on Detritus
+ !---------------------------------------------------------------------------
+ else
+ sms(k,izoo2c) = ( &
+ !-------------------------------------------------------------------
+ ! SOURCES: Grazing (C-basis, no detritus feeding)
+ !-------------------------------------------------------------------
+ + grazingFlux_phy2 * recipQuota * grazEff2 &
+ + grazingFlux_Dia2 * recipQuota_Dia * grazEff2 &
+ + grazingFlux_Cocco2 * recipQuota_Cocco * grazEff2 * is_coccos &
+ + grazingFlux_Phaeo2 * recipQuota_Phaeo * grazEff2 * is_coccos &
+ + grazingFlux_het2 * recipQZoo * grazEff2 &
+ + grazingFlux_miczoo2* recipQZoo3 * grazEff2 &
+ !-------------------------------------------------------------------
+ ! SINKS: Mortality, Respiration, Excretion, Fecal Pellets
+ !-------------------------------------------------------------------
+ - zoo2LossFlux * recipQZoo2 &
+ - lossC_z2 * Zoo2C &
+ - Zoo2RespFlux &
+ - Zoo2fecalloss_c &
+ ) * dt_b + sms(k,izoo2c)
- vertNNAd(k) = vertNNAd(k) + ( &
- + N_assim_dia * DiaC &
- - lossN * limitFacN_dia * DiaN &
- ) * recipbiostep
+ end if
-#if defined (__coccos)
- vertNNAc(k) = vertNNAc(k) + ( &
- + N_assim_cocco * CoccoC &
- - lossN * limitFacN_cocco * CoccoN &
- ) * recipbiostep
-#endif
+ !===============================================================================
+ ! 13. MICROZOOPLANKTON NITROGEN (MicZooN)
+ !===============================================================================
+ ! Small heterotrophic protists that graze on phytoplankton and are prey for
+ ! meso- and macrozooplankton.
+ !
+ ! Variables:
+ ! grazingFlux3 : Total N grazing rate [mmolN m-3 day-1]
+ ! grazEff3 : Grazing/assimilation efficiency [-]
+ ! grazingFlux_miczoo : Predation by mesozooplankton [mmolN m-3 day-1]
+ ! grazingFlux_miczoo2: Predation by macrozooplankton [mmolN m-3 day-1]
+ ! MicZooLossFlux : Mortality flux [mmolN m-3 day-1]
+ ! lossN_z3 : DON excretion rate [day-1]
+ !-------------------------------------------------------------------------------
+
+ sms(k,imiczoon) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Grazing
+ !-----------------------------------------------------------------------
+ + grazingFlux3 * grazEff3 & ! Assimilated N
+ !-----------------------------------------------------------------------
+ ! SINKS: Predation, Mortality, Excretion
+ !-----------------------------------------------------------------------
+ - grazingFlux_miczoo & ! Predation by mesozooplankton
+ - grazingFlux_miczoo2 & ! Predation by macrozooplankton
+ - MicZooLossFlux & ! Mortality
+ - lossN_z3 * MicZooN & ! DON excretion
+ ) * dt_b + sms(k,imiczoon)
+
+ !===============================================================================
+ ! 14. MICROZOOPLANKTON CARBON (MicZooC)
+ !===============================================================================
+ ! Carbon budget for microzooplankton with stoichiometric conversions.
+ !
+ ! Variables:
+ ! recipQuota, recipQuota_Dia, etc. : C:N ratios of prey [-]
+ ! recipQZoo3 : C:N ratio of microzooplankton [-]
+ ! MicZooRespFlux : Respiration to CO2 [mmolC m-3 day-1]
+ ! lossC_z3 : DOC excretion rate [day-1]
+ !-------------------------------------------------------------------------------
+
+ sms(k,imiczooc) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Grazing (C-basis)
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy3 * recipQuota * grazEff3 & ! Small phytoplankton
+ + grazingFlux_Dia3 * recipQuota_Dia * grazEff3 & ! Diatoms
+ + grazingFlux_Cocco3 * recipQuota_Cocco * grazEff3 * is_coccos & ! Coccolithophores
+ + grazingFlux_Phaeo3 * recipQuota_Phaeo * grazEff3 * is_coccos & ! Phaeocystis
+ !-----------------------------------------------------------------------
+ ! SINKS: Predation, Mortality, Respiration, Excretion
+ !-----------------------------------------------------------------------
+ - MicZooLossFlux * recipQZoo3 & ! Mortality
+ - grazingFlux_miczoo * recipQZoo3 & ! Predation by mesozooplankton
+ - grazingFlux_miczoo2 * recipQZoo3 & ! Predation by macrozooplankton
+ - lossC_z3 * MicZooC & ! DOC excretion
+ - MicZooRespFlux & ! Respiration to CO2
+ ) * dt_b + sms(k,imiczooc)
+
+ end if
+
+ !===============================================================================
+ ! 15. FAST-SINKING DETRITUS NITROGEN (DetZ2N)
+ !===============================================================================
+ ! Particulate organic matter produced from zooplankton mortality, fecal pellets,
+ ! and unassimilated grazing. Sinks faster than regular detritus.
+ ! Only active when enable_3zoo2det = .true.
+ !
+ ! Variables:
+ ! grazingFlux_phy, grazingFlux_phy2 : Grazing on small phyto [mmolN m-3 day-1]
+ ! grazingFlux_dia, grazingFlux_dia2 : Grazing on diatoms [mmolN m-3 day-1]
+ ! grazingFlux_het2 : Predation on mesozooplankton [mmolN m-3 day-1]
+ ! grazingFlux_miczoo, grazingFlux_miczoo2 : Grazing on microzooplankton [mmolN m-3 day-1]
+ ! grazingFlux_DetZ2, grazingFlux_DetZ22 : Grazing on fast detritus [mmolN m-3 day-1]
+ ! Zoo2LossFlux, hetLossFlux : Zooplankton mortality [mmolN m-3 day-1]
+ ! Zoo2fecalloss_n, Mesfecalloss_n : Fecal pellet production [mmolN m-3 day-1]
+ ! reminN : Remineralization rate [day-1]
+ !-------------------------------------------------------------------------------
+
+ if (enable_3zoo2det) then
+
+ !---------------------------------------------------------------------------
+ ! Configuration: Zooplankton CAN Graze on Fast-Sinking Detritus
+ !---------------------------------------------------------------------------
+ if (Grazing_detritus) then
+ sms(k,idetz2n) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Sloppy Feeding by Macrozooplankton
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy2 * (1.d0 - grazEff2) & ! Small phytoplankton
+ + grazingFlux_dia2 * (1.d0 - grazEff2) & ! Diatoms
+ + grazingFlux_Cocco * (1.d0 - grazEff) * is_coccos & ! Coccoliths (meso) ! grazEff2 --> grazEff
+ + grazingFlux_Cocco2 * (1.d0 - grazEff2) * is_coccos & ! Coccoliths (macro)
+ + grazingFlux_Phaeo * (1.d0 - grazEff) * is_coccos & ! Phaeocystis (meso)
+ + grazingFlux_Phaeo2 * (1.d0 - grazEff2) * is_coccos & ! Phaeocystis (macro)
+ + grazingFlux_het2 * (1.d0 - grazEff2) & ! Mesozooplankton (predation)
+ + grazingFlux_miczoo2 * (1.d0 - grazEff2) & ! Microzooplankton
+ !-----------------------------------------------------------------------
+ ! SOURCES: Sloppy Feeding by Mesozooplankton
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy * (1.d0 - grazEff) & ! Small phytoplankton
+ + grazingFlux_dia * (1.d0 - grazEff) & ! Diatoms
+ + grazingFlux_miczoo * (1.d0 - grazEff) & ! Microzooplankton
+ !-----------------------------------------------------------------------
+ ! SOURCES: Zooplankton Mortality
+ !-----------------------------------------------------------------------
+ + Zoo2LossFlux & ! Macrozooplankton
+ + hetLossFlux & ! Mesozooplankton
+ !-----------------------------------------------------------------------
+ ! SOURCES: Fecal Pellet Production
+ !-----------------------------------------------------------------------
+ + Zoo2fecalloss_n & ! Macrozooplankton
+ + Mesfecalloss_n & ! Mesozooplankton
+ !-----------------------------------------------------------------------
+ ! SINKS: Detritus Consumption (Coprophagy)
+ !-----------------------------------------------------------------------
+ - grazingFlux_DetZ2 * grazEff & ! Mesozooplankton
+ - grazingFlux_DetZ22 * grazEff2 & ! Macrozooplankton
+ !-----------------------------------------------------------------------
+ ! SINKS: Remineralization
+ !-----------------------------------------------------------------------
+ - reminN * arrFunc * O2Func * DetZ2N & ! Bacterial decomposition
+ ) * dt_b + sms(k,idetz2n)
+
+ !---------------------------------------------------------------------------
+ ! Configuration: Zooplankton CANNOT Graze on Fast-Sinking Detritus
+ !---------------------------------------------------------------------------
+ else
+ sms(k,idetz2n) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Sloppy Feeding by Macrozooplankton
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy2 & ! All grazing enters detritus
+ + grazingFlux_dia2 &
+ + grazingFlux_Cocco * is_coccos &
+ + grazingFlux_Cocco2 * is_coccos &
+ + grazingFlux_Phaeo * is_coccos &
+ + grazingFlux_Phaeo2 * is_coccos &
+ + grazingFlux_het2 &
+ + grazingFlux_miczoo2 &
+ - grazingFlux2 * grazEff2 & ! Minus assimilated portion
+ !-----------------------------------------------------------------------
+ ! SOURCES: Sloppy Feeding by Mesozooplankton
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy &
+ + grazingFlux_dia &
+ + grazingFlux_miczoo &
+ - grazingFlux * grazEff & ! Minus assimilated portion
+ !-----------------------------------------------------------------------
+ ! SOURCES: Zooplankton Mortality
+ !-----------------------------------------------------------------------
+ + Zoo2LossFlux &
+ + hetLossFlux &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Fecal Pellet Production
+ !-----------------------------------------------------------------------
+ + Zoo2fecalloss_n &
+ + Mesfecalloss_n &
+ !-----------------------------------------------------------------------
+ ! SINKS: Remineralization
+ !-----------------------------------------------------------------------
+ - reminN * arrFunc * O2Func * DetZ2N &
+ ) * dt_b + sms(k,idetz2n)
+ end if
+ !===============================================================================
+ ! 16. FAST-SINKING DETRITUS CARBON (DetZ2C)
+ !===============================================================================
+ ! Carbon budget for fast-sinking detritus with stoichiometric conversions.
+ !
+ ! Variables:
+ ! recipQuota, recipQuota_Dia, etc. : C:N ratios of phytoplankton [-]
+ ! recipQZoo, recipQZoo2, recipQZoo3: C:N ratios of zooplankton [-]
+ ! recipDet2 : C:N ratio of fast-sinking detritus [-]
+ ! reminC : C remineralization rate [day-1]
+ !-------------------------------------------------------------------------------
+
+ !---------------------------------------------------------------------------
+ ! Configuration: Zooplankton CAN Graze on Fast-Sinking Detritus
+ !---------------------------------------------------------------------------
+ if (Grazing_detritus) then
+ sms(k,idetz2c) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Sloppy Feeding by Macrozooplankton (C-basis)
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy2 * recipQuota * (1.d0 - grazEff2) & ! Small phyto
+ + grazingFlux_Dia2 * recipQuota_Dia * (1.d0 - grazEff2) & ! Diatoms
+ + grazingFlux_Cocco * recipQuota_Cocco * (1.d0 - grazEff) * is_coccos & ! Coccoliths (meso)
+ + grazingFlux_Cocco2 * recipQuota_Cocco * (1.d0 - grazEff2) * is_coccos & ! Coccoliths (macro)
+ + grazingFlux_Phaeo * recipQuota_Phaeo * (1.d0 - grazEff) * is_coccos & ! Phaeocystis (meso)
+ + grazingFlux_Phaeo2 * recipQuota_Phaeo * (1.d0 - grazEff2) * is_coccos & ! Phaeocystis (macro)
+ + grazingFlux_het2 * recipQZoo * (1.d0 - grazEff2) & ! Mesozooplankton
+ + grazingFlux_miczoo2 * recipQZoo3 * (1.d0 - grazEff2) & ! Microzooplankton
+ !-----------------------------------------------------------------------
+ ! SOURCES: Sloppy Feeding by Mesozooplankton (C-basis)
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy * recipQuota * (1.d0 - grazEff) & ! Small phyto
+ + grazingFlux_Dia * recipQuota_Dia * (1.d0 - grazEff) & ! Diatoms
+ + grazingFlux_miczoo * recipQZoo3 * (1.d0 - grazEff) & ! Microzooplankton
+ !-----------------------------------------------------------------------
+ ! SOURCES: Zooplankton Mortality (C-basis)
+ !-----------------------------------------------------------------------
+ + Zoo2LossFlux * recipQZoo2 & ! Macrozooplankton (N->C)
+ + hetLossFlux * recipQZoo & ! Mesozooplankton (N->C)
+ !-----------------------------------------------------------------------
+ ! SOURCES: Fecal Pellet Production (C-basis)
+ !-----------------------------------------------------------------------
+ + Zoo2fecalloss_c & ! Macrozooplankton
+ + Mesfecalloss_c & ! Mesozooplankton
+ !-----------------------------------------------------------------------
+ ! SINKS: Detritus Consumption (C-basis)
+ !-----------------------------------------------------------------------
+ - grazingFlux_DetZ2 * recipDet2 * grazEff & ! Mesozooplankton
+ - grazingFlux_DetZ22 * recipDet2 * grazEff2 & ! Macrozooplankton
+ !-----------------------------------------------------------------------
+ ! SINKS: Remineralization
+ !-----------------------------------------------------------------------
+ - reminC * arrFunc * O2Func * DetZ2C & ! Bacterial respiration
+ ) * dt_b + sms(k,idetz2c)
+
+ !---------------------------------------------------------------------------
+ ! Configuration: Zooplankton CANNOT Graze on Fast-Sinking Detritus
+ !---------------------------------------------------------------------------
+ else
+ sms(k,idetz2c) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Sloppy Feeding by Macrozooplankton (C-basis)
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy2 * recipQuota * (1.d0 - grazEff2) &
+ + grazingFlux_Dia2 * recipQuota_Dia * (1.d0 - grazEff2) &
+ + grazingFlux_Cocco * recipQuota_Cocco * (1.d0 - grazEff) * is_coccos &
+ + grazingFlux_Cocco2 * recipQuota_Cocco * (1.d0 - grazEff2) * is_coccos & ! grazEff -> grazEff2
+ + grazingFlux_Phaeo * recipQuota_Phaeo * (1.d0 - grazEff) * is_coccos &
+ + grazingFlux_Phaeo2 * recipQuota_Phaeo * (1.d0 - grazEff2) * is_coccos &
+ + grazingFlux_het2 * recipQZoo * (1.d0 - grazEff2) &
+ + grazingFlux_miczoo2 * recipQZoo3 * (1.d0 - grazEff2) &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Sloppy Feeding by Mesozooplankton (C-basis)
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy * recipQuota * (1.d0 - grazEff) &
+ + grazingFlux_Dia * recipQuota_Dia * (1.d0 - grazEff) &
+ + grazingFlux_miczoo * recipQZoo3 * (1.d0 - grazEff) &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Zooplankton Mortality (C-basis)
+ !-----------------------------------------------------------------------
+ + Zoo2LossFlux * recipQZoo2 &
+ + hetLossFlux * recipQZoo &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Fecal Pellet Production (C-basis)
+ !-----------------------------------------------------------------------
+ + Zoo2fecalloss_c &
+ + Mesfecalloss_c &
+ !-----------------------------------------------------------------------
+ ! SINKS: Remineralization
+ !-----------------------------------------------------------------------
+ - reminC * arrFunc * O2Func * DetZ2C &
+ ) * dt_b + sms(k,idetz2c)
+ end if
-!*** Changed to chlorophyll degradation (commented out gross N-assimilation below)
- vertChldegn(k) = vertChldegn(k) + ( &
- + KOchl &
- ) * recipbiostep
+ !===============================================================================
+ ! 17. FAST-SINKING DETRITUS SILICA (DetZ2Si)
+ !===============================================================================
+ ! Biogenic silica from diatom frustules in fast-sinking detritus.
+ !
+ ! Variables:
+ ! grazingFlux_dia, grazingFlux_dia2 : Grazing on diatoms [mmolN m-3 day-1]
+ ! qSiN : Si:N ratio in diatoms [mmolSi mmolN-1]
+ ! reminSiT : Temperature-dependent dissolution [day-1]
+ !-------------------------------------------------------------------------------
+
+ sms(k,idetz2si) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Grazing on Diatoms
+ !-----------------------------------------------------------------------
+ + grazingFlux_dia2 * qSiN & ! Macrozooplankton grazing
+ + grazingFlux_dia * qSiN & ! Mesozooplankton grazing
+ !-----------------------------------------------------------------------
+ ! SINKS: Dissolution
+ !-----------------------------------------------------------------------
+ - reminSiT * DetZ2Si & ! Temperature-dependent
+ ) * dt_b + sms(k,idetz2si)
+
+ !===============================================================================
+ ! 18. FAST-SINKING DETRITUS CALCITE (DetZ2Calc)
+ !===============================================================================
+ ! Calcite particles from coccolithophore shells in fast-sinking detritus.
+ !
+ ! Variables:
+ ! calc_loss_gra, calc_loss_gra2 : Calcite from grazing [mmolCaCO3 m-3 day-1]
+ ! calc_diss_guts : Gut dissolution fraction [-]
+ ! calc_diss2 : Water column dissolution rate [day-1]
+ !-------------------------------------------------------------------------------
+
+ sms(k,idetz2calc) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Grazing on Calcifying Phytoplankton
+ !-----------------------------------------------------------------------
+ + calc_loss_gra2 * (1.d0 - calc_diss_guts) & ! Macrozooplankton (net)
+ + calc_loss_gra * (1.d0 - calc_diss_guts) & ! Mesozooplankton (net)
+ !-----------------------------------------------------------------------
+ ! SINKS: Dissolution in Water Column
+ !-----------------------------------------------------------------------
+ - calc_diss2 * DetZ2Calc & ! CaCO3 dissolution
+ ) * dt_b + sms(k,idetz2calc)
+
+ endif ! enable_3zoo2det
+
+ !===============================================================================
+ ! 19. DISSOLVED ORGANIC NITROGEN (DON)
+ !===============================================================================
+ ! Dissolved organic nitrogen pool from phytoplankton excretion, zooplankton
+ ! metabolism, and detrital remineralization.
+ !
+ ! Variables:
+ ! lossN, lossN_d, lossN_c, lossN_p : Phytoplankton DON excretion rates [day-1]
+ ! limitFacN, limitFacN_Dia, etc. : N:C ratio limiters (regulate excretion) [-]
+ ! reminN : Detrital N remineralization rate [day-1]
+ ! rho_N : DON remineralization rate [day-1]
+ ! lossN_z, lossN_z2, lossN_z3 : Zooplankton DON excretion rates [day-1]
+ ! arrFunc : Arrhenius temperature function [-]
+ ! O2Func : Oxygen limitation function [-]
+ !-------------------------------------------------------------------------------
+
+ sms(k,idon) = ( &
+ !---------------------------------------------------------------------------
+ ! SOURCES: Phytoplankton Excretion
+ !---------------------------------------------------------------------------
+ + lossN * limitFacN * phyN & ! Small phytoplankton
+ + lossN_d * limitFacN_Dia * DiaN & ! Diatoms
+ + lossN_c * limitFacN_Cocco * CoccoN * is_coccos & ! Coccolithophores
+ + lossN_p * limitFacN_Phaeo * PhaeoN * is_coccos & ! Phaeocystis
+ !---------------------------------------------------------------------------
+ ! SOURCES: Detrital Remineralization
+ !---------------------------------------------------------------------------
+ + reminN * arrFunc * O2Func * DetN & ! Slow-sinking detritus
+ + reminN * arrFunc * O2Func * DetZ2N * is_3zoo2det & ! Fast-sinking detritus
+ !---------------------------------------------------------------------------
+ ! SOURCES: Zooplankton Excretion
+ !---------------------------------------------------------------------------
+ + lossN_z * HetN & ! Mesozooplankton
+ + lossN_z2 * Zoo2N * is_3zoo2det & ! Macrozooplankton
+ + lossN_z3 * MicZooN * is_3zoo2det & ! Microzooplankton
+ !---------------------------------------------------------------------------
+ ! SINKS: Remineralization to NH4
+ !---------------------------------------------------------------------------
+ - rho_N * arrFunc * O2Func * DON & ! Bacterial remineralization
+ ) * dt_b + sms(k,idon)
+
+ !===============================================================================
+ ! 20. EXTRACELLULAR ORGANIC CARBON (EOC / DOC)
+ !===============================================================================
+ ! Dissolved organic carbon pool from phytoplankton excretion, zooplankton
+ ! metabolism, and detrital remineralization.
+ !
+ ! Variables:
+ ! lossC, lossC_d, lossC_c, lossC_p : Phytoplankton DOC excretion rates [day-1]
+ ! limitFacN, limitFacN_dia, etc. : N:C ratio limiters (regulate excretion) [-]
+ ! reminC : Detrital C remineralization rate [day-1]
+ ! rho_c1 : DOC remineralization rate [day-1]
+ ! lossC_z, lossC_z2, lossC_z3 : Zooplankton DOC excretion rates [day-1]
+ !-------------------------------------------------------------------------------
+
+ sms(k,idoc) = ( &
+ !---------------------------------------------------------------------------
+ ! SOURCES: Phytoplankton Excretion
+ !---------------------------------------------------------------------------
+ + lossC * limitFacN * phyC & ! Small phytoplankton
+ + lossC_d * limitFacN_dia * DiaC & ! Diatoms
+ + lossC_c * limitFacN_cocco * CoccoC * is_coccos & ! Coccolithophores
+ + lossC_p * limitFacN_Phaeo * PhaeoC * is_coccos & ! Phaeocystis
+ !---------------------------------------------------------------------------
+ ! SOURCES: Detrital Remineralization
+ !---------------------------------------------------------------------------
+ + reminC * arrFunc * O2Func * DetC & ! Slow-sinking detritus
+ + reminC * arrFunc * O2Func * DetZ2C * is_3zoo2det & ! Fast-sinking detritus
+ !---------------------------------------------------------------------------
+ ! SOURCES: Zooplankton Excretion
+ !---------------------------------------------------------------------------
+ + lossC_z * HetC & ! Mesozooplankton
+ + lossC_z2 * Zoo2C * is_3zoo2det & ! Macrozooplankton
+ + lossC_z3 * MicZooC * is_3zoo2det & ! Microzooplankton
+ !---------------------------------------------------------------------------
+ ! SINKS: Remineralization to CO2
+ !---------------------------------------------------------------------------
+ - rho_c1 * arrFunc * O2Func * EOC & ! Bacterial respiration
+ ) * dt_b + sms(k,idoc)
+ if (useRivers) then
+ ! R2OMIP - terrestrial DOC
+ sms(k,idoct) = ( &
+ - rho_C1t * DOCt &
+ ) * dt_b + sms(k,idoct)
+ end if
+ !===============================================================================
+ ! 21. DIATOM NITROGEN (DiaN)
+ !===============================================================================
+ ! Tracks nitrogen content of diatoms (large phytoplankton with silica frustules).
+ !
+ ! Variables:
+ ! N_assim_dia : N assimilation rate [day-1]
+ ! lossN_d : N loss rate [day-1]
+ ! limitFacN_dia : Limiter function for N:C ratio regulation [-]
+ ! aggregationRate : Aggregation to detritus [day-1]
+ ! grazingFlux_Dia : Mesozooplankton grazing [mmolN m-3 day-1]
+ ! grazingFlux_Dia2 : Macrozooplankton grazing [mmolN m-3 day-1]
+ ! grazingFlux_Dia3 : Microzooplankton grazing [mmolN m-3 day-1]
+ !-------------------------------------------------------------------------------
+
+ sms(k,idian) = ( &
+ !---------------------------------------------------------------------------
+ ! SOURCES: Nitrogen Assimilation
+ !---------------------------------------------------------------------------
+ + N_assim_dia * DiaC &
+ !---------------------------------------------------------------------------
+ ! SINKS: DON Excretion
+ !---------------------------------------------------------------------------
+ - lossN_d * limitFacN_dia * DiaN &
+ !---------------------------------------------------------------------------
+ ! SINKS: Aggregation
+ !---------------------------------------------------------------------------
+ - aggregationRate * DiaN &
+ !---------------------------------------------------------------------------
+ ! SINKS: Grazing
+ !---------------------------------------------------------------------------
+ - grazingFlux_Dia & ! Mesozooplankton
+ - grazingFlux_Dia2 * is_3zoo2det & ! Macrozooplankton
+ - grazingFlux_Dia3 * is_3zoo2det & ! Microzooplankton
+ ) * dt_b + sms(k,idian)
+
+ !===============================================================================
+ ! 22. DIATOM CARBON (DiaC)
+ !===============================================================================
+ ! Tracks carbon content of diatoms.
+ !
+ ! Variables:
+ ! Cphot_dia : Gross photosynthesis rate [day-1]
+ ! phyRespRate_dia : Autotrophic respiration rate [day-1]
+ ! lossC_d : C loss rate [day-1]
+ ! recipQuota_dia : Reciprocal of N:C quota (for N->C conversion) [-]
+ !-------------------------------------------------------------------------------
+
+ sms(k,idiac) = ( &
+ !---------------------------------------------------------------------------
+ ! SOURCES: Net Photosynthesis
+ !---------------------------------------------------------------------------
+ + Cphot_dia * DiaC & ! Gross photosynthesis
+ !---------------------------------------------------------------------------
+ ! SINKS: DOC Excretion
+ !---------------------------------------------------------------------------
+ - lossC_d * limitFacN_dia * DiaC &
+ !---------------------------------------------------------------------------
+ ! SINKS: Respiration
+ !---------------------------------------------------------------------------
+ - phyRespRate_dia * DiaC &
+ !---------------------------------------------------------------------------
+ ! SINKS: Aggregation
+ !---------------------------------------------------------------------------
+ - aggregationRate * DiaC &
+ !---------------------------------------------------------------------------
+ ! SINKS: Grazing (C-basis)
+ !---------------------------------------------------------------------------
+ - grazingFlux_dia * recipQuota_dia & ! Mesozooplankton (N->C)
+ - grazingFlux_dia2 * recipQuota_dia * is_3zoo2det & ! Macrozooplankton
+ - grazingFlux_dia3 * recipQuota_dia * is_3zoo2det & ! Microzooplankton
+ ) * dt_b + sms(k,idiac)
+
+ !===============================================================================
+ ! 23. DIATOM CHLOROPHYLL-A (DiaChl)
+ !===============================================================================
+ ! Tracks chlorophyll-a content for light harvesting and photoacclimation.
+ !
+ ! Variables:
+ ! chlSynth_dia : Chlorophyll synthesis rate [mgChl mmolC-1 day-1]
+ ! KOchl_dia : Chlorophyll degradation rate [day-1]
+ ! Chl2N_dia : Chl:N ratio = DiaChl/DiaN [mgChl mmolN-1]
+ !-------------------------------------------------------------------------------
+
+ sms(k,idchl) = ( &
+ !---------------------------------------------------------------------------
+ ! SOURCES: Chlorophyll Synthesis
+ !---------------------------------------------------------------------------
+ + chlSynth_dia * DiaC & ! Photoacclimation
+ !---------------------------------------------------------------------------
+ ! SINKS: Photo-oxidation
+ !---------------------------------------------------------------------------
+ - KOchl_dia * DiaChl &
+ !---------------------------------------------------------------------------
+ ! SINKS: Aggregation
+ !---------------------------------------------------------------------------
+ - aggregationRate * DiaChl &
+ !---------------------------------------------------------------------------
+ ! SINKS: Grazing (Chl-basis)
+ !---------------------------------------------------------------------------
+ - grazingFlux_dia * Chl2N_dia & ! Mesozooplankton (N->Chl)
+ - grazingFlux_dia2 * Chl2N_dia * is_3zoo2det & ! Macrozooplankton
+ - grazingFlux_dia3 * Chl2N_dia * is_3zoo2det & ! Microzooplankton
+ ) * dt_b + sms(k,idchl)
+
+ !===============================================================================
+ ! 24. DIATOM SILICA (DiaSi)
+ !===============================================================================
+ ! Tracks biogenic silica content in diatom frustules.
+ !
+ ! Variables:
+ ! Si_assim : Silicic acid assimilation rate [day-1]
+ ! qSiN : Si:N ratio in diatoms [mmolSi mmolN-1]
+ !-------------------------------------------------------------------------------
+
+ sms(k,idiasi) = ( &
+ !---------------------------------------------------------------------------
+ ! SOURCES: Silicon Assimilation
+ !---------------------------------------------------------------------------
+ + Si_assim * DiaC &
+ !---------------------------------------------------------------------------
+ ! SINKS: Silicon Excretion
+ !---------------------------------------------------------------------------
+ - lossN_d * limitFacN_dia * DiaSi &
+ !---------------------------------------------------------------------------
+ ! SINKS: Aggregation
+ !---------------------------------------------------------------------------
+ - aggregationRate * DiaSi &
+ !---------------------------------------------------------------------------
+ ! SINKS: Grazing (Si-basis)
+ !---------------------------------------------------------------------------
+ - grazingFlux_dia * qSiN & ! Mesozooplankton (N->Si)
+ - grazingFlux_dia2 * qSiN * is_3zoo2det & ! Macrozooplankton
+ - grazingFlux_dia3 * qSiN * is_3zoo2det & ! Microzooplankton
+ ) * dt_b + sms(k,idiasi)
+
+ !===============================================================================
+ ! 25. COCCOLITHOPHORE NITROGEN (CoccoN)
+ !===============================================================================
+ ! Tracks nitrogen content of coccolithophores (calcifying small phytoplankton).
+ ! Only active when enable_coccos = .true.
+ !
+ ! Variables:
+ ! N_assim_cocco : N assimilation rate [day-1]
+ ! lossN_c : N loss rate [day-1]
+ ! limitFacN_cocco : Limiter function for N:C ratio regulation [-]
+ ! aggregationRate : Aggregation to detritus [day-1]
+ ! grazingFlux_Cocco : Mesozooplankton grazing [mmolN m-3 day-1]
+ ! grazingFlux_Cocco2 : Macrozooplankton grazing [mmolN m-3 day-1]
+ ! grazingFlux_Cocco3 : Microzooplankton grazing [mmolN m-3 day-1]
+ !-------------------------------------------------------------------------------
+
+ if (enable_coccos) then
+ sms(k,icocn) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Nitrogen Assimilation
+ !-----------------------------------------------------------------------
+ + N_assim_cocco * CoccoC &
+ !-----------------------------------------------------------------------
+ ! SINKS: DON Excretion
+ !-----------------------------------------------------------------------
+ - lossN_c * limitFacN_cocco * CoccoN &
+ !-----------------------------------------------------------------------
+ ! SINKS: Aggregation
+ !-----------------------------------------------------------------------
+ - aggregationRate * CoccoN &
+ !-----------------------------------------------------------------------
+ ! SINKS: Grazing
+ !-----------------------------------------------------------------------
+ - grazingFlux_Cocco & ! Mesozooplankton
+ - grazingFlux_Cocco2 * is_3zoo2det & ! Macrozooplankton
+ - grazingFlux_Cocco3 * is_3zoo2det & ! Microzooplankton
+ ) * dt_b + sms(k,icocn)
+
+ !===============================================================================
+ ! 26. COCCOLITHOPHORE CARBON (CoccoC)
+ !===============================================================================
+ ! Tracks carbon content of coccolithophores.
+ !
+ ! Variables:
+ ! Cphot_cocco : Gross photosynthesis rate [day-1]
+ ! phyRespRate_cocco : Autotrophic respiration rate [day-1]
+ ! lossC_c : C loss rate [day-1]
+ ! recipQuota_cocco : Reciprocal of N:C quota (for N->C conversion) [-]
+ !-------------------------------------------------------------------------------
+
+ sms(k,icocc) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Net Photosynthesis
+ !-----------------------------------------------------------------------
+ + Cphot_cocco * CoccoC & ! Gross photosynthesis
+ !-----------------------------------------------------------------------
+ ! SINKS: DOC Excretion
+ !-----------------------------------------------------------------------
+ - lossC_c * limitFacN_cocco * CoccoC &
+ !-----------------------------------------------------------------------
+ ! SINKS: Respiration
+ !-----------------------------------------------------------------------
+ - phyRespRate_cocco * CoccoC &
+ !-----------------------------------------------------------------------
+ ! SINKS: Aggregation
+ !-----------------------------------------------------------------------
+ - aggregationRate * CoccoC &
+ !-----------------------------------------------------------------------
+ ! SINKS: Grazing (C-basis)
+ !-----------------------------------------------------------------------
+ - grazingFlux_cocco * recipQuota_cocco & ! Mesozooplankton (N->C)
+ - grazingFlux_Cocco2 * recipQuota_cocco * is_3zoo2det & ! Macrozooplankton
+ - grazingFlux_Cocco3 * recipQuota_cocco * is_3zoo2det & ! Microzooplankton
+ ) * dt_b + sms(k,icocc)
+
+ !---------------------------------------------------------------------------
+ ! Error Check: Unrealistic CoccoC Growth
+ !---------------------------------------------------------------------------
+ if(sms(k,icocc) > 100) then
+ print*,'ERROR: Unrealistic CoccoC growth detected!'
+ print*,'k= ', k
+ print*,'dt= ', dt
+ print*,'dt_b= ', dt_b
+ print*,'state(k,icocc): ', state(k,icocc)
+ print*,'CoccoC: ', CoccoC
+ print*,'CoccoN: ', CoccoN
+ print*,'Cphot_cocco: ', Cphot_cocco*CoccoC
+ print*,'lossC_c: ', lossC_c
+ print*,'limitFacN_cocco: ', limitFacN_cocco
+ print*,'phyRespRate_cocco: ', phyRespRate_cocco
+ print*,'grazingFlux_cocco: ', grazingFlux_cocco
+ print*,'grazingFlux_Cocco2: ', grazingFlux_Cocco2
+ print*,'grazingFlux_Cocco3: ', grazingFlux_Cocco3
+ print*,'recipQuota_cocco: ', recipQuota_cocco
+ call par_ex(partit%MPI_COMM_FESOM, partit%mype)
+ stop
+ endif
- vertChldegd(k) = vertChldegd(k) + ( &
- + KOchl_dia &
- ) * recipbiostep
+ !===============================================================================
+ ! 27. COCCOLITHOPHORE CHLOROPHYLL-A (CoccoChl)
+ !===============================================================================
+ ! Tracks chlorophyll-a content for light harvesting and photoacclimation.
+ !
+ ! Variables:
+ ! ChlSynth_cocco : Chlorophyll synthesis rate [mgChl mmolC-1 day-1]
+ ! KOchl_cocco : Chlorophyll degradation rate [day-1]
+ ! Chl2N_cocco : Chl:N ratio = CoccoChl/CoccoN [mgChl mmolN-1]
+ !-------------------------------------------------------------------------------
+
+ sms(k,icchl) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Chlorophyll Synthesis
+ !-----------------------------------------------------------------------
+ + ChlSynth_cocco * CoccoC & ! Photoacclimation
+ !-----------------------------------------------------------------------
+ ! SINKS: Photo-oxidation
+ !-----------------------------------------------------------------------
+ - KOchl_cocco * CoccoChl &
+ !-----------------------------------------------------------------------
+ ! SINKS: Aggregation
+ !-----------------------------------------------------------------------
+ - aggregationRate * CoccoChl &
+ !-----------------------------------------------------------------------
+ ! SINKS: Grazing (Chl-basis)
+ !-----------------------------------------------------------------------
+ - grazingFlux_cocco * Chl2N_cocco & ! Mesozooplankton (N->Chl)
+ - grazingFlux_Cocco2 * Chl2N_cocco * is_3zoo2det & ! Macrozooplankton
+ - grazingFlux_Cocco3 * Chl2N_cocco * is_3zoo2det & ! Microzooplankton
+ ) * dt_b + sms(k,icchl)
+
+ !===============================================================================
+ ! 28. PHAEOCYSTIS NITROGEN (PhaeoN)
+ !===============================================================================
+ ! Tracks nitrogen content of Phaeocystis (colony-forming phytoplankton).
+ ! Only active when enable_coccos = .true.
+ !
+ ! Variables:
+ ! N_assim_phaeo : N assimilation rate [day-1]
+ ! lossN_p : N loss rate [day-1]
+ ! limitFacN_phaeo : Limiter function for N:C ratio regulation [-]
+ ! aggregationRate : Aggregation to detritus [day-1]
+ ! grazingFlux_phaeo : Mesozooplankton grazing [mmolN m-3 day-1]
+ ! grazingFlux_phaeo2 : Macrozooplankton grazing [mmolN m-3 day-1]
+ ! grazingFlux_phaeo3 : Microzooplankton grazing [mmolN m-3 day-1]
+ !-------------------------------------------------------------------------------
+
+ sms(k,iphan) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Nitrogen Assimilation
+ !-----------------------------------------------------------------------
+ + N_assim_phaeo * PhaeoC &
+ !-----------------------------------------------------------------------
+ ! SINKS: DON Excretion
+ !-----------------------------------------------------------------------
+ - lossN_p * limitFacN_phaeo * PhaeoN &
+ !-----------------------------------------------------------------------
+ ! SINKS: Aggregation
+ !-----------------------------------------------------------------------
+ - aggregationRate * PhaeoN &
+ !-----------------------------------------------------------------------
+ ! SINKS: Grazing
+ !-----------------------------------------------------------------------
+ - grazingFlux_phaeo & ! Mesozooplankton
+ - grazingFlux_phaeo2 * is_3zoo2det & ! Macrozooplankton
+ - grazingFlux_phaeo3 * is_3zoo2det & ! Microzooplankton
+ ) * dt_b + sms(k,iphan)
+
+ !===============================================================================
+ ! 29. PHAEOCYSTIS CARBON (PhaeoC)
+ !===============================================================================
+ ! Tracks carbon content of Phaeocystis.
+ !
+ ! Variables:
+ ! Cphot_phaeo : Gross photosynthesis rate [day-1]
+ ! phyRespRate_phaeo : Autotrophic respiration rate [day-1]
+ ! lossC_p : C loss rate [day-1]
+ ! recipQuota_phaeo : Reciprocal of N:C quota (for N->C conversion) [-]
+ !-------------------------------------------------------------------------------
+
+ sms(k,iphac) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Net Photosynthesis
+ !-----------------------------------------------------------------------
+ + Cphot_phaeo * PhaeoC & ! Gross photosynthesis
+ !-----------------------------------------------------------------------
+ ! SINKS: DOC Excretion
+ !-----------------------------------------------------------------------
+ - lossC_p * limitFacN_phaeo * PhaeoC &
+ !-----------------------------------------------------------------------
+ ! SINKS: Respiration
+ !-----------------------------------------------------------------------
+ - phyRespRate_phaeo * PhaeoC &
+ !-----------------------------------------------------------------------
+ ! SINKS: Aggregation
+ !-----------------------------------------------------------------------
+ - aggregationRate * PhaeoC &
+ !-----------------------------------------------------------------------
+ ! SINKS: Grazing (C-basis)
+ !-----------------------------------------------------------------------
+ - grazingFlux_phaeo * recipQuota_phaeo & ! Mesozooplankton (N->C)
+ - grazingFlux_phaeo2 * recipQuota_phaeo * is_3zoo2det & ! Macrozooplankton
+ - grazingFlux_phaeo3 * recipQuota_phaeo * is_3zoo2det & ! Microzooplankton
+ ) * dt_b + sms(k,iphac)
+
+ !===============================================================================
+ ! 30. PHAEOCYSTIS CHLOROPHYLL-A (PhaeoChl)
+ !===============================================================================
+ ! Tracks chlorophyll-a content for light harvesting and photoacclimation.
+ !
+ ! Variables:
+ ! chlSynth_phaeo : Chlorophyll synthesis rate [mgChl mmolC-1 day-1]
+ ! KOchl_phaeo : Chlorophyll degradation rate [day-1]
+ ! Chl2N_phaeo : Chl:N ratio = PhaeoChl/PhaeoN [mgChl mmolN-1]
+ !-------------------------------------------------------------------------------
+
+ sms(k,iphachl) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Chlorophyll Synthesis
+ !-----------------------------------------------------------------------
+ + chlSynth_phaeo * PhaeoC & ! Photoacclimation
+ !-----------------------------------------------------------------------
+ ! SINKS: Photo-oxidation
+ !-----------------------------------------------------------------------
+ - KOchl_phaeo * PhaeoChl &
+ !-----------------------------------------------------------------------
+ ! SINKS: Aggregation
+ !-----------------------------------------------------------------------
+ - aggregationRate * PhaeoChl &
+ !-----------------------------------------------------------------------
+ ! SINKS: Grazing (Chl-basis)
+ !-----------------------------------------------------------------------
+ - grazingFlux_phaeo * Chl2N_phaeo & ! Mesozooplankton (N->Chl)
+ - grazingFlux_phaeo2 * Chl2N_phaeo * is_3zoo2det & ! Macrozooplankton
+ - grazingFlux_phaeo3 * Chl2N_phaeo * is_3zoo2det & ! Microzooplankton
+ ) * dt_b + sms(k,iphachl)
+
+ endif ! enable_coccos
+
+ !===============================================================================
+ ! 31. DETRITAL SILICA (DetSi)
+ !===============================================================================
+ ! Biogenic silica from diatom frustules in slow-sinking detritus.
+ !
+ ! Variables:
+ ! aggregationRate : Diatom aggregation rate [day-1]
+ ! lossN_d : Diatom mortality/excretion rate [day-1]
+ ! grazingFlux_dia, grazingFlux_dia3 : Grazing on diatoms [mmolN m-3 day-1]
+ ! qSiN : Si:N ratio in diatoms [mmolSi mmolN-1]
+ ! reminSiT : Temperature-dependent dissolution [day-1]
+ !-------------------------------------------------------------------------------
+
+ sms(k,idetsi) = ( &
+ !---------------------------------------------------------------------------
+ ! SOURCES: Diatom Aggregation
+ !---------------------------------------------------------------------------
+ + aggregationRate * DiaSi &
+ !---------------------------------------------------------------------------
+ ! SOURCES: Diatom Excretion/Mortality
+ !---------------------------------------------------------------------------
+ + lossN_d * limitFacN_dia * DiaSi &
+ !---------------------------------------------------------------------------
+ ! SOURCES: Grazing on Diatoms (Si-basis)
+ !---------------------------------------------------------------------------
+ + grazingFlux_dia3 * qSiN * is_3zoo2det & ! Microzooplankton
+ + grazingFlux_dia * qSiN * (1.0 - is_3zoo2det) & ! Mesozooplankton (when 3zoo disabled)
+ !---------------------------------------------------------------------------
+ ! SINKS: Dissolution
+ !---------------------------------------------------------------------------
+ - reminSiT * DetSi & ! Temperature-dependent
+ ) * dt_b + sms(k,idetsi)
+
+ !===============================================================================
+ ! 32. DISSOLVED SILICATE (DSi)
+ !===============================================================================
+ ! Dissolved silicate available for diatom uptake.
+ ! Based on Schourup 2013 Eq. A3
+ !
+ ! Variables:
+ ! Si_assim : Silicic acid assimilation by diatoms [day-1]
+ ! reminSiT : Temperature-dependent dissolution [day-1]
+ ! DetSi, DetZ2Si : Detrital silica pools [mmolSi m-3]
+ !-------------------------------------------------------------------------------
+
+ sms(k,isi) = ( &
+ !---------------------------------------------------------------------------
+ ! SINKS: Biological Uptake
+ !---------------------------------------------------------------------------
+ - Si_assim * DiaC &
+ !---------------------------------------------------------------------------
+ ! SOURCES: Remineralization
+ !---------------------------------------------------------------------------
+ + reminSiT * DetSi & ! Slow-sinking detritus
+ + reminSiT * DetZ2Si * is_3zoo2det & ! Fast-sinking detritus
+ ) * dt_b + sms(k,isi)
+
+ !===============================================================================
+ ! 33. DISSOLVED IRON (Fe)
+ !===============================================================================
+ ! Tracks dissolved iron, a limiting micronutrient for phytoplankton growth.
+ !
+ ! Key Concept: Iron cycling is coupled to nitrogen via the Fe:N ratio (Fe2N)
+ ! All N-based fluxes are converted to Fe equivalents
+ !
+ ! Variables:
+ ! Fe2N : Intracellular Fe:N ratio [μmol Fe mmol N-1]
+ ! Note: Fe2N = Fe2C × 6.625 (Redfield conversion)
+ ! N_assim, N_assim_dia, etc. : N assimilation rates [mmol N mmol C-1 day-1]
+ ! lossN, lossN_d, etc. : N excretion rates [day-1]
+ ! limitFacN, etc. : Nutrient limitation factors [-]
+ ! reminN : Temperature-dependent remineralization [day-1]
+ ! kScavFe : Iron scavenging rate [m3 mmol C-1 day-1]
+ ! FreeFe : Free dissolved iron [μmol Fe m-3]
+ !-------------------------------------------------------------------------------
+
+ sms(k,ife) = ( &
+ !---------------------------------------------------------------------------
+ ! Iron Uptake/Release Coupled to Nitrogen Cycling (via Fe:N ratio)
+ !---------------------------------------------------------------------------
+ Fe2N * ( &
+ !-----------------------------------------------------------------------
+ ! SINKS: Phytoplankton Assimilation
+ !-----------------------------------------------------------------------
+ - N_assim * PhyC & ! Small phytoplankton
+ - N_assim_dia * DiaC & ! Diatoms
+ - N_assim_cocco * CoccoC * is_coccos & ! Coccolithophores
+ - N_assim_phaeo * PhaeoC * is_coccos & ! Phaeocystis
+ !-----------------------------------------------------------------------
+ ! SOURCES: Phytoplankton Excretion
+ !-----------------------------------------------------------------------
+ + lossN * limitFacN * PhyN & ! Small phytoplankton
+ + lossN_d * limitFacN_dia * DiaN & ! Diatoms
+ + lossN_c * limitFacN_cocco * CoccoN * is_coccos & ! Coccolithophores
+ + lossN_p * limitFacN_phaeo * PhaeoN * is_coccos & ! Phaeocystis
+ !-----------------------------------------------------------------------
+ ! SOURCES: Detrital Remineralization
+ !-----------------------------------------------------------------------
+ + reminN * arrFunc * O2Func * DetN & ! Slow-sinking detritus
+ + reminN * arrFunc * O2Func * DetZ2N * is_3zoo2det & ! Fast-sinking detritus
+ !-----------------------------------------------------------------------
+ ! SOURCES: Zooplankton Excretion
+ !-----------------------------------------------------------------------
+ + lossN_z * HetN & ! Mesozooplankton
+ + lossN_z2 * Zoo2N * is_3zoo2det & ! Macrozooplankton
+ + lossN_z3 * MicZooN * is_3zoo2det & ! Microzooplankton
+ ) &
+ !---------------------------------------------------------------------------
+ ! SINKS: Abiotic Iron Scavenging onto Particles
+ !---------------------------------------------------------------------------
+ - kScavFe * DetC * FreeFe & ! Slow-sinking detritus
+ - kScavFe * DetZ2C * FreeFe * is_3zoo2det & ! Fast-sinking detritus
+ ) * dt_b + sms(k,ife)
+
+ !===============================================================================
+ ! 34. PHYTOPLANKTON CALCITE (PhyCalc)
+ !===============================================================================
+ ! Tracks calcium carbonate in living phytoplankton (coccoliths).
+ !
+ ! Variables:
+ ! calcification : CaCO3 production rate [mmolCaCO3 m-3 day-1]
+ ! calc_loss_agg : Calcite loss to aggregation [mmolCaCO3 m-3 day-1]
+ ! calc_loss_gra, calc_loss_gra2, calc_loss_gra3 : Calcite loss to grazing [mmolCaCO3 m-3 day-1]
+ ! lossC, lossC_c : C excretion rates [day-1]
+ ! phyRespRate, phyRespRate_cocco : Respiration rates [day-1]
+ ! limitFacN, limitFacN_cocco : N:C ratio limiters [-]
+ !-------------------------------------------------------------------------------
+
+ if (enable_coccos) then
+ !---------------------------------------------------------------------------
+ ! Configuration: Coccolithophore-Specific Calcite Dynamics
+ !---------------------------------------------------------------------------
+ sms(k,iphycal) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Calcification
+ !-----------------------------------------------------------------------
+ + calcification & ! New CaCO3 production
+ !-----------------------------------------------------------------------
+ ! SINKS: Losses from Living Cells
+ !-----------------------------------------------------------------------
+ - lossC_c * limitFacN_cocco * PhyCalc & ! Excretion/exudation
+ - phyRespRate_cocco * PhyCalc & ! Respiration-associated loss
+ - calc_loss_agg & ! Aggregation/sinking
+ - calc_loss_gra & ! Mesozooplankton grazing
+ - calc_loss_gra2 * is_3zoo2det & ! Macrozooplankton grazing
+ - calc_loss_gra3 * is_3zoo2det & ! Microzooplankton grazing
+ ) * dt_b + sms(k,iphycal)
+ else
+ !---------------------------------------------------------------------------
+ ! Configuration: Generic Phytoplankton Calcite (Small Calcifiers)
+ !---------------------------------------------------------------------------
+ sms(k,iphycal) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Calcification
+ !-----------------------------------------------------------------------
+ + calcification &
+ !-----------------------------------------------------------------------
+ ! SINKS: Losses from Living Cells
+ !-----------------------------------------------------------------------
+ - lossC * limitFacN * PhyCalc &
+ - phyRespRate * PhyCalc &
+ - calc_loss_agg &
+ - calc_loss_gra &
+ - calc_loss_gra2 * is_3zoo2det &
+ - calc_loss_gra3 * is_3zoo2det &
+ ) * dt_b + sms(k,iphycal)
+ endif
-#if defined (__coccos)
- vertChldegc(k) = vertChldegc(k) + ( &
- + KOchl_cocco &
- ) * recipbiostep
-#endif
+ !===============================================================================
+ ! 35. DETRITAL CALCITE (DetCalc)
+ !===============================================================================
+ ! Tracks calcium carbonate in slow-sinking organic particles.
+ !
+ ! Variables:
+ ! calc_loss_agg : Calcite from aggregation [mmolCaCO3 m-3 day-1]
+ ! calc_loss_gra, calc_loss_gra3 : Calcite from grazing [mmolCaCO3 m-3 day-1]
+ ! calc_diss_guts : Gut dissolution fraction [-]
+ ! calc_diss : Water column dissolution rate [day-1]
+ !-------------------------------------------------------------------------------
+
+ if (enable_coccos) then
+ if (enable_3zoo2det) then
+ !-----------------------------------------------------------------------
+ ! Configuration: Coccolithophore Calcite with 3-Zooplankton Model
+ !-----------------------------------------------------------------------
+ sms(k,idetcal) = ( &
+ !-------------------------------------------------------------------
+ ! SOURCES: Transfer from Living Cells
+ !-------------------------------------------------------------------
+ + lossC_c * limitFacN_cocco * PhyCalc & ! Excretion
+ + phyRespRate_cocco * PhyCalc & ! Respiration products
+ + calc_loss_agg & ! Aggregation products
+ + calc_loss_gra3 & ! Microzooplankton grazing
+ !-------------------------------------------------------------------
+ ! SINKS: Dissolution
+ !-------------------------------------------------------------------
+ - calc_loss_gra3 * calc_diss_guts & ! Gut dissolution
+ - calc_diss * DetCalc & ! Water column dissolution
+ ) * dt_b + sms(k,idetcal)
+ else
+ !-----------------------------------------------------------------------
+ ! Configuration: Coccolithophore Calcite with Standard Zooplankton
+ !-----------------------------------------------------------------------
+ sms(k,idetcal) = ( &
+ !-------------------------------------------------------------------
+ ! SOURCES: Transfer from Living Cells
+ !-------------------------------------------------------------------
+ + lossC_c * limitFacN_cocco * PhyCalc &
+ + phyRespRate_cocco * PhyCalc &
+ + calc_loss_agg &
+ + calc_loss_gra &
+ !-------------------------------------------------------------------
+ ! SINKS: Dissolution
+ !-------------------------------------------------------------------
+ - calc_loss_gra * calc_diss_guts &
+ - calc_diss * DetCalc &
+ ) * dt_b + sms(k,idetcal)
+ endif
+ else
+ if (enable_3zoo2det) then
+ !-----------------------------------------------------------------------
+ ! Configuration: Generic Phytoplankton Calcite with 3-Zooplankton
+ !-----------------------------------------------------------------------
+ sms(k,idetcal) = ( &
+ !-------------------------------------------------------------------
+ ! SOURCES: Transfer from Living Cells
+ !-------------------------------------------------------------------
+ + lossC * limitFacN * PhyCalc &
+ + phyRespRate * PhyCalc &
+ + calc_loss_agg &
+ + calc_loss_gra3 &
+ !-------------------------------------------------------------------
+ ! SINKS: Dissolution
+ !-------------------------------------------------------------------
+ - calc_loss_gra3 * calc_diss_guts &
+ - calc_diss * DetCalc &
+ ) * dt_b + sms(k,idetcal)
+ else
+ !-----------------------------------------------------------------------
+ ! Configuration: Generic Phytoplankton Calcite with Standard Zooplankton
+ !-----------------------------------------------------------------------
+ sms(k,idetcal) = ( &
+ !-------------------------------------------------------------------
+ ! SOURCES: Transfer from Living Cells
+ !-------------------------------------------------------------------
+ + lossC * limitFacN * PhyCalc &
+ + phyRespRate * PhyCalc &
+ + calc_loss_agg &
+ + calc_loss_gra &
+ !-------------------------------------------------------------------
+ ! SINKS: Dissolution
+ !-------------------------------------------------------------------
+ - calc_loss_gra * calc_diss_guts &
+ - calc_diss * DetCalc &
+ ) * dt_b + sms(k,idetcal)
+ endif
+ endif
-!*** zooplankton1 respiration
- vertrespmeso(k) = vertrespmeso(k) + ( &
- + HetRespFlux &
- ) * recipbiostep
-#if defined (__3Zoo2Det)
-!*** zooplankton2 respiration
- vertrespmacro(k) = vertrespmacro(k) + ( &
- + Zoo2RespFlux &
- ) * recipbiostep
+ !===============================================================================
+ ! 36. DISSOLVED OXYGEN (O2)
+ !===============================================================================
+ ! Tracks oxygen production (photosynthesis) and consumption (respiration,
+ ! remineralization).
+ !
+ ! Variables:
+ ! Cphot, Cphot_dia, etc. : Gross photosynthesis rates [day-1]
+ ! phyRespRate, phyRespRate_dia, etc. : Autotrophic respiration rates [day-1]
+ ! rho_C1 : DOC remineralization rate [day-1]
+ ! hetRespFlux, Zoo2RespFlux, MicZooRespFlux : Zooplankton respiration [mmolC m-3 day-1]
+ ! redO2C : O2:C stoichiometric ratio (Redfield) [-]
+ ! Typically ~170/122 = 1.39 mol O2/mol C
+ !-------------------------------------------------------------------------------
+
+ sms(k,ioxy) = ( &
+ !---------------------------------------------------------------------------
+ ! SOURCES: Photosynthetic Oxygen Production
+ !---------------------------------------------------------------------------
+ + Cphot * phyC & ! Small phytoplankton
+ + Cphot_dia * diaC & ! Diatoms
+ + Cphot_cocco * CoccoC * is_coccos & ! Coccolithophores
+ + Cphot_phaeo * PhaeoC * is_coccos & ! Phaeocystis
+ !---------------------------------------------------------------------------
+ ! SINKS: Autotrophic Respiration
+ !---------------------------------------------------------------------------
+ - phyRespRate * phyC & ! Small phytoplankton
+ - phyRespRate_dia * diaC & ! Diatoms
+ - phyRespRate_cocco * CoccoC * is_coccos & ! Coccolithophores
+ - phyRespRate_phaeo * PhaeoC * is_coccos & ! Phaeocystis
+ !---------------------------------------------------------------------------
+ ! SINKS: Heterotrophic Respiration and Remineralization
+ !---------------------------------------------------------------------------
+ - rho_C1 * arrFunc * O2Func * EOC & ! DOC remineralization
+ - rho_C1t * DOCt * is_riverinput &
+ - hetRespFlux & ! Mesozooplankton
+ - Zoo2RespFlux * is_3zoo2det & ! Macrozooplankton
+ - MicZooRespFlux * is_3zoo2det & ! Microzooplankton
+ ) * redO2C * dt_b + sms(k,ioxy)
+ ! Note: redO2C converts carbon-based rates to oxygen equivalents
+ ! using the Redfield ratio (typically ~170/122 = 1.39 mol O2/mol C)
+
+ if (ciso) then
+
+ !===========================================================================
+ ! 1. CARBON-13 (13C) BUDGETS
+ !===========================================================================
+ ! Calculates 13C budgets for all carbon pools with isotope fractionation.
+ ! Parallel structure to total carbon budgets.
+ !---------------------------------------------------------------------------
+
+ !===========================================================================
+ ! DISSOLVED INORGANIC CARBON (DIC_13)
+ !===========================================================================
+ ! Source-minus-sink budget for 13C in dissolved inorganic carbon pool.
+ !
+ ! SOURCES (+):
+ ! - Phytoplankton respiration (returns 13C to DIC)
+ ! - Diatom respiration
+ ! - DOC remineralization (aerobic respiration)
+ ! - Heterotroph respiration
+ ! - Calcite dissolution (releases 13C from CaCO3)
+ ! - Calcite dissolution in grazer guts
+ !
+ ! SINKS (-):
+ ! - Phytoplankton photosynthesis (fixes 13C into organic matter)
+ ! - Diatom photosynthesis
+ ! - Calcification (removes 13C for CaCO3 formation)
+ !
+ ! Variables:
+ ! Cphot, Cphot_Dia : Photosynthesis rates [day-1]
+ ! PhyC_13, DiaC_13 : Phytoplankton 13C pools [mmol13C m-3]
+ ! phyRespRate : Phytoplankton respiration rates [day-1]
+ ! rho_C1 : DOC remineralization rate [day-1]
+ ! arrFunc : Temperature function [-]
+ ! EOC_13 : Dissolved organic 13C [mmol13C m-3]
+ ! HetRespFlux_13 : Heterotroph respiration flux [mmol13C m-3 day-1]
+ ! calc_diss_13 : Calcite dissolution rate [day-1]
+ ! DetCalc_13 : Detrital calcite 13C [mmol13C m-3]
+ ! calc_loss_gra_13 : Calcite grazing flux [mmol13C m-3 day-1]
+ ! calc_diss_guts : Gut dissolution fraction [-]
+ ! calcification_13 : Calcification flux [mmol13C m-3 day-1]
+ ! dt_b : Biogeochemistry time step [day]
+ !
+ ! Note: Photosynthesis preferentially takes up 12C, leaving DIC enriched in 13C
+ ! Respiration returns carbon with original isotopic composition
+ !---------------------------------------------------------------------------
+
+ sms(k, idic_13) = ( &
+ !-----------------------------------------------------------------------
+ ! SINKS: Carbon fixation (removes 13C-DIC)
+ !-----------------------------------------------------------------------
+ - Cphot * PhyC_13 & ! Small phyto photosynthesis
+ - Cphot_Dia * DiaC_13 & ! Diatom photosynthesis
+ !
+ !-----------------------------------------------------------------------
+ ! SOURCES: Respiration and remineralization (returns 13C to DIC)
+ !-----------------------------------------------------------------------
+ + phyRespRate * PhyC_13 & ! Small phyto respiration
+ + phyRespRate_Dia * DiaC_13 & ! Diatom respiration
+ + rho_C1 * arrFunc * EOC_13 & ! DOC remineralization
+ + HetRespFlux_13 & ! Heterotroph respiration
+ !
+ !-----------------------------------------------------------------------
+ ! SOURCES: Calcite dissolution (releases 13C from CaCO3)
+ !-----------------------------------------------------------------------
+ + calc_diss_13 * DetCalc_13 & ! Water column dissolution
+ + calc_loss_gra_13 * calc_diss_guts & ! Gut dissolution
+ !
+ !-----------------------------------------------------------------------
+ ! SINKS: Calcification (removes 13C for CaCO3 formation)
+ !-----------------------------------------------------------------------
+ - calcification_13 & ! CaCO3 precipitation
+ !
+ ) * dt_b + sms(k, idic_13)
+
+ !===========================================================================
+ ! SMALL PHYTOPLANKTON ORGANIC CARBON (PhyC_13)
+ !===========================================================================
+ ! 13C budget for small phytoplankton biomass.
+ !
+ ! SOURCES (+):
+ ! - Photosynthesis (fixes 13C-DIC into biomass)
+ !
+ ! SINKS (-):
+ ! - Nutrient-stress mortality (lysis)
+ ! - Respiration (maintenance costs)
+ ! - Aggregation (particle formation)
+ ! - Grazing by zooplankton
+ !
+ ! Variables:
+ ! lossC : Mortality rate constant [day-1]
+ ! limitFacN : Nutrient limitation factor [0-1]
+ ! aggregationRate : Aggregation rate [day-1]
+ ! grazingFlux_phy : Grazing flux on small phyto [mmolN m-3 day-1]
+ ! recipQuota_13 : 13C:N ratio [mmol13C mmolN-1]
+ !
+ ! Note: Grazing uses recipQuota_13 to convert N-based flux to 13C flux
+ !---------------------------------------------------------------------------
+
+ sms(k, iphyc_13) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Photosynthetic production
+ !-----------------------------------------------------------------------
+ + Cphot * PhyC_13 & ! 13C fixation
+ !
+ !-----------------------------------------------------------------------
+ ! SINKS: Mortality, respiration, and losses
+ !-----------------------------------------------------------------------
+ - lossC * limitFacN * PhyC_13 & ! Nutrient-stress mortality
+ - phyRespRate * PhyC_13 & ! Respiration
+ - aggregationRate * PhyC_13 & ! Aggregation loss
+ - grazingFlux_phy * recipQuota_13 & ! Grazing loss (N->C conversion)
+ !
+ ) * dt_b + sms(k, iphyc_13)
+
+ !===========================================================================
+ ! DETRITAL ORGANIC CARBON (DetC_13)
+ !===========================================================================
+ ! 13C budget for dead organic matter (detritus pool).
+ !
+ ! SOURCES (+):
+ ! - Unassimilated grazing (sloppy feeding + egestion)
+ ! - Phytoplankton aggregation
+ ! - Diatom aggregation
+ ! - Heterotroph mortality
+ !
+ ! SINKS (-):
+ ! - Remineralization (aerobic respiration)
+ ! - Assimilated grazing (efficient consumption)
+ !
+ ! Variables:
+ ! grazEff : Grazing efficiency (fraction assimilated) [-]
+ ! hetLossFlux : Heterotroph mortality flux [mmolN m-3 day-1]
+ ! recipQZoo_13 : Heterotroph 13C:N ratio [mmol13C mmolN-1]
+ ! reminC : Detritus remineralization rate [day-1]
+ !
+ ! Grazing Partitioning:
+ ! Total ingestion = Assimilated + Unassimilated
+ ! Assimilated: Goes to heterotroph biomass (grazEff × flux)
+ ! Unassimilated: Goes to detritus ((1-grazEff) × flux)
+ !---------------------------------------------------------------------------
+
+ sms(k, idetc_13) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Unassimilated grazing (sloppy feeding)
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy * recipQuota_13 & ! Total small phyto grazing
+ - grazingFlux_phy * recipQuota_13 * grazEff & ! Minus assimilated portion
+ + grazingFlux_Dia * recipQuota_dia_13 & ! Total diatom grazing
+ - grazingFlux_Dia * recipQuota_dia_13 * grazEff & ! Minus assimilated portion
+ !
+ !-----------------------------------------------------------------------
+ ! SOURCES: Aggregation and mortality
+ !-----------------------------------------------------------------------
+ + aggregationRate * phyC_13 & ! Small phyto aggregation
+ + aggregationRate * DiaC_13 & ! Diatom aggregation
+ + hetLossFlux * recipQZoo_13 & ! Heterotroph mortality
+ !
+ !-----------------------------------------------------------------------
+ ! SINKS: Remineralization
+ !-----------------------------------------------------------------------
+ - reminC * arrFunc * DetC_13 & ! Aerobic respiration
+ !
+ ) * dt_b + sms(k, idetc_13)
+
+ !===========================================================================
+ ! HETEROTROPH ORGANIC CARBON (HetC_13)
+ !===========================================================================
+ ! 13C budget for zooplankton biomass.
+ !
+ ! SOURCES (+):
+ ! - Assimilated grazing on phytoplankton
+ ! - Assimilated grazing on diatoms
+ !
+ ! SINKS (-):
+ ! - Mortality (density-dependent)
+ ! - Non-predatory losses (diseases, senescence)
+ ! - Respiration (metabolic costs)
+ !
+ ! Variables:
+ ! lossC_z : Non-predatory loss rate [day-1]
+ ! hetRespFlux_13: Heterotroph respiration flux [mmol13C m-3 day-1]
+ !
+ ! Note: Grazing efficiency (grazEff) determines assimilation fraction
+ ! Typical values: 0.6-0.8 (60-80% assimilated)
+ !---------------------------------------------------------------------------
+
+ sms(k, ihetc_13) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Assimilated food
+ !-----------------------------------------------------------------------
+ + grazingFlux_phy * recipQuota_13 * grazEff & ! Small phyto consumption
+ + grazingFlux_Dia * recipQuota_dia_13 * grazEff & ! Diatom consumption
+ !
+ !-----------------------------------------------------------------------
+ ! SINKS: Mortality and respiration
+ !-----------------------------------------------------------------------
+ - hetLossFlux * recipQZoo_13 & ! Mortality flux
+ - lossC_z * HetC_13 & ! Non-predatory losses
+ - hetRespFlux_13 & ! Respiration
+ !
+ ) * dt_b + sms(k, ihetc_13)
+
+ !===========================================================================
+ ! DISSOLVED ORGANIC CARBON (EOC_13)
+ !===========================================================================
+ ! 13C budget for dissolved organic carbon pool.
+ !
+ ! SOURCES (+):
+ ! - Phytoplankton exudation (nutrient-stress losses)
+ ! - Diatom exudation
+ ! - Detritus remineralization (solubilization)
+ ! - Heterotroph exudation (sloppy feeding, excretion)
+ ! - River input (terrestrial DOC)
+ !
+ ! SINKS (-):
+ ! - Remineralization (microbial respiration)
+ !
+ ! Variables:
+ ! lossC, lossC_d : Exudation rate constants [day-1]
+ ! limitFacN : Nutrient limitation factors [0-1]
+ ! LocRiverDOC : River DOC input flux [mmolC m-3 day-1]
+ ! r_iorg_13 : River 13C:12C ratio (isotopic signature) [-]
+ !
+ ! DOC Pool Characteristics:
+ ! - Labile fraction: Days to weeks turnover
+ ! - Semi-labile fraction: Months to years turnover
+ ! - Model uses bulk DOC with single remineralization rate
+ !
+ ! River Isotope Signature:
+ ! - Terrestrial organic matter typically depleted in 13C
+ ! - δ13C ≈ -27‰ for C3 plants, -13‰ for C4 plants
+ ! - Marine phytoplankton: δ13C ≈ -20 to -22‰
+ !---------------------------------------------------------------------------
+
+ sms(k, idoc_13) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Exudation and solubilization
+ !-----------------------------------------------------------------------
+ + lossC * limitFacN * phyC_13 & ! Small phyto exudation
+ + lossC_d * limitFacN_dia * DiaC_13 & ! Diatom exudation
+ + reminC * arrFunc * DetC_13 & ! Detritus solubilization
+ + lossC_z * HetC_13 & ! Heterotroph exudation
+ !
+ !-----------------------------------------------------------------------
+ ! SOURCES: River input (terrestrial DOC)
+ !-----------------------------------------------------------------------
+ + LocRiverDOC * r_iorg_13 & ! River 13C input
+ !
+ !-----------------------------------------------------------------------
+ ! SINKS: Remineralization
+ !-----------------------------------------------------------------------
+ - rho_c1 * arrFunc * EOC_13 & ! Microbial respiration
+ !
+ ) * dt_b + sms(k, idoc_13)
+
+ !===========================================================================
+ ! DIATOM ORGANIC CARBON (DiaC_13)
+ !===========================================================================
+ ! 13C budget for diatom biomass (large phytoplankton).
+ !
+ ! Structure identical to small phytoplankton (section 1.2)
+ ! with diatom-specific parameters and fluxes.
+ !---------------------------------------------------------------------------
+
+ sms(k, idiac_13) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Photosynthetic production
+ !-----------------------------------------------------------------------
+ + Cphot_dia * DiaC_13 & ! 13C fixation
+ !
+ !-----------------------------------------------------------------------
+ ! SINKS: Mortality, respiration, and losses
+ !-----------------------------------------------------------------------
+ - lossC_d * limitFacN_dia * DiaC_13 & ! Nutrient-stress mortality
+ - phyRespRate_dia * DiaC_13 & ! Respiration
+ - aggregationRate * DiaC_13 & ! Aggregation loss
+ - grazingFlux_dia * recipQuota_dia_13 & ! Grazing loss
+ !
+ ) * dt_b + sms(k, idiac_13)
+
+ !===========================================================================
+ ! PHYTOPLANKTON CALCITE (PhyCalc_13)
+ !===========================================================================
+ ! 13C budget for calcium carbonate associated with living phytoplankton.
+ !
+ ! SOURCES (+):
+ ! - Calcification (CaCO3 precipitation on cells)
+ !
+ ! SINKS (-):
+ ! - Nutrient-stress mortality (CaCO3 to detritus)
+ ! - Cell death respiration (CaCO3 to detritus)
+ ! - Aggregation (CaCO3 incorporated in aggregates)
+ ! - Grazing (CaCO3 consumed with cells)
+ !
+ ! Variables:
+ ! calcification_13 : 13C calcification flux [mmol13C m-3 day-1]
+ ! phyCalc_13 : Phytoplankton calcite 13C [mmol13C m-3]
+ ! calc_loss_agg_13 : Aggregation loss flux [mmol13C m-3 day-1]
+ ! calc_loss_gra_13 : Grazing loss flux [mmol13C m-3 day-1]
+ !
+ ! Calcite Isotope Fractionation:
+ ! - Small enrichment in 13C relative to DIC (~+1‰)
+ ! - Temperature-dependent fractionation
+ ! - Important for paleoclimate proxies (foraminifera, coccoliths)
+ !---------------------------------------------------------------------------
+
+ sms(k, iphycal_13) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Calcification
+ !-----------------------------------------------------------------------
+ + calcification_13 & ! CaCO3 precipitation
+ !
+ !-----------------------------------------------------------------------
+ ! SINKS: Mortality and losses
+ !-----------------------------------------------------------------------
+ - lossC * limitFacN * phyCalc_13 & ! Mortality to detritus
+ - phyRespRate * phyCalc_13 & ! Death to detritus
+ - calc_loss_agg_13 & ! Aggregation
+ - calc_loss_gra_13 & ! Grazing
+ !
+ ) * dt_b + sms(k, iphycal_13)
+
+ !===========================================================================
+ ! DETRITAL CALCITE (DetCalc_13)
+ !===========================================================================
+ ! 13C budget for calcium carbonate in detritus/particles.
+ !
+ ! SOURCES (+):
+ ! - Phytoplankton mortality (CaCO3 from dead cells)
+ ! - Cell death (respiratory loss to detritus)
+ ! - Aggregation (CaCO3 in aggregates)
+ ! - Grazing (CaCO3 in fecal pellets)
+ !
+ ! SINKS (-):
+ ! - Dissolution in water column
+ ! - Dissolution in grazer guts
+ !
+ ! Variables:
+ ! calc_diss_guts : Fraction dissolved in guts (typically 0.1-0.5) [-]
+ !
+ ! Calcite Dissolution:
+ ! - Thermodynamically driven (saturation state dependent)
+ ! - Faster in undersaturated waters (deep ocean, high CO2)
+ ! - Gut dissolution: Acidic environment accelerates dissolution
+ ! - Returns 13C to DIC pool (source for DIC_13 budget)
+ !---------------------------------------------------------------------------
+
+ sms(k, idetcal_13) = ( &
+ !-----------------------------------------------------------------------
+ ! SOURCES: Mortality and transfer from living cells
+ !-----------------------------------------------------------------------
+ + lossC * limitFacN * phyCalc_13 & ! Mortality
+ + phyRespRate * phyCalc_13 & ! Death
+ + calc_loss_agg_13 & ! Aggregation
+ + calc_loss_gra_13 & ! Grazing (to fecal pellets)
+ !
+ !-----------------------------------------------------------------------
+ ! SINKS: Dissolution
+ !-----------------------------------------------------------------------
+ - calc_loss_gra_13 * calc_diss_guts & ! Gut dissolution
+ - calc_diss_13 * DetCalc_13 & ! Water column dissolution
+ !
+ ) * dt_b + sms(k, idetcal_13)
+
+ if (ciso_14) then
+
+ if (ciso_organic_14) then
+
+ !===================================================================
+ ! CARBON-14 (14C) BUDGETS
+ !===================================================================
+ ! Calculates 14C budgets for radiocarbon applications.
+ ! Structure identical to 13C budgets (sections 1.1-1.8).
+ !
+ ! Additional Consideration:
+ ! - Radioactive decay (half-life 5,730 years)
+ ! - Decay term handled separately in forcing module
+ ! - Bomb radiocarbon (anthropogenic 14C pulse)
+ !
+ ! Applications:
+ ! - Ocean ventilation age (Δ14C)
+ ! - Carbon residence time
+ ! - Mixing timescales
+ ! - Model validation (WOCE/CLIVAR 14C data)
+ !
+ ! Notation:
+ ! All variables end in _14 (e.g., PhyC_14, DiaC_14)
+ ! Structure parallels 13C budgets exactly
+ !-------------------------------------------------------------------
+
+ !===================================================================
+ ! DIC_14
+ !===================================================================
+ sms(k, idic_14) = ( &
+ - Cphot * PhyC_14 &
+ + phyRespRate * PhyC_14 &
+ - Cphot_Dia * DiaC_14 &
+ + phyRespRate_Dia * DiaC_14 &
+ + rho_C1 * arrFunc * EOC_14 &
+ + HetRespFlux_14 &
+ + calc_diss_14 * DetCalc_14 &
+ + calc_loss_gra_14 * calc_diss_guts &
+ - calcification_14 &
+ ) * dt_b + sms(k, idic_14)
+
+ !===================================================================
+ ! PhyC_14
+ !===================================================================
+ sms(k, iphyc_14) = ( &
+ + Cphot * PhyC_14 &
+ - lossC * limitFacN * PhyC_14 &
+ - phyRespRate * PhyC_14 &
+ - aggregationRate * PhyC_14 &
+ - grazingFlux_phy * recipQuota_14 &
+ ) * dt_b + sms(k, iphyc_14)
+
+ !===================================================================
+ ! DetC_14
+ !===================================================================
+ sms(k, idetc_14) = ( &
+ + grazingFlux_phy * recipQuota_14 &
+ - grazingFlux_phy * recipQuota_14 * grazEff &
+ + grazingFlux_Dia * recipQuota_dia_14 &
+ - grazingFlux_Dia * recipQuota_dia_14 * grazEff &
+ + aggregationRate * phyC_14 &
+ + aggregationRate * DiaC_14 &
+ + hetLossFlux * recipQZoo_14 &
+ - reminC * arrFunc * DetC_14 &
+ ) * dt_b + sms(k, idetc_14)
+
+ !===================================================================
+ ! HetC_14
+ !===================================================================
+ sms(k, ihetc_14) = ( &
+ + grazingFlux_phy * recipQuota_14 * grazEff &
+ + grazingFlux_Dia * recipQuota_dia_14 * grazEff &
+ - hetLossFlux * recipQZoo_14 &
+ - lossC_z * HetC_14 &
+ - hetRespFlux_14 &
+ ) * dt_b + sms(k, ihetc_14)
+
+ !===================================================================
+ ! EOC_14
+ !===================================================================
+ sms(k, idoc_14) = ( &
+ + lossC * limitFacN * phyC_14 &
+ + lossC_d * limitFacN_dia * DiaC_14 &
+ + reminC * arrFunc * DetC_14 &
+ + lossC_z * HetC_14 &
+ - rho_c1 * arrFunc * EOC_14 &
+ + LocRiverDOC * r_iorg_14 &
+ ) * dt_b + sms(k, idoc_14)
+
+ !===================================================================
+ ! DiaC_14
+ !===================================================================
+ sms(k, idiac_14) = ( &
+ + Cphot_dia * DiaC_14 &
+ - lossC_d * limitFacN_dia * DiaC_14 &
+ - phyRespRate_dia * DiaC_14 &
+ - aggregationRate * DiaC_14 &
+ - grazingFlux_dia * recipQuota_dia_14 &
+ ) * dt_b + sms(k, idiac_14)
+
+ !===================================================================
+ ! PhyCalc_14
+ !===================================================================
+ sms(k, iphycal_14) = ( &
+ + calcification_14 &
+ - lossC * limitFacN * phyCalc_14 &
+ - phyRespRate * phyCalc_14 &
+ - calc_loss_agg_14 &
+ - calc_loss_gra_14 &
+ ) * dt_b + sms(k, iphycal_14)
+
+ !===================================================================
+ ! DetCalc_14
+ !===================================================================
+ sms(k, idetcal_14) = ( &
+ + lossC * limitFacN * phyCalc_14 &
+ + phyRespRate * phyCalc_14 &
+ + calc_loss_agg_14 &
+ + calc_loss_gra_14 &
+ - calc_loss_gra_14 * calc_diss_guts &
+ - calc_diss_14 * DetCalc_14 &
+ ) * dt_b + sms(k, idetcal_14)
+
+ else
+
+ !===================================================================
+ ! ABIOTIC DIC_14 (SIMPLIFIED MODE)
+ !===================================================================
+ ! "Abiotic" 14C tracking without explicit organic pools
+ ! DIC_14 tracks total carbon with radioactive decay only
+ !
+ ! Use Case:
+ ! - Simplified radiocarbon tracer
+ ! - Tracks ventilation/mixing without biology
+ ! - Computationally efficient
+ ! - Decay handled in forcing module (recom_forcing)
+ !
+ ! Equation:
+ ! DIC_14 changes identically to DIC (conservative tracer)
+ ! Plus: Radioactive decay (handled separately)
+ !
+ ! Limitation:
+ ! - No isotope fractionation during biological processes
+ ! - Cannot capture biological isotope signals
+ ! - Suitable only for physical circulation studies
+ !-------------------------------------------------------------------
+
+ sms(k, idic_14) = sms(k, idic)
+
+ end if ! ciso_organic_14
+
+ end if ! ciso_14
+
+ end if ! ciso
+
+ !-------------------------------------------------------------------------------
+ ! DIAGNOSTIC ACCUMULATION INITIALIZATION
+ !-------------------------------------------------------------------------------
+ ! Calculate averaging weight for accumulating diagnostics over biogeochemical
+ ! sub-time steps.
+ !
+ ! Variables:
+ ! recipbiostep : Reciprocal of number of bio sub-steps (averaging weight) [-]
+ ! biostep : Number of biogeochemistry steps per physics step [-]
+ !
+ ! Averaging Approach:
+ ! Each sub-step contributes: (1/biostep) × rate
+ ! After biostep iterations: average rate over physics time step
+ !
+ ! Example:
+ ! If biostep = 4 (4 bio steps per physics step)
+ ! recipbiostep = 0.25
+ ! Each contribution weighted by 0.25
+ ! Sum of 4 contributions = time-averaged rate
+ !-------------------------------------------------------------------------------
+
+ recipbiostep = 1.d0 / real(biostep)
+
+ if (Diags) then
+
+ !===========================================================================
+ ! PRIMARY PRODUCTION DIAGNOSTICS
+ !===========================================================================
+ ! Net Primary Production (NPP) = Gross Production - Autotrophic Respiration
+ ! Gross Primary Production (GPP) = Photosynthetic carbon fixation only
+ !
+ ! NPP represents carbon available for:
+ ! - Growth (biomass increase)
+ ! - Exudation (DOC production)
+ ! - Grazing by herbivores
+ !
+ ! Units: mmolC m-3 day-1
+ !---------------------------------------------------------------------------
+
+ !===========================================================================
+ ! NET PRIMARY PRODUCTION (NPP)
+ !===========================================================================
+ ! NPP = Photosynthesis - Respiration
+ ! Carbon available after meeting metabolic maintenance costs
+ !
+ ! Variables (Small phytoplankton):
+ ! vertNPPn(k) : Time-averaged NPP for small phyto [mmolC m-3 day-1]
+ ! Cphot : Carbon-specific photosynthesis rate [day-1]
+ ! PhyC : Small phytoplankton carbon [mmolC m-3]
+ ! PhyRespRate : Respiration rate [day-1]
+ !
+ ! Ecological Interpretation:
+ ! High NPP: Nutrient replete, optimal growth conditions
+ ! Low NPP: Nutrient/light limited, high respiration costs
+ ! Negative NPP: Respiration exceeds photosynthesis (rare, stress)
+ !
+ ! Validation Targets:
+ ! - 14C uptake measurements
+ ! - Satellite-based NPP estimates (VGPM, CbPM, CAFE)
+ ! - Time series stations (HOT, BATS)
+ ! - Typical range: 0.1-10 mmolC m-3 day-1 (surface)
+ !---------------------------------------------------------------------------
+
+ ! Small phytoplankton NPP
+ vertNPPn(k) = vertNPPn(k) + ( &
+ + Cphot * PhyC & ! Photosynthetic production
+ - PhyRespRate * PhyC & ! Minus respiration costs
+ ) * recipbiostep
+
+ ! Diatom NPP
+ vertNPPd(k) = vertNPPd(k) + ( &
+ + Cphot_dia * DiaC &
+ - PhyRespRate_dia * DiaC &
+ ) * recipbiostep
+
+ if (enable_coccos) then
+ ! Coccolithophore NPP
+ vertNPPc(k) = vertNPPc(k) + ( &
+ + Cphot_cocco * CoccoC &
+ - PhyRespRate_cocco * CoccoC &
+ ) * recipbiostep
+
+ ! Phaeocystis NPP
+ vertNPPp(k) = vertNPPp(k) + ( &
+ + Cphot_phaeo * PhaeoC &
+ - PhyRespRate_phaeo * PhaeoC &
+ ) * recipbiostep
+ endif
+
+ !===========================================================================
+ ! GROSS PRIMARY PRODUCTION (GPP)
+ !===========================================================================
+ ! GPP = Total photosynthetic carbon fixation (before respiration)
+ ! Represents maximum potential carbon uptake
+ !
+ ! Relationship:
+ ! GPP = NPP + Respiration
+ ! Growth efficiency = NPP / GPP (typically 0.6-0.8)
+ !
+ ! Uses:
+ ! - Calculate carbon use efficiency
+ ! - Compare to oxygen evolution (photosynthetic quotient)
+ ! - Understand temperature effects (GPP and R differ)
+ !
+ ! Typical Values:
+ ! Surface: 1-20 mmolC m-3 day-1
+ ! Deep chlorophyll max: 0.1-5 mmolC m-3 day-1
+ ! Below euphotic zone: <0.01 mmolC m-3 day-1
+ !---------------------------------------------------------------------------
+
+ ! Small phytoplankton GPP
+ vertGPPn(k) = vertGPPn(k) + ( &
+ + Cphot * PhyC & ! Total photosynthetic fixation
+ ) * recipbiostep
+
+ ! Diatom GPP
+ vertGPPd(k) = vertGPPd(k) + ( &
+ + Cphot_dia * DiaC &
+ ) * recipbiostep
+
+ if (enable_coccos) then
+ ! Coccolithophore GPP
+ vertGPPc(k) = vertGPPc(k) + ( &
+ + Cphot_cocco * CoccoC &
+ ) * recipbiostep
+
+ ! Phaeocystis GPP
+ vertGPPp(k) = vertGPPp(k) + ( &
+ + Cphot_phaeo * PhaeoC &
+ ) * recipbiostep
+ endif
+
+ !===========================================================================
+ ! NET NITROGEN ASSIMILATION
+ !===========================================================================
+ ! Net nitrogen uptake = Assimilation - Exudation losses
+ ! Represents nitrogen incorporation into biomass
+ !
+ ! Variables (Small phytoplankton):
+ ! vertNNAn(k) : Net N assimilation for small phyto [mmolN m-3 day-1]
+ ! N_assim : N-specific assimilation rate [mmolN mmolC-1 day-1]
+ ! PhyC : Small phytoplankton carbon [mmolC m-3]
+ ! lossN : N exudation rate constant [day-1]
+ ! limitFacN : Nutrient limitation factor [0-1]
+ ! PhyN : Small phytoplankton nitrogen [mmolN m-3]
+ !
+ ! Ecological Interpretation:
+ ! Positive: Net nitrogen accumulation (growth)
+ ! Negative: Net nitrogen loss (stress-induced exudation)
+ ! Zero: Balanced uptake and loss (steady state)
+ !
+ ! Relationship to C:N Ratio:
+ ! Net N assimilation / NPP = change in N:C quota
+ ! High ratio -> decreasing C:N (N accumulation)
+ ! Low ratio -> increasing C:N (N limitation)
+ !
+ ! Validation:
+ ! - 15N tracer studies
+ ! - Nutrient depletion experiments
+ ! - Typical range: 0.01-2 mmolN m-3 day-1
+ !---------------------------------------------------------------------------
+
+ ! Small phytoplankton net N assimilation
+ vertNNAn(k) = vertNNAn(k) + ( &
+ + N_assim * PhyC & ! Nitrogen uptake from DIN
+ - lossN * limitFacN * PhyN & ! Minus exudation (stress-induced)
+ ) * recipbiostep
+
+ ! Diatom net N assimilation
+ vertNNAd(k) = vertNNAd(k) + ( &
+ + N_assim_dia * DiaC &
+ - lossN * limitFacN_dia * DiaN &
+ ) * recipbiostep
+
+ if (enable_coccos) then
+ ! Coccolithophore net N assimilation
+ vertNNAc(k) = vertNNAc(k) + ( &
+ + N_assim_cocco * CoccoC &
+ - lossN * limitFacN_cocco * CoccoN &
+ ) * recipbiostep
+
+ ! Phaeocystis net N assimilation
+ vertNNAp(k) = vertNNAp(k) + ( &
+ + N_assim_phaeo * PhaeoC &
+ - lossN * limitFacN_phaeo * PhaeoN &
+ ) * recipbiostep
+ endif
+
+ !===========================================================================
+ ! CHLOROPHYLL DEGRADATION RATES
+ !===========================================================================
+ ! Tracks chlorophyll turnover rates (photodamage + senescence)
+ ! Important for understanding chlorophyll:carbon dynamics
+ !
+ ! Variables:
+ ! vertChldegn(k) : Small phyto Chl degradation rate [day-1]
+ ! KOchl : Chlorophyll degradation rate coefficient [day-1]
+ !
+ ! Rate Components:
+ ! - Base degradation: Constant senescence (~0.01-0.05 day-1)
+ ! - Photodamage: Light-dependent additional degradation
+ ! - Total: KOchl = base + photodamage component
+ !
+ ! Ecological Significance:
+ ! - High rates: Photodamage stress, high light
+ ! - Low rates: Low light, minimal photoinhibition
+ ! - Affects Chl:C ratio and satellite retrievals
+ !
+ ! Applications:
+ ! - Understand Chl:C variability
+ ! - Validate photoacclimation dynamics
+ ! - Interpret satellite chlorophyll trends
+ !
+ ! Note: Changed from gross N-assimilation diagnostic (previous version)
+ !---------------------------------------------------------------------------
+
+ ! Small phytoplankton Chl degradation
+ vertChldegn(k) = vertChldegn(k) + ( &
+ + KOchl & ! Degradation rate [day-1]
+ ) * recipbiostep
+
+ ! Diatom Chl degradation
+ vertChldegd(k) = vertChldegd(k) + ( &
+ + KOchl_dia &
+ ) * recipbiostep
+
+ if (enable_coccos) then
+ ! Coccolithophore Chl degradation
+ vertChldegc(k) = vertChldegc(k) + ( &
+ + KOchl_cocco &
+ ) * recipbiostep
+
+ ! Phaeocystis Chl degradation
+ vertChldegp(k) = vertChldegp(k) + ( &
+ + KOchl_phaeo &
+ ) * recipbiostep
+ endif
+
+!--------------------------------------------------------------------------------------------------------------------------------------
+
+! GRAZING FLUXES
+! Only for the case with detritus grazing, not without detritus grazing, because this output is probably anyway not needed as a default.
+! diagnostics, combined from Onur and Cara, modified by Miriam
-!*** zooplankton3 respiration
- vertrespmicro(k) = vertrespmicro(k) + ( &
- + MicZooRespFlux &
- ) * recipbiostep
-#endif
-!*** calc_diss
- vertcalcdiss(k) = vertcalcdiss(k) + ( &
- + calc_diss * DetCalc &
- ) * recipbiostep
+ if (Grazing_detritus) then
-!*** aggregation by small phytoplankton
- vertaggn(k) = vertaggn(k) + ( &
- + aggregationrate * PhyC &
+!===========================================================================
+! MESOZOOPLANKTON GRAZING
+!===========================================================================
+! Tracks grazing by mesozooplankton (100-2000 μm) on multiple prey types
+! Central trophic link connecting primary producers to higher consumers
+!
+! Variables:
+! vertgrazmeso_tot(k) : Total assimilated grazing [mmolC m-3 day-1]
+! vertgrazmeso_n(k) : Grazing on nanophytoplankton [mmolC m-3 day-1]
+! vertgrazmeso_d(k) : Grazing on diatoms [mmolC m-3 day-1]
+! vertgrazmeso_c(k) : Grazing on coccolithophores [mmolC m-3 day-1]
+! vertgrazmeso_p(k) : Grazing on Phaeocystis [mmolC m-3 day-1]
+! vertgrazmeso_det(k) : Grazing on detritus 1 [mmolC m-3 day-1]
+! vertgrazmeso_det2(k) : Grazing on detritus 2 [mmolC m-3 day-1]
+! vertgrazmeso_mic(k) : Grazing on microzooplankton [mmolC m-3 day-1]
+!
+! Prey Composition:
+! PHY : Nanophytoplankton (2-20 μm) - primary prey
+! DIA : Diatoms (>20 μm) - silicified cells
+! COCCO : Coccolithophores - calcifying cells (optional)
+! PHAEO : Phaeocystis colonies (optional)
+! DET : Detritus type 1 - particulate organic matter
+! DET2 : Detritus type 2 - larger particles (optional)
+! MICZOO : Microzooplankton - intraguild predation (optional)
+!
+! Ecological Significance:
+! - Grazing efficiency (grazEff): 30-70%, rest to fecal pellets
+! - Prey selection via Holling Type II/III functional response
+! - Major pathway for carbon export via fecal pellets
+! - Controls phytoplankton bloom magnitude/duration
+!
+! Validation:
+! - Gut content analysis & pigment measurements
+! - Dilution experiments (Landry-Hassett method)
+! - Typical rates: 0.01-10 mmolC m-3 day-1
+! - Clearance rates: 1-100 mL ind-1 day-1
+!---------------------------------------------------------------------------
+
+ ! Total assimilated grazing (with efficiency applied)
+ vertgrazmeso_tot(k) = vertgrazmeso_tot(k) + ( &
+ + grazingFlux_phy * recipQuota * grazEff & ! Nanophytoplankton
+ + grazingFlux_Dia * recipQuota_Dia * grazEff & ! Diatoms
+ + grazingFlux_Det * recipDet * grazEff & ! Detritus 1
) * recipbiostep
+
+ if (enable_coccos) then
+ vertgrazmeso_tot(k) = vertgrazmeso_tot(k) + ( &
+ + grazingFlux_Cocco * recipQuota_Cocco * grazEff & ! Coccolithophores
+ + grazingFlux_Phaeo * recipQuota_Phaeo * grazEff & ! Phaeocystis
+ ) * recipbiostep
+ endif
-!*** aggregation by diatoms
- vertaggd(k) = vertaggd(k) + ( &
- + aggregationrate * DiaC &
- ) * recipbiostep
+ if (enable_3zoo2det) then
+ vertgrazmeso_tot(k) = vertgrazmeso_tot(k) + ( &
+ + GrazingFlux_DetZ2 * recipDet2 * grazEff & ! Detritus 2
+ + grazingFlux_miczoo * recipQZoo3 * grazEff & ! Microzooplankton
+ ) * recipbiostep
+ endif
-#if defined (__coccos)
-!*** aggregation by coccolithophores
- vertaggc(k) = vertaggc(k) + ( &
- + aggregationrate * CoccoC &
+ ! Prey-specific mortality (loss terms, no efficiency applied)
+ ! These track carbon removal from each prey population
+
+ ! Small phytoplankton mortality
+ vertgrazmeso_n(k) = vertgrazmeso_n(k) + ( &
+ + grazingFlux_phy * recipQuota &
) * recipbiostep
-#endif
-
-!*** excrection of DOC by phytoplankton
- vertdocexn(k) = vertdocexn(k) + ( &
- + lossC * limitFacN * phyC &
+
+ ! Diatom mortality
+ vertgrazmeso_d(k) = vertgrazmeso_d(k) + ( &
+ + grazingFlux_dia * recipQuota_dia &
) * recipbiostep
-!*** excrection of DOC by diatoms
- vertdocexd(k) = vertdocexd(k) + ( &
- + lossC_d * limitFacN_dia * DiaC &
- ) * recipbiostep
-
-#if defined (__coccos)
-!*** excretion of DOC by coccolithophores
- vertdocexc(k) = vertdocexc(k) + ( &
- + lossC_c * limitFacN_cocco * CoccoC &
- ) * recipbiostep
-#endif
+ if (enable_coccos) then
+ ! Coccolithophore mortality
+ vertgrazmeso_c(k) = vertgrazmeso_c(k) + ( &
+ + grazingFlux_Cocco * recipQuota_cocco &
+ ) * recipbiostep
-!*** calcification
- vertcalcif(k) = vertcalcif(k) + ( &
- + calcification &
- ) * recipbiostep
+ ! Phaeocystis mortality
+ vertgrazmeso_p(k) = vertgrazmeso_p(k) + ( &
+ + grazingFlux_Phaeo * recipQuota_Phaeo &
+ ) * recipbiostep
+ endif
-! phy respiration
- vertrespn(k) = vertrespn(k) + ( &
- + PhyRespRate * PhyC &
+ ! Detritus 1 consumption
+ vertgrazmeso_det(k) = vertgrazmeso_det(k) + ( &
+ + grazingFlux_Det * recipDet &
) * recipbiostep
+
+ if (enable_3zoo2det) then
+ ! Microzooplankton mortality (intraguild predation)
+ vertgrazmeso_mic(k) = vertgrazmeso_mic(k) + ( &
+ + grazingFlux_miczoo * recipQZoo3 &
+ ) * recipbiostep
+
+ ! Detritus 2 consumption
+ vertgrazmeso_det2(k) = vertgrazmeso_det2(k) + ( &
+ + GrazingFlux_DetZ2 * recipDet2 &
+ ) * recipbiostep
+ endif
-! dia respiration
- vertrespd(k) = vertrespd(k) + ( &
- + PhyRespRate_dia * DiaC &
- ) * recipbiostep
-
-#if defined (__coccos)
-! cocco resipration
- vertrespc(k) = vertrespc(k) + ( &
- + PhyRespRate_cocco * CoccoC &
- ) * recipbiostep
-#endif
-endif
- end do ! Main vertikal loop ends
-!-------------------------------------------------------------------------------
-! Remineralization from the sediments into the bottom layer
-!*** DIN ***
-!< decayRateBenN: Remineralization rate for benthic N [day^-1]
-!< LocBenthos(1): Vertically integrated N concentration in benthos (1 layer) [mmolN/m^2]
- decayBenthos(1) = decayRateBenN * LocBenthos(1)
- LocBenthos(1) = LocBenthos(1) - decaybenthos(1) * dt_b ! remove from benthos (flux)
+!===========================================================================
+! MACROZOOPLANKTON GRAZING (KRILL)
+!===========================================================================
+! Tracks grazing by macrozooplankton (2-20 mm), often dominated by krill
+! Top mesozooplankton predator with omnivorous feeding strategy
+!
+! Variables:
+! vertgrazmacro_tot(k) : Total assimilated grazing [mmolC m-3 day-1]
+! vertgrazmacro_n(k) : Grazing on small phytoplankton [mmolC m-3 day-1]
+! vertgrazmacro_d(k) : Grazing on diatoms [mmolC m-3 day-1]
+! vertgrazmacro_c(k) : Grazing on coccolithophores [mmolC m-3 day-1]
+! vertgrazmacro_p(k) : Grazing on Phaeocystis [mmolC m-3 day-1]
+! vertgrazmacro_mes(k) : Grazing on mesozooplankton [mmolC m-3 day-1]
+! vertgrazmacro_mic(k) : Grazing on microzooplankton [mmolC m-3 day-1]
+! vertgrazmacro_det(k) : Grazing on detritus 1 [mmolC m-3 day-1]
+! vertgrazmacro_det2(k) : Grazing on detritus 2 [mmolC m-3 day-1]
+!
+! Prey Composition:
+! PHY : Small phytoplankton - supplementary prey
+! DIA : Diatoms - preferred prey in productive waters
+! COCCO : Coccolithophores (optional)
+! PHAEO : Phaeocystis colonies (optional)
+! HET : Mesozooplankton - carnivory/cannibalism
+! MICZOO : Microzooplankton - smaller zooplankton
+! DET : Detritus 1 - opportunistic feeding
+! DET2 : Detritus 2 - larger particles
+!
+! Ecological Significance:
+! - Grazing efficiency (grazEff2): typically 30-60%
+! - Major prey for fish, seabirds, marine mammals
+! - Produces large, fast-sinking fecal pellets
+! - Vertical migration enhances carbon export
+! - Key species: Antarctic krill (Euphausia superba)
+!
+! Validation:
+! - Net tows & acoustic surveys for biomass
+! - Feeding experiments with size-fractionated prey
+! - Typical rates: 0.1-50 mmolC m-3 day-1
+! - Individual ingestion: 10-100% body C day-1
+!---------------------------------------------------------------------------
+
+ if (enable_3zoo2det) then
+
+ ! Total assimilated grazing (with efficiency applied)
+ vertgrazmacro_tot(k) = vertgrazmacro_tot(k) + ( &
+ + grazingFlux_phy2 * recipQuota * grazEff2 & ! Small phytoplankton
+ + grazingFlux_Dia2 * recipQuota_Dia * grazEff2 & ! Diatoms
+ + grazingFlux_het2 * recipQZoo * grazEff2 & ! Mesozooplankton
+ + grazingFlux_miczoo2 * recipQZoo3 * grazEff2 & ! Microzooplankton
+ + grazingFlux_Det2 * recipDet * grazEff2 & ! Detritus 1
+ + grazingFlux_DetZ22 * recipDet2 * grazEff2 & ! Detritus 2
+ ) * recipbiostep
+
+ if (enable_coccos) then
+ vertgrazmacro_tot(k) = vertgrazmacro_tot(k) + ( &
+ + grazingFlux_Cocco2 * recipQuota_Cocco * grazEff2 & ! Coccolithophores
+ + grazingFlux_Phaeo2 * recipQuota_Phaeo * grazEff2 & ! Phaeocystis
+ ) * recipbiostep
+ endif
-!*** DIC ***
-!< decayRateBenC: Remineralization rate for benthic C [day^-1]
-!< LocBenthos(2): Vertically integrated C concentration in benthos (1 layer) [mmolC/m^2]
- decayBenthos(2) = decayRateBenC * LocBenthos(2)
- LocBenthos(2) = LocBenthos(2) - decaybenthos(2) * dt_b
+ ! Prey-specific mortality (loss terms, no efficiency applied)
+ ! These track carbon removal from each prey population
+
+ ! Small phytoplankton mortality
+ vertgrazmacro_n(k) = vertgrazmacro_n(k) + ( &
+ + grazingFlux_phy2 * recipQuota &
+ ) * recipbiostep
+
+ ! Diatom mortality
+ vertgrazmacro_d(k) = vertgrazmacro_d(k) + ( &
+ + grazingFlux_Dia2 * recipQuota_Dia &
+ ) * recipbiostep
+
+ if (enable_coccos) then
+ ! Coccolithophore mortality
+ vertgrazmacro_c(k) = vertgrazmacro_c(k) + ( &
+ + grazingFlux_Cocco2 * recipQuota_cocco &
+ ) * recipbiostep
+
+ ! Phaeocystis mortality
+ vertgrazmacro_p(k) = vertgrazmacro_p(k) + ( &
+ + grazingFlux_Phaeo2 * recipQuota_Phaeo &
+ ) * recipbiostep
+ endif
+
+ ! Mesozooplankton mortality (carnivory)
+ vertgrazmacro_mes(k) = vertgrazmacro_mes(k) + ( &
+ + grazingFlux_het2 * recipQZoo &
+ ) * recipbiostep
+
+ ! Detritus 1 consumption
+ vertgrazmacro_det(k) = vertgrazmacro_det(k) + ( &
+ + grazingFlux_Det2 * recipDet &
+ ) * recipbiostep
+
+ ! Microzooplankton mortality
+ vertgrazmacro_mic(k) = vertgrazmacro_mic(k) + ( &
+ + grazingFlux_miczoo2 * recipQZoo3 &
+ ) * recipbiostep
+
+ ! Detritus 2 consumption
+ vertgrazmacro_det2(k) = vertgrazmacro_det2(k) + ( &
+ + GrazingFlux_DetZ22 * recipDet2 &
+ ) * recipbiostep
+
+ endif
-!*** Si ***
-!< decayRateBenSi: Remineralization rate for benthic Si [day^-1]
-!< LocBenthos(3) : Vertically integrated N concentration in benthos (1 layer) [mmolSi/m^2]
- decayBenthos(3) = decayRateBenSi * LocBenthos(3) ! [1/day] * [mmolSi/m2] -> [mmolSi/m2/day]
- LocBenthos(3) = LocBenthos(3) - decaybenthos(3) * dt_b
+!===========================================================================
+! MICROZOOPLANKTON GRAZING
+!===========================================================================
+! Tracks grazing by microzooplankton (20-200 μm), mainly ciliates/dinoflagellates
+! Critical link between picoplankton and mesozooplankton
+!
+! Variables:
+! vertgrazmicro_tot(k) : Total assimilated grazing [mmolC m-3 day-1]
+! vertgrazmicro_n(k) : Grazing on nanophytoplankton [mmolC m-3 day-1]
+! vertgrazmicro_d(k) : Grazing on diatoms [mmolC m-3 day-1]
+! vertgrazmicro_c(k) : Grazing on coccolithophores [mmolC m-3 day-1]
+! vertgrazmicro_p(k) : Grazing on Phaeocystis [mmolC m-3 day-1]
+!
+! Prey Composition:
+! PHY : Snall phytoplankton (2-20 μm) - primary prey
+! DIA : Small diatoms - when available
+! COCCO : Coccolithophores - calcifying prey (optional)
+! PHAEO : Phaeocystis colonies/single cells (optional)
+!
+! Ecological Significance:
+! - Grazing efficiency (grazEff3): typically 40-70%
+! - Consumes 60-100% of primary production in oligotrophic waters
+! - High growth rates (1-2 doublings day-1 at 20°C)
+! - Size-selective feeding (optimal prey 10-50% predator size)
+! - Regenerates nutrients in upper water column
+!
+! Validation:
+! - Dilution experiments (most common method)
+! - Epifluorescence microscopy for biomass
+! - Typical rates: 0.01-5 mmolC m-3 day-1
+! - Clearance rates: 10-10,000 nL ind-1 hour-1
+!---------------------------------------------------------------------------
+
+ if (enable_3zoo2det) then
+
+ ! Total assimilated grazing (with efficiency applied)
+ vertgrazmicro_tot(k) = vertgrazmicro_tot(k) + ( &
+ + grazingFlux_phy3 * recipQuota * grazEff3 & ! Small phytoplankton
+ + grazingFlux_Dia3 * recipQuota_Dia * grazEff3 & ! Diatoms
+ ) * recipbiostep
+
+ if (enable_coccos) then
+ vertgrazmicro_tot(k) = vertgrazmicro_tot(k) + ( &
+ + grazingFlux_Cocco3 * recipQuota_Cocco * grazEff3 & ! Coccolithophores
+ + grazingFlux_Phaeo3 * recipQuota_Phaeo * grazEff3 & ! Phaeocystis
+ ) * recipbiostep
+ endif
+
+ ! Prey-specific mortality (loss terms, no efficiency applied)
+ ! These track carbon removal from each prey population
+
+ ! Small phytoplankton mortality
+ vertgrazmicro_n(k) = vertgrazmicro_n(k) + ( &
+ + grazingFlux_phy3 * recipQuota &
+ ) * recipbiostep
+
+ ! Diatom mortality
+ vertgrazmicro_d(k) = vertgrazmicro_d(k) + ( &
+ + grazingFlux_Dia3 * recipQuota_Dia &
+ ) * recipbiostep
+
+ if (enable_coccos) then
+ ! Coccolithophore mortality
+ vertgrazmicro_c(k) = vertgrazmicro_c(k) + ( &
+ + grazingFlux_Cocco3 * recipQuota_cocco &
+ ) * recipbiostep
+
+ ! Phaeocystis mortality
+ vertgrazmicro_p(k) = vertgrazmicro_p(k) + ( &
+ + grazingFlux_Phaeo3 * recipQuota_Phaeo &
+ ) * recipbiostep
+ endif
+
+ endif
+
+ end if ! Grazing_detritus
+
+!===========================================================================
+! DISSOLUTION AND REMINERALIZATION ! R2OMIP
+!===========================================================================
+
+ vertDISSOC(k) = vertDISSOC(k) + ( &
+ + reminC * arrFunc * O2Func * DetC & ! Slow-sinking detritus dissolution
+ + reminC * arrFunc * O2Func * DetZ2C * is_3zoo2det & ! Fast-sinking detritus dissolution
+ ) * recipbiostep
+
+ vertDISSON(k) = vertDISSON(k) + ( &
+ + reminN * arrFunc * O2Func * DetN & ! Slow-sinking detritus dissolution
+ + reminN * arrFunc * O2Func * DetZ2N * is_3zoo2det & ! Fast-sinking detritus dissolution
+ ) * recipbiostep
+
+ vertDISSOSi(k) = vertDISSOSi(k) + ( &
+ + reminSiT * DetSi & ! Slow-sinking detritus dissolution
+ ) * recipbiostep
+
+ vertREMOC(k) = vertREMOC(k) + ( &
+ + rho_c1 * arrFunc * O2Func * EOC & ! Bacterial respiration / remineralization of oceanic DOC
+! + rho_C1t * DOCt & ! Bacterial respiration / remineralization of terrestriel DOC
+ ) * recipbiostep
+
+! vertREMOCt(k) = vertREMOCt(k) + ( &
+! + rho_C1t * DOCt & ! Bacterial respiration / remineralization of terrestriel DOC
+! ) * recipbiostep
+
+ vertREMON(k) = vertREMON(k) + ( &
+ + rho_N * arrFunc * O2Func * DON & ! Bacterial respiration / remineralization
+ ) * recipbiostep
+
+ !===========================================================================
+ ! ZOOPLANKTON RESPIRATION
+ !===========================================================================
+ ! Tracks heterotrophic respiration (metabolic CO2 release)
+ ! Key component of carbon cycling and food web energetics
+ !
+ ! Variables:
+ ! vertrespmeso(k) : Mesozooplankton respiration [mmolC m-3 day-1]
+ ! HetRespFlux : Meso respiration flux [mmolC m-3 day-1]
+ !
+ ! Ecological Significance:
+ ! - Represents metabolic carbon loss
+ ! - Typically 20-40% of ingested carbon
+ ! - Temperature-dependent (Q10 ≈ 2-3)
+ ! - Increases with activity level
+ !
+ ! Validation:
+ ! - Incubation experiments (O2 consumption)
+ ! - ETS (electron transport system) measurements
+ ! - Typical range: 0.01-1 mmolC m-3 day-1
+ !---------------------------------------------------------------------------
+
+ ! Mesozooplankton respiration
+ vertrespmeso(k) = vertrespmeso(k) + ( &
+ + HetRespFlux & ! Carbon respiration flux
+ ) * recipbiostep
+
+ if (enable_3zoo2det) then
+ ! Macrozooplankton (krill) respiration
+ vertrespmacro(k) = vertrespmacro(k) + ( &
+ + Zoo2RespFlux &
+ ) * recipbiostep
+
+ ! Microzooplankton respiration
+ vertrespmicro(k) = vertrespmicro(k) + ( &
+ + MicZooRespFlux &
+ ) * recipbiostep
+ endif
+
+ !===========================================================================
+ ! CALCITE DISSOLUTION
+ !===========================================================================
+ ! Tracks calcium carbonate dissolution in water column
+ ! Critical for carbonate counter-pump and alkalinity cycling
+ !
+ ! Variables:
+ ! vertcalcdiss(k) : Calcite dissolution rate [mmolC m-3 day-1]
+ ! calc_diss : Dissolution rate coefficient [day-1]
+ ! DetCalc : Detrital calcite concentration [mmolC m-3]
+ !
+ ! Process:
+ ! CaCO3 -> Ca²⁺ + CO3²⁻
+ ! Releases DIC (+1) and alkalinity (+2)
+ !
+ ! Controls:
+ ! - Saturation state (Ω < 1 favors dissolution)
+ ! - Temperature (higher T -> faster kinetics)
+ ! - Pressure (higher P -> lower Ω)
+ !
+ ! Depth Pattern:
+ ! - Surface: Minimal (supersaturated, Ω > 1)
+ ! - Intermediate: Moderate (Ω ≈ 1)
+ ! - Deep: High (undersaturated, Ω < 1)
+ !
+ ! Applications:
+ ! - Ocean acidification impacts
+ ! - Carbon export efficiency
+ ! - Sediment CaCO3 preservation
+ !---------------------------------------------------------------------------
+
+ vertcalcdiss(k) = vertcalcdiss(k) + ( &
+ + calc_diss * DetCalc & ! Dissolution flux
+ ) * recipbiostep
+
+ !*** meso-zooplankton dissolution !RP 14.07.2025
+ vertmesocdis(k) = vertmesocdis(k) + ( &
+ + calc_loss_gra * calc_diss_guts &
+ ) * recipbiostep
+
+ if (enable_3zoo2det) then
+ !*** micro-zooplankton dissolution !RP 14.07.2025
+ vertmicrocdis(k) = vertmicrocdis(k) + ( &
+ + calc_loss_gra2 * calc_diss_guts &
+ ) * recipbiostep
+
+ !*** macro-zooplankton dissolution !RP 14.07.2025
+ vertmacrocdis(k) = vertmacrocdis(k) + ( &
+ + calc_loss_gra3 * calc_diss_guts &
+ ) * recipbiostep
+
+ !*** calc_diss by fast-sinking detritus !RP 14.07.2025
+ vertfastcdis(k) = vertfastcdis(k) + ( &
+ + calc_diss2 * DetZ2Calc &
+ ) * recipbiostep
+
+ endif
+ !===========================================================================
+ ! PARTICLE AGGREGATION
+ !===========================================================================
+ ! Tracks formation of large particles through aggregation
+ ! Key process for biological pump and carbon export
+ !
+ ! Variables:
+ ! vertaggn(k) : Small phyto aggregation [mmolC m-3 day-1]
+ ! aggregationrate : Aggregation rate coefficient [day-1]
+ ! PhyC : Small phytoplankton carbon [mmolC m-3]
+ !
+ ! Aggregation Mechanisms:
+ ! - Brownian motion (small particles)
+ ! - Differential settling (size-dependent)
+ ! - Shear aggregation (turbulence)
+ ! - Mucus/TEP gluing (especially diatoms)
+ !
+ ! Enhancement Factors:
+ ! - High phytoplankton concentration
+ ! - Nutrient limitation (mucus production)
+ ! - Turbulence (increased collision rate)
+ ! - Sticky exudates (TEP, polysaccharides)
+ !
+ ! Ecological Significance:
+ ! - Increases sinking velocity (export)
+ ! - Forms marine snow
+ ! - Provides food for deep-sea organisms
+ ! - Removes surface biomass
+ !
+ ! Typical Rates:
+ ! - Low aggregation: <0.01 day-1
+ ! - Moderate: 0.01-0.1 day-1
+ ! - High (bloom collapse): >0.1 day-1
+ !---------------------------------------------------------------------------
+
+ ! Small phytoplankton aggregation
+ vertaggn(k) = vertaggn(k) + ( &
+ + aggregationrate * PhyC & ! Aggregate formation
+ ) * recipbiostep
+
+ ! Diatom aggregation
+ vertaggd(k) = vertaggd(k) + ( &
+ + aggregationrate * DiaC &
+ ) * recipbiostep
+
+ if (enable_coccos) then
+ ! Coccolithophore aggregation
+ vertaggc(k) = vertaggc(k) + ( &
+ + aggregationrate * CoccoC &
+ ) * recipbiostep
+
+ ! Phaeocystis aggregation
+ vertaggp(k) = vertaggp(k) + ( &
+ + aggregationrate * PhaeoC &
+ ) * recipbiostep
+ endif
+
+ !===========================================================================
+ ! N ASSIMILATION and REMINERALIZATION
+ !===========================================================================
+
+ !*** N assim by small phytoplankton !RP 15.07.2025
+ vertNassimn(k) = vertNassimn(k) + ( &
+ + N_assim * PhyC &
+ ) * recipbiostep
+
+ !*** N assim by diatoms !RP 15.07.2025
+ vertNassimd(k) = vertNassimd(k) + ( &
+ + N_assim_Dia * DiaC &
+ ) * recipbiostep
+
+ if (enable_coccos) then
+ !*** N assim by coccolithophores !RP 15.07.2025
+ vertNassimc(k) = vertNassimc(k) + ( &
+ + N_assim_Cocco * CoccoC &
+ ) * recipbiostep
+
+ !*** N assim by phaeocystis !OG 08.01.2026
+ vertNassimp(k) = vertNassimp(k) + ( &
+ + N_assim_Phaeo * PhaeoC &
+ ) * recipbiostep
+ endif
+
+ !*** DON remineralization !RP 15.07.2025
+ vertDONremin(k) = vertDONremin(k) + ( &
+ + rho_N * arrFunc * O2Func * DON &
+ ) * recipbiostep
+
+ !*** DOC remineralization !RP 15.07.2025
+ vertDOCremin(k) = vertDOCremin(k) + ( &
+ + rho_C1 * arrFunc * O2Func * EOC &
+ ) * recipbiostep
+
+ !===========================================================================
+ ! DOC EXCRETION
+ !===========================================================================
+ ! Tracks dissolved organic carbon release by phytoplankton
+ ! Important for microbial loop and carbon cycling
+ !
+ ! Variables:
+ ! vertdocexn(k) : Small phyto DOC excretion [mmolC m-3 day-1]
+ ! lossC : Carbon exudation rate constant [day-1]
+ ! limitFacN : Nutrient limitation factor [0-1]
+ ! phyC : Small phytoplankton carbon [mmolC m-3]
+ !
+ ! Exudation Mechanisms:
+ ! - Passive leakage (diffusion across membranes)
+ ! - Overflow metabolism (excess photosynthate)
+ ! - Stress response (nutrient limitation)
+ ! - Viral lysis (cell breakage)
+ !
+ ! Nutrient Stress Effect:
+ ! - High limitFacN (replete): Low exudation
+ ! - Low limitFacN (limited): High exudation
+ ! - C:N imbalance drives carbon overflow
+ !
+ ! DOC Fate:
+ ! - Labile fraction: Rapid bacterial uptake (hours-days)
+ ! - Semi-labile: Slower degradation (weeks-months)
+ ! - Refractory: Accumulates (years-millennia)
+ !
+ ! Ecological Role:
+ ! - Fuels microbial loop
+ ! - Carbon loss without grazing
+ ! - Nutrient regeneration (after remineralization)
+ !
+ ! Typical Rates:
+ ! - Percent of GPP: 5-30%
+ ! - Higher under nutrient stress
+ ! - Lower for healthy, growing cells
+ !---------------------------------------------------------------------------
+
+ ! Small phytoplankton DOC excretion
+ vertdocexn(k) = vertdocexn(k) + ( &
+ + lossC * limitFacN * phyC & ! Stress-induced exudation
+ ) * recipbiostep
+
+ ! Diatom DOC excretion
+ vertdocexd(k) = vertdocexd(k) + ( &
+ + lossC_d * limitFacN_dia * DiaC &
+ ) * recipbiostep
+
+ if (enable_coccos) then
+ ! Coccolithophore DOC excretion
+ vertdocexc(k) = vertdocexc(k) + ( &
+ + lossC_c * limitFacN_cocco * CoccoC &
+ ) * recipbiostep
+
+ ! Phaeocystis DOC excretion
+ vertdocexp(k) = vertdocexp(k) + ( &
+ + lossC_p * limitFacN_phaeo * PhaeoC &
+ ) * recipbiostep
+ endif
+
+ !===========================================================================
+ ! CALCIFICATION
+ !===========================================================================
+ ! Tracks calcium carbonate precipitation by phytoplankton
+ ! Key process for carbonate counter-pump
+ !
+ ! Variables:
+ ! vertcalcif(k) : Calcification rate [mmolC m-3 day-1]
+ ! calcification : CaCO3 precipitation flux [mmolC m-3 day-1]
+ !
+ ! Process:
+ ! Ca²⁺ + 2HCO3⁻ -> CaCO3 + CO2 + H2O
+ ! Consumes DIC (-1) and alkalinity (-2)
+ ! Releases CO2 (carbonate counter-pump)
+ !
+ ! Organisms:
+ ! - Coccolithophores (calcite plates)
+ ! - Foraminifera (calcite shells)
+ ! - Pteropods (aragonite shells - not in this model)
+ !
+ ! Environmental Controls:
+ ! - Temperature (warmer favors calcification)
+ ! - Carbonate saturation (Ω > 1 required)
+ ! - pH/CO2 (ocean acidification reduces rate)
+ ! - Nutrient availability (affects PIC:POC ratio)
+ !
+ ! Ecological Significance:
+ ! - Ballast for sinking (increases export)
+ ! - Protection from grazers
+ ! - CO2 source (opposite to photosynthesis)
+ ! - Sensitive to ocean acidification
+ !
+ ! Typical Rates:
+ ! - Surface (bloom): 0.1-2 mmolC m-3 day-1
+ ! - Background: 0.001-0.05 mmolC m-3 day-1
+ !---------------------------------------------------------------------------
+
+ vertcalcif(k) = vertcalcif(k) + ( &
+ + calcification & ! CaCO3 precipitation
+ ) * recipbiostep
+
+ !===========================================================================
+ ! PHYTOPLANKTON PHOTOSYNTHESIS
+ !===========================================================================
+
+ ! phy photosynthesis !RP 14.07.2025
+ vertphotn(k) = vertphotn(k) + ( &
+ + Cphot * PhyC &
+ ) * recipbiostep
+
+ ! dia photosynthesis !RP 14.07.2025
+ vertphotd(k) = vertphotd(k) + ( &
+ + Cphot_Dia * DiaC &
+ ) * recipbiostep
+
+ if (enable_coccos) then
+ ! cocco photosynthesis !RP 14.07.2025
+ vertphotc(k) = vertphotc(k) + ( &
+ + Cphot_Cocco * CoccoC &
+ ) * recipbiostep
+
+ ! phaeocystis photosynthesis !OG 08.01.2026
+ vertphotp(k) = vertphotp(k) + ( &
+ + Cphot_Phaeo * PhaeoC &
+ ) * recipbiostep
+
+ endif
+ !===========================================================================
+ ! PHYTOPLANKTON RESPIRATION
+ !===========================================================================
+ ! Tracks autotrophic respiration (maintenance costs)
+ ! Component of community respiration, complement to GPP
+ !
+ ! Variables:
+ ! vertrespn(k) : Small phyto respiration [mmolC m-3 day-1]
+ ! PhyRespRate : Respiration rate coefficient [day-1]
+ ! PhyC : Small phytoplankton carbon [mmolC m-3]
+ !
+ ! Respiration Components:
+ ! - Basal metabolism: Maintenance of cellular machinery
+ ! - Biosynthesis: Costs of growth (protein synthesis, etc.)
+ ! - Active transport: Nutrient uptake against gradients
+ ! - Photorespiration: Oxygenase activity of Rubisco
+ !
+ ! Temperature Dependence:
+ ! - Q10 ≈ 2-3 (doubles per 10degC increase)
+ ! - Often higher than photosynthesis Q10
+ ! - Creates temperature-dependent growth efficiency
+ !
+ ! Relationship to NPP:
+ ! GPP = NPP + Respiration
+ ! Growth efficiency = NPP/GPP = 1 - (Resp/GPP)
+ ! Typical: 0.6-0.8 (60-80% efficiency)
+ !
+ ! Ecological Patterns:
+ ! - Increases with biomass (proportional)
+ ! - Higher in warm waters (temperature effect)
+ ! - Lower in nutrient-replete conditions (efficient growth)
+ ! - Higher during stress (maintenance costs)
+ !---------------------------------------------------------------------------
+
+ ! Small phytoplankton respiration
+ vertrespn(k) = vertrespn(k) + ( &
+ + PhyRespRate * PhyC & ! Maintenance respiration
+ ) * recipbiostep
+
+ ! Diatom respiration
+ vertrespd(k) = vertrespd(k) + ( &
+ + PhyRespRate_dia * DiaC &
+ ) * recipbiostep
+
+ if (enable_coccos) then
+ ! Coccolithophore respiration
+ vertrespc(k) = vertrespc(k) + ( &
+ + PhyRespRate_cocco * CoccoC &
+ ) * recipbiostep
+
+ ! Phaeocystis respiration
+ vertrespp(k) = vertrespp(k) + ( &
+ + PhyRespRate_phaeo * PhaeoC &
+ ) * recipbiostep
+ endif
+
+ endif ! Diags
+
+ end do ! Main vertikal loop ends
+
+ !===============================================================================
+ ! BENTHIC REMINERALIZATION
+ !===============================================================================
+ ! Simulates nutrient return from sediments to the bottom water layer through
+ ! remineralization of organic matter and calcite dissolution.
+ !
+ ! This part calculates:
+ ! 1. Remineralization of benthic organic matter (N, C, Si)
+ ! 2. Dissolution of benthic calcite (CaCO3)
+ ! 3. Carbon isotope remineralization (13C, 14C - optional)
+ ! 4. Nutrient flux from sediments to bottom water
+ !
+ ! Key Features:
+ ! - Single benthic layer (vertically integrated)
+ ! - First-order decay kinetics for remineralization
+ ! - Separate rates for N, C, Si, and calcite
+ ! - Optional MEDUSA sediment flux forcing
+ ! - Isotope fractionation during remineralization
+ ! - Conservative tracer return to water column
+ !
+ ! Benthic Processes:
+ ! - Aerobic respiration: Organic matter -> DIN + DIC
+ ! - Silica dissolution: Biogenic SiO2 -> Si(OH)4
+ ! - Calcite dissolution: CaCO3 -> Ca²⁺ + CO3²⁻ (affects DIC + Alk)
+ ! - Denitrification: In anoxic sediments (not explicitly modeled)
+ !
+ ! Model Structure:
+ ! - Benthos as single well-mixed compartment
+ ! - Area-integrated concentrations [mmol m-2]
+ ! - Decay rates calibrated to observations
+ ! - Instant return to bottom water layer
+ !
+ ! Ecological/Biogeochemical Significance:
+ ! - Closes nutrient cycles (prevents accumulation in benthos)
+ ! - Critical for shallow shelf ecosystems
+ ! - Supports benthic-pelagic coupling
+ ! - Affects bottom water oxygen and pH
+ ! - Important for coastal carbon budgets
+ !
+ ! Limitations:
+ ! - No explicit burial (all material eventually remineralized)
+ ! - No bioturbation or bioirrigation
+ ! - No redox zonation in sediments
+ ! - Simplified single-layer representation
+ !
+ ! References:
+ ! - Schourup-Kristensen et al. (2013) - REcoM benthic module
+ ! - MEDUSA forcing for data-constrained sediment fluxes
+ !===============================================================================
+
+ !===============================================================================
+ ! REMINERALIZATION MODE SELECTION
+ !===============================================================================
+ ! Determines whether to use MEDUSA sediment flux forcing or internal
+ ! benthic remineralization calculations.
+ !
+ ! Variables:
+ ! use_MEDUSA : Flag to enable MEDUSA sediment forcing [logical]
+ ! sedflx_num : Number of MEDUSA sediment flux entries [-]
+ ! mype : Processor ID for parallel output [integer]
+ !
+ ! MEDUSA Mode:
+ ! - Uses observationally-constrained sediment fluxes
+ ! - Overrides internal benthic calculations
+ ! - Typically used for hindcast simulations
+ ! - Requires external data file
+ !
+ ! Internal Mode:
+ ! - Uses prognostic benthic compartment
+ ! - First-order decay kinetics
+ ! - Suitable for future projections
+ ! - No external data required
+ !-------------------------------------------------------------------------------
+
+ if (use_MEDUSA .and. (sedflx_num /= 0)) then
+
+ !===========================================================================
+ ! MEDUSA SEDIMENT FLUX FORCING MODE
+ !===========================================================================
+ ! Use externally prescribed sediment nutrient fluxes
+ ! This overrides all internal benthic calculations
+ !---------------------------------------------------------------------------
+
+ if (mype == 0) then
+ ! Print message only on master processor (parallel computing)
+ write(*, *) ' --> Sedimentary input of nutrients through MEDUSA'
+ endif
-!*** Calc: DIC, Alk *** ! OG calc_diss_ben is taken from the deepest level
- decayBenthos(4) = calc_diss_ben * LocBenthos(4) ! NEW DISS changed calc_diss to calc_diss_ben to not make the dissolution omega dependent when using the switch OmegaC_diss
- LocBenthos(4) = LocBenthos(4) - decayBenthos(4) * dt_b
+ ! Note: MEDUSA fluxes are applied elsewhere in the code
+ ! This section simply skips internal benthic calculations
- end do ! Main time loop ends
+ else
+ !===========================================================================
+ ! INTERNAL BENTHIC REMINERALIZATION (DEFAULT MODE)
+ !===========================================================================
+ ! Calculates nutrient return from benthic compartment using first-order
+ ! decay kinetics for each element.
+ !---------------------------------------------------------------------------
+
+ !===========================================================================
+ ! DISSOLVED INORGANIC NITROGEN (DIN) REMINERALIZATION
+ !===========================================================================
+ ! Aerobic remineralization of organic nitrogen in sediments releases
+ ! bioavailable nitrogen (NH4+ and NO3-) back to the water column.
+ ! Burial for R2OMIP
+ !
+ ! Variables:
+ ! decayBenthos(1) : N remineralization flux [mmolN m-2 day-1]
+ ! decayRateBenN : Benthic N remineralization rate [day-1]
+ ! LocBenthos(1) : Benthic N pool (area-integrated) [mmolN m-2]
+ ! dt_b : REcoM time step [day]
+ !
+ ! Equation:
+ ! Flux = decayRateBenN × LocBenthos(1)
+ ! LocBenthos(1)_new = LocBenthos(1)_old - Flux × dt_b
+ !
+ ! Process Representation:
+ ! Organic N (proteins, amino acids, etc.) -> NH4+ -> NO3-
+ ! First-order decay: rate proportional to benthic N pool
+ !
+ ! Typical Values:
+ ! decayRateBenN ~ 0.01-0.1 day-1 (10-100 day turnover)
+ ! Higher rates in warm, oxygenated sediments
+ !---------------------------------------------------------------------------
+
+ ! Calculate N remineralization flux [mmolN m-2 day-1]
+ decayBenthos(1) = decayRateBenN * LocBenthos(1)
+
+ ! Update benthic N pool (remove remineralized N)
+ LocBenthos(1) = LocBenthos(1) - decayBenthos(1) * dt_b - BurialBen(1) !R2OMIP (Burial) remove from benthos (flux)
+
+ !===========================================================================
+ ! DISSOLVED INORGANIC CARBON (DIC) REMINERALIZATION
+ !===========================================================================
+ ! Aerobic respiration of organic carbon releases CO2 to bottom water.
+ ! Affects carbonate system (pH, pCO2, saturation state).
+ ! Burial for R2OMIP
+ !
+ ! Variables:
+ ! decayBenthos(2) : C remineralization flux [mmolC m-2 day-1]
+ ! decayRateBenC : Benthic C remineralization rate [day-1]
+ ! LocBenthos(2) : Benthic C pool (area-integrated) [mmolC m-2]
+ !
+ ! Process Representation:
+ ! Organic C (carbohydrates, lipids, etc.) + O2 -> CO2 + H2O
+ ! Releases DIC and consumes O2 (not explicitly tracked)
+ !
+ ! Stoichiometry:
+ ! C:N remineralization ratio typically near Redfield (6.6:1)
+ ! Can vary with organic matter source and degradation state
+ !
+ ! Typical Values:
+ ! decayRateBenC ~ 0.01-0.1 day-1
+ ! May differ from N rate due to preferential degradation
+ !---------------------------------------------------------------------------
+
+ ! Calculate C remineralization flux [mmolC m-2 day-1]
+ decayBenthos(2) = decayRateBenC * LocBenthos(2)
+
+ ! Update benthic C pool
+ LocBenthos(2) = LocBenthos(2) - decayBenthos(2) * dt_b - BurialBen(2) !R2OMIP (Burial)
+
+ !===========================================================================
+ ! SILICATE (Si) DISSOLUTION
+ !===========================================================================
+ ! Dissolution of biogenic silica (diatom frustules) releases Si(OH)4.
+ ! Temperature-dependent process (faster in warm water).
+ ! Burial for R2OMIP
+ !
+ ! Variables:
+ ! decayBenthos(3) : Si dissolution flux [mmolSi m-2 day-1]
+ ! decayRateBenSi : Benthic Si dissolution rate [day-1]
+ ! LocBenthos(3) : Benthic Si pool (area-integrated) [mmolSi m-2]
+ !
+ ! Process Representation:
+ ! Biogenic SiO2 (opal) + H2O -> Si(OH)4 (silicic acid)
+ ! Thermodynamically driven dissolution (opal undersaturated in seawater)
+ !
+ ! Typical Values:
+ ! decayRateBenSi ~ 0.001-0.01 day-1 (100-1000 day turnover)
+ ! Slower than organic matter (opal is recalcitrant)
+ ! Temperature-dependent (see reminSiT calculation earlier)
+ !
+ ! Ecological Significance:
+ ! - Returns Si to support diatom production
+ ! - Critical in Si-limited regions
+ ! - Permanent burial in deep sediments affects long-term Si cycle
+ !---------------------------------------------------------------------------
+
+ ! Calculate Si dissolution flux [mmolSi m-2 day-1]
+ decayBenthos(3) = decayRateBenSi * LocBenthos(3)
+
+ ! Update benthic Si pool
+ LocBenthos(3) = LocBenthos(3) - decayBenthos(3) * dt_b - BurialBen(3) !R2OMIP (Burial)
+
+ !===========================================================================
+ ! CALCITE (CaCO3) DISSOLUTION
+ !===========================================================================
+ ! Dissolution of calcium carbonate affects both DIC and alkalinity.
+ ! Rate depends on saturation state (calculated in deepest water layer).
+ ! Burial for R2OMIP
+ !
+ ! Variables:
+ ! decayBenthos(4) : Calcite dissolution flux [mmolC m-2 day-1]
+ ! calc_diss_ben : Benthic calcite dissolution rate [day-1]
+ ! LocBenthos(4) : Benthic calcite pool [mmolC m-2]
+ !
+ ! Process Representation:
+ ! CaCO3 + CO2 + H2O ⇌ Ca²⁺ + 2HCO3-
+ ! Increases DIC (+1) and alkalinity (+2)
+ !
+ ! Rate Determination:
+ ! calc_diss_ben taken from deepest water layer
+ ! Uses either saturation-state or depth-dependent formulation
+ ! (see calcite dissolution module earlier in code)
+ !
+ ! Carbonate Chemistry Effect:
+ ! - Raises pH (consumes CO2)
+ ! - Increases carbonate saturation
+ ! - Buffers ocean acidification locally
+ !
+ ! Note: Changed from calc_diss to calc_diss_ben to allow independent
+ ! control when using OmegaC_diss switch
+ !---------------------------------------------------------------------------
+
+ ! Calculate calcite dissolution flux [mmolC m-2 day-1]
+ decayBenthos(4) = calc_diss_ben * LocBenthos(4)
+
+ ! Update benthic calcite pool
+ LocBenthos(4) = LocBenthos(4) - decayBenthos(4) * dt_b - BurialBen(4) !R2OMIP (Burial)
+
+ if (ciso) then
+
+ !=======================================================================
+ ! CARBON ISOTOPE REMINERALIZATION (OPTIONAL)
+ !=======================================================================
+ ! Tracks 13C and 14C through benthic remineralization processes.
+ ! Important for paleoclimate reconstructions and carbon cycle studies.
+ !-----------------------------------------------------------------------
+
+ !=======================================================================
+ ! Carbon-13 (13C) Remineralization
+ !=======================================================================
+ ! Organic matter remineralization with isotopic fractionation
+ !
+ ! Variables:
+ ! decayBenthos(5) : 13C remineralization flux [mmol13C m-2 day-1]
+ ! alpha_dcal_13 : 13C fractionation factor for remineralization [-]
+ ! LocBenthos(5) : Benthic 13C pool [mmol13C m-2]
+ !
+ ! Note: Assumes same decay rate as total carbon (decayRateBenC)
+ ! Fractionation factor typically near 1.0 (minimal fractionation)
+ !-----------------------------------------------------------------------
+
+ ! Calculate 13C remineralization flux
+ ! Ignores isotopic fractionation during remineralization (alpha ≈ 1)
+ decayBenthos(5) = alpha_dcal_13 * decayRateBenC * LocBenthos(5)
+
+ ! Update benthic 13C pool
+ LocBenthos(5) = LocBenthos(5) - decayBenthos(5) * dt_b
+
+ !=======================================================================
+ ! Carbon-13 Calcite Dissolution
+ !=======================================================================
+ ! Dissolution of 13C-containing calcite
+ !
+ ! Variables:
+ ! decayBenthos(6) : 13C calcite dissolution flux [mmol13C m-2 day-1]
+ ! calc_diss_13 : 13C calcite dissolution rate [day-1]
+ ! LocBenthos(6) : Benthic 13C-calcite pool [mmol13C m-2]
+ !-----------------------------------------------------------------------
+
+ ! Calculate 13C calcite dissolution flux
+ decayBenthos(6) = calc_diss_13 * LocBenthos(6)
+
+ ! Update benthic 13C-calcite pool
+ LocBenthos(6) = LocBenthos(6) - decayBenthos(6) * dt_b
+
+ if (ciso_14) then
+
+ if (ciso_organic_14) then
+
+ !===============================================================
+ ! Carbon-14 (14C) Remineralization
+ !===============================================================
+ ! Radiocarbon remineralization for age dating and residence times
+ !
+ ! Variables:
+ ! decayBenthos(7) : 14C remineralization flux [mmol14C m-2 day-1]
+ ! alpha_dcal_14 : 14C fractionation factor [-]
+ ! LocBenthos(7) : Benthic 14C pool [mmol14C m-2]
+ !
+ ! Note: 14C also subject to radioactive decay (half-life ~5730 years)
+ ! This is typically handled separately in full carbon cycle models
+ !---------------------------------------------------------------
+
+ ! Calculate 14C remineralization flux
+ ! Ignores isotopic fractionation during remineralization
+ decayBenthos(7) = alpha_dcal_14 * decayRateBenC * LocBenthos(7)
+
+ ! Update benthic 14C pool
+ LocBenthos(7) = LocBenthos(7) - decayBenthos(7) * dt_b
+
+ !===============================================================
+ ! 3.4 Carbon-14 Calcite Dissolution
+ !===============================================================
+ ! Dissolution of 14C-containing calcite
+ !
+ ! Variables:
+ ! decayBenthos(8) : 14C calcite dissolution flux [mmol14C m-2 day-1]
+ ! calc_diss_14 : 14C calcite dissolution rate [day-1]
+ ! LocBenthos(8) : Benthic 14C-calcite pool [mmol14C m-2]
+ !---------------------------------------------------------------
+
+ ! Calculate 14C calcite dissolution flux
+ decayBenthos(8) = calc_diss_14 * LocBenthos(8)
+
+ ! Update benthic 14C-calcite pool
+ LocBenthos(8) = LocBenthos(8) - decayBenthos(8) * dt_b
+
+ else
+ !---------------------------------------------------------------
+ ! Alternative 14C handling
+ !---------------------------------------------------------------
+ ! When ciso_organic_14 = FALSE:
+ ! 14C defined as proportional to total DIC elsewhere in code
+ ! No separate remineralization calculation needed
+ ! (sms(idic_14) = sms(idic) × isotope_ratio)
+ !---------------------------------------------------------------
+
+ end if ! ciso_organic_14
+
+ end if ! ciso_14
+
+ end if ! ciso
+
+ endif ! use_MEDUSA
+
+ end do ! Main time loop ends
end subroutine REcoM_sms
@@ -2190,7 +7563,7 @@ function recom_limiter(slope,qa,qb)
Real(kind=8) :: recom_limiter
Real(kind=8) :: slope, qa, qb
Real(kind=8) :: dq
-
+
dq = qa - qb
if (REcoM_Geider_limiter) then
recom_limiter = max(min( -slope*dq, 1.d0),0.d0)
@@ -2259,7 +7632,7 @@ function iron_chemistry(Fe, totalLigand, ligandStabConst)
b = ligandstabConst * (Fe - totalLigand) + 1.d0
c = -totalLigand
discrim = b*b - 4.d0 * a * c
-
+
if (a .ne. 0.d0 .and. discrim .ge. 0.d0) then
ligand = ( -b + sqrt(discrim) ) / (2.d0 * a)
FeL = totalLigand - ligand
diff --git a/src/io_meandata.F90 b/src/io_meandata.F90
index fba00c3d8..362d979fe 100644
--- a/src/io_meandata.F90
+++ b/src/io_meandata.F90
@@ -570,125 +570,1061 @@ subroutine ini_mean_io(ice, dynamics, tracers, partit, mesh)
! output RECOM 2D
#if defined(__recom)
+!===============================================================================
+! RECOM BIOGEOCHEMICAL MODEL - OUTPUT VARIABLE DEFINITIONS
+!===============================================================================
+! This module defines output streams for the REcoM (Regulated Ecosystem Model)
+! biogeochemical tracer variables. Variables are organized by functional groups.
+!===============================================================================
+
+! =====================================================================
+! CARBONATE CHEMISTRY & AIR-SEA GAS EXCHANGE
+! =====================================================================
+! These variables control and diagnose the exchange of CO2 and O2 between
+! the ocean and atmosphere, as well as ocean acidification processes.
+! =====================================================================
+
+CASE ('alphaCO2 ')
+ ! =====================================================================
+ ! Variable: alphaCO2
+ ! Description: CO2 solubility coefficient (Henry's Law constant)
+ ! Function: Determines how much CO2 dissolves in seawater at equilibrium
+ ! Dependencies: Temperature and salinity dependent
+ ! Units: mol/kg/atm
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'alphaCO2', 'CO2 solubility', 'mol/kg/atm', alphaCO2(:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('Kw ')
+ ! =====================================================================
+ ! Variable: Kw (also known as k660 or gas transfer velocity)
+ ! Description: Air-sea piston velocity for gas exchange
+ ! Function: Controls the rate of gas transfer across the air-sea interface
+ ! Dependencies: Wind speed, sea state, and gas-specific Schmidt number
+ ! Units: m/s
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'Kw', 'Air-sea piston velocity', 'm/s', PistonVelocity(:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
CASE ('dpCO2s ')
+ ! =====================================================================
+ ! Variable: dpCO2s (Delta pCO2)
+ ! Description: Air-sea pCO2 gradient (ocean minus atmosphere)
+ ! Function: Driving force for CO2 flux; positive = ocean supersaturated
+ ! Sign convention: Positive when ocean releases CO2 to atmosphere
+ ! Units: μatm (microatmospheres)
+ ! =====================================================================
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'dpCO2s', 'Difference of oceanic pCO2 minus atmospheric pCO2', 'uatm', GlodPCO2surf(:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, &
+ 'dpCO2s', 'Difference of oceanic pCO2 minus atmospheric pCO2', 'uatm', GlodPCO2surf(:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
CASE ('pCO2s ')
+ ! =====================================================================
+ ! Variable: pCO2s
+ ! Description: Oceanic partial pressure of CO2 at the surface
+ ! Function: Measures CO2 concentration in surface waters
+ ! Context: Atmospheric pCO2 ≈ 420 μatm (as of 2024)
+ ! Units: μatm (microatmospheres)
+ ! =====================================================================
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'pCO2s', 'Partial pressure of oceanic CO2', 'uatm', GloPCO2surf(:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, &
+ 'pCO2s', 'Partial pressure of oceanic CO2', 'uatm', GloPCO2surf(:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
CASE ('CO2f ')
+ ! =====================================================================
+ ! Variable: CO2f
+ ! Description: Net CO2 flux across the air-sea interface
+ ! Function: Quantifies ocean carbon uptake (or release)
+ ! Sign convention: Positive = flux into ocean (ocean is a CO2 sink)
+ ! Calculation: Flux = Kw × alphaCO2 × dpCO2s
+ ! Units: mmolC/m²/d (millimoles carbon per square meter per day)
+ ! =====================================================================
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'CO2f', 'CO2-flux into the surface water', 'mmolC/m2/d', GloCO2flux(:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, &
+ 'CO2f', 'CO2-flux into the surface water', 'mmolC/m2/d', GloCO2flux(:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
CASE ('O2f ')
+ ! =====================================================================
+ ! Variable: O2f
+ ! Description: Net O2 flux across the air-sea interface
+ ! Function: Balances photosynthetic O2 production and respiratory consumption
+ ! Sign convention: Positive = flux into ocean
+ ! Context: Opposite sign to CO2 flux in productive regions
+ ! Units: mmolO/m²/d (millimoles oxygen per square meter per day)
+ ! =====================================================================
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'O2f', 'O2-flux into the surface water', 'mmolO/m2/d', GloO2flux(:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, &
+ 'O2f', 'O2-flux into the surface water', 'mmolO/m2/d', GloO2flux(:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
CASE ('Hp ')
+ ! =====================================================================
+ ! Variable: Hp (H⁺ concentration)
+ ! Description: Hydrogen ion concentration in surface water
+ ! Function: Direct measure of ocean acidity (pH = -log₁₀[H⁺])
+ ! Context: pH ≈ 8.1 in modern ocean → [H⁺] ≈ 10⁻⁸·¹ mol/kg
+ ! Relevance: Ocean acidification monitoring
+ ! Units: mol/kg
+ ! =====================================================================
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'Hp', 'Mean of H-plus ions in the surface water', 'mol/kg', GloHplus(:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, &
+ 'Hp', 'Mean of H-plus ions in the surface water', 'mol/kg', GloHplus(:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
+! =====================================================================
+! ATMOSPHERIC DEPOSITION
+! =====================================================================
+! External nutrient inputs to the ocean surface from atmospheric sources
+! =====================================================================
+
CASE ('aFe ')
+ ! =====================================================================
+ ! Variable: aFe
+ ! Description: Atmospheric iron deposition flux
+ ! Function: Primary iron source for open ocean phytoplankton
+ ! Sources: Mineral dust (especially from deserts), combustion aerosols
+ ! Importance: Iron limits primary production in HNLC regions
+ ! Units: μmolFe/m²/s (micromoles iron per square meter per second)
+ ! =====================================================================
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'aFe','Atmospheric iron input','umolFe/m2/s', AtmFeInput(:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, &
+ 'aFe', 'Atmospheric iron input', 'umolFe/m2/s', AtmFeInput(:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
CASE ('aN ')
+ ! =====================================================================
+ ! Variable: aN
+ ! Description: Atmospheric dissolved inorganic nitrogen (DIN) deposition
+ ! Function: External nitrogen input to surface ocean
+ ! Sources: NOₓ from combustion, ammonia from agriculture, natural sources
+ ! Forms: Primarily nitrate (NO₃⁻) and ammonium (NH₄⁺)
+ ! Units: mmolN/m²/s (millimoles nitrogen per square meter per second)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'aN', 'Atmospheric DIN input', 'mmolN/m2/s', AtmNInput(:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('riverDIN ')
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, 'riverDIN','riverine DIN input','mmolN/m2/s', RiverDIN2D(:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('riverDIC ')
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, 'riverDIC','riverine DIC input','mmolC/m2/s', RiverDIC2D(:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('riverDOCsl ')
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, 'riverDOCsl','riverine semi-labile DOC input','mmolC/m2/s', RiverDOCsl2D(:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('riverDOCl ')
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, 'riverDOCl','riverine labile DOC input','mmolC/m2/s', RiverDOCl2D(:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('riverPOC ')
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, 'riverPOC','riverine POC input','mmolC/m2/s', RiverPOC2D(:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('riverDFe ')
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'aN','Atmospheric DIN input','mmolN/m2/s', AtmNInput(:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, 'riverDFe','riverine DFe input','mmolC/m2/s', RiverFe(:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
+
+! =====================================================================
+! BENTHIC (SEAFLOOR) POOLS
+! =====================================================================
+! Accumulation of particulate organic and inorganic material in sediments
+! These pools act as temporary storage before remineralization/burial
+! =====================================================================
+
CASE ('benN ')
+ ! =====================================================================
+ ! Variable: benN
+ ! Description: Benthic nitrogen pool
+ ! Function: Sedimentary organic nitrogen awaiting remineralization
+ ! Process: Sinking particles → benthos → remineralization → DIN
+ ! Role: Nutrient recycling in shallow waters; burial in deep ocean
+ ! Units: mmol (millimoles per grid cell)
+ ! =====================================================================
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'benN','Benthos Nitrogen','mmol', Benthos(:,1), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, &
+ 'benN', 'Benthos Nitrogen', 'mmol', Benthos(:,1), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
CASE ('benC ')
+ ! =====================================================================
+ ! Variable: benC
+ ! Description: Benthic carbon pool
+ ! Function: Sedimentary organic carbon storage
+ ! Process: POC sinking → benthic accumulation → remineralization/burial
+ ! Importance: Long-term carbon sequestration pathway
+ ! Units: mmol (millimoles per grid cell)
+ ! =====================================================================
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'benC','Benthos Carbon','mmol', Benthos(:,2), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, &
+ 'benC', 'Benthos Carbon', 'mmol', Benthos(:,2), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
CASE ('benSi ')
+ ! =====================================================================
+ ! Variable: benSi
+ ! Description: Benthic silicon pool (biogenic silica)
+ ! Function: Opal (SiO₂) from diatom frustules in sediments
+ ! Process: Diatom mortality → opal dissolution in water column/benthos
+ ! Fate: Slow dissolution returns Si to dissolved silicate pool
+ ! Units: mmol (millimoles per grid cell)
+ ! =====================================================================
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'benSi','Benthos silicon','mmol', Benthos(:,3), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, &
+ 'benSi', 'Benthos silicon', 'mmol', Benthos(:,3), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
CASE ('benCalc ')
+ ! =====================================================================
+ ! Variable: benCalc
+ ! Description: Benthic calcite pool (calcium carbonate)
+ ! Function: CaCO₃ from coccolithophore shells and other sources
+ ! Process: Calcifier mortality → CaCO₃ sinking → accumulation/dissolution
+ ! Importance: Carbonate chemistry buffering; geological carbon burial
+ ! Units: mmol (millimoles per grid cell)
+ ! =====================================================================
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'benCalc','Benthos calcite','mmol', Benthos(:,4), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, &
+ 'benCalc','Benthos calcite','mmol', Benthos(:,4), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
-CASE ('NPPn ')
+
+CASE ('denb ')
+ ! Variable: denb
+ ! Description: Benthic denitrification rate
+ ! Function: Conversion of nitrate to N₂ gas in anoxic sediments
+ ! Process: NO₃⁻ → NO₂⁻ → NO → N₂O → N₂ (anaerobic respiration pathway)
+ ! Role: Permanent nitrogen loss from ocean; regulates ocean N inventory
+ ! Units: mmol/m² (millimoles per square meter)
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'NPPn','Mean NPP nanophytoplankton','mmolC/m2/d', NPPn, io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, &
+ 'denb', 'Benthic denitrification rate', 'mmol/m2', DenitBen(:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
-CASE ('NPPd ')
+! =====================================================================
+! BURIAL FLUXES
+! =====================================================================
+CASE ('BurialN ')
+ ! Variable: BurialN
+ ! Description: Nitrogen burial rate
+ ! Function: Permanent removal of nitrogen from biogeochemical cycling
+ ! Process: Benthic N → deep sediments → geological timescale storage
+ ! Role: Long-term nitrogen sink; reduces ocean fixed-N inventory
+ ! Units: mmolN/m² (millimoles nitrogen per square meter)
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'NPPd','Mean NPP diatoms','mmolC/m2/d', NPPd, io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, &
+ 'BurialN', 'Benthic Burial rate of Nitrogen', 'mmolN/m2', Burial(1,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
-CASE ('GPPn ')
+CASE ('BurialC ')
+ ! Variable: BurialC
+ ! Description: Carbon burial rate
+ ! Function: Permanent sequestration of organic carbon in sediments
+ ! Process: Benthic C → deep sediments → long-term CO₂ drawdown
+ ! Role: Major carbon sink; climate regulation on geological timescales
+ ! Units: mmolC/m² (millimoles carbon per square meter)
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'GPPn','Mean GPP nanophytoplankton','mmolC/m2/d', GPPn, io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, &
+ 'BurialC', 'Benthic Burial rate of Carbon', 'mmolC/m2', Burial(2,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
-CASE ('GPPd ')
+CASE ('BurialSi ')
+ ! Variable: BurialSi
+ ! Description: Biogenic silica burial rate
+ ! Function: Permanent removal of opal from dissolution-precipitation cycle
+ ! Process: Benthic opal → deep sediments → geological storage
+ ! Role: Silicon sink; sedimentary opal record of diatom productivity
+ ! Units: mmolSi/m² (millimoles silicon per square meter)
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'GPPd','Mean GPP diatoms','mmolC/m2/d', GPPd, io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, &
+ 'BurialSi', 'Benthic Burial rate', 'mmolSi/m2', Burial(3,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
-CASE ('NNAn ')
+CASE ('BurialCalc ')
+ ! Variable: BurialCalc
+ ! Description: Calcite burial rate
+ ! Function: Permanent sequestration of CaCO₃ in sediments
+ ! Process: Benthic calcite → deep sediments → limestone formation
+ ! Role: Long-term alkalinity/DIC sink; carbonate compensation depth control
+ ! Units: mmolC/m² (millimoles carbon as CaCO₃ per square meter)
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'NNAn','Net N-assimilation nanophytoplankton','mmolN/m2/d', NNAn, io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, &
+ 'BurialCalc', 'Benthic Burial rate of Calcite', 'mmolC/m2', Burial(4,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
-CASE ('NNAd ')
+! =====================================================================
+! OCEAN → SEDIMENT FLUXES
+! =====================================================================
+CASE ('wFNb ')
+ ! Variable: wFNb
+ ! Description: Sinking particulate nitrogen flux to benthos
+ ! Function: Downward transport of organic nitrogen to seafloor
+ ! Process: Detritus/phytoplankton → sinking → benthic deposition
+ ! Role: Primary nitrogen input to sediments; fuels benthic remineralization
+ ! Units: mmolN/(m²·d) (millimoles nitrogen per square meter per day)
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'wFNb', 'Sinking flux into benthic N', 'mmolN/(m2*d)', Ocean_2_Sed_flux(:,1), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('wFCb ')
+ ! Variable: wFCb
+ ! Description: Sinking particulate organic carbon flux to benthos
+ ! Function: Downward transport of organic carbon to seafloor
+ ! Process: POC/phytoplankton → sinking → benthic deposition
+ ! Role: Primary carbon input to sediments; energy source for benthos
+ ! Units: mmolC/(m²·d) (millimoles carbon per square meter per day)
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'wFCb', 'Sinking flux into benthic C', 'mmolC/(m2*d)', Ocean_2_Sed_flux(:,2), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('wFSib ')
+ ! Variable: wFSib
+ ! Description: Sinking biogenic silica flux to benthos
+ ! Function: Downward transport of opal (diatom frustules) to seafloor
+ ! Process: Diatom detritus → sinking → benthic deposition
+ ! Role: Primary silicon input to sediments; creates opal-rich sediments
+ ! Units: mmolSi/(m²·d) (millimoles silicon per square meter per day)
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'wFSib', 'Sinking flux into benthic Si', 'mmolSi/(m2*d)', Ocean_2_Sed_flux(:,3), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('wFCalcb ')
+ ! Variable: wFCalcb
+ ! Description: Sinking calcite flux to benthos
+ ! Function: Downward transport of CaCO₃ (coccoliths, foraminifera) to seafloor
+ ! Process: Calcifying organisms → sinking → benthic deposition
+ ! Role: Primary carbonate input; lysocline/CCD depth control
+ ! Units: mmolC/(m²·d) (millimoles carbon as CaCO₃ per square meter per day)
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'wFCalcb', 'Sinking flux into benthic Carb', 'mmolC/(m2*d)', Ocean_2_Sed_flux(:,4), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+! =====================================================================
+! SEDIMENT → OCEAN FLUXES (REMINERALIZATION/DISSOLUTION)
+! =====================================================================
+CASE ('ReNb ')
+ ! Variable: ReNb
+ ! Description: Benthic nitrogen remineralization flux
+ ! Function: Release of dissolved inorganic nitrogen from sediments
+ ! Process: Benthic organic N → bacterial degradation → NH₄⁺/NO₃⁻ → ocean
+ ! Role: Nutrient regeneration; supports primary production in shallow waters
+ ! Units: mmolN/(m²·s) (millimoles nitrogen per square meter per second)
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'NNAd','Net N-assimilation diatoms','mmolN/m2/d', NNAd, io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, &
+ 'ReNb', 'benthic N release to the ocean (remineralization)', 'mmolN/(m2*s)', &
+ Sed_2_Ocean_Flux(:,1), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('ReCb ')
+ ! Variable: ReCb
+ ! Description: Benthic carbon remineralization + calcite dissolution flux
+ ! Function: Release of dissolved inorganic carbon from sediments
+ ! Process: Organic C → remineralization → DIC + CaCO₃ dissolution → ocean
+ ! Role: CO₂ source; carbonate system buffering; alkalinity regulation
+ ! Units: mmolC/(m²·s) (millimoles carbon per square meter per second)
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'ReCb', 'benthic C release to the ocean (remineralization + calcification)', &
+ 'mmolC/(m2*s)', Sed_2_Ocean_Flux(:,2), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('ReSib ')
+ ! Variable: ReSib
+ ! Description: Benthic silica dissolution flux
+ ! Function: Release of dissolved silicon from opal dissolution
+ ! Process: Benthic opal → porewater dissolution → Si(OH)₄ → ocean
+ ! Role: Silicon regeneration; supports diatom productivity
+ ! Units: mmolSi/(m²·s) (millimoles silicon per square meter per second)
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'ReSib', 'benthic Si release to the ocean (dissolution)', 'mmolSi/(m2*s)', &
+ Sed_2_Ocean_Flux(:,4), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('ReAlkb ')
+ ! Variable: ReAlkb
+ ! Description: Benthic alkalinity flux
+ ! Function: Release of alkalinity from organic matter and CaCO₃ processing
+ ! Process: Denitrification + sulfate reduction + CaCO₃ dissolution → Alk
+ ! Role: pH buffering; carbonate system regulation; CO₂ uptake capacity
+ ! Units: mmolC-eq/(m²·s) (millimole carbon-equivalents per square meter per second)
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'ReAlkb', 'benthic Alk release to the ocean', 'mmolC-eq/(m2*s)', &
+ Sed_2_Ocean_Flux(:,3), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('ReFeb ')
+ ! Variable: ReFeb
+ ! Description: Benthic iron flux
+ ! Function: Release of dissolved iron from reducing sediments
+ ! Process: Benthic Fe-oxides → anoxic reduction → Fe²⁺ → ocean
+ ! Role: Micronutrient supply; supports primary production in Fe-limited regions
+ ! Units: mmolFe/(m²·s) (millimoles iron per square meter per second)
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'ReFeb', 'benthic Fe release to the ocean', 'mmolFe/(m2*s)', &
+ Sed_2_Ocean_Flux(:,5), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('ReO2b ')
+ ! Variable: ReO2b
+ ! Description: Benthic oxygen consumption flux
+ ! Function: Oxygen demand from aerobic remineralization in sediments
+ ! Process: Organic matter + O₂ → CO₂ + nutrients (negative flux = consumption)
+ ! Role: Sediment oxygen demand; creates anoxic conditions; hypoxia indicator
+ ! Units: mmolO₂/(m²·s) (millimoles oxygen per square meter per second)
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'ReO2b', 'benthic O2 release to the ocean', 'mmolO2/(m2*s)', &
+ Sed_2_Ocean_Flux(:,6), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+! =====================================================================
+! PHYTOPLANKTON PRIMARY PRODUCTION
+! =====================================================================
+! Production and nutrient assimilation by different phytoplankton groups
+! NPP = Net Primary Production (photosynthesis - respiration)
+! GPP = Gross Primary Production (total photosynthesis)
+! NNA = Net Nitrogen Assimilation (nitrogen uptake - excretion)
+! ChlDeg = Chlorophyll degradation rate
+! =====================================================================
+
+! ---------------------------------------------------------------------
+! SMALL PHYTOPLANKTON
+! ---------------------------------------------------------------------
+! Small phytoplankton (typically < 20 μm; e.g., small flagellates)
+! Ecological role: Dominant in oligotrophic (nutrient-poor) regions
+! ---------------------------------------------------------------------
+
+CASE ('NPPn ')
+ ! =====================================================================
+ ! Variable: NPPn
+ ! Description: Net Primary Production of nanophytoplankton
+ ! Function: Carbon fixation minus autotrophic respiration
+ ! Integration: Vertically integrated over water column
+ ! Units: mmolC/m²/d (millimoles carbon per square meter per day)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'NPPn', 'Mean NPP nanophytoplankton', 'mmolC/m2/d', NPPn, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('GPPn ')
+ ! =====================================================================
+ ! Variable: GPPn
+ ! Description: Gross Primary Production of nanophytoplankton
+ ! Function: Total photosynthetic carbon fixation (before respiration)
+ ! Relationship: GPPn = NPPn + autotrophic respiration
+ ! Units: mmolC/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'GPPn', 'Mean GPP nanophytoplankton', 'mmolC/m2/d', GPPn, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('NNAn ')
+ ! =====================================================================
+ ! Variable: NNAn
+ ! Description: Net Nitrogen Assimilation by nanophytoplankton
+ ! Function: Nitrogen uptake (NO₃⁻, NH₄⁺) minus excretion
+ ! Stoichiometry: Related to NPPn via Redfield ratio (C:N ≈ 6.6:1)
+ ! Units: mmolN/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'NNAn', 'Net N-assimilation nanophytoplankton', 'mmolN/m2/d', NNAn, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
CASE ('Chldegn ')
+ ! =====================================================================
+ ! Variable: Chldegn
+ ! Description: Chlorophyll degradation rate for nanophytoplankton
+ ! Function: Loss rate of chlorophyll (photopigment bleaching)
+ ! Causes: Photo-oxidation, senescence, nutrient stress
+ ! Application: Chlorophyll evolution = synthesis - degradation
+ ! Units: 1/d (per day; first-order rate constant)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'ChlDegn', 'Chlorophyll degradation nanophytoplankton', '1/d', Chldegn, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+! ---------------------------------------------------------------------
+! DIATOMS
+! ---------------------------------------------------------------------
+! Silica-shelled phytoplankton (typically 20-200 μm)
+! Ecological role: Bloom formers in nutrient-rich upwelling regions
+! Requirement: Need silicate (Si(OH)₄) for frustule construction
+! ---------------------------------------------------------------------
+
+CASE ('NPPd ')
+ ! =====================================================================
+ ! Variable: NPPd
+ ! Description: Net Primary Production of diatoms
+ ! Function: Diatom carbon fixation minus respiration
+ ! Ecological context: Dominates spring blooms, coastal upwelling
+ ! Units: mmolC/m²/d
+ ! =====================================================================
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'ChlDegn','Chlorophyll degradation nanophytoplankton','1/d', Chldegn, io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, &
+ 'NPPd', 'Mean NPP diatoms', 'mmolC/m2/d', NPPd, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('GPPd ')
+ ! =====================================================================
+ ! Variable: GPPd
+ ! Description: Gross Primary Production of diatoms
+ ! Function: Total diatom photosynthesis
+ ! Importance: Major contributor to biological carbon pump
+ ! Units: mmolC/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'GPPd', 'Mean GPP diatoms', 'mmolC/m2/d', GPPd, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('NNAd ')
+ ! =====================================================================
+ ! Variable: NNAd
+ ! Description: Net Nitrogen Assimilation by diatoms
+ ! Function: Diatom nitrogen uptake
+ ! Preference: Often prefer NH₄⁺ but can use NO₃⁻
+ ! Units: mmolN/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'NNAd', 'Net N-assimilation diatoms', 'mmolN/m2/d', NNAd, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
CASE ('Chldegd ')
+ ! =====================================================================
+ ! Variable: Chldegd
+ ! Description: Chlorophyll degradation rate for diatoms
+ ! Function: Diatom chlorophyll loss rate
+ ! Context: Can be elevated during silicate stress
+ ! Units: 1/d
+ ! =====================================================================
if (use_REcoM) then
- call def_stream(nod2D, myDim_nod2D, 'ChlDegd','Chlorophyll degradation diatoms','1/d', Chldegd, io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream(nod2D, myDim_nod2D, &
+ 'ChlDegd', 'Chlorophyll degradation diatoms', '1/d', Chldegd, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
+
+
+! ---------------------------------------------------------------------
+! COCCOLITHOPHORES
+! ---------------------------------------------------------------------
+! Calcite-producing phytoplankton (e.g., Emiliania huxleyi)
+! Ecological role: CaCO₃ production affects alkalinity and air-sea CO₂
+! Distribution: Temperate and subtropical regions
+! ---------------------------------------------------------------------
+
CASE ('NPPc ')
+ ! =====================================================================
+ ! Variable: NPPc
+ ! Description: Net Primary Production of coccolithophores
+ ! Function: Coccolith carbon fixation
+ ! Special feature: Both organic C (photosynthesis) and inorganic C (CaCO₃)
+ ! Units: mmolC/(m²*d)
+ ! =====================================================================
if (use_REcoM) then
-! call def_stream(nod2D, myDim_nod2D, 'NPPc','Mean NPP coccolithophores','mmolC/(m2*d)', diags2D(:,9), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, mesh) ! NEW
- call def_stream(nod2D, myDim_nod2D, 'NPPc','Mean NPP coccolithophores','mmolC/(m2*d)', NPPc, io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh) ! NEW
+ call def_stream(nod2D, myDim_nod2D, &
+ 'NPPc', 'Mean NPP coccolithophores', 'mmolC/(m2*d)', NPPc, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
CASE ('GPPc ')
+ ! =====================================================================
+ ! Variable: GPPc
+ ! Description: Gross Primary Production of coccolithophores
+ ! Function: Total coccolith photosynthesis
+ ! Climate impact: Calcification increases surface pCO₂ (CO₂ source)
+ ! Units: mmolC/(m²*d)
+ ! =====================================================================
if (use_REcoM) then
-! call def_stream(nod2D, myDim_nod2D, 'GPPc','Mean GPP coccolithophores','mmolC/(m2*d)', diags2D(:,10), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, mesh) ! NEW
- call def_stream(nod2D, myDim_nod2D, 'GPPc','Mean GPP coccolithophores','mmolC/(m2*d)', GPPc, io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh) ! NEW
+ call def_stream(nod2D, myDim_nod2D, &
+ 'GPPc', 'Mean GPP coccolithophores','mmolC/(m2*d)', GPPc, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
CASE ('NNAc ')
+ ! =====================================================================
+ ! Variable: NNAc
+ ! Description: Net Nitrogen Assimilation by coccolithophores
+ ! Function: Coccolith nitrogen uptake
+ ! Competition: Less competitive for nutrients than diatoms
+ ! Units: mmolN/(m²*d)
+ ! =====================================================================
if (use_REcoM) then
-! call def_stream(nod2D, myDim_nod2D, 'NNAc','Net N-assimilation coccolithophores','mmolN/(m2*d)', diags2D(:,11), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, mesh) ! NEW
- call def_stream(nod2D, myDim_nod2D, 'NNAc','Net N-assimilation coccolithophores','mmolN/(m2*d)', NNAc, io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh) !NEW
+ call def_stream(nod2D, myDim_nod2D, &
+ 'NNAc', 'Net N-assimilation coccolithophores', 'mmolN/(m2*d)', NNAc, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
CASE ('Chldegc ')
+ ! =====================================================================
+ ! Variable: Chldegc
+ ! Description: Chlorophyll degradation rate for coccolithophores
+ ! Function: Coccolith chlorophyll loss
+ ! Units: 1/d
+ ! =====================================================================
if (use_REcoM) then
-! call def_stream(nod2D, myDim_nod2D, 'GNAc','Gross N-assimilation coccolithophores','mmolN/(m2*d)', diags2D(:,12), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, mesh) ! NEW
- call def_stream(nod2D, myDim_nod2D, 'ChlDegc','Chlorophyll degradation coccolithophores','1/d', Chldegc, io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh) ! NEW
+ call def_stream(nod2D, myDim_nod2D, &
+ 'ChlDegc', 'Chlorophyll degradation coccolithophores', '1/d', Chldegc, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
-#endif
+
+! ---------------------------------------------------------------------
+! PHAEOCYSTIS
+! ---------------------------------------------------------------------
+! Colony-forming phytoplankton (Phaeocystis spp.)
+! Ecological role: Forms massive blooms in polar/subpolar regions
+! Unique feature: Can exist as single cells or large mucilaginous colonies
+! ---------------------------------------------------------------------
+
+CASE ('NPPp ')
+ ! =====================================================================
+ ! Variable: NPPp
+ ! Description: Net Primary Production of Phaeocystis
+ ! Function: Phaeocystis carbon fixation
+ ! Regional importance: Dominant in Southern Ocean, North Sea blooms
+ ! Units: mmolC/(m²*d)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'NPPp', 'Mean NPP phaeocystis', 'mmolC/(m2*d)', NPPp, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('GPPp ')
+ ! =====================================================================
+ ! Variable: GPPp
+ ! Description: Gross Primary Production of Phaeocystis
+ ! Function: Total Phaeocystis photosynthesis
+ ! Biogeochemical role: Colonial form less grazed; affects food web
+ ! Units: mmolC/(m²*d)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'GPPp', 'Mean GPP phaeocystis', 'mmolC/(m2*d)', GPPp, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('NNAp ')
+ ! =====================================================================
+ ! Variable: NNAp
+ ! Description: Net Nitrogen Assimilation by Phaeocystis
+ ! Function: Phaeocystis nitrogen uptake
+ ! Nutrient preference: Can efficiently use various N forms
+ ! Units: mmolN/(m²*d)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'NNAp', 'Net N-assimilation phaeocystis', 'mmolN/(m2*d)', NNAp, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('Chldegp ')
+ ! =====================================================================
+ ! Variable: Chldegp
+ ! Description: Chlorophyll degradation rate for Phaeocystis
+ ! Function: Phaeocystis chlorophyll loss
+ ! Units: 1/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, &
+ 'ChlDegp', 'Chlorophyll degradation phaeocystis', '1/d', Chldegp, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+! =====================================================================
+! ZOOPLANKTON GRAZING FLUXES
+! =====================================================================
+! Predation fluxes by three zooplankton functional groups
+!
+! IMPORTANT DISTINCTION:
+! - Fluxes "without grazing efficiency" = loss from prey's perspective
+! (all carbon removed from prey pool)
+! - "Total grazing" = actual ingestion by predator
+! (accounts for grazing efficiency < 1; rest becomes detritus)
+!
+! Model structure: Three zooplankton size classes
+! - Microzooplankton: Small (e.g., ciliates, heterotrophic flagellates)
+! - Mesozooplankton: Medium (e.g., copepods)
+! - Macrozooplankton: Large (e.g., euphausiids, large copepods)
+! =====================================================================
+
+! ---------------------------------------------------------------------
+! MESOZOOPLANKTON GRAZING
+! ---------------------------------------------------------------------
+! Medium-sized zooplankton (typically copepods, 0.2-2 mm)
+! Diet: Omnivorous - phytoplankton, microzooplankton, detritus
+! Ecological role: Link between primary producers and fish
+! ---------------------------------------------------------------------
+
+CASE ('grazmeso_tot')
+ ! =====================================================================
+ ! Variable: grazmeso_tot
+ ! Description: Total mesozooplankton grazing (carbon ingested)
+ ! Function: Sum of all prey items × grazing efficiency
+ ! Fate of ingested C: Growth + respiration + excretion + egestion
+ ! Units: mmolC/(m²d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmeso_tot', 'Total grazing flux of mesozooplankton, dependent on grazing efficiency', 'mmolC/(m2d)', grazmeso_tot, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+
+CASE ('grazmeso_n')
+ ! =====================================================================
+ ! Variable: grazmeso_n
+ ! Description: Mesozooplankton grazing on nanophytoplankton
+ ! Function: Carbon loss from nanophyto pool due to mesozoo predation
+ ! Note: Includes both ingested and sloppy feeding (→ DOM/detritus)
+ ! Units: mmolC/(m²d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmeso_n', 'Grazing flux of mesozooplankton on small phytoplankton without grazing efficiency (i.e., = loss small phytoplankton)', 'mmolC/(m2d)', grazmeso_n, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('grazmeso_d')
+ ! =====================================================================
+ ! Variable: grazmeso_d
+ ! Description: Mesozooplankton grazing on diatoms
+ ! Function: Carbon loss from diatom pool
+ ! Ecological note: Copepods are major diatom grazers in blooms
+ ! Units: mmolC/(m²d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmeso_d', 'Grazing flux of mesozooplankton on diatoms without grazing efficiency (i.e., = loss diatoms)', 'mmolC/(m2d)', grazmeso_d, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('grazmeso_c')
+ ! =====================================================================
+ ! Variable: grazmeso_c
+ ! Description: Mesozooplankton grazing on coccolithophores
+ ! Function: Carbon loss from coccolithophore pool
+ ! Units: mmolC/(m²d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmeso_c', 'Grazing flux of mesozooplankton on coccolithophores without grazing efficiency (i.e., = loss coccolithophores)', 'mmolC/(m2d)', grazmeso_c, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('grazmeso_p')
+ ! =====================================================================
+ ! Variable: grazmeso_p
+ ! Description: Mesozooplankton grazing on Phaeocystis
+ ! Function: Carbon loss from Phaeocystis pool
+ ! Ecological note: Colonial Phaeocystis often poorly grazed
+ ! Units: mmolC/(m²*d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmeso_p', 'Grazing flux of mesozooplankton on phaeocystis without grazing efficiency (i.e., = loss phaeocystis)', 'mmolC/(m2*d)', grazmeso_p, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('grazmeso_det')
+ ! =====================================================================
+ ! Variable: grazmeso_det
+ ! Description: Mesozooplankton grazing on first detritus group
+ ! Function: Detritivory by mesozooplankton
+ ! Ecological role: Repackaging of detritus into fecal pellets
+ ! Units: mmolC/(m²d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmeso_det','Grazing flux of mesozooplankton on first detritus group without grazing efficiency (i.e., = loss first detritus group)', 'mmolC/(m2d)', grazmeso_det, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('grazmeso_mic')
+ ! =====================================================================
+ ! Variable: grazmeso_mic
+ ! Description: Mesozooplankton predation on microzooplankton
+ ! Function: Trophic transfer from micro- to mesozooplankton
+ ! Ecological significance: Microbial loop → classical food chain link
+ ! Units: mmolC/(m²d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmeso_mic', 'Grazing flux of mesozooplankton on microzooplankton without grazing efficiency (i.e., = loss microzooplankton)', 'mmolC/(m2d)', grazmeso_mic, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('grazmeso_det2')
+ ! =====================================================================
+ ! Variable: grazmeso_det2
+ ! Description: Mesozooplankton grazing on second detritus group
+ ! Function: Feeding on different detritus pool (possibly larger/slower sinking)
+ ! Model structure: Multiple detritus pools represent different size classes
+ ! Units: mmolC/(m²*d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmeso_det2', 'Grazing flux of mesozooplankton on first detritus without grazing efficiency (i.e., = loss second detritus group)', 'mmolC/(m2*d)', grazmeso_det2, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+! ---------------------------------------------------------------------
+! MACROZOOPLANKTON GRAZING
+! ---------------------------------------------------------------------
+! Large zooplankton (euphausiids/krill, large copepods, >2 mm)
+! Diet: Phytoplankton, smaller zooplankton, detritus
+! Ecological role: Major prey for fish, seabirds, marine mammals
+! ---------------------------------------------------------------------
+
+CASE ('grazmacro_tot')
+ ! =====================================================================
+ ! Variable: grazmacro_tot
+ ! Description: Total macrozooplankton grazing (carbon ingested)
+ ! Function: Total carbon intake by macrozooplankton
+ ! Ecological importance: Critical for upper trophic levels
+ ! Units: mmolC/(m²d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmacro_tot', 'Total grazing flux of macrozooplankton, dependent on grazing efficiency', 'mmolC/(m2d)', grazmacro_tot, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('grazmacro_n')
+ ! =====================================================================
+ ! Variable: grazmacro_n
+ ! Description: Macrozooplankton grazing on nanophytoplankton
+ ! Function: Loss from nanophyto due to macrozooplankton
+ ! Units: mmolC/(m²d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmacro_n','Grazing flux of macrozooplankton on small phytoplankton without grazing efficiency (i.e., = loss small phytoplankton)', 'mmolC/(m2d)', grazmacro_n, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('grazmacro_d')
+ ! =====================================================================
+ ! Variable: grazmacro_d
+ ! Description: Macrozooplankton grazing on diatoms
+ ! Function: Loss from diatoms due to macrozooplankton
+ ! Example: Antarctic krill feeding on diatom blooms
+ ! Units: mmolC/(m²d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmacro_d', 'Grazing flux of macrozooplankton on diatoms without grazing efficiency (i.e., = loss diatoms)','mmolC/(m2d)', grazmacro_d, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('grazmacro_c')
+ ! =====================================================================
+ ! Variable: grazmacro_c
+ ! Description: Macrozooplankton grazing on coccolithophores
+ ! Function: Loss from coccolithophores due to macrozooplankton
+ ! Units: mmolC/(m²d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmacro_c', 'Grazing flux of macrozooplankton on coccolithophores without grazing efficiency (i.e., = loss coccolithophores)','mmolC/(m2d)', grazmacro_c, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('grazmacro_p')
+ ! =====================================================================
+ ! Variable: grazmacro_p
+ ! Description: Macrozooplankton grazing on Phaeocystis
+ ! Function: Loss from Phaeocystis due to macrozooplankton
+ ! Units: mmolC/(m²*d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmacro_p', 'Grazing flux of macrozooplankton on phaeocystis without grazing efficiency (i.e., = loss phaeocystis)', 'mmolC/(m2*d)', grazmacro_p, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('grazmacro_mes')
+ ! =====================================================================
+ ! Variable: grazmacro_mes
+ ! Description: Macrozooplankton predation on mesozooplankton
+ ! Function: Carnivory - trophic transfer to higher level
+ ! Ecological note: Intraguild predation within zooplankton
+ ! Units: mmolC/(m²d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmacro_mes', 'Grazing flux of mesozooplankton on macrozooplankton without grazing efficiency (i.e., = loss mesozooplankton)', 'mmolC/(m2d)', grazmacro_mes, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('grazmacro_det')
+ ! =====================================================================
+ ! Variable: grazmacro_det
+ ! Description: Macrozooplankton grazing on first detritus group
+ ! Function: Detritivory by macrozooplankton
+ ! Units: mmolC/(m²d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmacro_det', 'Grazing flux of macrozooplankton on first detritus group without grazing efficiency (i.e., = loss first detritus group)', 'mmolC/(m2d)', grazmacro_det, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('grazmacro_mic')
+ ! =====================================================================
+ ! Variable: grazmacro_mic
+ ! Description: Macrozooplankton predation on microzooplankton
+ ! Function: Loss from microzooplankton to macrozooplankton
+ ! Units: mmolC/(m²d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmacro_mic', 'Grazing flux of macrozooplankton on microzooplankton without grazing efficiency (i.e., = loss microzooplankton)', 'mmolC/(m2d)', grazmacro_mic, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('grazmacro_det2')
+ ! =====================================================================
+ ! Variable: grazmacro_det2
+ ! Description: Macrozooplankton grazing on second detritus group
+ ! Function: Feeding on alternative detritus pool
+ ! Units: mmolC/(m²d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmacro_det2', 'Grazing flux of macrozooplankton on first detritus without grazing efficiency (i.e., = loss second detritus group)', 'mmolC/(m2d)', grazmacro_det2, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+! ---------------------------------------------------------------------
+! MICROZOOPLANKTON GRAZING
+! ---------------------------------------------------------------------
+! Small zooplankton (ciliates, heterotrophic flagellates, <200 μm)
+! Diet: Primarily nanophytoplankton and bacteria
+! Ecological role: Microbial loop - recycles nutrients rapidly
+! ---------------------------------------------------------------------
+
+CASE ('grazmicro_tot')
+ ! =====================================================================
+ ! Variable: grazmicro_tot
+ ! Description: Total microzooplankton grazing (carbon ingested)
+ ! Function: Total carbon intake by microzooplankton
+ ! Ecological importance: Dominant grazers in oligotrophic systems
+ ! Units: mmolC/(m²d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmicro_tot', 'Total grazing flux of microzooplankton, dependent on grazing efficiency', 'mmolC/(m2d)', grazmicro_tot, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('grazmicro_n')
+ ! =====================================================================
+ ! Variable: grazmicro_n
+ ! Description: Microzooplankton grazing on nanophytoplankton
+ ! Function: Primary grazing pressure on small phytoplankton
+ ! Ecological note: Can control nanophyto biomass in stratified waters
+ ! Units: mmolC/(m²d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmicro_n', 'Grazing flux of microzooplankton on small phytoplankton without grazing efficiency (i.e., = loss small phytoplankton)', 'mmolC/(m2d)', grazmicro_n, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('grazmicro_d')
+ ! =====================================================================
+ ! Variable: grazmicro_d
+ ! Description: Microzooplankton grazing on diatoms
+ ! Function: Microzoo predation on diatoms (less common, size-limited)
+ ! Note: Typically graze smaller diatom species/early stages
+ ! Units: mmolC/(m²d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmicro_d', 'Grazing flux of microzooplankton on diatoms without grazing efficiency (i.e., = loss diatoms)', 'mmolC/(m2d)', grazmicro_d, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('grazmicro_c')
+ ! =====================================================================
+ ! Variable: grazmicro_c
+ ! Description: Microzooplankton grazing on coccolithophores
+ ! Function: Microzoo predation on coccolithophores
+ ! Units: mmolC/(m²d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, 'grazmicro_c', &
+ 'Grazing flux of microzooplankton on coccolithophores without grazing efficiency (i.e., = loss coccolithophores)', 'mmolC/(m2d)', grazmicro_c, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('grazmicro_p')
+ ! =====================================================================
+ ! Variable: grazmicro_p
+ ! Description: Microzooplankton grazing on Phaeocystis
+ ! Function: Microzoo predation on Phaeocystis
+ ! Note: Primarily graze solitary cells, not large colonies
+ ! Units: mmolC/(m²*d)
+ ! =====================================================================
+ call def_stream(nod2D, myDim_nod2D, &
+ 'grazmicro_p', 'Grazing flux of microzooplankton on phaeocystis without grazing efficiency (i.e., = loss phaeocystis)', 'mmolC/(m2*d)', grazmicro_p, &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('REMOC ')
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, 'REMOC','Total remineralization of DOC','mmolN/(m2*d)', REMOC, io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('REMOCt ')
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, 'REMOCt','Remineralization of terrigenous DOC','mmolC/(m2*d)', REMOCt, io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+CASE ('REMON ')
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, 'REMON','Total remineralization of DON','mmolC/(m2*d)', REMON, io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('DISSOSi ')
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, 'DISSOSi','Dissolution of Si','mmolSi/(m2*d)', DISSOSi, io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('DISSOC ')
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, 'DISSOC','Dissolution of POC','mmolC/(m2*d)', DISSOC, io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('DISSON ')
+ if (use_REcoM) then
+ call def_stream(nod2D, myDim_nod2D, 'DISSON','Dissolution of PON','mmolN/(m2*d)', DISSON, io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+#endif
+
!___________________________________________________________________________________________________________________________________
!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3D streams <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
!___________________________________________________________________________________________________________________________________
@@ -699,122 +1635,1080 @@ subroutine ini_mean_io(ice, dynamics, tracers, partit, mesh)
#if defined(__recom)
+! =====================================================================
+! CARBONATE CHEMISTRY VARIABLES
+! Description: Variables related to ocean carbon chemistry and pH
+! =====================================================================
+
CASE ('PAR ')
+ ! =====================================================================
+ ! Variable: PAR
+ ! Description: Photosynthetically Active Radiation
+ ! Function: Light energy available for photosynthesis (400-700nm wavelength)
+ ! Role: Primary driver of phytoplankton growth
+ ! Units: W/m²
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'PAR', 'PAR', 'W/m2', PAR3D(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('CO2 ')
+ ! =====================================================================
+ ! Variable: CO2
+ ! Description: Aqueous CO2 concentration
+ ! Function: Dissolved CO2 in seawater, primary inorganic carbon form
+ ! Role: Substrate for phytoplankton photosynthesis, pH regulator
+ ! Units: mol/m³
+ ! =====================================================================
if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'PAR', 'PAR', 'W/m2', PAR3D(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'CO2', 'Aqueous CO2 concentration', 'mol/m3', CO23D(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
end if
+CASE ('pH ')
+ ! =====================================================================
+ ! Variable: pH
+ ! Description: Acidity/alkalinity of seawater (total scale)
+ ! Function: Measure of hydrogen ion concentration
+ ! Role: Affects carbonate chemistry, organism physiology, calcification
+ ! Units: total scale (dimensionless, typically 7.5-8.5 in ocean)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'pH', 'pH', 'total scale', pH3D(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('pCO2 ')
+ ! =====================================================================
+ ! Variable: pCO2
+ ! Description: Partial pressure of CO2 in seawater
+ ! Function: CO2 fugacity in equilibrium with atmosphere
+ ! Role: Determines air-sea CO2 flux direction and magnitude
+ ! Units: μatm (microatmospheres)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'pCO2', 'CO2 partial pressure', 'uatm', pCO23D(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('HCO3 ')
+ ! =====================================================================
+ ! Variable: HCO3
+ ! Description: Bicarbonate ion concentration
+ ! Function: Major dissolved inorganic carbon species (~90% of DIC)
+ ! Role: pH buffer, carbon source for some phytoplankton
+ ! Units: mol/m³
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'HCO3', 'Bicarbonate ion concentration', 'mol/m3', HCO33D(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('CO3 ')
+ ! =====================================================================
+ ! Variable: CO3
+ ! Description: Carbonate ion concentration
+ ! Function: Secondary dissolved inorganic carbon species
+ ! Role: Building block for calcium carbonate (CaCO3) formation
+ ! Units: mol/m³
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'CO3', 'Carbonate ion concentration', 'mol/m3', CO33D(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('OmegaC ')
+ ! =====================================================================
+ ! Variable: OmegaC
+ ! Description: Calcite saturation state (Ω)
+ ! Function: Ratio of [Ca²⁺][CO3²⁻] to calcite solubility product
+ ! Role: Determines calcification vs dissolution; Ω>1 favors precipitation
+ ! Context: Ocean acidification reduces Ω, threatening calcifying organisms
+ ! Units: NN (dimensionless)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'OmegaC','calcite saturation state', 'NN', OmegaC3D(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('kspc ')
+ ! =====================================================================
+ ! Variable: kspc
+ ! Description: Calcite solubility product
+ ! Function: Equilibrium constant for CaCO3 dissolution
+ ! Role: Temperature/pressure dependent; controls calcite stability
+ ! Units: mol²/kg²
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'kspc', 'calcite solubility product', 'mol^2/kg^2', kspc3D(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+CASE ('rhoSW ')
+ ! =====================================================================
+ ! Variable: rhoSW
+ ! Description: In-situ seawater density
+ ! Function: Density at ambient temperature, salinity, and pressure
+ ! Role: Physical property affecting stratification and mixing
+ ! Units: mol/m³ (CHECK: unusual units, typically kg/m³)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'rhoSW', 'in-situ density of seawater', 'mol/m3', rhoSW3D(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+! =====================================================================
+! PARTICLE DYNAMICS - DENSITY AND SINKING
+! Description: Physical properties of detrital particles
+! =====================================================================
+
+CASE ('rho_det1 ')
+ ! =====================================================================
+ ! Variable: rho_det1
+ ! Description: Density of detrital particles in size class 1
+ ! Function: Mass per unit volume of small/slow-sinking particles
+ ! Role: Determines sinking speed via Stokes' law
+ ! Context: Lower density = slower sinking = longer remineralization time
+ ! Units: kg/m³
+ ! =====================================================================
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'rho_det1', 'rho of particles in class 1', 'kg/m3', rho_particle1(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('rho_det2 ')
+ ! =====================================================================
+ ! Variable: rho_det2
+ ! Description: Density of detrital particles in size class 2
+ ! Function: Mass per unit volume of large/fast-sinking particles
+ ! Role: Determines sinking speed via Stokes' law
+ ! Context: Higher density = faster sinking = efficient carbon export
+ ! Units: kg/m³
+ ! =====================================================================
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'rho_det2', 'rho of particles in class 2', 'kg/m3', rho_particle2(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('scaling_visc ')
+ ! =====================================================================
+ ! Variable: scaling_visc
+ ! Description: Viscosity-based scaling factor for sinking speed
+ ! Function: Adjusts particle sinking based on water viscosity
+ ! Role: Temperature/salinity affect viscosity, thus sinking rates
+ ! Context: Warmer water = lower viscosity = faster sinking
+ ! Units: n.d. (non-dimensional scaling factor)
+ ! =====================================================================
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'scaling_visc', 'scaling factor of particle sinking speed', 'n.d.', scaling_visc_3D(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('wsink_det1')
+ ! =====================================================================
+ ! Variable: wsink_det1
+ ! Description: Sinking velocity of particle class 1
+ ! Function: Vertical descent rate of small detrital particles
+ ! Role: Controls residence time in euphotic zone, carbon export efficiency
+ ! Context: Typically 1-50 m/day for small aggregates
+ ! Units: m/s
+ ! =====================================================================
+ call def_stream((/nl, nod2D/), (/nl, myDim_nod2D/), &
+ 'wsink_det1', 'sinking speed of particles in class 1', 'm s-1', Sinkingvel1(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('wsink_det2')
+ ! =====================================================================
+ ! Variable: wsink_det2
+ ! Description: Sinking velocity of particle class 2
+ ! Function: Vertical descent rate of large detrital particles
+ ! Role: Fast export pathway for carbon to deep ocean
+ ! Context: Typically 50-200+ m/day for large aggregates/fecal pellets
+ ! Units: m/s
+ ! =====================================================================
+ call def_stream((/nl, nod2D/), (/nl, myDim_nod2D/), &
+ 'wsink_det2', 'sinking speed of particles in class 2', 'm s-1', Sinkingvel2(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+! =====================================================================
+! BENTHIC NUTRIENT FLUXES
+! Description: Sediment-water interface nutrient release
+! =====================================================================
+
+CASE ('DIC_bf')
+ ! =====================================================================
+ ! Variable: DIC_bf
+ ! Description: Dissolved Inorganic Carbon bottom flux
+ ! Function: Release of CO2/HCO3/CO3 from sediment remineralization
+ ! Role: Recycles organic carbon back to water column
+ ! Context: Important in shallow seas, negligible in deep ocean
+ ! Units: mmolC/m³
+ ! =====================================================================
+ call def_stream((/nl, nod2D/), (/nl, myDim_nod2D/), &
+ 'DIC_bf', 'DIC bottom flux', 'mmolC/m3', dtr_bflux_dic(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('DIN_bf')
+ ! =====================================================================
+ ! Variable: DIN_bf
+ ! Description: Dissolved Inorganic Nitrogen bottom flux
+ ! Function: Release of NH4⁺/NO3⁻ from sediment remineralization
+ ! Role: Nutrient regeneration supporting primary production
+ ! Context: Major N source in coastal/shelf systems
+ ! Units: mmolN/m³
+ ! =====================================================================
+ call def_stream((/nl, nod2D/), (/nl, myDim_nod2D/), &
+ 'DIN_bf', 'DIN bottom flux', 'mmolC/m3', dtr_bflux_din(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('Alk_bf')
+ ! =====================================================================
+ ! Variable: Alk_bf
+ ! Description: Alkalinity bottom flux
+ ! Function: Release of acid-neutralizing capacity from sediments
+ ! Role: Affects pH and carbonate chemistry of bottom waters
+ ! Context: Dominated by NH4⁺ production and CaCO3 dissolution
+ ! Units: mmolC/m³ (CHECK: should be meq/m³)
+ ! =====================================================================
+ call def_stream((/nl, nod2D/), (/nl, myDim_nod2D/), &
+ 'Alk_bf', 'Alk bottom flux', 'mmolC/m3', dtr_bflux_alk(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+CASE ('DSi_bf')
+ ! =====================================================================
+ ! Variable: DSi_bf
+ ! Description: Dissolved Silicate bottom flux
+ ! Function: Release of Si(OH)4 from opal dissolution in sediments
+ ! Role: Critical nutrient for diatom growth
+ ! Context: Can control diatom vs non-diatom dominance
+ ! Units: mmolSi/m³
+ ! =====================================================================
+ call def_stream((/nl, nod2D/), (/nl, myDim_nod2D/), &
+ 'DSi_bf', 'DSi bottom flux', 'mmolC/m3', dtr_bflux_dsi(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+! =====================================================================
+! ZOOPLANKTON RESPIRATION
+! Description: Metabolic CO2 production by different zooplankton size classes
+! =====================================================================
+
CASE ('respmeso ')
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'respmeso','Respiration rate of mesozooplankton', 'mmolC/m2/d', respmeso(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
- endif
+ ! =====================================================================
+ ! Variable: respmeso
+ ! Description: Respiration rate of mesozooplankton
+ ! Function: Metabolic CO2 release by medium-sized grazers (0.2-2 mm)
+ ! Role: Returns carbon to DIC pool, drives oxygen consumption
+ ! Taxa: Copepods, euphausiids, chaetognaths
+ ! Units: mmolC/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'respmeso', 'Respiration rate of mesozooplankton', 'mmolC/m2/d', respmeso(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
CASE ('respmacro ')
- if (use_REcoM) then ! .and. three_zoo_two_det) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'respmacro','Respiration rate of macrozooplankton', 'mmolC/m2/d', respmacro(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
- endif
+ ! =====================================================================
+ ! Variable: respmacro
+ ! Description: Respiration rate of macrozooplankton
+ ! Function: Metabolic CO2 release by large grazers (>2 mm)
+ ! Role: Produces fast-sinking fecal pellets, vertical carbon transport
+ ! Taxa: Large euphausiids, amphipods, jellyfish
+ ! Units: mmolC/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'respmacro', 'Respiration rate of macrozooplankton', 'mmolC/m2/d', respmacro(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
CASE ('respmicro ')
- if (use_REcoM) then ! .and. three_zoo_two_det) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'respmicro','Respiration rate of microzooplankton', 'mmolC/m2/d', respmicro(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
- endif
+ ! =====================================================================
+ ! Variable: respmicro
+ ! Description: Respiration rate of microzooplankton
+ ! Function: Metabolic CO2 release by small grazers (<0.2 mm)
+ ! Role: Rapid nutrient recycling in microbial loop
+ ! Taxa: Ciliates, heterotrophic dinoflagellates
+ ! Units: mmolC/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'respmicro', 'Respiration rate of microzooplankton', 'mmolC/m2/d', respmicro(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+! =====================================================================
+! SECTION 5: CALCIUM CARBONATE DYNAMICS
+! Description: Calcification and dissolution processes
+! =====================================================================
CASE ('calcdiss ')
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'calcdiss','Calcite dissolution', 'mmolC/m2/d', calcdiss(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
- endif
+ ! =====================================================================
+ ! Variable: calcdiss
+ ! Description: Calcite (CaCO3) dissolution rate
+ ! Function: Conversion of solid CaCO3 back to dissolved Ca²⁺ and CO3²⁻
+ ! Role: Increases alkalinity, releases CO2, occurs when Ω < 1
+ ! Context: Accelerated by ocean acidification
+ ! Units: mmolC/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'calcdiss', 'Calcite dissolution', 'mmolC/m2/d', calcdiss(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
CASE ('calcif ')
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'calcif','Calcification', 'mmolC/m2/d', calcif(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
- endif
+ ! =====================================================================
+ ! Variable: calcif
+ ! Description: Calcification rate (CaCO3 formation)
+ ! Function: Precipitation of calcium carbonate shells/tests
+ ! Role: Decreases alkalinity, releases CO2, ballasts organic carbon
+ ! Organisms: Coccolithophores, foraminifera, pteropods
+ ! Units: mmolC/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'calcif', 'Calcification', 'mmolC/m2/d', calcif(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+! =====================================================================
+! PHYTOPLANKTON AGGREGATION
+! Description: Formation of larger particles from small cells
+! =====================================================================
CASE ('aggn ')
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'aggn','Aggregation of small phytoplankton', 'mmolC/m2/d', aggn(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
- endif
+ ! =====================================================================
+ ! Variable: aggn
+ ! Description: Aggregation of small (nano) phytoplankton
+ ! Function: Collision-driven clumping of 2-20 μm cells
+ ! Role: Converts slow-sinking cells to faster-sinking aggregates
+ ! Context: Enhanced by stickiness (TEP), turbulence, high cell density
+ ! Units: mmolC/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'aggn', 'Aggregation of small phytoplankton', 'mmolC/m2/d', aggn(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
CASE ('aggd ')
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'aggd','Aggregation of diatoms', 'mmolC/m2/d', aggd(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
- endif
+ ! =====================================================================
+ ! Variable: aggd
+ ! Description: Aggregation of diatoms
+ ! Function: Formation of diatom-dominated marine snow
+ ! Role: Major pathway for carbon export during bloom collapse
+ ! Context: Si:C ballasting enhances sinking speed (100-200 m/day)
+ ! Units: mmolC/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'aggd', 'Aggregation of diatoms', 'mmolC/m2/d', aggd(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
CASE ('aggc ')
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'aggc','Aggregation of coccolithophores', 'mmolC/m2/d', aggc(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
- endif
+ ! =====================================================================
+ ! Variable: aggc
+ ! Description: Aggregation of coccolithophores
+ ! Function: Formation of coccolith-bearing aggregates
+ ! Role: CaCO3 ballasting enhances export efficiency
+ ! Context: Creates "white waters" visible from space during blooms
+ ! Units: mmolC/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'aggc', 'Aggregation of coccolithophores', 'mmolC/m2/d', aggc(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('aggp ')
+ ! =====================================================================
+ ! Variable: aggp
+ ! Description: Aggregation of Phaeocystis
+ ! Function: Colony formation and aggregation of colonial haptophyte
+ ! Role: Forms mucilaginous colonies up to 3 cm, efficient export
+ ! Context: Dominant in polar/subpolar regions, nuisance blooms
+ ! Units: mmolC/(m²*d)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'aggp', 'Aggregation of phaeocystis', 'mmolC/(m2*d)', aggp(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+! =====================================================================
+! DISSOLVED ORGANIC CARBON (DOC) EXCRETION
+! Description: Release of dissolved organics by phytoplankton
+! =====================================================================
CASE ('docexn ')
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'docexn','DOC excretion by small phytoplankton', 'mmolC/m2/d', docexn(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
- endif
+ ! =====================================================================
+ ! Variable: docexn
+ ! Description: DOC excretion by nanophytoplankton
+ ! Function: Passive/active release of dissolved organic compounds
+ ! Role: Fuels microbial loop, can be 5-20% of gross production
+ ! Context: Increases under nutrient stress or viral lysis
+ ! Units: mmolC/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'docexn', 'DOC excretion by small phytoplankton', 'mmolC/m2/d', docexn(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
CASE ('docexd ')
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'docexd','DOC excretion by diatoms', 'mmolC/m2/d', docexd(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
- endif
+ ! =====================================================================
+ ! Variable: docexd
+ ! Description: DOC excretion by diatoms
+ ! Function: Release of organic compounds from diatom metabolism
+ ! Role: Can be substantial during stationary phase or Si limitation
+ ! Context: Includes transparent exopolymer particles (TEP)
+ ! Units: mmolC/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'docexd', 'DOC excretion by diatoms', 'mmolC/m2/d', docexd(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
CASE ('docexc ')
+ ! =====================================================================
+ ! Variable: docexc
+ ! Description: DOC excretion by coccolithophores
+ ! Function: Release of organic compounds during calcification/growth
+ ! Role: Links organic and inorganic carbon cycles
+ ! Context: May increase under high pCO2 (ocean acidification)
+ ! Units: mmolC/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'docexc', 'DOC excretion by coccolithophores', 'mmolC/m2/d', docexc(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('docexp ')
+ ! =====================================================================
+ ! Variable: docexp
+ ! Description: DOC excretion by Phaeocystis
+ ! Function: Release of polysaccharides forming colonial matrix
+ ! Role: Major mucus producer, can create foam on beaches
+ ! Context: High C:N ratio DOC, relatively refractory
+ ! Units: mmolC/(m²*d)
+ ! =====================================================================
if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'docexc','DOC excretion by coccolithophores', 'mmolC/m2/d', docexc(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'docexp', 'DOC excretion by phaeocystis', 'mmolC/(m2*d)', docexp(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+! =====================================================================
+! PHYTOPLANKTON RESPIRATION
+! Description: Metabolic CO2 release by autotrophs
+! =====================================================================
+
CASE ('respn ')
+ ! =====================================================================
+ ! Variable: respn
+ ! Description: Respiration by nanophytoplankton
+ ! Function: Maintenance metabolism and biosynthesis costs
+ ! Role: Determines net vs gross primary production (NPP vs GPP)
+ ! Context: Typically 10-30% of GPP, increases with temperature
+ ! Units: mmolC/m²/d
+ ! =====================================================================
if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'respn','Respiration by small phytoplankton', 'mmolC/m2/d', respn(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'respn', 'Respiration by small phytoplankton', 'mmolC/m2/d', respn(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
CASE ('respd ')
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'respd','Respiration by diatoms', 'mmolC/m2/d', respd(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
- endif
+ ! =====================================================================
+ ! Variable: respd
+ ! Description: Respiration by diatoms
+ ! Function: Metabolic costs of rapid growth and Si metabolism
+ ! Role: Higher in fast-growing bloom-forming species
+ ! Context: Can increase under nutrient limitation
+ ! Units: mmolC/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'respd', 'Respiration by diatoms', 'mmolC/m2/d', respd(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
CASE ('respc ')
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'respc','Respiration by coccolithophores', 'mmolC/(m2*d)', respc(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
- endif
+ ! =====================================================================
+ ! Variable: respc
+ ! Description: Respiration by coccolithophores
+ ! Function: Metabolic costs including calcification energy
+ ! Role: Calcification requires ~20% additional energy vs non-calcifiers
+ ! Context: May increase under ocean acidification stress
+ ! Units: mmolC/(m²*d)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'respc', 'Respiration by coccolithophores', 'mmolC/(m2*d)', respc(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('respp ')
+ ! =====================================================================
+ ! Variable: respp
+ ! Description: Respiration by Phaeocystis
+ ! Function: Metabolic costs of colonial vs solitary forms
+ ! Role: Colonial forms may have lower specific respiration rates
+ ! Context: Life cycle shifts affect carbon cycling
+ ! Units: mmolC/(m²*d)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'respp', 'Respiration by phaeocystis', 'mmolC/(m2*d)', respp(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+! =====================================================================
+! NET PRIMARY PRODUCTION (NPP) BY FUNCTIONAL GROUP
+! Description: Net carbon fixation after respiration losses
+! =====================================================================
CASE ('NPPn3D ')
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'NPPn3D','Net primary production of small phytoplankton', 'mmolC/m2/d', NPPn3D(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
- endif
+ ! =====================================================================
+ ! Variable: NPPn3D
+ ! Description: Net Primary Production of nanophytoplankton
+ ! Function: Gross photosynthesis minus respiration and exudation
+ ! Role: Sustained baseline production in oligotrophic waters
+ ! Ecology: Dominant in stratified, nutrient-poor conditions
+ ! Units: mmolC/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'NPPn3D', 'Net primary production of small phytoplankton', 'mmolC/m2/d', NPPn3D(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
CASE ('NPPd3D ')
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'NPPd3D','Net primary production of diatoms', 'mmolC/m2/d', NPPd3D(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
- endif
+ ! =====================================================================
+ ! Variable: NPPd3D
+ ! Description: Net Primary Production of diatoms
+ ! Function: Net carbon fixation by silicified phytoplankton
+ ! Role: Bloom-forming, episodic production pulses
+ ! Ecology: Dominant in upwelling, mixed, nutrient-rich waters
+ ! Units: mmolC/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'NPPd3D', 'Net primary production of diatoms', 'mmolC/m2/d', NPPd3D(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
CASE ('NPPc3D ')
+ ! =====================================================================
+ ! Variable: NPPc3D
+ ! Description: Net Primary Production of coccolithophores
+ ! Function: Net carbon fixation by calcifying haptophytes
+ ! Role: Links organic and inorganic carbon pumps
+ ! Ecology: Bloom in stratified, post-bloom nutrient-depleted waters
+ ! Units: mmolC/m²/d
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'NPPc3D', 'Net primary production of coccolithophores', 'mmolC/m2/d', NPPc3D(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('NPPp3D ')
+ ! =====================================================================
+ ! Variable: NPPp3D
+ ! Description: Net Primary Production of Phaeocystis
+ ! Function: Net carbon fixation by colonial haptophyte
+ ! Role: High-latitude spring bloom specialist
+ ! Ecology: Tolerates low light, cold temperatures, ice-edge blooms
+ ! Units: mmolC/(m²*d)
+ ! =====================================================================
if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'NPPc3D','Net primary production of coccolithophores', 'mmolC/m2/d', NPPc3D(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'NPPp3D', 'Net primary production of phaeocystis', 'mmolC/(m2*d)', NPPp3D(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
-#endif
-!CASE ('otracers ')
-! do j=3, tracers%num_tracers
-! write (id_string, "(I3.3)") tracers%data(j)%ID
-! call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'tra_'//id_string, 'pasive tracer ID='//id_string, 'n/a', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
-! end do
+! =====================================================================
+! TEMPERATURE EFFECTS ON PHOTOSYNTHESIS
+! Description: Temperature-dependent growth rate modifiers
+! =====================================================================
+
+CASE ('TTemp_diatoms ')
+ ! =====================================================================
+ ! Variable: TTemp_diatoms
+ ! Description: Temperature dependence factor for diatom photosynthesis
+ ! Function: Q10-based or Arrhenius growth rate modifier
+ ! Role: Accelerates growth in warmer waters
+ ! Context: Diatoms often have lower temperature optimum than flagellates
+ ! Units: per day (dimensionless multiplier)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TTemp_diatoms', 'Temperature dependence of diatoms PS', 'per day', TTemp_diatoms(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('TTemp_phyto ')
+ ! =====================================================================
+ ! Variable: TTemp_phyto
+ ! Description: Temperature dependence factor for nanophytoplankton
+ ! Function: Growth rate scaling with temperature
+ ! Role: Often have broader temperature tolerance than specialists
+ ! Context: May benefit from warming in temperate/tropical regions
+ ! Units: per day (dimensionless multiplier)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TTemp_phyto', 'Temperature dependence of small phytoplankton PS', 'per day', TTemp_phyto(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('TTemp_cocco ')
+ ! =====================================================================
+ ! Variable: TTemp_cocco
+ ! Description: Temperature dependence factor for coccolithophores
+ ! Function: Growth rate and calcification temperature sensitivity
+ ! Role: Often have higher temperature optima than diatoms
+ ! Context: May expand poleward with warming
+ ! Units: per day (dimensionless multiplier)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TTemp_cocco', 'Temperature dependence of coccolithophores PS', 'per day', TTemp_cocco(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('TTemp_phaeo ')
+ ! =====================================================================
+ ! Variable: TTemp_phaeo
+ ! Description: Temperature dependence factor for Phaeocystis
+ ! Function: Growth rate scaling in cold polar waters
+ ! Role: Adapted to low temperatures (0-10°C optimum)
+ ! Context: Climate warming may reduce competitive advantage
+ ! Units: per day (dimensionless multiplier)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TTemp_phaeo', 'Temperature dependence of phaeocystis PS', 'per day', TTemp_phaeo(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+! =====================================================================
+! SECTION 11: CO2 EFFECTS ON PHOTOSYNTHESIS
+! Description: pCO2-dependent growth modifiers (ocean acidification impacts)
+! =====================================================================
+
+CASE ('TPhyCO2 ')
+ ! =====================================================================
+ ! Variable: TPhyCO2
+ ! Description: Effect of CO2 on nanophytoplankton growth
+ ! Function: Carbon concentration mechanism (CCM) efficiency modifier
+ ! Role: Some species benefit from higher CO2 (reduced CCM energy cost)
+ ! Context: Generally small positive or neutral effect
+ ! Units: per day (dimensionless multiplier)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TPhyCO2', 'Effect of CO2 of phyto growth/PS', 'per day', TPhyCO2(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('TDiaCO2 ')
+ ! =====================================================================
+ ! Variable: TDiaCO2
+ ! Description: Effect of CO2 on diatom growth
+ ! Function: CCM efficiency and photorespiration modifier
+ ! Role: Mixed responses, some species C3-like, others have efficient CCMs
+ ! Context: High CO2 may reduce competitive advantage vs other groups
+ ! Units: per day (dimensionless multiplier)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TDiaCO2', 'Effect of CO2 of phyto growth/PS', 'per day', TDiaCO2(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('TCoccoCO2 ')
+ ! =====================================================================
+ ! Variable: TCoccoCO2
+ ! Description: Effect of CO2 on coccolithophore growth
+ ! Function: Photosynthesis vs calcification trade-off under high CO2
+ ! Role: High pCO2 may benefit photosynthesis but impair calcification
+ ! Context: Net effect species-specific, generally negative at >1000 μatm
+ ! Units: per day (dimensionless multiplier)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TCoccoCO2', 'Effect of CO2 of phyto growth/PS', 'per day', TCoccoCO2(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('TPhaeoCO2 ')
+ ! =====================================================================
+ ! Variable: TPhaeoCO2
+ ! Description: Effect of CO2 on Phaeocystis growth
+ ! Function: CCM efficiency in high-latitude species
+ ! Role: May benefit from CO2 enrichment in cold waters
+ ! Context: Limited experimental data compared to other groups
+ ! Units: per day (dimensionless multiplier)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TPhaeoCO2', 'Effect of CO2 of phyto growth/PS', 'per day', TPhaeoCO2(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+! =====================================================================
+! SECTION 12: NUTRIENT LIMITATION FACTORS
+! Description: Multi-nutrient limitation of photosynthesis
+! =====================================================================
+
+CASE ('TqLF_phyto ')
+ ! =====================================================================
+ ! Variable: TqLF_phyto
+ ! Description: Nutrient limitation factor for nanophytoplankton
+ ! Function: Minimum of N, P, Fe limitation (Liebig's Law)
+ ! Role: Determines realized vs maximum potential growth rate
+ ! Context: Often N-limited in stratified waters, Fe-limited in HNLC
+ ! Units: per day (0-1 dimensionless multiplier)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TqLF_phyto', 'Nutrient limitation effect of phyto PS', 'per day', TqlimitFac_phyto(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('TqLF_diatoms ')
+ ! =====================================================================
+ ! Variable: TqLF_diatoms
+ ! Description: Nutrient limitation factor for diatoms
+ ! Function: Minimum of N, P, Si, Fe limitation
+ ! Role: Si limitation unique to diatoms, controls bloom termination
+ ! Context: Si:N ratio critical for diatom vs flagellate competition
+ ! Units: per day (0-1 dimensionless multiplier)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TqLF_diatoms', 'Nutrient limitation effect of diatoms PS', 'per day', TqlimitFac_diatoms(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('TqLF_cocco ')
+ ! =====================================================================
+ ! Variable: TqLF_cocco
+ ! Description: Nutrient limitation factor for coccolithophores
+ ! Function: Minimum of N, P limitation (no Si requirement)
+ ! Role: Can exploit low-nutrient conditions after diatom bloom collapse
+ ! Context: High C:N, C:P ratios during severe limitation
+ ! Units: per day (0-1 dimensionless multiplier)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'TqLF_cocco','Nutrient limitation effect of diatoms PS', 'per day',TqlimitFac_cocco(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('TqLF_phaeo ')
+ ! =====================================================================
+ ! Variable: TqLF_phaeo
+ ! Description: Nutrient limitation factor for Phaeocystis
+ ! Function: Minimum of N, P, Fe limitation
+ ! Role: Can form luxury nutrient reserves in colonial form
+ ! Context: Often blooms early when nutrients still replete
+ ! Units: per day (0-1 dimensionless multiplier)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TqLF_phaeo', 'Nutrient limitation effect of diatoms PS', 'per day', TqlimitFac_phaeo(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+! =====================================================================
+! LIGHT LIMITATION FACTORS
+! Description: Photosynthesis-irradiance relationship modifiers
+! =====================================================================
+
+CASE ('TCphotLL_phyto ')
+ ! =====================================================================
+ ! Variable: TCphotLL_phyto
+ ! Description: Light limitation factor for nanophytoplankton
+ ! Function: P-I curve response (typically hyperbolic tangent or exponential)
+ ! Role: Reduces growth in low light, photoinhibition at high light
+ ! Context: Small cells acclimate faster to changing light
+ ! Units: per day (0-1 dimensionless multiplier)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TCphotLL_phyto', 'Light limitation on phyto PS', 'per day', TCphotLigLim_phyto(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('TCphotLL_dia ')
+ ! =====================================================================
+ ! Variable: TCphotLL_dia
+ ! Description: Light limitation factor for diatoms
+ ! Function: P-I curve with potentially higher light saturation point
+ ! Role: Often shade-adapted in coastal turbid waters
+ ! Context: Larger cells = slower photoacclimation
+ ! Units: per day (0-1 dimensionless multiplier)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TCphotLL_dia', 'Light limitation on diatoms PS', 'per day', TCphotLigLim_diatoms(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('TCphotLL_cocco ')
+ ! =====================================================================
+ ! Variable: TCphotLL_cocco
+ ! Description: Light limitation factor for coccolithophores
+ ! Function: P-I curve for high-light adapted species
+ ! Role: Often prefer high irradiance, stratified waters
+ ! Context: Bloom in clear waters with deep light penetration
+ ! Units: per day (0-1 dimensionless multiplier)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TCphotLL_cocco', 'Light limitation on phyto PS', 'per day', TCphotLigLim_cocco(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('TCphotLL_phaeo ')
+ ! =====================================================================
+ ! Variable: TCphotLL_phaeo
+ ! Description: Light limitation factor for Phaeocystis
+ ! Function: P-I curve for low-light adapted polar species
+ ! Role: Low light saturation point, efficient in weak polar light
+ ! Context: Can grow under sea ice with <1% surface irradiance
+ ! Units: per day (0-1 dimensionless multiplier)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TCphotLL_phaeo', 'Light limitation on phyto PS', 'per day', TCphotLigLim_phaeo(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+
+! =====================================================================
+! CARBON-SPECIFIC PHOTOSYNTHESIS RATES
+! Description: Actual photosynthetic carbon fixation rates
+! =====================================================================
+
+CASE ('TCphot_phyto ')
+ ! =====================================================================
+ ! Variable: TCphot_phyto
+ ! Description: Carbon-specific photosynthesis rate of nanophytoplankton
+ ! Function: Gross carbon fixation per unit biomass
+ ! Role: Product of all limiting factors × maximum rate
+ ! Context: Typically 0.5-3.0 d⁻¹ in natural populations
+ ! Units: per day (d⁻¹)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TCphot_phyto', 'Light limitation on phyto PS', 'per day', TCphot_phyto(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('TCphot_diatoms ')
+ ! =====================================================================
+ ! Variable: TCphot_diatoms
+ ! Description: Carbon-specific photosynthesis rate of diatoms
+ ! Function: Gross carbon fixation per unit biomass
+ ! Role: Can reach very high rates (>5 d⁻¹) during blooms
+ ! Context: r-strategists with high maximum growth rates
+ ! Units: per day (d⁻¹)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TCphot_diatoms', 'Light limitation on phyto PS', 'per day', TCphot_diatoms(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('TCphot_cocco ')
+ ! =====================================================================
+ ! Variable: TCphot_cocco
+ ! Description: Carbon-specific photosynthesis rate of coccolithophores
+ ! Function: Gross carbon fixation including calcification costs
+ ! Role: Lower than diatoms but sustained in stratified conditions
+ ! Context: Additional energy for CaCO3 formation reduces net efficiency
+ ! Units: per day (d⁻¹)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TCphot_cocco', 'Light limitation on phyto PS', 'per day', TCphot_cocco(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+CASE ('TCphot_phaeo ')
+ ! =====================================================================
+ ! Variable: TCphot_phaeo
+ ! Description: Carbon-specific photosynthesis rate of Phaeocystis
+ ! Function: Gross carbon fixation in colonial or solitary forms
+ ! Role: Efficient at low temperature and light
+ ! Context: Colonial forms may have lower per-cell rates but higher bloom biomass
+ ! Units: per day (d⁻¹)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TCphot_phaeo', 'Light limitation on phyto PS', 'per day', TCphot_phaeo(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+! =====================================================================
+! SILICATE ASSIMILATION
+! Description: Diatom-specific nutrient uptake
+! =====================================================================
+
+CASE ('TSi_assimDia ')
+ ! =====================================================================
+ ! Variable: TSi_assimDia
+ ! Description: Silicate assimilation rate by diatoms
+ ! Function: Uptake of Si(OH)4 for frustule (shell) construction
+ ! Role: Couples diatom growth to silicon cycle
+ ! Context: Si:C ratio varies 0.1-1.0 depending on species and conditions
+ ! Ecology: Si depletion terminates diatom blooms, shifts to flagellates
+ ! Units: per day (d⁻¹)
+ ! =====================================================================
+ if (use_REcoM) then
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), &
+ 'TSi_assimDia', 'Silicate assimilation', 'per day', TSi_assimDia(:,:), &
+ io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+#endif
CASE ('otracers ')
do j=3, tracers%num_tracers
write (id_string, "(I4.4)") tracers%data(j)%ID
#if defined(__recom)
+ ! =====================================================================
+ ! Base tracers (always present in all configurations)
+ ! Tracer IDs: 1001-1022 (indices 3-24)
+ ! =====================================================================
if (tracers%data(j)%ID==1001) then
if (use_REcoM) then
call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIN', 'Dissolved Inorganic Nitrogen', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+
+
+ if (tracers%data(j)%ltra_diag) then
+ ! horizontal advection
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIN_hor_adv', 'Horizontal advection part of dissolved Inorganic N', '[mmol/m3]', tracers%work%tra_advhoriz(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ ! horizontal advection LO
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIN_lo_hor_adv', 'LO Horizontal advection part of dissolved Inorganic N', '[mmol/m3]', tracers%work%tra_advhoriz_LO(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ ! vertical advection
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIN_ver_adv', 'Vertical advection part of dissolved Inorganic N', '[mmol/m3]', tracers%work%tra_advvert(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ ! vertical advection LO
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIN_lo_ver_adv', 'LO Vertical advection part of dissolved Inorganic N', '[mmol/m3]', tracers%work%tra_advvert_LO(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ ! horizontal diffusion
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIN_tra_diff_part_hor_redi', 'Horizontal diffusion of dissolved Inorganic N (includes Redi diffusivity if Redi=.true.)', '[mmol/m3]', tracers%work%tra_diff_part_hor_redi(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ if (tracers%data(j)%i_vert_diff) then
+ ! vertical diffusion (Explicit)
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIN_tra_diff_part_ver_expl', 'Vertical diffusion of dissolved Inorganic N (Explicit)', '[mmol/m3]', tracers%work%tra_diff_part_ver_expl(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+ ! projection of horizontal Redi diffussivity onto vertical
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIN_tra_diff_part_ver_redi_expl', 'Projection of horizontal Redi diffussivity onto vertical for dissolved Inorganic N (Explicit)', '[mmol/m3]', tracers%work%tra_diff_part_ver_redi_expl(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ ! vertical diffusion (Implicit)
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIN_tra_diff_part_ver_impl', 'Vertical diffusion of dissolved Inorganic N (Implicit)', '[mmol/m3]', tracers%work%tra_diff_part_ver_impl(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ ! recom_sms
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIN_recom_sms', 'Recom SMS', '[mmol/m3]', tracers%work%tra_recom_sms(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+
+
+
+
+
+
+
else if (tracers%data(j)%ID==1002) then
if (use_REcoM) then
call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIC', 'Dissolved Inorganic C', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ if (tracers%data(j)%ltra_diag) then
+ ! horizontal advection
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIC_hor_adv', 'Horizontal advection part of dissolved Inorganic C', '[mmol/m3]', tracers%work%tra_advhoriz(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ ! horizontal advection LO
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIC_lo_hor_adv', 'LO Horizontal advection part of dissolved Inorganic C', '[mmol/m3]', tracers%work%tra_advhoriz_LO(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ ! vertical advection
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIC_ver_adv', 'Vertical advection part of dissolved Inorganic C', '[mmol/m3]', tracers%work%tra_advvert(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ ! vertical advection LO
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIC_lo_ver_adv', 'LO Vertical advection part of dissolved Inorganic C', '[mmol/m3]', tracers%work%tra_advvert_LO(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ ! horizontal diffusion
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIC_tra_diff_part_hor_redi', 'Horizontal diffusion of dissolved Inorganic C (includes Redi diffusivity if Redi=.true.)', '[mmol/m3]', tracers%work%tra_diff_part_hor_redi(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ if (tracers%data(j)%i_vert_diff) then
+ ! vertical diffusion (Explicit)
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIC_tra_diff_part_ver_expl', 'Vertical diffusion of dissolved Inorganic C (Explicit)', '[mmol/m3]', tracers%work%tra_diff_part_ver_expl(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+ ! projection of horizontal Redi diffussivity onto vertical
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIC_tra_diff_part_ver_redi_expl', 'Projection of horizontal Redi diffussivity onto vertical for dissolved Inorganic C (Explicit)', '[mmol/m3]', tracers%work%tra_diff_part_ver_redi_expl(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ ! vertical diffusion (Implicit)
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIC_tra_diff_part_ver_impl', 'Vertical diffusion of dissolved Inorganic C (Implicit)', '[mmol/m3]', tracers%work%tra_diff_part_ver_impl(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ ! recom_sms
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DIC_recom_sms', 'Recom SMS', '[mmol/m3]', tracers%work%tra_recom_sms(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
endif
else if (tracers%data(j)%ID==1003) then
if (use_REcoM) then
call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Alk', 'Total Alkalinity', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+!!!!24.06.2025
+ if (tracers%data(j)%ltra_diag) then ! OG - tra_diag
+ ! horizontal advection
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Alk_hor_adv', 'Horizontal advection part of Total Alkalinity', '[mmol/m3]', tracers%work%tra_advhoriz(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ ! horizontal advection LO
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Alk_lo_hor_adv', 'LO Horizontal advection part of Total Alkalinity', '[mmol/m3]', tracers%work%tra_advhoriz_LO(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ ! vertical advection
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Alk_ver_adv', 'Vertical advection part of Total Alkalinity', '[mmol/m3]', tracers%work%tra_advvert(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ ! horizontal diffusion
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Alk_tra_diff_part_hor_redi', 'Horizontal diffusion of Total Alkalinity (includes Redi diffusivity if Redi=.true.)', '[mmol/m3]', tracers%work%tra_diff_part_hor_redi(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ if (.not. tracers%data(j)%i_vert_diff) then
+ ! vertical diffusion (Explicit)
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Alk_tra_diff_part_ver_expl', 'Vertical diffusion of Total Alkalinity (Explicit)', '[mmol/m3]', tracers%work%tra_diff_part_ver_expl(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+ ! projection of horizontal Redi diffussivity onto vertical
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Alk_tra_diff_part_ver_redi_expl', 'Projection of horizontal Redi diffussivity onto vertical for Total Alkalinity (Explicit)', '[mmol/m3]', tracers%work%tra_diff_part_ver_redi_expl(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ ! vertical diffusion (Implicit)
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Alk_tra_diff_part_ver_impl', 'Vertical diffusion of Total Alkalinity (Implicit)', '[mmol/m3]', tracers%work%tra_diff_part_ver_impl(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ ! recom_sms
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Alk_recom_sms', 'Recom SMS', '[mmol/m3]', tracers%work%tra_recom_sms(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ end if
endif
+ ! =====================================================================
+ ! Small phytoplankton
+ ! =====================================================================
else if (tracers%data(j)%ID==1004) then
if (use_REcoM) then
call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'PhyN', 'Intracellular conc of Nitrogen in small phytoplankton', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
@@ -830,6 +2724,9 @@ subroutine ini_mean_io(ice, dynamics, tracers, partit, mesh)
call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'PhyChl', 'Current intracellular ChlA conc.', '[mg/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+ ! =====================================================================
+ ! Detritus 1
+ ! =====================================================================
else if (tracers%data(j)%ID==1007) then
if (use_REcoM) then
call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DetN', 'Conc of N in Detritus', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
@@ -840,6 +2737,9 @@ subroutine ini_mean_io(ice, dynamics, tracers, partit, mesh)
call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DetC', 'Conc of C in Detritus', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+ ! =====================================================================
+ ! Mesozooplankton
+ ! =====================================================================
else if (tracers%data(j)%ID==1009) then
if (use_REcoM) then
call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'HetN', 'Conc of N in heterotrophs', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
@@ -850,6 +2750,9 @@ subroutine ini_mean_io(ice, dynamics, tracers, partit, mesh)
call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'HetC', 'Conc of C in heterotrophs', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+ ! =====================================================================
+ ! Dissolved organic matter
+ ! =====================================================================
else if (tracers%data(j)%ID==1011) then
if (use_REcoM) then
call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DON', 'Dissolved organic N in the water', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
@@ -860,6 +2763,10 @@ subroutine ini_mean_io(ice, dynamics, tracers, partit, mesh)
call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DOC', 'Dissolved Organic C in the water', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+ ! =====================================================================
+ ! Diatoms
+ ! =====================================================================
+
else if (tracers%data(j)%ID==1013) then
if (use_REcoM) then
call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DiaN', 'DiaN', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
@@ -880,6 +2787,10 @@ subroutine ini_mean_io(ice, dynamics, tracers, partit, mesh)
call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DiaSi', 'DiaSi', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+ ! =====================================================================
+ ! Detrital silica and other base tracers
+ ! =====================================================================
+
else if (tracers%data(j)%ID==1017) then
if (use_REcoM) then
call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DetSi', 'DetSi', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
@@ -890,6 +2801,43 @@ subroutine ini_mean_io(ice, dynamics, tracers, partit, mesh)
call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DSi', 'DSi', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+
+ if (tracers%data(j)%ltra_diag) then
+ ! horizontal advection
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DSi_hor_adv', 'Horizontal advection part of dissolved Silicic Acid', '[mmol/m3]', tracers%work%tra_advhoriz(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ ! horizontal advection LO
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DSi_lo_hor_adv', 'LO Horizontal advection part of dissolved Silicic Acid', '[mmol/m3]', tracers%work%tra_advhoriz_LO(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ ! vertical advection
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DSi_ver_adv', 'Vertical advection part of dissolved Silicic Acid', '[mmol/m3]', tracers%work%tra_advvert(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ ! vertical advection LO
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DSi_lo_ver_adv', 'LO Vertical advection part of dissolved Silicic Acid', '[mmol/m3]', tracers%work%tra_advvert_LO(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ ! horizontal diffusion
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DSi_tra_diff_part_hor_redi', 'Horizontal diffusion of dissolved Silicic Acid (includes Redi diffusivity if Redi=.true.)', '[mmol/m3]', tracers%work%tra_diff_part_hor_redi(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ if (tracers%data(j)%i_vert_diff) then
+ ! vertical diffusion (Explicit)
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DSi_tra_diff_part_ver_expl', 'Vertical diffusion of dissolved Silicic Acid (Explicit)', '[mmol/m3]', tracers%work%tra_diff_part_ver_expl(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+ ! projection of horizontal Redi diffussivity onto vertical
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DSi_tra_diff_part_ver_redi_expl', 'Projection of horizontal Redi diffussivity onto vertical for dissolved Silicic Acid (Explicit)', '[mmol/m3]', tracers%work%tra_diff_part_ver_redi_expl(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ ! vertical diffusion (Implicit)
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DSi_tra_diff_part_ver_impl', 'Vertical diffusion of dissolved Silicic Acid (Implicit)', '[mmol/m3]', tracers%work%tra_diff_part_ver_impl(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+
+ ! recom_sms
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DSi_recom_sms', 'Recom SMS', '[mmol/m3]', tracers%work%tra_recom_sms(:,:,j), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ end if
+
+
+
+
+
+
+
else if (tracers%data(j)%ID==1019) then
if (use_REcoM) then
call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DFe', 'DFe', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
@@ -910,60 +2858,247 @@ subroutine ini_mean_io(ice, dynamics, tracers, partit, mesh)
call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'O2', 'O2', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+ ! =====================================================================
+ ! CONFIGURATION-SPECIFIC TRACERS (IDs 1023+)
+ ! The meaning of these IDs changes based on model configuration!
+ ! =====================================================================
+
+ ! =====================================================================
+ ! Tracer ID 1023:
+ ! - In COCCOS-ONLY config: CoccoN (Coccolithophore Nitrogen)
+ ! - In 3ZOO2DET configs: Zoo2N (Macrozooplankton Nitrogen)
+ ! - In BASE config with rivers: DOCt (Terrestrial DOC)
+ ! =====================================================================
else if (tracers%data(j)%ID==1023) then
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Zoo2N', 'Intracellular conc of Nitrogen in second zooplankton', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ if (use_REcoM .and. enable_coccos .and. .not. enable_3zoo2det) then
+ ! Coccos-only configuration: This is Coccolithophore Nitrogen
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'CoccoN', 'Coccolithophore Nitrogen', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ else if (use_REcoM .and. enable_3zoo2det) then
+ ! 3zoo2det configurations: This is Macrozooplankton Nitrogen
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Zoo2N', 'Macrozooplankton Nitrogen', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ else if (use_REcoM .and. useRivers) then
+ ! Base configuration with rivers: This is Terrestrial DOC
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DOCt', 'Terrestrial Dissolved Organic Carbon', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+ !else if (tracers%data(j)%ID==1023) then
+ !if (use_REcoM .and. enable_3zoo2det) then
+ !call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Zoo2N', 'Intracellular conc of Nitrogen in second zooplankton', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ !endif
+
+ ! =====================================================================
+ ! Tracer ID 1024:
+ ! - In COCCOS-ONLY config: CoccoC (Coccolithophore Carbon)
+ ! - In 3ZOO2DET configs: Zoo2C (Macrozooplankton Carbon)
+ ! =====================================================================
else if (tracers%data(j)%ID==1024) then
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Zoo2C', 'Intracellular conc of Carbon in second zooplankton', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ if (use_REcoM .and. enable_coccos .and. .not. enable_3zoo2det) then
+ ! Coccos-only configuration: This is Coccolithophore Carbon
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'CoccoC', 'Coccolithophore Carbon', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ else if (use_REcoM .and. enable_3zoo2det) then
+ ! 3zoo2det configurations: This is Macrozooplankton Carbon
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Zoo2C', 'Macrozooplankton Carbon', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+ !else if (tracers%data(j)%ID==1024) then
+ !if (use_REcoM .and. enable_3zoo2det) then
+ !call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Zoo2C', 'Intracellular conc of Carbon in second zooplankton', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ !endif
+
+ ! =====================================================================
+ ! Tracer ID 1025:
+ ! - In COCCOS-ONLY config: CoccoChl (Coccolithophore Chlorophyll)
+ ! - In 3ZOO2DET configs: Det2N (Second detritus pool Nitrogen)
+ ! =====================================================================
+
else if (tracers%data(j)%ID==1025) then
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'idetz2n', 'idetz2n', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ if (use_REcoM .and. enable_coccos .and. .not. enable_3zoo2det) then
+ ! Coccos-only configuration: This is Coccolithophore Chlorophyll
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'CoccoChl', 'Coccolithophore Chlorophyll', '[mg/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ else if (use_REcoM .and. enable_3zoo2det) then
+ ! 3zoo2det configurations: This is second detritus pool Nitrogen
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Det2N', 'Conc of N in second detritus pool', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+ !else if (tracers%data(j)%ID==1025) then
+ !if (use_REcoM .and. enable_3zoo2det) then
+ !call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'idetz2n', 'idetz2n', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ !endif
+
+ ! =====================================================================
+ ! Tracer ID 1026:
+ ! - In COCCOS-ONLY config: PhaeoN (Phaeocystis Nitrogen)
+ ! - In 3ZOO2DET configs: Det2C (Second detritus pool Carbon)
+ ! =====================================================================
else if (tracers%data(j)%ID==1026) then
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'idetz2c', 'idetz2c', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ if (use_REcoM .and. enable_coccos .and. .not. enable_3zoo2det) then
+ ! Coccos-only configuration: This is Phaeocystis Nitrogen
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'PhaeoN', 'Phaeocystis Nitrogen', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ else if (use_REcoM .and. enable_3zoo2det) then
+ ! 3zoo2det configurations: This is second detritus pool Carbon
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Det2C', 'Conc of C in second detritus pool', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+ !else if (tracers%data(j)%ID==1026) then
+ !if (use_REcoM .and. enable_3zoo2det) then
+ !call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'idetz2c', 'idetz2c', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ !endif
+
+ ! =====================================================================
+ ! Tracer ID 1027:
+ ! - In COCCOS-ONLY config: PhaeoC (Phaeocystis Carbon)
+ ! - In 3ZOO2DET configs: Det2Si (Second detritus pool Silica)
+ ! =====================================================================
else if (tracers%data(j)%ID==1027) then
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'idetz2si', 'idetz2si', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ if (use_REcoM .and. enable_coccos .and. .not. enable_3zoo2det) then
+ ! Coccos-only configuration: This is Phaeocystis Carbon
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'PhaeoC', 'Phaeocystis Carbon', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ else if (use_REcoM .and. enable_3zoo2det) then
+ ! 3zoo2det configurations: This is second detritus pool Silica
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Det2Si', 'Conc of Si in second detritus pool', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+ !else if (tracers%data(j)%ID==1027) then
+ !if (use_REcoM .and. enable_3zoo2det) then
+ !call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'idetz2si', 'idetz2si', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ !endif
+
+ ! =====================================================================
+ ! Tracer ID 1028:
+ ! - In COCCOS-ONLY config: PhaeoChl (Phaeocystis Chlorophyll)
+ ! - In 3ZOO2DET configs: Det2Calc (Second detritus pool Calcium)
+ ! =====================================================================
else if (tracers%data(j)%ID==1028) then
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'idetz2calc', 'idetz2calc', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ if (use_REcoM .and. enable_coccos .and. .not. enable_3zoo2det) then
+ ! Coccos-only configuration: This is Phaeocystis Chlorophyll
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'PhaeoChl', 'Phaeocystis Chlorophyll', '[mg/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ else if (use_REcoM .and. enable_3zoo2det) then
+ ! 3zoo2det configurations: This is second detritus pool Calcium
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Det2Calc', 'Conc of Calc in second detritus pool', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+ !else if (tracers%data(j)%ID==1028) then
+ !if (use_REcoM .and. enable_3zoo2det) then
+ !call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'idetz2calc', 'idetz2calc', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ !endif
+
+ ! =====================================================================
+ ! Tracer ID 1029:
+ ! - In COCCOS-ONLY config with rivers: DOCt (Terrestrial DOC)
+ ! - In 3ZOO2DET-ONLY config: Zoo3N (Microzooplankton Nitrogen)
+ ! - In FULL model config: CoccoN (Coccolithophore Nitrogen)
+ ! =====================================================================
else if (tracers%data(j)%ID==1029) then
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'CoccoN', 'CoccoN', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ if (use_REcoM .and. enable_coccos .and. enable_3zoo2det) then
+ ! Full model: This is Coccolithophore Nitrogen
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'CoccoN', 'Coccolithophore Nitrogen', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ else if (use_REcoM .and. enable_3zoo2det .and. .not. enable_coccos) then
+ ! 3zoo2det-only configuration: This is Microzooplankton Nitrogen
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Zoo3N', 'Microzooplankton Nitrogen', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ else if (use_REcoM .and. enable_coccos .and. .not. enable_3zoo2det .and. useRivers) then
+ ! Coccos-only configuration with rivers: This is Terrestrial DOC
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DOCt', 'Terrestrial Dissolved Organic Carbon', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+ !else if (tracers%data(j)%ID==1029) then
+ !if (use_REcoM .and. enable_coccos) then
+ !call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'CoccoN', 'CoccoN', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ !endif
+
+ ! =====================================================================
+ ! Tracer ID 1030:
+ ! - In 3ZOO2DET-ONLY config: Zoo3C (Microzooplankton Carbon)
+ ! - In FULL model config: CoccoC (Coccolithophore Carbon)
+ ! =====================================================================
else if (tracers%data(j)%ID==1030) then
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'CoccoC', 'CoccoC', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ if (use_REcoM .and. enable_coccos .and. enable_3zoo2det) then
+ ! Full model: This is Coccolithophore Carbon
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'CoccoC', 'Coccolithophore Carbon', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ else if (use_REcoM .and. enable_3zoo2det .and. .not. enable_coccos) then
+ ! 3zoo2det-only configuration: This is Microzooplankton Carbon
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Zoo3C', 'Microzooplankton Carbon', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+ !else if (tracers%data(j)%ID==1030) then
+ !if (use_REcoM .and. enable_coccos) then
+ !call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'CoccoC', 'CoccoC', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ !endif
+
+ ! =====================================================================
+ ! Tracer ID 1031:
+ ! - In 3ZOO2DET-ONLY config with rivers: DOCt (Terrestrial DOC)
+ ! - In FULL model config: CoccoChl (Coccolithophore Chlorophyll)
+ ! =====================================================================
else if (tracers%data(j)%ID==1031) then
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'CoccoChl', 'CoccoChl', '[mg/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ if (use_REcoM .and. enable_coccos .and. enable_3zoo2det) then
+ ! Full model: This is Coccolithophore Chlorophyll
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'CoccoChl', 'Coccolithophore Chlorophyll', '[mg/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ else if (use_REcoM .and. enable_3zoo2det .and. .not. enable_coccos .and. useRivers) then
+ ! 3zoo2det-only configuration with rivers: This is Terrestrial DOC
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DOCt', 'Terrestrial Dissolved Organic Carbon', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+ !else if (tracers%data(j)%ID==1031) then
+ !if (use_REcoM .and. enable_coccos) then
+ !call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'CoccoChl', 'CoccoChl', '[mg/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ !endif
+
+ ! =====================================================================
+ ! Tracer IDs 1032-1034: Only in FULL model configuration
+ ! These are Phaeocystis tracers
+ ! =====================================================================
else if (tracers%data(j)%ID==1032) then
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Zoo3N', 'Zoo3N', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ if (use_REcoM .and. enable_coccos .and. enable_3zoo2det) then
+ ! Full model: This is Phaeocystis Nitrogen
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'PhaeoN', 'Phaeocystis Nitrogen', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+ !else if (tracers%data(j)%ID==1032) then
+ !if (use_REcoM) then
+ !call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Zoo3N', 'Zoo3N', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ !endif
+
else if (tracers%data(j)%ID==1033) then
- if (use_REcoM) then
- call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Zoo3C', 'Zoo3C', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ if (use_REcoM .and. enable_coccos .and. enable_3zoo2det) then
+ ! Full model: This is Phaeocystis Carbon
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'PhaeoC', 'Phaeocystis Carbon', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+ !else if (tracers%data(j)%ID==1033) then
+ !if (use_REcoM) then
+ !call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Zoo3C', 'Zoo3C', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ !endif
+
+ else if (tracers%data(j)%ID==1034) then
+ if (use_REcoM .and. enable_coccos .and. enable_3zoo2det) then
+ ! Full model: This is Phaeocystis Chlorophyll
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'PhaeoChl', 'Phaeocystis Chlorophyll', '[mg/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
endif
+
+ ! =====================================================================
+ ! Tracer IDs 1035-1036: Only in FULL model configuration
+ ! These are Microzooplankton tracers
+ ! =====================================================================
+ else if (tracers%data(j)%ID==1035) then
+ if (use_REcoM .and. enable_coccos .and. enable_3zoo2det) then
+ ! Full model: This is Microzooplankton Nitrogen
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Zoo3N', 'Microzooplankton Nitrogen', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+
+ else if (tracers%data(j)%ID==1036) then
+ if (use_REcoM .and. enable_coccos .and. enable_3zoo2det) then
+ ! Full model: This is Microzooplankton Carbon
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'Zoo3C', 'Microzooplankton Carbon', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
+ ! =====================================================================
+ ! Tracer ID 1037: Only in FULL model configuration with rivers
+ ! This is Terrestrial DOC
+ ! =====================================================================
+ else if (tracers%data(j)%ID==1037) then
+ if (use_REcoM .and. enable_coccos .and. enable_3zoo2det .and. useRivers) then
+ ! Full model with rivers: This is Terrestrial DOC
+ call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'DOCt', 'Terrestrial Dissolved Organic Carbon', '[mmol/m3]', tracers%data(j)%values(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh)
+ endif
else
#endif
diff --git a/src/io_restart_file_group.F90 b/src/io_restart_file_group.F90
index 31c9263f5..78a24ff42 100644
--- a/src/io_restart_file_group.F90
+++ b/src/io_restart_file_group.F90
@@ -17,7 +17,7 @@ module restart_file_group_module
type restart_file_group
private
- type(restart_file_type), public :: files(112)
+ type(restart_file_type), public :: files(200) ! was (112) before OG
integer, public :: nfiles = 0 ! todo: allow dynamically allocated size without messing with shallow copied pointers
contains
diff --git a/src/oce_adv_tra_driver.F90 b/src/oce_adv_tra_driver.F90
index 9b9606ea8..482bc2e8e 100644
--- a/src/oce_adv_tra_driver.F90
+++ b/src/oce_adv_tra_driver.F90
@@ -22,14 +22,17 @@ end module oce_adv_tra_driver_interfaces
module oce_tra_adv_flux2dtracer_interface
interface
- subroutine oce_tra_adv_flux2dtracer(dt, dttf_h, dttf_v, flux_h, flux_v, partit, mesh, use_lo, ttf, lo)
+ subroutine oce_tra_adv_flux2dtracer(dt, dttf_h, dttf_v, flux_h, flux_v, partit, mesh, use_lo, ttf, lo, tr_num, tracers)
!update the solution for vertical and horizontal flux contributions
use MOD_MESH
+ use MOD_TRACER
USE MOD_PARTIT
USE MOD_PARSUP
real(kind=WP), intent(in), target :: dt
+ integer, intent(in) :: tr_num
type(t_partit),intent(inout), target :: partit
type(t_mesh), intent(in), target :: mesh
+ type(t_tracer), intent(inout), target :: tracers
real(kind=WP), intent(inout) :: dttf_h(mesh%nl-1, partit%myDim_nod2D+partit%eDim_nod2D)
real(kind=WP), intent(inout) :: dttf_v(mesh%nl-1, partit%myDim_nod2D+partit%eDim_nod2D)
real(kind=WP), intent(inout) :: flux_h(mesh%nl-1, partit%myDim_edge2D)
@@ -209,6 +212,27 @@ subroutine do_oce_adv_tra(dt, vel, w, wi, we, tr_num, dynamics, tracers, partit,
#endif
#endif
+
+! O:G - tra_diag
+! LO solution
+! fct_LO is zero before adv_flux_hor
+! Up to now only horizontal
+! contribution
+
+
+!#if defined (__recom)
+ if (tracers%data(tr_num)%ltra_diag) then
+ do n=1, myDim_nod2D+eDim_nod2D
+ nu1 = ulevels_nod2D(n)
+ nl1 = nlevels_nod2D(n)
+ do nz = nu1, nl1-1
+ ! Horizontal advection part for LO (FCT is .TRUE.)
+ tracers%work%tra_advhoriz_LO(nz,n,tr_num) = fct_LO(nz,n) * dt/areasvol(nz,n)/hnode_new(nz,n)
+ end do
+ end do
+ end if
+!#endif
+
! compute the low order upwind vertical flux (explicit part only)
! zero the input/output flux before computation
call adv_tra_ver_upw1(we, ttf, partit, mesh, adv_flux_ver, o_init_zero=.true.)
@@ -277,6 +301,24 @@ subroutine do_oce_adv_tra(dt, vel, w, wi, we, tr_num, dynamics, tracers, partit,
end if
+! O:G - tra_diag
+! LO solution
+! fct_LO is zero before adv_flux_ver
+! vertical contribution
+
+!#if defined (__recom)
+ if (tracers%data(tr_num)%ltra_diag) then
+ do n=1, myDim_nod2D+eDim_nod2D
+ nu1 = ulevels_nod2D(n)
+ nl1 = nlevels_nod2D(n)
+ do nz = nu1, nl1-1
+ ! Vertical advection part for LO (FCT is .TRUE.)
+ tracers%work%tra_advvert_LO (nz,n,tr_num) = (adv_flux_ver(nz, n)-adv_flux_ver(nz+1, n))*dt/areasvol(nz,n)/hnode_new(nz,n)
+ end do
+ end do
+ end if
+!#endif
+
!_______________________________________________________________________
if (dynamics%use_wsplit) then !wvel/=wvel_e
@@ -301,7 +343,7 @@ subroutine do_oce_adv_tra(dt, vel, w, wi, we, tr_num, dynamics, tracers, partit,
! do horizontal tracer advection, in case of FCT high order solution
SELECT CASE(trim(tracers%data(tr_num)%tra_adv_hor))
CASE('MUSCL')
- ! compute the untidiffusive horizontal flux (o_init_zero=.false.: input is the LO horizontal flux computed above)
+ ! compute the antidiffusive horizontal flux (o_init_zero=.false.: input is the LO horizontal flux computed above)
call adv_tra_hor_muscl(vel, ttfAB, partit, mesh, opth, adv_flux_hor, edge_up_dn_grad, nboundary_lay, o_init_zero=do_zero_flux)
CASE('MFCT')
call adv_tra_hor_mfct(vel, ttfAB, partit, mesh, opth, adv_flux_hor, edge_up_dn_grad, o_init_zero=do_zero_flux)
@@ -341,9 +383,9 @@ subroutine do_oce_adv_tra(dt, vel, w, wi, we, tr_num, dynamics, tracers, partit,
if (trim(tracers%data(tr_num)%tra_adv_lim)=='FCT') then
!edge_up_dn_grad will be used as an auxuary array here
call oce_tra_adv_fct(dt, ttf, fct_LO, adv_flux_hor, adv_flux_ver, fct_ttf_min, fct_ttf_max, fct_plus, fct_minus, edge_up_dn_grad, partit, mesh)
- call oce_tra_adv_flux2dtracer(dt, dttf_h, dttf_v, adv_flux_hor, adv_flux_ver, partit, mesh, use_lo=.TRUE., ttf=ttf, lo=fct_LO)
+ call oce_tra_adv_flux2dtracer(dt, dttf_h, dttf_v, adv_flux_hor, adv_flux_ver, partit, mesh, use_lo=.TRUE., ttf=ttf, lo=fct_LO, tr_num=tr_num, tracers=tracers)
else
- call oce_tra_adv_flux2dtracer(dt, dttf_h, dttf_v, adv_flux_hor, adv_flux_ver, partit, mesh)
+ call oce_tra_adv_flux2dtracer(dt, dttf_h, dttf_v, adv_flux_hor, adv_flux_ver, partit, mesh,tr_num=tr_num, tracers=tracers)
end if
!___________________________________________________________________________
@@ -416,12 +458,14 @@ subroutine do_oce_adv_tra(dt, vel, w, wi, we, tr_num, dynamics, tracers, partit,
end if
end if !-->if ((ldiag_DVD) .and. (tr_num<=2)) then
+
end subroutine do_oce_adv_tra
!
!
!===============================================================================
-subroutine oce_tra_adv_flux2dtracer(dt, dttf_h, dttf_v, flux_h, flux_v, partit, mesh, use_lo, ttf, lo)
+subroutine oce_tra_adv_flux2dtracer(dt, dttf_h, dttf_v, flux_h, flux_v, partit, mesh, use_lo, ttf, lo,tr_num, tracers)
use MOD_MESH
+ use MOD_TRACER
use o_ARRAYS
USE MOD_PARTIT
USE MOD_PARSUP
@@ -430,6 +474,8 @@ subroutine oce_tra_adv_flux2dtracer(dt, dttf_h, dttf_v, flux_h, flux_v, partit,
real(kind=WP), intent(in), target :: dt
type(t_partit),intent(inout), target :: partit
type(t_mesh), intent(in), target :: mesh
+ integer, intent(in) :: tr_num !RP
+ type(t_tracer), intent(inout), target :: tracers !RP
real(kind=WP), intent(inout) :: dttf_h(mesh%nl-1, partit%myDim_nod2D+partit%eDim_nod2D)
real(kind=WP), intent(inout) :: dttf_v(mesh%nl-1, partit%myDim_nod2D+partit%eDim_nod2D)
real(kind=WP), intent(inout) :: flux_h(mesh%nl-1, partit%myDim_edge2D)
@@ -486,6 +532,17 @@ subroutine oce_tra_adv_flux2dtracer(dt, dttf_h, dttf_v, flux_h, flux_v, partit,
end do
!$ACC END LOOP
end do
+#if defined (__recom)
+ if (tracers%data(tr_num)%ltra_diag) then
+ do n=1, myDim_nod2d
+ nu1 = ulevels_nod2D(n)
+ nl1 = nlevels_nod2D(n)
+ do nz=nu1,nl1-1
+ tracers%work%tra_advvert(nz,n,tr_num) = dttf_v(nz,n)
+ end do
+ end do
+ end if
+#endif
#ifndef ENABLE_OPENACC
!$OMP END DO
#else
@@ -548,6 +605,18 @@ subroutine oce_tra_adv_flux2dtracer(dt, dttf_h, dttf_v, flux_h, flux_v, partit,
#endif
dttf_h(nz,enodes(2))=dttf_h(nz,enodes(2))-flux_h(nz,edge)*dt/areasvol(nz,enodes(2))
end do
+#if defined (__recom)
+ if (tracers%data(tr_num)%ltra_diag) then
+ do n=1, myDim_nod2d
+ nu1 = ulevels_nod2D(n)
+ nl1 = nlevels_nod2D(n)
+ do nz=nu1,nl1-1
+ tracers%work%tra_advhoriz(nz,n,tr_num) = dttf_h(nz,n)
+ end do
+ end do
+ end if
+#endif
+
#ifndef ENABLE_OPENACC
#if defined(_OPENMP) && !defined(__openmp_reproducible)
call omp_unset_lock(partit%plock(enodes(2)))
diff --git a/src/oce_ale_tracer.F90 b/src/oce_ale_tracer.F90
index dd4ce9101..513212ae4 100644
--- a/src/oce_ale_tracer.F90
+++ b/src/oce_ale_tracer.F90
@@ -165,6 +165,9 @@ subroutine solve_tracers_ale(ice, dynamics, tracers, partit, mesh)
type(t_mesh) , intent(in) , target :: mesh
!___________________________________________________________________________
integer :: i, tr_num, node, elem, nzmax, nzmin
+ real(kind=WP) :: ttf_rhs_bak (mesh%nl-1, partit%myDim_nod2D+partit%eDim_elem2D) ! local variable
+ real(kind=WP) :: ttf_rhs_bak_tend (mesh%nl-1, partit%myDim_nod2D+partit%eDim_nod2D)
+ integer :: nz, n, nu1, nl1
!___________________________________________________________________________
! pointer on necessary derived types
real(kind=WP), dimension(:,:,:), pointer :: UV, fer_UV
@@ -190,7 +193,7 @@ subroutine solve_tracers_ale(ice, dynamics, tracers, partit, mesh)
call cal_rejected_salt(ice, partit, mesh)
if (flag_debug .and. mype==0) print *, achar(27)//'[37m'//' --> call app_rejected_salt'//achar(27)//'[0m'
call app_rejected_salt(tracers%data(2)%values, partit, mesh)
- end if
+ end if
!___________________________________________________________________________
! update 3D velocities with the bolus velocities:
@@ -210,6 +213,15 @@ subroutine solve_tracers_ale(ice, dynamics, tracers, partit, mesh)
!$OMP END PARALLEL DO
end if
+ ! Set advective and diffusive components of total tracer fluxes to zero
+ ! Before tr_num loop
+!#if defined (__recom) ! not necessarily should belong to recom case
+! tracers%work%tra_advhoriz = 0.0 ! O:G - tra_diag
+! tracers%work%tra_advvert = 0.0
+ ttf_rhs_bak = 0.0
+ ttf_rhs_bak_tend = 0.0
+!#endif
+
!___________________________________________________________________________
! loop over all tracers
!$ACC UPDATE DEVICE(dynamics%w, dynamics%w_e, dynamics%uv) !!! async(1)
@@ -217,13 +229,34 @@ subroutine solve_tracers_ale(ice, dynamics, tracers, partit, mesh)
!$ACC UPDATE DEVICE (mesh%helem, mesh%hnode, mesh%hnode_new, mesh%zbar_3d_n, mesh%z_3d_n)
do tr_num=1, tracers%num_tracers
+#if defined(__recom)
+!YY: sinkflx needs to be reset at each time step
+ if(use_MEDUSA) then
+ SinkFlx = 0.0d0
+ endif
+ SinkingVel1 = 0.0d0
+ SinkingVel2 = 0.0d0
+#endif
! do tracer AB (Adams-Bashfort) interpolation only for advectiv part
! needed
if (flag_debug .and. mype==0) print *, achar(27)//'[37m'//' --> call init_tracers_AB'//achar(27)//'[0m'
call init_tracers_AB(tr_num, tracers, partit, mesh)
-
+
! advect tracers
if (flag_debug .and. mype==0) print *, achar(27)//'[37m'//' --> call adv_tracers_ale'//achar(27)//'[0m'
+
+ !============================================================
+
+ if (tracers%data(tr_num)%ltra_diag) then ! OG - tra_diag
+ do n=1, myDim_nod2D+eDim_nod2D
+ nu1 = ulevels_nod2D(n)
+ nl1 = nlevels_nod2D(n)
+ do nz = nu1, nl1-1
+ ttf_rhs_bak_tend(nz,n) = tracers%data(tr_num)%values(nz,n)
+ end do
+ end do
+ end if
+ !============================================================
!here update only those initialized in the init_tracers. (values, valuesAB, edge_up_dn_grad, ...)
!!$ACC UPDATE DEVICE(tracers%data(tr_num)%values, tracers%data(tr_num)%valuesAB, tracers%data(tr_num)%valuesold)
!$ACC UPDATE DEVICE(tracers%work%edge_up_dn_grad) !!&
@@ -246,6 +279,7 @@ subroutine solve_tracers_ale(ice, dynamics, tracers, partit, mesh)
if (flag_debug .and. mype==0) print *, achar(27)//'[37m'//' --> call diff_tracers_ale'//achar(27)//'[0m'
call diff_tracers_ale(tr_num, dynamics, tracers, ice, partit, mesh)
+ !___________________________________________________________________________
! Radioactive decay of 14C and 39Ar
if (tracers%data(tr_num)%ID == 14) tracers%data(tr_num)%values(:,:) = tracers%data(tr_num)%values(:,:) * exp(-decay14 * dt)
if (tracers%data(tr_num)%ID == 39) tracers%data(tr_num)%values(:,:) = tracers%data(tr_num)%values(:,:) * exp(-decay39 * dt)
@@ -254,7 +288,7 @@ subroutine solve_tracers_ale(ice, dynamics, tracers, partit, mesh)
! relax to salt and temp climatology
if (flag_debug .and. mype==0) print *, achar(27)//'[37m'//' --> call relax_to_clim'//achar(27)//'[0m'
! if ((toy_ocean) .AND. ((tr_num==1) .AND. (TRIM(which_toy)=="soufflet"))) then
- if ((toy_ocean) .AND. ((TRIM(which_toy)=="soufflet"))) then
+ if ((toy_ocean) .AND. ((TRIM(which_toy)=="soufflet"))) then
call relax_zonal_temp(tracers%data(1), partit, mesh)
elseif ((toy_ocean) .AND. ((TRIM(which_toy)=="neverworld2"))) then
@@ -272,6 +306,17 @@ subroutine solve_tracers_ale(ice, dynamics, tracers, partit, mesh)
!!! !$ACC UPDATE HOST (tracers%work%fct_ttf_min, tracers%work%fct_ttf_max, tracers%work%fct_plus, tracers%work%fct_minus) &
!!! !$ACC HOST (tracers%work%edge_up_dn_grad)
+#if defined(__recom)
+ do tr_num = 1, tracers%num_tracers
+ if (use_MEDUSA) then
+ SinkFlx = SinkFlx + SinkFlx_tr(:, :, tr_num)
+ endif
+! Benthos = Benthos + Benthos_tr(:, :, tr_num)
+ Sinkingvel1(:,:) = Sinkingvel1(:,:) + Sinkvel1_tr(:, :, tr_num)
+ Sinkingvel2(:,:) = Sinkingvel2(:,:) + Sinkvel2_tr(:, :, tr_num)
+ end do
+#endif
+
!___________________________________________________________________________
! 3D restoring for "passive" tracers
!!!$OMPTODO: add OpenMP later, not needed right now!
@@ -349,6 +394,7 @@ subroutine diff_tracers_ale(tr_num, dynamics, tracers, ice, partit, mesh)
use ver_sinking_recom_interface
use diff_ver_recom_expl_interface
use ver_sinking_recom_benthos_interface
+ use recom_nitrogenss_interface
use recom_glovar
use recom_config
use g_comm_auto
@@ -364,6 +410,8 @@ subroutine diff_tracers_ale(tr_num, dynamics, tracers, ice, partit, mesh)
type(t_mesh) , intent(in) , target :: mesh
!___________________________________________________________________________
integer :: n, nzmax, nzmin
+ real(kind=WP) :: ttf_rhs_bak (mesh%nl-1, partit%myDim_nod2D+partit%eDim_nod2D)
+ integer :: nz, nu1, nl1
!___________________________________________________________________________
! pointer on necessary derived types
real(kind=WP), pointer :: del_ttf(:,:)
@@ -378,21 +426,90 @@ subroutine diff_tracers_ale(tr_num, dynamics, tracers, ice, partit, mesh)
vert_sink = 0.0_WP
#endif
+ ttf_rhs_bak = 0.0
+
+ if (tracers%data(tr_num)%ltra_diag) then
+ do n=1, myDim_nod2D+eDim_nod2D
+ nu1 = ulevels_nod2D(n)
+ nl1 = nlevels_nod2D(n)
+ do nz = nu1, nl1-1
+ ttf_rhs_bak(nz,n) = del_ttf(nz,n)
+ end do
+ end do
+ end if
!___________________________________________________________________________
- ! do horizontal diffusiion
+ ! do horizontal diffusion
! write there also horizontal diffusion rhs to del_ttf which is equal the R_T^n
! in danilovs srcipt
! includes Redi diffusivity if Redi=.true.
call diff_part_hor_redi(tracers, partit, mesh) ! seems to be ~9% faster than diff_part_hor
-
+
+ if (tracers%data(tr_num)%ltra_diag) then
+ do n=1, myDim_nod2D+eDim_nod2D
+ nu1 = ulevels_nod2D(n)
+ nl1 = nlevels_nod2D(n)
+ do nz = nu1, nl1-1
+ ! horizontal diffusion (w/out Redi)
+ tracers%work%tra_diff_part_hor_redi(nz,n,tr_num) = (del_ttf(nz,n) - ttf_rhs_bak(nz,n)) ! Unit [Conc]
+ !if (mype==0) print *, tracers%work%tra_diff_part_hor_redi(nz,n,tr_num)
+ end do
+ end do
+ end if
+
+ if ((.not. tracers%data(tr_num)%i_vert_diff) .and. tracers%data(tr_num)%ltra_diag) then
+ do n=1, myDim_nod2D+eDim_nod2D
+ nu1 = ulevels_nod2D(n)
+ nl1 = nlevels_nod2D(n)
+ do nz = nu1, nl1-1
+ ttf_rhs_bak(nz,n) = del_ttf(nz,n)
+ end do
+ end do
+ end if
!___________________________________________________________________________
! do vertical diffusion: explicit
if (.not. tracers%data(tr_num)%i_vert_diff) call diff_ver_part_expl_ale(tr_num, tracers, partit, mesh)
-
+
+ ! OG i_vert_diff = TRUE so, we dont call explicit scheme
+ ! If we use this, check surface forcing for recom variables (They are not updated)
+ if ((.not. tracers%data(tr_num)%i_vert_diff) .and. tracers%data(tr_num)%ltra_diag) then
+ do n=1, myDim_nod2D+eDim_nod2D
+ nu1 = ulevels_nod2D(n)
+ nl1 = nlevels_nod2D(n)
+ do nz = nu1, nl1-1
+ ! vertical diffusion: explicit
+ tracers%work%tra_diff_part_ver_expl(nz,n,tr_num) = (del_ttf(nz,n) - ttf_rhs_bak(nz,n)) ! Unit [Conc]
+ !if (mype==0) print *, tra_diff_part_ver_expl(:,:,tr_num)
+ end do
+ end do
+ end if
+
! A projection of horizontal Redi diffussivity onto vertical. This par contains horizontal
! derivatives and has to be computed explicitly!
+
+ if (tracers%data(tr_num)%ltra_diag .and. Redi) then
+ do n=1, myDim_nod2D+eDim_nod2D
+ nu1 = ulevels_nod2D(n)
+ nl1 = nlevels_nod2D(n)
+ do nz = nu1, nl1-1
+ ttf_rhs_bak(nz,n) = del_ttf(nz,n)
+ end do
+ end do
+ end if
+
if (Redi) call diff_ver_part_redi_expl(tracers, partit, mesh)
+ if (tracers%data(tr_num)%ltra_diag .and. Redi) then
+ do n=1, myDim_nod2D+eDim_nod2D
+ nu1 = ulevels_nod2D(n)
+ nl1 = nlevels_nod2D(n)
+ do nz = nu1, nl1-1
+ ! Redi diffussivity onto vertical: explicit
+ tracers%work%tra_diff_part_ver_redi_expl(nz,n,tr_num) = (del_ttf(nz,n) - ttf_rhs_bak(nz,n)) ! Unit [Conc]
+ !if (mype==0) print *, tra_diff_part_ver_redi_expl(:,:,tr_num)
+ end do
+ end do
+ end if
+
! if (recom_debug .and. mype==0) print *, tracers%data(tr_num)%ID
#if defined(__recom)
@@ -404,14 +521,43 @@ subroutine diff_tracers_ale(tr_num, dynamics, tracers, ice, partit, mesh)
! call bottom boundary
call diff_ver_recom_expl(tr_num, tracers, partit, mesh)
+! print*, 'Calling diff_ver_recom_expl and tr_num is:',tracers%data(tr_num)%ID
+ SELECT CASE (tracers%data(tr_num)%ID)
+ CASE (1001) ! DIN
+ dtr_bflux_din(:,:) = 0.0d0 !tracers%data(tr_num)%values(:,:)*0.0d0
+ CASE (1002) ! DIC
+ dtr_bflux_dic(:,:) = 0.0d0 !tracers%data(tr_num)%values(:,:)*0.0d0
+ CASE (1003) ! Alk
+ dtr_bflux_alk(:,:) = 0.0d0 !tracers%data(tr_num)%values(:,:)*0.0d0
+ CASE (1018) ! DSi
+ dtr_bflux_dsi(:,:) = 0.0d0 !tracers%data(tr_num)%values(:,:)*0.0d0
+ END SELECT
! update tracer fields
do n=1, myDim_nod2D
nzmax=nlevels_nod2D(n)-1
nzmin=ulevels_nod2D(n)
-! tr_arr(nzmin:nzmax,n,tr_num)=tr_arr(nzmin:nzmax,n,tr_num)+ &
-! dtr_bf(nzmin:nzmax,n)
- tracers%data(tr_num)%values(nzmin:nzmax,n)=tracers%data(tr_num)%values(nzmin:nzmax,n)+ &
+ SELECT CASE (tracers%data(tr_num)%ID)
+ CASE (1001) ! DIN
+ tracers%data(tr_num)%values(nzmin:nzmax,n)=tracers%data(tr_num)%values(nzmin:nzmax,n)+ &
+ dtr_bf(nzmin:nzmax,n)
+ dtr_bflux_din(nzmin:nzmax,n) = dtr_bflux_din(nzmin:nzmax,n) + dtr_bf(nzmin:nzmax,n)
+ CASE (1002) ! DIC
+ tracers%data(tr_num)%values(nzmin:nzmax,n)=tracers%data(tr_num)%values(nzmin:nzmax,n)+ &
+ dtr_bf(nzmin:nzmax,n)
+ dtr_bflux_dic(nzmin:nzmax,n) = dtr_bflux_dic(nzmin:nzmax,n) + dtr_bf(nzmin:nzmax,n)
+ CASE (1003) ! Alk
+ tracers%data(tr_num)%values(nzmin:nzmax,n)=tracers%data(tr_num)%values(nzmin:nzmax,n)+ &
dtr_bf(nzmin:nzmax,n)
+ dtr_bflux_alk(nzmin:nzmax,n) = dtr_bflux_alk(nzmin:nzmax,n) + dtr_bf(nzmin:nzmax,n)
+ CASE (1018) ! DSi
+ tracers%data(tr_num)%values(nzmin:nzmax,n)=tracers%data(tr_num)%values(nzmin:nzmax,n)+ &
+ dtr_bf(nzmin:nzmax,n)
+ dtr_bflux_dsi(nzmin:nzmax,n) = dtr_bflux_dsi(nzmin:nzmax,n) + dtr_bf(nzmin:nzmax,n)
+
+ CASE DEFAULT
+ tracers%data(tr_num)%values(nzmin:nzmax,n)=tracers%data(tr_num)%values(nzmin:nzmax,n)+ &
+ dtr_bf(nzmin:nzmax,n)
+ END SELECT
end do
end if
@@ -443,7 +589,7 @@ subroutine diff_tracers_ale(tr_num, dynamics, tracers, ice, partit, mesh)
call ver_sinking_recom_benthos(tr_num, tracers, partit, mesh) !--- str_bf ---
! update tracer fields
-
+!print*, 'Calling ver_sinking_recom_benthos and tr_num is:',tracers%data(tr_num)%ID
do n=1, myDim_nod2D
nzmax=nlevels_nod2D(n)-1
nzmin=ulevels_nod2D(n)
@@ -457,6 +603,18 @@ subroutine diff_tracers_ale(tr_num, dynamics, tracers, ice, partit, mesh)
str_bf(nzmin:nzmax,n)
end do
endif
+
+! 3) Nitrogen SS
+ if (NitrogenSS .and. tracers%data(tr_num)%ID==1008) then ! idetc
+ call recom_nitrogenss(tracers, partit, mesh) !--- nss for idetc ---
+ do n=1, myDim_nod2D
+ nzmax=nlevels_nod2D(n)-1
+ nzmin=ulevels_nod2D(n)
+ tracers%data(3)%values(nzmin:nzmax,n)=tracers%data(3)%values(nzmin:nzmax,n)+ & ! tracer_id(tr_num)==1001 !idin
+ nss(nzmin:nzmax,n)
+ end do
+ end if
+
#endif
!___________________________________________________________________________
! Update tracers --> calculate T* see Danilov et al. (2017)
@@ -479,15 +637,40 @@ subroutine diff_tracers_ale(tr_num, dynamics, tracers, ice, partit, mesh)
!___________________________________________________________________________
if (tracers%data(tr_num)%i_vert_diff) then
! do vertical diffusion: implicite
+
+ if (tracers%data(tr_num)%ltra_diag) then
+ do n=1, myDim_nod2D+eDim_nod2D
+ nu1 = ulevels_nod2D(n)
+ nl1 = nlevels_nod2D(n)
+ do nz = nu1, nl1-1
+ ttf_rhs_bak(nz,n) = tracers%data(tr_num)%values(nz,n)
+ end do
+ end do
+ end if
+
+ ! (w/out Redi)
call diff_ver_part_impl_ale(tr_num, dynamics, tracers, ice, partit, mesh)
+
+ ! vertical diffusion: implicit
+ if (tracers%data(tr_num)%ltra_diag) then
+ do n=1, myDim_nod2D+eDim_nod2D
+ nu1 = ulevels_nod2D(n)
+ nl1 = nlevels_nod2D(n)
+ do nz = nu1, nl1-1
+ tracers%work%tra_diff_part_ver_impl(nz,n,tr_num) = tracers%data(tr_num)%values(nz,n) - ttf_rhs_bak(nz,n)
+ !if (mype==0) print *, tra_diff_part_ver_impl(:,:,tr_num)
+ end do
+ end do
+ end if
+
end if
-
+
!We DO not set del_ttf to zero because it will not be used in this timestep anymore
!init_tracers_AB will set it to zero for the next timestep
if (tracers%data(tr_num)%smooth_bh_tra) then
call diff_part_bh(tr_num, dynamics, tracers, partit, mesh) ! alpply biharmonic diffusion (implemented as filter)
end if
-
+
end subroutine diff_tracers_ale
!
!
@@ -857,7 +1040,7 @@ subroutine diff_ver_part_impl_ale(tr_num, dynamics, tracers, ice, partit, mesh)
a(nz)=a(nz)+min(0._WP, Wvel_i(nz, n))*v_adv
b(nz)=b(nz)+max(0._WP, Wvel_i(nz, n))*v_adv
end if
-
+
!_______________________________________________________________________
! the rhs (inhomogene part): --> rhs = K_33*dt*d/dz*Tstar --> Tstar...trarr
! solve difference quotient for rhs --> tr
@@ -882,7 +1065,7 @@ subroutine diff_ver_part_impl_ale(tr_num, dynamics, tracers, ice, partit, mesh)
nz=nzmax-1
dz=hnode_new(nz,n)
tr(nz)=-a(nz)*trarr(nz-1,n)-(b(nz)-dz)*trarr(nz,n)
-
+
!_______________________________________________________________________
! Add KPP nonlocal fluxes to the rhs (only T and S currently)
! use here blmc or kpp_oblmixc instead of Kv, since Kv already contains
@@ -985,7 +1168,7 @@ subroutine diff_ver_part_impl_ale(tr_num, dynamics, tracers, ice, partit, mesh)
#endif
end if
end if ! --> if (use_kpp_nonlclflx) then
-
+
!_______________________________________________________________________
! case of activated shortwave penetration into the ocean, ad 3d contribution
if (use_sw_pene .and. tracers%data(tr_num)%ID==1 .and. .not. toy_ocean) then
@@ -1067,7 +1250,7 @@ subroutine diff_ver_part_impl_ale(tr_num, dynamics, tracers, ice, partit, mesh)
do nz = nzmax-2, nzmin, -1
tr(nz) = tp(nz)-cp(nz)*tr(nz+1)
end do
-
+
!_______________________________________________________________________
! update tracer
! tr ... dTnew = T^(n+0.5) - T*
@@ -1482,6 +1665,10 @@ FUNCTION bc_surface(n, id, sval, nzmin, partit, mesh, sst, sss, aice)
#if defined (__recom)
use recoM_declarations
use recom_glovar
+ use recom_config
+#endif
+#if defined (__ciso)
+ use recom_ciso
#endif
use mod_transit
use g_clock
@@ -1515,7 +1702,7 @@ FUNCTION bc_surface(n, id, sval, nzmin, partit, mesh, sst, sss, aice)
!___temperature_____________________________________________________________
CASE (1)
bc_surface=-dt*(heat_flux(n)/vcpw + sval*water_flux(n)*is_nonlinfs)
-
+
!___salinity________________________________________________________________
CASE (2)
! --> real_salt_flux(:): salt flux due to containment/releasing of salt
@@ -1609,38 +1796,125 @@ FUNCTION bc_surface(n, id, sval, nzmin, partit, mesh, sst, sss, aice)
!--- Done with boundary conditions for transient tracers.
#if defined(__recom)
CASE (1001) ! DIN
+ if (use_MEDUSA .and. add_loopback) then ! OG: add is_MEDUSA_loopback flag is_MEDUSA_loopback flag * lb_flux(n,1)
+ bc_surface= dt*(AtmNInput(n) + RiverDIN2D(n) * is_riverinput &
+ + ErosionTON2D(n) * is_erosioninput + lb_flux(n,1))
+ else
bc_surface= dt*(AtmNInput(n) + RiverDIN2D(n) * is_riverinput &
+ ErosionTON2D(n) * is_erosioninput)
+ end if
+
CASE (1002) ! DIC
+ if (use_MEDUSA .and. add_loopback) then
+ bc_surface= dt*(GloCO2flux_seaicemask(n) &
+ + RiverDIC2D(n) * is_riverinput &
+ + ErosionTOC2D(n) * is_erosioninput &
+ + lb_flux(n,2) + lb_flux(n,5))
+ else
bc_surface= dt*(GloCO2flux_seaicemask(n) &
+ RiverDIC2D(n) * is_riverinput &
+ + RiverDOCl2D(n) * is_riverinput & ! OG R2OMIP
+ ErosionTOC2D(n) * is_erosioninput)
+ end if
+
CASE (1003) ! Alk
+ if (use_MEDUSA .and. add_loopback) then
bc_surface= dt*(virtual_alk(n) + relax_alk(n) &
- + RiverAlk2D(n) * is_riverinput)
- !bc_surface=0.0_WP
- CASE (1004:1010)
+ + RiverDIC2D(n) * is_riverinput &
+ + lb_flux(n,3) + lb_flux(n,5)*2) !CaCO3:Alk burial=1:2
+ else
+ bc_surface= dt*(virtual_alk(n) + relax_alk(n) & ! &
+ + RiverDIC2D(n) * is_riverinput)
+ end if
+ CASE (1004:1006)
+ bc_surface=0.0_WP
+ CASE (1007) ! PON / detN ! R2OMIP
+ bc_surface= (25/276)*dt*RiverPOC2D(n) * is_riverinput
+ CASE (1008) ! POC / detC ! R2OMIP
+ bc_surface= dt*RiverPOC2D(n) * is_riverinput
+ CASE (1009:1010)
bc_surface=0.0_WP
- CASE (1011) ! DON
- bc_surface= dt*RiverDON2D(n) * is_riverinput
+ CASE (1011) ! DON ! R2OMIP
+ !bc_surface= dt*RiverDON2D(n) * is_riverinput
+ bc_surface= (103/2583)*dt*RiverDOCsl2D(n) * is_riverinput
CASE (1012) ! DOC
- bc_surface= dt*RiverDOC2D(n) * is_riverinput
+ !bc_surface= dt*RiverDOC2D(n) * is_riverinput
+ bc_surface= 0.0_WP
CASE (1013:1017)
bc_surface=0.0_WP
- CASE (1018) ! DSi
- bc_surface=dt*(RiverDSi2D(n) * is_riverinput + ErosionTSi2D(n) * is_erosioninput)
+ CASE (1018) ! DSi ! From Turner et al. 2003 ! R2OMIP
+ if (use_MEDUSA .and. add_loopback) then
+ !bc_surface=dt*(RiverDSi2D(n) * is_riverinput &
+ ! + ErosionTSi2D(n) * is_erosioninput &
+ ! + lb_flux(n,4))
+ bc_surface=0.0_WP
+ else
+ !bc_surface=dt*(RiverDSi2D(n) * is_riverinput + ErosionTSi2D(n) * is_erosioninput)
+ bc_surface=dt*((194/16.2)*RiverDIN2D(n) * is_riverinput + ErosionTSi2D(n) * is_erosioninput)
+ end if
+
CASE (1019) ! Fe
+ if (useRivFe) then
+ bc_surface= dt*(AtmFeInput(n) + RiverFe(n))
+ else
bc_surface= dt*AtmFeInput(n)
+ !bc_surface= dt*AtmFeInput(n) + dt*(0.002*(RiverDOCsl2D(n)**(-1.616))) * is_riverinput ! From Tashiro et al. 2023 - R2OMIP (OG model explodes here)
+ end if
CASE (1020:1021) ! Cal
bc_surface=0.0_WP
+
CASE (1022) ! OXY
bc_surface= dt*GloO2flux_seaicemask(n)
! bc_surface=0.0_WP
- CASE (1023:1035)
+ CASE (1023:1030)
bc_surface=0.0_WP ! OG added bc for recom fields
+
+ CASE (1031) ! DOC terrigenous ! R2OMIP
+ bc_surface= dt*RiverDOCsl2D(n) * is_riverinput
+ !bc_surface=0.0_WP ! OG added bc for recom fields
+ CASE (1032:1036)
+ bc_surface=0.0_WP ! OG added bc for recom fields
+
+ CASE (1302) ! Before (1037) ! DIC_13
+
+#if defined (__ciso)
+ if (ciso) then
+ if (use_MEDUSA .and. add_loopback) then
+ bc_surface= dt*(GloCO2flux_seaicemask_13(n) &
+ + lb_flux(n,6) + lb_flux(n,7))
+ else
+ bc_surface= dt*(GloCO2flux_seaicemask_13(n))
+ end if
+ else
+ bc_surface=0.0_WP
+ end if
#endif
+
+ CASE (1305:1321)
+ bc_surface=0.0_WP ! organic 13C
+
+ CASE (1402) ! Before (1034) ! DIC_14
+#if defined (__ciso)
+ if (ciso .and. ciso_14) then
+ if (use_MEDUSA .and. add_loopback .and. ciso_organic_14) then
+ bc_surface= dt*(GloCO2flux_seaicemask_14(n) &
+ + lb_flux(n,8) + lb_flux(n,9))
+ else
+ bc_surface= dt*GloCO2flux_seaicemask_14(n)
+ end if
+ else
+ bc_surface=0.0_WP
+ end if
+#endif
+
+ CASE (1405:1421)
+ bc_surface=0.0_WP ! organic 14C
+#endif
+
CASE (101) ! apply boundary conditions to tracer ID=101
bc_surface= dt*(prec_rain(n))! - real_salt_flux(n)*is_nonlinfs)
+!---Transient tracers (case ##6,12,14,39) need additional input parameters
+! and are considered in the separate function transit_bc_surface
!---wiso-code
CASE (102) ! apply boundary conditions to tracer ID=101 (H218O)
bc_surface = dt*wiso_flux_oce(n,1)
diff --git a/src/oce_modules.F90 b/src/oce_modules.F90
index a71f60758..477700ae7 100755
--- a/src/oce_modules.F90
+++ b/src/oce_modules.F90
@@ -250,6 +250,8 @@ MODULE o_ARRAYS
#if defined(__recom)
real(kind=WP), allocatable :: dtr_bf(:,:), str_bf(:,:)
real(kind=WP), allocatable :: vert_sink(:,:)
+real(kind=WP), allocatable :: nss(:,:) ! OG -> vertical sinking !R2OMIP (Burial)
+real(kind=WP), allocatable :: bur(:,:,:) ! LO !R2OMIP (Burial)
#endif
!Viscosity and diff coefs
diff --git a/src/oce_setup_step.F90 b/src/oce_setup_step.F90
index 18900f749..d436d2069 100755
--- a/src/oce_setup_step.F90
+++ b/src/oce_setup_step.F90
@@ -314,7 +314,7 @@ SUBROUTINE tracer_init(tracers, partit, mesh)
!___________________________________________________________________________
! define tracer namelist parameter
integer :: num_tracers
- logical :: i_vert_diff, smooth_bh_tra
+ logical :: i_vert_diff, smooth_bh_tra , ltra_diag
real(kind=WP) :: gamma0_tra, gamma1_tra, gamma2_tra
integer :: AB_order = 2
namelist /tracer_listsize/ num_tracers
@@ -477,6 +477,7 @@ SUBROUTINE tracer_init(tracers, partit, mesh)
tracers%data(n)%valuesAB = 0.
tracers%data(n)%valuesold = 0.
tracers%data(n)%i_vert_diff = i_vert_diff
+ tracers%data(n)%ltra_diag = ltra_diag
end do
allocate(tracers%work%del_ttf(nl-1,node_size))
allocate(tracers%work%del_ttf_advhoriz(nl-1,node_size),tracers%work%del_ttf_advvert(nl-1,node_size))
@@ -489,6 +490,24 @@ SUBROUTINE tracer_init(tracers, partit, mesh)
tracers%work%dvd_trflx_hor = 0.0_WP
tracers%work%dvd_trflx_ver = 0.0_WP
end if
+ if (ltra_diag) then
+ allocate(tracers%work%tra_advhoriz(nl-1,node_size,num_tracers),tracers%work%tra_advvert(nl-1,node_size,num_tracers))
+ tracers%work%tra_advhoriz = 0.0_WP
+ tracers%work%tra_advvert = 0.0_WP
+ allocate(tracers%work%tra_diff_part_hor_redi(nl-1,node_size,num_tracers),tracers%work%tra_diff_part_ver_expl(nl-1,node_size,num_tracers))
+ allocate(tracers%work%tra_diff_part_ver_redi_expl(nl-1,node_size,num_tracers),tracers%work%tra_diff_part_ver_impl(nl-1,node_size,num_tracers))
+ allocate(tracers%work%tra_recom_sms(nl-1,node_size,num_tracers))
+ allocate(tracers%work%tra_advhoriz_LO(nl-1,node_size,num_tracers))
+ allocate(tracers%work%tra_advvert_LO(nl-1,node_size,num_tracers))
+ tracers%work%tra_diff_part_hor_redi = 0.0_WP
+ tracers%work%tra_diff_part_ver_expl = 0.0_WP
+ tracers%work%tra_diff_part_ver_redi_expl = 0.0_WP
+ tracers%work%tra_diff_part_ver_impl = 0.0_WP
+ tracers%work%tra_recom_sms = 0.0_WP
+ tracers%work%tra_advhoriz_LO = 0.0_WP
+ tracers%work%tra_advvert_LO = 0.0_WP
+
+ end if
END SUBROUTINE tracer_init
!
!
@@ -873,6 +892,8 @@ SUBROUTINE arrays_init(num_tracers, partit, mesh)
allocate(str_bf ( nl-1, node_size ))
allocate(vert_sink ( nl-1, node_size ))
allocate(Alk_surf ( node_size ))
+ allocate(nss ( nl-1, node_size )) !R2OMIP (Burial)
+ allocate(bur ( 1:benthos_num, nl-1, node_size )) ! LO !R2OMIP (Burial)
#endif
! =================
! Visc and Diff coefs
@@ -985,6 +1006,8 @@ SUBROUTINE arrays_init(num_tracers, partit, mesh)
str_bf = 0.0_WP
vert_sink = 0.0_WP
Alk_surf = 0.0_WP
+ nss = 0.0_WP !R2OMIP (Burial)
+ bur = 0.0_WP !R2OMIP (Burial)
#endif
! init field for pressure force
@@ -1189,7 +1212,7 @@ SUBROUTINE oce_initial_state(tracers, partit, mesh)
write (id_string, "(I4)") id
write(*,*) 'initializing '//trim(i_string)//'th tracer with ID='//trim(id_string)
end if
- CASE (1023:1033)
+ CASE (1023:1037)
tracers%data(i)%values(:,:)=0.0_WP
if (mype==0) then
write (i_string, "(I4)") i
diff --git a/test/input/recom/DustClimMonthlyAlbani_pimesh.nc b/test/input/recom/DustClimMonthlyAlbani_pimesh.nc
new file mode 100644
index 000000000..01d17125e
Binary files /dev/null and b/test/input/recom/DustClimMonthlyAlbani_pimesh.nc differ
diff --git a/test/input/recom/GLODAPv2.2016b.PI_TCO2_fesom2_mmol_fix_z_Fillvalue.nc b/test/input/recom/GLODAPv2.2016b.PI_TCO2_fesom2_mmol_fix_z_Fillvalue.nc
new file mode 100644
index 000000000..3c5292ae1
Binary files /dev/null and b/test/input/recom/GLODAPv2.2016b.PI_TCO2_fesom2_mmol_fix_z_Fillvalue.nc differ
diff --git a/test/input/recom/MonthlyAtmCO2_gcb2024.nc b/test/input/recom/MonthlyAtmCO2_gcb2024.nc
new file mode 100644
index 000000000..1874cf8f3
Binary files /dev/null and b/test/input/recom/MonthlyAtmCO2_gcb2024.nc differ
diff --git a/test/input/recom/din5deg.nc b/test/input/recom/din5deg.nc
new file mode 100644
index 000000000..74d678dbc
Binary files /dev/null and b/test/input/recom/din5deg.nc differ
diff --git a/test/input/recom/fe5deg.nc b/test/input/recom/fe5deg.nc
new file mode 100644
index 000000000..76d5c8e4b
Binary files /dev/null and b/test/input/recom/fe5deg.nc differ
diff --git a/test/input/recom/oxy5deg.nc b/test/input/recom/oxy5deg.nc
new file mode 100644
index 000000000..6298ec1d2
Binary files /dev/null and b/test/input/recom/oxy5deg.nc differ
diff --git a/test/input/recom/si5deg.nc b/test/input/recom/si5deg.nc
new file mode 100644
index 000000000..a81e284b4
Binary files /dev/null and b/test/input/recom/si5deg.nc differ
diff --git a/test/input/recom/talk5deg.nc b/test/input/recom/talk5deg.nc
new file mode 100644
index 000000000..25fde4bdc
Binary files /dev/null and b/test/input/recom/talk5deg.nc differ
diff --git a/test/input/recom/tco2_5deg.nc b/test/input/recom/tco2_5deg.nc
new file mode 100644
index 000000000..7fdad5948
Binary files /dev/null and b/test/input/recom/tco2_5deg.nc differ
diff --git a/test/input/recom/woa18_netcdf_5deg.nc b/test/input/recom/woa18_netcdf_5deg.nc
new file mode 100644
index 000000000..2215b266a
Binary files /dev/null and b/test/input/recom/woa18_netcdf_5deg.nc differ