second
This commit is contained in:
parent
5f7fcb96ed
commit
01204dfa2f
34 changed files with 1498 additions and 0 deletions
32
ecology/resources.js
Normal file
32
ecology/resources.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import {clamp} from './units.js';
|
||||
|
||||
export class ResourceField{
|
||||
constructor({id,role,cellCount,energyDensityKJPerKg,representation='field'}){this.id=id;this.role=role;this.energyDensityKJPerKg=energyDensityKJPerKg;this.representation=representation;this.biomass=new Float32Array(cellCount)}
|
||||
consume(index,amountKg,cellAreaM2){const available=this.biomass[index]*cellAreaM2,taken=Math.min(Math.max(0,amountKg),available);this.biomass[index]=Math.max(0,this.biomass[index]-taken/cellAreaM2);return taken}
|
||||
}
|
||||
|
||||
export const phytoplanktonMuMax = temperatureC => 0.81 * Math.exp(0.0631 * temperatureC);
|
||||
|
||||
export function producerCapacity(profile,{moisture=1,shade=0,blocked=false}={}){
|
||||
if(blocked)return 0;
|
||||
if(profile.type==='terrestrial')return profile.producer.carryingCapacityKgPerM2 * clamp(0.35 + 0.65*moisture,0,1) * (1 - 0.18*clamp(shade,0,1));
|
||||
return profile.producer.carryingCapacityKgPerM2;
|
||||
}
|
||||
|
||||
export function producerGrowthPerDay(profile,temperatureC,{moisture=1,light,nutrientN,nutrientP}={}){
|
||||
if(profile.type==='terrestrial'){
|
||||
const fT=Math.exp(-0.5*((temperatureC-20)/13)**2),fW=clamp(moisture,0,1),fL=clamp(light ?? profile.environment.light,0,1);
|
||||
return profile.producer.rMaxPerDay * fT * fW * fL;
|
||||
}
|
||||
const fI=clamp(light ?? profile.environment.light,0,1),fN=clamp(nutrientN ?? profile.environment.nutrientN,0,1),fP=clamp(nutrientP ?? profile.environment.nutrientP,0,1);
|
||||
return phytoplanktonMuMax(temperatureC) * Math.min(fN,fP) * fI;
|
||||
}
|
||||
|
||||
export function updateProducerBiomass(biomass,capacity,growthPerDay,consumedKgPerM2,dtDays){
|
||||
if(capacity<=0)return 0;const growth=growthPerDay*biomass*(1-biomass/capacity);return clamp(biomass + growth*dtDays - Math.max(0,consumedKgPerM2),0,capacity*1.05);
|
||||
}
|
||||
|
||||
export function updateZooplanktonCohort(producerKgPerM2,zooplanktonKgPerM2,dtDays=1){
|
||||
const z=Math.max(0,zooplanktonKgPerM2),p=Math.max(0,producerKgPerM2),ingestion=Math.min(p,.9*z*p/(.035+p))*dtDays,assimilated=ingestion*.45,mortality=.10*z*dtDays;
|
||||
return {producerConsumedKgPerM2:ingestion,nextZooplanktonKgPerM2:Math.max(0,z+assimilated-mortality),productionKgPerM2:Math.max(0,assimilated-mortality)};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue