This commit is contained in:
33333-33333 2026-09-29 23:45:12 +09:00
commit f5fc9b76ce
73 changed files with 32628 additions and 376 deletions

View file

@ -1,4 +1,4 @@
import {clamp,rateToProbability} from './units.js';
import {clamp,rateToProbability} from './units.js?v=45';
export const TROPHIC_ROLES = Object.freeze(['primary-consumer','secondary-consumer','tertiary-consumer','detritivore']);
export const RESOURCE_ROLES = Object.freeze(['producer','zooplankton','primary-consumer','secondary-consumer','tertiary-consumer','detritus']);
@ -62,12 +62,19 @@ export function functionalResponseRatePerDay(params,resourceDensity,denominatorT
return numerator/Math.max(1e-12,denominator);
}
export function producerIntakeKgPerDay(massKg,producerKgPerM2,edge,temperatureC=20,profile={feeding:{preferredPredatorPreyMassRatio:35,massRatioSigma:1.05}}){
export function fieldResourceIntakeKgPerDay(massKg,resourceDensityKgPerM2,edge,resourceRole='producer'){
if(!edge)return 0;
const resourceMassEquivalent=Math.max(1e-5,producerKgPerM2*.01),params=rallFeedingParameters(edge,massKg,resourceMassEquivalent,temperatureC,profile),q=edge.functionalResponse===3?2:1;
const raw=functionalResponseRatePerDay(params,producerKgPerM2,[{...params,resourceDensity:producerKgPerM2,q}],q);
const maxIntake=Math.max(.002,.16*Math.pow(Math.max(massKg,.001),.78))*edge.preferenceWeight;
return Math.min(maxIntake,raw*Math.max(.03,Math.pow(massKg,.58)));
const mass=Math.max(massKg,.001),density=Math.max(0,resourceDensityKgPerM2),q=edge.functionalResponse===3?2:1;
// A biomass field has no single prey body mass. Do not feed field density into
// predator:prey body-mass scaling. Use a density-based Holling saturation instead.
const halfSaturation=resourceRole==='zooplankton'?.012:.08;
const x=Math.pow(density,q),half=Math.pow(halfSaturation,q),saturation=x/Math.max(1e-12,half+x);
const coefficient=resourceRole==='zooplankton'?.12:.16;
const maxIntakeKgPerDay=Math.max(.002,coefficient*Math.pow(mass,.78))*edge.preferenceWeight;
return maxIntakeKgPerDay*saturation;
}
export function producerIntakeKgPerDay(massKg,producerKgPerM2,edge){
return fieldResourceIntakeKgPerDay(massKg,producerKgPerM2,edge,'producer');
}
export function attackProbabilityPerStep(ratePerDay,dtDays){return rateToProbability(ratePerDay,dtDays)}