class NPZsystem extends dynamicalSystem { float totalN, totalN0; // internal variables int N_, P_, Z_; float ln2 = 0.6931; NPZsystem() { // separating the constructor and define() means you can easily make a variant that calls the same define() but does other things in the constructor define(); } void define() { int numFramesToSave = 100; int maxvars = 3; int maxfluxes = 12; int maxparams = 14; allocate(numFramesToSave, maxvars, maxfluxes, maxparams); name = "NPZ"; shortname = "NPZ"; totalN0 = 8; float P0 = 1; float Z0 = 1; modelTimePerSecond = 4; timeUnits = "days"; varUnits = "µmol nitrogen"; tolerance = 1e-5; color Pcol = greenColor; color Zcol = redColor; color Ncol = color(20,30,90); float R = 1; float po = PI/180; N_ = addVar("nutrients","N", totalN0-P0-Z0, Ncol, 0,-R); P_ = addVar("phytoplankton","P", P0, Pcol,R*cos(150*po),R*sin(150*po)); Z_ = addVar("zooplankton","Z", Z0, Zcol,R*cos(30*po),R*sin(30*po)); addFlux("uptake","upt", N_, P_, Pcol,120-20); addFlux("ingestion","ingest", P_, Z_, Zcol,120); addFlux("P mortality","Pmort", P_, N_, Ncol,120); addFlux("Z baseline losses","Zmort", Z_, N_, Ncol,120); addFlux("Z ingestion-related losses","excret", Z_, N_, darken(Pcol),120-30); addParam("P max growth (doublings/day)","Vm",1,0,1.5, Pcol); addParam("Z max growth (doublings/day)","Rgr",0.75, 0, 1.5, Zcol); addParam("nutrient uptake half-saturation (µmol/L)","k",5, 0.1, 5, Pcol); addParam("P mortality (1/day)","m",0.1, 0, 0.4, Pcol); addParam("grazing half-saturation (µmol/L)","K",2, 0, 4, Zcol); addParam("fraction of prey re-excreted","Rex",0.5, 0, 1, Zcol); addParam("Z baseline losses (1/day)","g",0.2, 0, 0.4, Zcol); } float[] CALCFLUXES(float[] vslice) { float[] F = new float[nfluxes]; float K = readout("K"); float k = readout("k"); float Vm = readout("Vm"); float m = readout("m"); F[find("upt")] = Vm * ln2 * vslice[N_]/(k+vslice[N_]) * vslice[P_]; F[find("ingest")] = readout("Rgr") * ln2 * vslice[Z_] * vslice[P_] / (readout("K") + vslice[P_]); F[find("Pmort")] = m * vslice[P_]; F[find("Zmort")] = readout("g") * vslice[Z_]; F[find("excret")] = readout("Rex") * F[find("ingest")]; // note: this may not be how ROMS defines it return F; } void adjustments_after_calc_step() { totalN = vars[N_].current + vars[P_].current + vars[Z_].current; for (int i=0; i40) {showFluxes = false;} showHistory = false; showDetails = false; showDetailsButton = true; // set values passed to the constructor; // allocate arrays totalN0 = totalnitrogen; totalN = totalN0; NP = nphytos; NZ = nzoop; Nsub = nsubsystems; int vars_to_allocate = Nsub*(NP+NZ+3) + 1 +10; int fluxes_to_allocate = Nsub*(NP+NZ)*(NZ+4)+10+100; allocate(numFramesToSave, vars_to_allocate, fluxes_to_allocate, params_to_allocate); // layout parameters dot_minsize = dot_minsize/2; dot_stdsize = 0.25-0.03*(Nsub-2); vang = 15; float spacing = 0.7+0.14*(Nsub-2); color[] Pcolor = new color[NP]; color[] Zcolor = new color[NZ]; for (int i=0; i