-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #31 from PALEOtoolkit/napc_tutorial
Check-in of examples/NAPC_tutorial
- Loading branch information
Showing
5 changed files
with
558 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,296 @@ | ||
######################################################## | ||
# NP model from Armstrong 1994 in 1D shelf setting | ||
######################################################## | ||
|
||
NP_shelf: | ||
parameters: | ||
CIsotope: ScalarData | ||
SIsotope: ScalarData | ||
phys_file: S2P3_depth80_m2amp04_phys.nc | ||
surf_file: S2P3_depth80_m2amp04_surf.nc | ||
domains: | ||
global: | ||
# scalar domain | ||
|
||
reactions: | ||
total_O2: | ||
class: ReactionSum | ||
parameters: | ||
vars_to_add: [atm.O2, ocean.O2_total, -106*ocean.P0_total, -106*ocean.POP_total] | ||
variable_links: | ||
sum: total_O2 | ||
|
||
total_P: | ||
class: ReactionSum | ||
parameters: | ||
vars_to_add: [ocean.P_total, ocean.POP_total, ocean.P0_total] | ||
variable_links: | ||
sum: total_P | ||
|
||
fluxAtmtoOceansurface: | ||
reactions: | ||
fluxtarget: | ||
class: ReactionFluxTarget | ||
parameters: | ||
flux_totals: true | ||
fluxlist: ["O2"] | ||
|
||
fluxOceanfloor: | ||
reactions: | ||
particulatefluxtarget: | ||
class: ReactionFluxTarget | ||
parameters: | ||
flux_totals: true | ||
target_prefix: particulateflux_ | ||
fluxlist: ["P", "N", "Corg::CIsotope", "Ccarb::CIsotope"] # fluxlist_BioParticulate | ||
|
||
solutefluxtarget: | ||
class: ReactionFluxTarget | ||
parameters: | ||
flux_totals: true | ||
target_prefix: soluteflux_ | ||
fluxlist: ["DIC::CIsotope", "TAlk", "P", "O2"] #, "SO4::SIsotope", "H2S::SIsotope", "CH4::CIsotope"] # fluxlist_Solute | ||
|
||
transferPOP: | ||
class: ReactionFluxToComponents | ||
parameters: | ||
outputflux_prefix: particulateflux_ | ||
outputflux_names: ["Corg", "N", "P"] | ||
outputflux_stoich: [106.0, 0.0, 1.0] # must match bioprod stoich | ||
variable_links: | ||
inputflux: sinkflux_POP | ||
|
||
atm: | ||
reactions: | ||
reservoir_O2: | ||
# NB: rescaled to 1e-14 * global atmosphere, to workaround loss of numerical precision when tracking | ||
# exchanges with a 1 m^2 ocean column | ||
class: ReactionReservoirAtm | ||
parameters: | ||
moles1atm: 1.77e6 # mol 1e-14*1.77e20 | ||
variable_links: | ||
R*: O2* | ||
pRatm: pO2atm | ||
pRnorm: pO2PAL | ||
variable_attributes: | ||
R:norm_value: 3.7e5 # mol 1e-14 * present-day global atmospheric level | ||
R:initial_value: 3.7e5 # mol for 1e-14 * global atmosphere | ||
|
||
transfer_AtmtoOceansurface: | ||
class: ReactionFluxTransfer | ||
parameters: | ||
transfer_matrix: Distribute | ||
transfer_multiplier: -1.0 | ||
input_fluxes: fluxAtmtoOceansurface.flux_$fluxname$ | ||
output_fluxes: $fluxname$_sms | ||
|
||
|
||
oceansurface: | ||
reactions: | ||
airsea_O2: | ||
class: ReactionAirSeaO2 | ||
parameters: | ||
# piston: 4.8 # m d-1 | ||
piston_fixed: false | ||
|
||
insol: | ||
class: ReactionForceInsolationModernEarth | ||
parameters: | ||
latitude: [50.0] # degrees N | ||
variable_links: | ||
insolation: surface_insol | ||
|
||
open_area_fraction: | ||
class: ReactionConst | ||
parameters: | ||
constnames: ["open_area_fraction"] | ||
variable_attributes: | ||
open_area_fraction%initial_value: 1.0 | ||
|
||
wind_speed: | ||
class: ReactionForceGrid | ||
parameters: | ||
netcdf_file: external%surf_file | ||
data_var: wspeedms | ||
time_var: time | ||
tidx_start: 1 | ||
tidx_end: 365 | ||
cycle_time: 1.0 # yr (periodic annual forcing) | ||
variable_links: | ||
F: wind_speed | ||
|
||
transfer_AtmtoOceansurface: | ||
class: ReactionFluxTransfer | ||
parameters: | ||
transfer_matrix: Identity | ||
input_fluxes: fluxAtmtoOceansurface.flux_$fluxname$ | ||
output_fluxes: ocean.oceansurface.$fluxname$_sms | ||
variable_links: | ||
# output_CO2: ocean.oceansurface.DIC_sms | ||
|
||
ocean: | ||
reactions: | ||
transport1D: | ||
class: ReactionOceanTransportColumn | ||
parameters: | ||
grid_file: external%phys_file | ||
|
||
sal: | ||
class: ReactionConst | ||
parameters: | ||
constnames: ["sal"] | ||
variable_attributes: | ||
sal%initial_value: 35.0 | ||
|
||
temp: | ||
class: ReactionForceGrid | ||
parameters: | ||
netcdf_file: external%phys_file | ||
data_var: temp | ||
constant_offset: 273.15 # convert deg C in netcdf file to K | ||
time_var: time | ||
tidx_start: 1 | ||
tidx_end: 8760 | ||
cycle_time: 1.0 # yr (periodic annual forcing) | ||
variable_links: | ||
F: temp # Kelvin, Ocean temperature | ||
|
||
rho: | ||
class: ReactionForceGrid | ||
parameters: | ||
netcdf_file: external%phys_file | ||
data_var: sigmat | ||
constant_offset: 1000.0 # convert to kg m-3 ocean density | ||
time_var: time | ||
tidx_start: 1 | ||
tidx_end: 8760 | ||
cycle_time: 1.0 # yr (periodic annual forcing) | ||
variable_links: | ||
F: rho # kg m-3, ocean density | ||
|
||
Kz: | ||
class: ReactionForceGrid | ||
parameters: | ||
netcdf_file: external%phys_file | ||
data_var: Kz | ||
time_var: time | ||
tidx_start: 1 | ||
tidx_end: 8760 | ||
cycle_time: 1.0 # yr (periodic annual forcing) | ||
variable_links: | ||
F: Kz # m^2 s-1 eddy diffusivity on upper cell surfaces | ||
|
||
sinkfloat: | ||
class: ReactionSinkFloat | ||
parameters: | ||
transportfloor: true | ||
|
||
reservoir_O2: | ||
class: ReactionReservoirTotal | ||
variable_links: | ||
R*: O2* | ||
variable_attributes: | ||
R:initial_value: 0.2054 # concentration m-3 (1027 kg m-3 * 200e-6 mol/kg-sw) | ||
|
||
reservoir_P: | ||
class: ReactionReservoirTotal | ||
variable_links: | ||
R*: P* | ||
variable_attributes: | ||
R:initial_value: 2.208e-3 # concentration m-3 (1027 kg m-3 * 2.15e-6 mol/kg-sw) | ||
|
||
light: | ||
class: ReactionLightColumn | ||
parameters: | ||
background_opacity: 0.1 # m-1 | ||
|
||
reservoir_P0: | ||
class: ReactionReservoirTotal | ||
parameters: | ||
variable_links: | ||
R*: P0* | ||
variable_attributes: | ||
R:norm_value: 0.001 | ||
R:initial_value: 0.001 | ||
R_conc:vertical_movement: 0.0 # m d-1 | ||
R_conc:advect: true | ||
R_conc:specific_light_extinction: 0.0 # m^2 mol-1 | ||
|
||
P0_growth: | ||
class: ReactionPhytoplankton | ||
parameters: | ||
mumax: 1.4 #units="d-1" max growth rate | ||
Ks: 1e-3 #units="mol m-3 nutrient limitation factor | ||
insol_scale: 0.005 #units="" insolation scale factor | ||
O2_thresh: 1e-6 #units="mol m-3" oxygen threshold constant | ||
stoich_PtoO2: -106.0 #units="" stoichiometry, negative by convention | ||
variable_links: | ||
PX*: P0* | ||
|
||
P0_decay: | ||
class: ReactionParticleDecay | ||
parameters: | ||
decay_timescale: 0.17 # yr | ||
variable_links: | ||
Particle*: P0* | ||
decayflux: POP_sms | ||
|
||
reservoir_POP: | ||
class: ReactionReservoirTotal | ||
variable_links: | ||
R*: POP* | ||
variable_attributes: | ||
R:initial_value: 0.0 # concentration m-3 | ||
R_conc:vertical_movement: -100.0 # m d-1 | ||
R_conc:advect: true | ||
|
||
POP_decay: | ||
class: ReactionParticleDecay | ||
parameters: | ||
decay_timescale: 0.05 # yr | ||
variable_links: | ||
Particle*: POP* | ||
decayflux: POP_decay | ||
|
||
POP_decaycomponents: | ||
class: ReactionFluxToComponents | ||
parameters: | ||
outputflux_prefix: remin_ | ||
outputflux_names: ["Corg", "N", "P"] | ||
outputflux_stoich: [106.0, 0.0, 1.0] # must match bioprod stoich | ||
variable_links: | ||
inputflux: POP_decay | ||
|
||
reminocean: | ||
class: ReactionReminO2 | ||
parameters: | ||
variable_links: | ||
soluteflux_P: P_sms | ||
soluteflux_O2: O2_sms | ||
|
||
|
||
oceanfloor: | ||
reactions: | ||
reminoceanfloor: | ||
class: ReactionReminO2 | ||
parameters: | ||
variable_links: | ||
remin*: particulateflux* | ||
soluteflux_P: fluxOceanfloor.soluteflux_P | ||
soluteflux_O2: fluxOceanfloor.soluteflux_O2 | ||
|
||
transfer_particulatefluxOceanfloor: | ||
class: ReactionFluxTransfer | ||
parameters: | ||
transfer_matrix: Identity | ||
input_fluxes: fluxOceanfloor.particulateflux_$fluxname$ | ||
output_fluxes: particulateflux_$fluxname$ | ||
variable_links: | ||
|
||
transfer_solutefluxOceanfloor: | ||
class: ReactionFluxTransfer | ||
parameters: | ||
transfer_matrix: Identity | ||
input_fluxes: fluxOceanfloor.soluteflux_$fluxname$ | ||
output_fluxes: ocean.oceanfloor.$fluxname$_sms | ||
variable_links: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
using Logging | ||
using OrdinaryDiffEq | ||
using Sundials | ||
using Plots | ||
|
||
@info "Start $(@__FILE__)" | ||
|
||
@info "importing modules ... (may take a few seconds)" | ||
import PALEOboxes as PB | ||
import PALEOocean | ||
using PALEOmodel | ||
@info " ... done" | ||
|
||
global_logger(ConsoleLogger(stderr,Logging.Info)) | ||
|
||
# include("NAPC_expts.jl") | ||
include("NAPC_reactions.jl") | ||
include("atmreservoirreaction.jl") # for ReactionReservoirAtm | ||
|
||
transport_dir = "S2P3_transport_20240614" # folder containing S2P3 physical variables output collated to netcdf files | ||
|
||
# P, O2 only population-based phytoplankton model | ||
model = PB.create_model_from_config( | ||
joinpath(@__DIR__, "NAPC_cfg.yaml"), | ||
"NP_shelf"; | ||
modelpars=Dict( | ||
"phys_file"=>joinpath(transport_dir, "S2P3_depth80_m2amp04_phys.nc"), | ||
"surf_file"=>joinpath(transport_dir, "S2P3_depth80_m2amp04_surf.nc"), | ||
) | ||
) | ||
|
||
tspan=(0,5.0) | ||
|
||
initial_state, modeldata = PALEOmodel.initialize!(model) | ||
|
||
paleorun = PALEOmodel.Run(model=model, output = PALEOmodel.OutputWriters.OutputMemory()) | ||
|
||
# first run includes JIT time | ||
sol = PALEOmodel.ODE.integrateForwardDiff( | ||
paleorun, initial_state, modeldata, tspan, | ||
solvekwargs=(saveat=1/8760, reltol=1e-5, maxiters=1000000), | ||
) | ||
|
||
######################################## | ||
# Plot output | ||
######################################## | ||
|
||
colT=collect(range(start=tspan[1], stop=tspan[end], step=0.5)) | ||
|
||
# individual plots | ||
#plotlyjs(size=(500, 300)) | ||
#pager = PALEOmodel.DefaultPlotPager() | ||
|
||
# assemble plots onto screens with 6 subplots | ||
gr(size=(1600, 800)) # gr backend (plotly merges captions with multiple panels) | ||
pager=PALEOmodel.PlotPager((2, 3), (legend_background_color=nothing, margin=(5, :mm))) | ||
|
||
pager(plot(title="Total P", paleorun.output, "global.total_P")) | ||
pager(plot(title="Total O2", paleorun.output, "global.total_O2")) | ||
pager(:newpage) # flush output | ||
|
||
pager(heatmap(title="O2", paleorun.output, "ocean.O2", (column=1, ), clim=(0,Inf))) | ||
pager(heatmap(title="P", paleorun.output, "ocean.P", (column=1, ), clim=(0,Inf))) | ||
|
||
pager(heatmap(title="P0", paleorun.output, "ocean.P0", (column=1, ), clim=(0,Inf))) | ||
pager(heatmap(title="P0_growth", paleorun.output, "ocean.P0_growth_rate", (column=1, ), clim=(0,Inf))) | ||
pager(:newpage) # flush output | ||
|
||
@info "End $(@__FILE__)" |
Oops, something went wrong.