// Farm Aquaculture Resource Management (FARM) Model // Copyright notices // Copyright General modelling approach Longline Ltd. March 2006 // Copyright Individual models as below: // Generic: Longline Ltd March 2006 // Manila Clam: Solidoro et al, 2000, MEPS 199, 137-148 // Cockle : Rueda et al, 2005. J. Sea Res. 54, 76-298 // V1 - J.G.Ferreira, Rev. A 2006/07/01 // V2 - J.G.Ferreira, Rev. B 2006/12/07 // V3 - J.G.Ferreira, Rev. C 2008/04/20 Removed all ShellSIM code // All rates in the model are per day, regardless of whether // they are defined per second, hour etc in the inputs // Timestep is calculated based on the Courant condition // Classes function Farmscale() { Farmscale.prototype.getParameters = GetParameters; Farmscale.prototype.decimalPlaces = DecimalPlaces; Farmscale.prototype.log10 = Log10; Farmscale.prototype.calculateVolume = CalculateVolume; Farmscale.prototype.defineModelSettings = DefineModelSettings; Farmscale.prototype.showInitialStatusBar = ShowInitialStatusBar; Farmscale.prototype.updatePopulation = UpdatePopulation; Farmscale.prototype.updateOutputs = UpdateOutputs; Farmscale.prototype.updateBottomCulture = UpdateBottomCulture; Farmscale.prototype.initialize = Initialize; Farmscale.prototype.transport = Transport; Farmscale.prototype.sediment = Sediment; Farmscale.prototype.graze = Graze; Farmscale.prototype.clamGraze = ClamGraze; Farmscale.prototype.cockleGraze = CockleGraze; Farmscale.prototype.polycultureGraze = PolycultureGraze; Farmscale.prototype.demographicUpwind = DemographicUpwind; Farmscale.prototype.splitBoxes = SplitBoxes; Farmscale.prototype.clearElements = ClearElements; Farmscale.prototype.prepareRun = PrepareRun; Farmscale.prototype.endRun = EndRun; Farmscale.prototype.processFileData = ProcessFileData; Farmscale.prototype.calculateASSETS = CalculateASSETS; Farmscale.prototype.loadModel = LoadModel; Farmscale.prototype.saveModel = SaveModel; Farmscale.prototype.listModels = ListModels; Farmscale.prototype.findModels = FindModels; Farmscale.prototype.liveDisk = LiveDisk; Farmscale.prototype.deadDisk = DeadDisk; Farmscale.prototype.deleteModel = DeleteModel; Farmscale.prototype.liveDelete = LiveDelete; Farmscale.prototype.deadDelete = DeadDelete; Farmscale.prototype.showDebugger = ShowDebugger; Farmscale.prototype.getCannedData = GetCannedData; // Shellfish private methods // Generic Farmscale.prototype.genericFeed = GenericFeed; Farmscale.prototype.genericRespire = GenericRespire; Farmscale.prototype.genericAssimilate = GenericAssimilate; // Manila clam - Tapes phillipinarum Farmscale.prototype.clamAnabolism = ClamAnabolism; Farmscale.prototype.clamCatabolism = ClamCatabolism; // Cockle - Cerastoderma edule Farmscale.prototype.cockleFeed = CockleFeed; Farmscale.prototype.cockleRespire = CockleRespire; Farmscale.prototype.cockleAssimilate = CockleAssimilate; // Conversion methods Farmscale.prototype.getOxygenSaturation = GetOxygenSaturation; Farmscale.prototype.updateOxygenSaturation = UpdateOxygenSaturation; Farmscale.prototype.getDensity = GetDensity; Farmscale.prototype.getViscosity = GetViscosity; Farmscale.prototype.getFallVelocity = GetFallVelocity; Farmscale.prototype.runModel = ExecuteModel; Farmscale.prototype.writeData = WriteData; Farmscale.prototype.go = Go; Farmscale.prototype.integrate = Integrate; } function DefineModelSettings() { // Model save data // FS.Separator = "\x23"; // "#" in hex FS.Separator = "\x1F"; // ASCII 31 in hex - not on keyboard FS.Fields = 36; // 35 before usebottomculture, 18; // Number of fields in model save // Run switch FS.ModelRunning = 0; // Set timestep and runtime FS.YearsToDays = 365; FS.DaysToHours = 24; FS.DaysToSeconds = 24*3600; FS.CUBIC = 1000; FS.TimeNow = 0; var CourantFactor = 2; // This number is critical for model stability // Universal constants FS.AccelerationOfGravity = 9.78031; // m s-2 FS.SedimentParticleDensity = 2600; // kg m-3 // Shellfish classes // Rationale for seed weight - 1. classes all equal, start at zero // e.g. n classes 10g amplitude, seed is 5g, centre of 0-10g // or n classes 18g amplitude, seed is 9g, centre of 0-18g FS.Classes = 6; // 6 shellfish weight classes FS.ClassAmplitude = 10; // g TFW for tests FS.SeedClassTFW = FS.ClassAmplitude/2; // g TFW // Proportion of first species (oyster) for two species polyculture FS.PolycultureSpeciesRatio = 0.5; FS.getParameters(); // Get parameters of farm var BoxTravelTime = FS.Length/FS.Boxes/FS.Velocity; // d FS.DeltaT = BoxTravelTime/CourantFactor; // FS.DeltaT = 1; // For tests, one day // FS.RunTime = 180; // days FS.TotalTimesteps = Math.round(FS.RunTime/FS.DeltaT); // alert(FS.TotalTimesteps); // For the time being, cutoff is a 4 year run FS.MaxRunTime = 1460; if ( FS.RunTime > FS.MaxRunTime ) FS.RunTime = FS.MaxRunTime; FS.ChlorophyllRemoval = 0; FS.NitrogenRemoval = 0; FS.NitrogenAddition = 0; FS.NitrogenInFaeces = 0; FS.DetritusFitration = 0; FS.PhytoFiltration = 0; FS.DetritusIngestion = 0; FS.PhytoIngestion = 0; FS.showInitialStatusBar(); document.farm.volume.value = FS.calculateVolume(); FS.splitBoxes(); if (FS.Boxes == 1) { document.farm.densitymiddle.value = "-"; document.farm.densitylast.value = "-"; FS.DensityMiddle = FS.DensityFirst; FS.DensityLast = FS.DensityFirst; } else if (FS.Boxes == 2) { document.farm.densitymiddle.value = "-"; FS.DensityMiddle = FS.DensityFirst; if (document.farm.densitylast.value == "-") { document.farm.densitylast.value = FS.DensityFirst; FS.DensityLast = FS.DensityFirst; } } else if (FS.Boxes > 2) { if (document.farm.densitylast.value == "-") { document.farm.densitylast.value = FS.DensityFirst; FS.DensityLast = FS.DensityFirst; } if (document.farm.densitymiddle.value == "-") { document.farm.densitymiddle.value = FS.DensityFirst; FS.DensityMiddle = FS.DensityFirst; } } // if more than 3 boxes, split into thirds if (FS.Boxes <= 3) FS.TotalIndividuals = FS.Volume * ( FS.DensityFirst * 1 + FS.DensityMiddle * 1 + FS.DensityLast * 1 ); else { // FS.splitBoxes(); FS.TotalIndividuals = FS.Volume * ( FS.DensityFirst * FS.P1 + FS.DensityMiddle * FS.P2 + FS.DensityLast * FS.P3 ); } document.farm.totalindividuals.value = Math.round(FS.TotalIndividuals); // ind FS.listModels(); } // display initial status bar function ShowInitialStatusBar() { var ModelSpecies = ": "; if ( document.farm.useshellfish.checked == 1 ) { switch(FS.MySpecies) { case 0: // generic ModelSpecies = " for Mussels: "; break; case 1: // clams ModelSpecies = " for Manila clams: "; break; case 2: // cockles ModelSpecies = " for cockles: "; break; case 3: // polyculture ModelSpecies = " for polyculture: "; break; default: break; } } var OutputRunTime = Math.round(FS.RunTime); status = "Model run" + ModelSpecies + OutputRunTime + " days"; } // Initialize for simulation function Initialize() { FS.getParameters(); FS.Chl = new Array(FS.Boxes), FS.ChlFlux = new Array(FS.Boxes), FS.Oxygen = new Array(FS.Boxes), FS.OxygenFlux = new Array(FS.Boxes), FS.POM = new Array(FS.Boxes), FS.POMFlux = new Array(FS.Boxes), FS.FATPOM = new Array(FS.Boxes), FS.FATPOMFlux = new Array(FS.Boxes), FS.TPM = new Array(FS.Boxes), FS.TPMFlux = new Array(FS.Boxes), FS.FATTPM = new Array(FS.Boxes), FS.FATTPMFlux = new Array(FS.Boxes); FS.Flow = FS.Velocity * FS.Width * FS.Depth; // m3 d-1 // Zero arrays for ( i = 0; i < (FS.Boxes); i++ ) { FS.Chl[i] = 0; FS.ChlFlux[i] = 0; FS.Oxygen[i] = 0; FS.OxygenFlux[i] = 0; FS.POM[i] = 0; FS.POMFlux[i] = 0; FS.FATPOM[i] = 0; FS.FATPOMFlux[i] = 0; FS.TPM[i] = 0; FS.TPMFlux[i] = 0; FS.FATTPM[i] = 0; FS.FATTPMFlux[i] = 0; } // Fill arrays for water quality variables for ( i = 0; i < (FS.Boxes); i++ ) { // x 1.0 to convert to float FS.Chl[i] = FS.ChlBoundary * 1.0; FS.Oxygen[i] = FS.DOBoundary * 1.0; FS.POM[i] = FS.POMBoundary * 1.0; FS.TPM[i] = FS.TPMBoundary * 1.0; } // Initialise with boundary, not saturation, // otherwise user-defined O2 will never be used // for ( i = 0; i < (FS.Boxes); i++ ) // FS.Oxygen[i] = FS.getOxygenSaturation(FS.WaterTemperature, FS.Salinity); if ( document.farm.useshellfish.checked == 1 ) { FS.ClassDensity = new Array(FS.Boxes * FS.Classes), FS.ClassDensityFlux = new Array(FS.Boxes * FS.Classes), FS.GrowthRate = new Array(FS.Boxes * FS.Classes), FS.Mortality = new Array(FS.Boxes * FS.Classes), FS.OrganismGrowth = new Array(FS.Boxes * FS.Classes), FS.OrganismScopeForGrowth = new Array(FS.Boxes * FS.Classes), FS.OrganismMortality = new Array(FS.Boxes * FS.Classes), // For polyculture FS.OysterClassDensity = new Array(FS.Boxes * FS.Classes), FS.OysterClassDensityFlux = new Array(FS.Boxes * FS.Classes), FS.OysterGrowthRate = new Array(FS.Boxes * FS.Classes), FS.OysterMortality = new Array(FS.Boxes * FS.Classes), FS.MusselClassDensity = new Array(FS.Boxes * FS.Classes), FS.MusselClassDensityFlux = new Array(FS.Boxes * FS.Classes), FS.MusselGrowthRate = new Array(FS.Boxes * FS.Classes), FS.MusselMortality = new Array(FS.Boxes * FS.Classes); // For individual biomass of one animal FS.IndividualBiomass = new Array(FS.Boxes), FS.IndividualBiomassFlux = new Array(FS.Boxes), FS.IndividualShellDryWeight = new Array(FS.Boxes), FS.IndividualShellDryWeightFlux = new Array(FS.Boxes), // For polyculture FS.IndividualOysterBiomass = new Array(FS.Boxes), FS.IndividualOysterBiomassFlux = new Array(FS.Boxes), FS.IndividualOysterShellDryWeight = new Array(FS.Boxes), FS.IndividualOysterShellDryWeightFlux = new Array(FS.Boxes), FS.IndividualMusselBiomass = new Array(FS.Boxes), FS.IndividualMusselBiomassFlux = new Array(FS.Boxes), FS.IndividualMusselShellDryWeight = new Array(FS.Boxes), FS.IndividualMusselShellDryWeightFlux = new Array(FS.Boxes); for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) { FS.ClassDensity[i] = 0; FS.ClassDensityFlux[i] = 0; FS.GrowthRate[i] = 0; FS.Mortality[i] = 0; FS.OrganismGrowth[i] = 0; FS.OrganismScopeForGrowth[i] = 0; FS.OrganismMortality[i] = 0; // For polyculture FS.OysterClassDensity[i] = 0; FS.OysterClassDensityFlux[i] = 0; FS.OysterGrowthRate[i] = 0; FS.OysterMortality[i] = 0; FS.MusselClassDensity[i] = 0; FS.MusselClassDensityFlux[i] = 0; FS.MusselGrowthRate[i] = 0; FS.MusselMortality[i] = 0; } for ( i = 0; i < FS.Boxes; i++ ) { FS.IndividualBiomass[i] = 0; FS.IndividualBiomassFlux[i] = 0; FS.IndividualShellDryWeight[i] = 0; FS.IndividualShellDryWeightFlux[i] = 0; // For polyculture FS.IndividualOysterBiomass[i] = 0; FS.IndividualOysterBiomassFlux[i] = 0; FS.IndividualOysterShellDryWeight[i] = 0; FS.IndividualOysterShellDryWeightFlux[i] = 0; FS.IndividualMusselBiomass[i] = 0; FS.IndividualMusselBiomassFlux[i] = 0; FS.IndividualMusselShellDryWeight[i] = 0; FS.IndividualMusselShellDryWeightFlux[i] = 0; } var MusselTotalFWToMeatDW = 15.06, // Estimated from Garen et al 2004, NEEDS IMPROVING MusselInitialTFW = 0.65, // g TFW OysterInitialTFW = 8.00; // g TFW for (k = 0; k < FS.Classes; k++) for (j = 0; j < FS.Boxes; j++) { if ( k == 0 ) { if ( FS.Boxes == 1 ) FS.ClassDensity[k * FS.Boxes + j] = FS.DensityFirst * FS.Volume; else if ( FS.Boxes == 2 ) { if (j==0) FS.ClassDensity[k * FS.Boxes + j] = FS.DensityFirst * FS.Volume; else if (j==1) FS.ClassDensity[k * FS.Boxes + j] = FS.DensityLast * FS.Volume; } else if ( FS.Boxes == 3 ) { if (j==0) FS.ClassDensity[k * FS.Boxes + j] = FS.DensityFirst * FS.Volume; else if (j==1) FS.ClassDensity[k * FS.Boxes + j] = FS.DensityMiddle * FS.Volume; else if (j==2) FS.ClassDensity[k * FS.Boxes + j] = FS.DensityLast * FS.Volume; } else // split into thirds { if ( j < FS.P1 ) FS.ClassDensity[k * FS.Boxes + j] = FS.DensityFirst * FS.Volume; else if ( j >= FS.P1 && j < (FS.P1 + FS.P2) ) FS.ClassDensity[k * FS.Boxes + j] = FS.DensityMiddle * FS.Volume; else FS.ClassDensity[k * FS.Boxes + j] = FS.DensityLast * FS.Volume; } } // alert(FS.ClassDensity[k * FS.Boxes + j]); } FS.NumberSeed = 0; for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) FS.NumberSeed = FS.NumberSeed + FS.ClassDensity[i]; // Proportion of first species for two species polyculture for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) { FS.OysterClassDensity[i] = FS.ClassDensity[i] * FS.PolycultureSpeciesRatio; FS.MusselClassDensity[i] = FS.ClassDensity[i] * (1-FS.PolycultureSpeciesRatio); } } if ( document.farm.useshellfish.checked == 1 ) { switch(FS.MySpecies) { case 0: // Generic shellfish aka mussels // Set all individual biomasses for ( i = 0; i < FS.Boxes; i++ ) FS.IndividualBiomass[i] = 5; // TFW 2006.05.03 // Set mortality for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) FS.Mortality[i] = 0.2 // 20% y-1 / FS.YearsToDays; // to d-1 break; case 1: // Clams // Set all individual biomasses for ( i = 0; i < FS.Boxes; i++ ) FS.IndividualBiomass[i] = 0.2; // TFW clams Pastres // Set mortality for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) FS.Mortality[i] = 0.2 // 20% y-1 / FS.YearsToDays; // to d-1 break; case 2: // Cockles // Set all individual biomasses for ( i = 0; i < FS.Boxes; i++ ) FS.IndividualBiomass[i] = 5; // TFW 2006.05.03 // Set mortality for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) FS.Mortality[i] = 0.2 // 20% y-1 / FS.YearsToDays; // to d-1 break; case 3: // Polyculture of oysters and mussels // Set all individual biomasses for ( i = 0; i < FS.Boxes; i++ ) FS.IndividualBiomass[i] = 5; // TFW 2006.05.03 // Set mortality for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) FS.Mortality[i] = 0.2 // 20% y-1 / FS.YearsToDays; // to d-1 break; default: break; } } } function ClearElements() { document.farm.chlfirst.value = "-"; document.farm.chlmiddle.value = "-"; document.farm.chllast.value = "-"; document.farm.chlaverage.value = "-"; document.farm.chlreduction.value = "-"; document.farm.dominimum.value = "-"; document.farm.doreduction.value = "-"; document.assetschlreduction.src="/images/ASSETSblank.jpg"; document.assetsdoreduction.src="/images/ASSETSblank.jpg"; document.assetsscorebeforerun.src="/images/ASSETSblank.jpg"; document.assetsscoreafterrun.src="/images/ASSETSblank.jpg"; ASSETSAFTER.innerText = ""; document.farm.adultsfirst.value = "-"; document.farm.adultsmiddle.value = "-"; document.farm.adultslast.value = "-"; document.farm.adultstotal.value = "-"; document.farm.adultsratio.value = "-"; document.farm.biomassfirst.value = "-"; document.farm.biomassmiddle.value = "-"; document.farm.biomasslast.value = "-"; document.farm.biomasstotal.value = "-"; document.farm.biomassratio.value = "-"; } function GetParameters() { FS.clearElements(); FS.Width = document.farm.width.value; FS.Length = document.farm.length.value; FS.Depth = document.farm.depth.value; FS.Boxes = document.farm.boxes.value; FS.Volume = FS.Width * FS.Length * FS.Depth / FS.Boxes; FS.ChlBoundary = document.farm.chlorophyll.value; // mg m-3 FS.POMBoundary = document.farm.pom.value; // g m-3 FS.TPMBoundary = document.farm.tpm.value; // g m-3 FS.Velocity = document.farm.currentspeed.value // m s-1 * FS.DaysToSeconds; // to m d-1 FS.WaterTemperature = document.farm.watertemperature.value; // oC // Environmental parameters FS.Salinity = 35.0; // default value if (document.farm.dissolvedoxygen.value != "") FS.DOBoundary = document.farm.dissolvedoxygen.value else { FS.DOBoundary = FS.getOxygenSaturation(FS.WaterTemperature, FS.Salinity); document.farm.dissolvedoxygen.value = FS.decimalPlaces(FS.DOBoundary,2); // mg L-1 } FS.CultivationPeriod = document.farm.cultivationperiod.value; // days if ( FS.CultivationPeriod != 1 ) CPE.innerText = "days" else CPE.innerText = "day"; if ( FS.CultivationPeriod > FS.MaxRunTime ) { FS.CultivationPeriod = FS.MaxRunTime; document.farm.cultivationperiod.value = FS.CultivationPeriod; } FS.RunTime = FS.CultivationPeriod; // days // FS.showInitialStatusBar(); FS.DensityFirst = document.farm.densityfirst.value; // ind FS.DensityMiddle = document.farm.densitymiddle.value; // ind FS.DensityLast = document.farm.densitylast.value; // ind // ASSETS chlorophyll a if (FS.ChlBoundary <= 5) document.assetschl.src="/images/ASSETShigh.jpg"; else if (FS.ChlBoundary > 5 && FS.ChlBoundary <= 10) document.assetschl.src="/images/ASSETSgood.jpg"; else if (FS.ChlBoundary > 10 && FS.ChlBoundary <= 20) document.assetschl.src="/images/ASSETSmoderate.jpg"; else if (FS.ChlBoundary > 20 && FS.ChlBoundary <= 60) document.assetschl.src="/images/ASSETSpoor.jpg"; else if (FS.ChlBoundary > 60) document.assetschl.src="/images/ASSETSbad.jpg"; else document.assetschl.src="/images/ASSETSblank.jpg"; // ASSETS Dissolved oxygen if (FS.DOBoundary == 0) document.assetsDO.src="/images/ASSETSbad.jpg"; else if (FS.DOBoundary > 0 && FS.DOBoundary <= 2) document.assetsDO.src="/images/ASSETSpoor.jpg"; else if (FS.DOBoundary > 2 && FS.DOBoundary <= 5) document.assetsDO.src="/images/ASSETSmoderate.jpg"; else if (FS.DOBoundary > 5 && FS.DOBoundary <= 8) document.assetsDO.src="/images/ASSETSgood.jpg"; else if (FS.DOBoundary > 8) document.assetsDO.src="/images/ASSETShigh.jpg"; else document.assetsDO.src="/images/ASSETSblank.jpg"; // ASSETS scores // Boundary chlorophyll var PrimarySymptomScore; if (FS.ChlBoundary <= 5) PrimarySymptomScore = 0.25; else if (FS.ChlBoundary > 5 && FS.ChlBoundary <= 10) PrimarySymptomScore = 0.5; else if (FS.ChlBoundary > 10 && FS.ChlBoundary <= 20) PrimarySymptomScore = 0.5; else if (FS.ChlBoundary > 20 && FS.ChlBoundary <= 60) PrimarySymptomScore = 1; else if (FS.ChlBoundary > 60) PrimarySymptomScore = 1; // Boundary dissolved oxygen var SecondarySymptomScore; if (FS.DOBoundary == 0 ) SecondarySymptomScore = 1; else if (FS.DOBoundary > 0 && FS.DOBoundary <= 2) SecondarySymptomScore = 1; else if (FS.DOBoundary > 2 && FS.DOBoundary <= 5) SecondarySymptomScore = 0.5; else if (FS.DOBoundary > 5 && FS.DOBoundary <= 8) SecondarySymptomScore = 0.25; else if (FS.DOBoundary > 8) SecondarySymptomScore = 0.25; // Final score var FinalScore = 0; if (PrimarySymptomScore <= 0.3) if ( SecondarySymptomScore <= 0.3 ) FinalScore = 5; else if ( SecondarySymptomScore > 0.3 && SecondarySymptomScore <= 0.6 ) FinalScore = 4; else FinalScore = 2; else if (PrimarySymptomScore > 0.3 && PrimarySymptomScore <= 0.6) if ( SecondarySymptomScore <= 0.3 ) FinalScore = 4; else if ( SecondarySymptomScore > 0.3 && SecondarySymptomScore <= 0.6 ) FinalScore = 3; else FinalScore = 1; else if ( SecondarySymptomScore <= 0.3 ) FinalScore = 3; else if ( SecondarySymptomScore > 0.3 && SecondarySymptomScore <= 0.6 ) FinalScore = 2; else FinalScore = 1; switch (FinalScore) { case 1: document.assetsscorebeforerun.src="/images/ASSETSbad.jpg"; ASSETS.style.color = "red"; ASSETS.innerText = "Bad"; break; case 2: document.assetsscorebeforerun.src="/images/ASSETSpoor.jpg"; ASSETSBEFORE.style.color = "orange"; // orange ASSETSBEFORE.innerText = "Poor"; break; case 3: document.assetsscorebeforerun.src="/images/ASSETSmoderate.jpg"; ASSETSBEFORE.style.color = "yellow"; // yellow ASSETSBEFORE.innerText = "Moderate"; break; case 4: document.assetsscorebeforerun.src="/images/ASSETSgood.jpg"; ASSETSBEFORE.style.color = "green"; ASSETSBEFORE.innerText = "Good"; break; case 5: document.assetsscorebeforerun.src="/images/ASSETShigh.jpg"; ASSETSBEFORE.style.color = "blue"; ASSETSBEFORE.innerText = "High"; break; default: document.assetsscorebeforerun.src="/images/ASSETSblank.jpg"; ASSETSBEFORE.innerText = ""; break; } if (FS.Boxes==1) { FS.DensityMiddle = FS.DensityFirst; // ind FS.DensityLast = FS.DensityFirst; // ind } else if (FS.Boxes==2) { FS.DensityMiddle = (FS.DensityFirst + // ind FS.DensityLast) / 2; // ind } FS.MySpecies = document.getElementById('selectspecies').selectedIndex; // document.farm.selectspecies.options.length = 0; // clear // document.farm.selectspecies.options[1] = null; // remove oysters // var FS.Species = document.selectspecies.selectedIndex; // breaks // alert(document.getElementById('selectspecies').selectedIndex); } function Go() { // alert("Before canned"); FS.getCannedData(); // alert("After canned"); // "Private" calculation functions here FS.transport(); FS.sediment(); // alert("After T&S"); // Graze if checked if ( document.farm.useshellfish.checked == 1 ) { switch(FS.MySpecies) { case 0: // generic FS.graze(); break; case 1: // clams FS.clamGraze(); break; case 2: // cockles FS.cockleGraze(); break; case 3: // polyculture FS.graze(); break; default: FS.graze(); break; } } } function Integrate() { // integration functions here var EnforceZero = 1; // Zero negative values when switched on (on=1, off=0) // Transport for ( i = 0; i < FS.Boxes; i++ ) { FS.Chl[i] = FS.Chl[i] + FS.ChlFlux[i] * FS.DeltaT; if (( EnforceZero ) && ( FS.Chl[i] < 0 )) FS.Chl[i] = 0; FS.ChlFlux[i] = 0; FS.Oxygen[i] = FS.Oxygen[i] + FS.OxygenFlux[i] * FS.DeltaT; if (( EnforceZero ) && ( FS.Oxygen[i] < 0 )) FS.Oxygen[i] = 0; FS.OxygenFlux[i] = 0; FS.POM[i] = FS.POM[i] + FS.POMFlux[i] * FS.DeltaT; if (( EnforceZero ) && ( FS.POM[i] < 0 )) FS.POM[i] = 0; FS.POMFlux[i] = 0; // FATPOM is the proportion of larger grain POM FS.FATPOM[i] = 0; if ( FS.POM[i] >= 0 ) FS.FATPOM[i] = FS.FATPOMFlux[i] * FS.DeltaT / FS.POM[i]; FS.FATPOMFlux[i] = 0; FS.TPM[i] = FS.TPM[i] + FS.TPMFlux[i] * FS.DeltaT; if (( EnforceZero ) && ( FS.TPM[i] < 0 )) FS.TPM[i] = 0; FS.TPMFlux[i] = 0; // FATTPM is the proportion of larger grain TPM FS.FATTPM[i] = 0; if ( FS.TPM[i] >= 0 ) FS.FATTPM[i] = FS.FATTPMFlux[i] * FS.DeltaT / FS.TPM[i]; FS.FATTPMFlux[i] = 0; } // Shellfish if ( document.farm.useshellfish.checked == 1 ) { if ( document.farm.usepopulation.checked == 1 ) { switch(FS.MySpecies) { case 3: // polyculture FS.demographicUpwind(); for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) FS.ClassDensityFlux[i] = FS.ClassDensityFlux[i] + FS.OrganismScopeForGrowth[i]; for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) { FS.ClassDensity[i] = FS.ClassDensity[i] + FS.ClassDensityFlux[i] * FS.DeltaT; FS.ClassDensityFlux[i] = 0; } break; default: FS.demographicUpwind(); for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) FS.ClassDensityFlux[i] = FS.ClassDensityFlux[i] + FS.OrganismScopeForGrowth[i]; for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) { FS.ClassDensity[i] = FS.ClassDensity[i] + FS.ClassDensityFlux[i] * FS.DeltaT; FS.ClassDensityFlux[i] = 0; } break; } } // Always do individual biomass code switch(FS.MySpecies) { case 3: // polyculture for ( i = 0; i < FS.Boxes; i++ ) { FS.IndividualBiomass[i] = FS.IndividualBiomass[i] + FS.IndividualBiomassFlux[i] * FS.DeltaT; FS.IndividualBiomassFlux[i] = 0; FS.IndividualShellDryWeight[i] = FS.IndividualShellDryWeight[i] + FS.IndividualShellDryWeightFlux[i] * FS.DeltaT; FS.IndividualShellDryWeightFlux[i] = 0; } break; default: // all single culture for ( i = 0; i < FS.Boxes; i++ ) { FS.IndividualBiomass[i] = FS.IndividualBiomass[i] + FS.IndividualBiomassFlux[i] * FS.DeltaT; FS.IndividualBiomassFlux[i] = 0; FS.IndividualShellDryWeight[i] = FS.IndividualShellDryWeight[i] + FS.IndividualShellDryWeightFlux[i] * FS.DeltaT; FS.IndividualShellDryWeightFlux[i] = 0; } break; } } // of shellfish loop } function GetCannedData() { return; // Enable for normal public operation // For the arrays below, the length is automatically read. Data // must be within one year, which iterates over multiple years // Clew Bay data for Keyzones var MyDayArray = [39,73,101,150,177,198,226,268]; var MyTArray = [7.8,8.1,8.75,12.35,15,17.15,16.55,15.35]; var MyChlArray = [0.80,9.61,1.20,0.40,0.67,0.67,1.87,1.07]; var MyPOMArray = [2.0479,3.2979,2.0979,2.1479,2.5479,1.9979,2.0479,3.5479]; var MyTPMArray = [12.5383,18.8883,12.6383,14.2883,13.5383,11.7383,12.2883,20.2883]; /* // Tagus data for station #3.0, APRH case study var MyDayArray = [21,54,111,138,168,230,294,348]; var MyTArray = [10.4,11.7,16,16.3,21.3,22,18.9,14.9]; var MyChlArray = [6.8,2.3,15.5,12.8,4.6,7.8,5.7,42.3]; var MyPOMArray = [26.4,24.82,21.37,25,36.05,24.49,67.2,19.2]; var MyTPMArray = [133,95.04,350.13,572.42,43.38,162.92,43,656]; */ /* // Ria Formosa data for station Ponte da Praia de Faro, no growth var MyDayArray = [100,129,158,187,217,246,274]; var MyTArray = [18.2,19.5,22.9,23.2,26.8,25.9,21.4]; var MyChlArray = [0.801,2.54,5.874,0.534,1.335,4.717,1.78]; var MyPOMArray = [1.7,7.2,2.6,4.2,3.8,7.5,5.5]; var MyTPMArray = [15.7,36,32.2,24.8,23.4,39.7,38.3]; */ /* // Carlingford Lough SMILE data for station 36, book case study var MyDayArray = [15,45,75,105,135,165,195,225,255,285,315,345]; var MyTArray = [4.48,7.86,11.99,15.99,18.33,18.69,16.96,13.60,9.48,5.68,3.19,2.72]; var MyChlArray = [0.05,0.23,5.08,9.04,2.93,2.61,2.43,2.54,2.00,1.01,0.25,0.05]; var MyPOMArray = [1.62,1.65,1.63,1.69,1.64,1.68,1.61,1.64,1.61,1.49,1.60,1.64]; var MyTPMArray = [6.55,6.64,6.49,6.35,6.25,6.35,6.07,5.94,5.89,6.16,6.52,6.63]; */ /* // Carlingford Lough SMILE data var MyDayArray = [27,61,102,139,235,348]; var MyTArray = [6.81,5.62,9.02,11.64,16.01,8.73]; var MyChlArray = [0.36,0.70,3.86,2.56,2.24,0.09]; var MyPOMArray = [2.61,2.71,2.54,2.22,1.66,1.78]; var MyTPMArray = [9.82,7.41,6.21,4.84,8.20,7.41]; */ /* // Sanggou Bay 1999 and 2000 var MyDayArray = [28,56,85,119,125,159,191,213,252,281,323,349]; var MyChlArray = [0.75,2.10,0.58,0.59,1.15,1.43,2.13,1.57,2.93,1.73,0.42,0.54]; var MyPOMArray = [15.52,2.06,3.14,4.17,1.34,2.54,5.22,3.01,3.33,4.24,6.75,0.72]; var MyTPMArray = [27.77,14.90,18.83,24.16,12.88,15.07,38.67,16.31,17.10,31.16,21.70,9.25]; var MyTArray = [0.56,2.50,6.40,11.84,13.94,17.77,20.92,24.14,25.00,20.41,28.04,7.66]; */ // alert(FS.RunTime); // alert(Math.floor(FS.TimeNow * FS.DeltaT)); // returns time in d // Calculates Julian Day correctly for periods greater than one year // previous formulation broke after 365 days var MyDay = Math.floor(FS.TimeNow * FS.DeltaT); var MyYear = Math.floor(MyDay / FS.YearsToDays); MyDay = MyDay - MyYear * FS.YearsToDays; FS.ChlBoundary = MyChlArray[0]; FS.POMBoundary = MyPOMArray[0]; FS.TPMBoundary = MyTPMArray[0]; /* // Square (no interpolation) for ( i = 0; i < MyDayArray.length; i++ ) if ( MyDayArray[i] == MyDay ) { FS.ChlBoundary = MyChlArray[i]; FS.POMBoundary = MyPOMArray[i]; FS.TPMBoundary = MyTPMArray[i]; FS.WaterTemperature = MyTArray[i]; // alert(FS.ChlBoundary); break; } */ // Linear interpolation var DayBefore, DayAfter; for ( i = 0; i < MyDayArray.length; i++ ) if ( MyDay == MyDayArray[i] ) { FS.ChlBoundary = MyChlArray[i]; FS.POMBoundary = MyPOMArray[i]; FS.TPMBoundary = MyTPMArray[i]; FS.WaterTemperature = MyTArray[i]; // alert(FS.ChlBoundary); break; } else if ( MyDay < MyDayArray[i] ) { DayAfter = MyDayArray[i]; // alert(DayAfter); if ( i == 0 ) DayBefore = MyDayArray[MyDayArray.length-1]; // last element else DayBefore = MyDayArray[i-1]; // alert(DayBefore); if ( DayAfter > DayBefore ) // normal case { FS.ChlBoundary = MyChlArray[i-1] + ( MyChlArray[i] - MyChlArray[i-1] ) * ( MyDay - DayBefore ) / ( DayAfter - DayBefore); FS.POMBoundary = MyPOMArray[i-1] + ( MyPOMArray[i] - MyPOMArray[i-1] ) * ( MyDay - DayBefore ) / ( DayAfter - DayBefore); FS.TPMBoundary = MyTPMArray[i-1] + ( MyTPMArray[i] - MyTPMArray[i-1] ) * ( MyDay - DayBefore ) / ( DayAfter - DayBefore); FS.WaterTemperature = MyTArray[i-1] + ( MyTArray[i] - MyTArray[i-1] ) * ( MyDay - DayBefore ) / ( DayAfter - DayBefore); } else { // alert("Hi"); FS.ChlBoundary = MyChlArray[MyDayArray.length-1] + ( MyChlArray[i] - MyChlArray[MyDayArray.length-1] ) * ( MyDay + 365 - DayBefore ) / ( DayAfter + 365 - DayBefore); // alert(FS.ChlBoundary); FS.POMBoundary = MyPOMArray[MyDayArray.length-1] + ( MyPOMArray[i] - MyPOMArray[MyDayArray.length-1] ) * ( MyDay + 365 - DayBefore ) / ( DayAfter + 365 - DayBefore); // alert(FS.POMBoundary); FS.TPMBoundary = MyTPMArray[MyDayArray.length-1] + ( MyTPMArray[i] - MyTPMArray[MyDayArray.length-1] ) * ( MyDay + 365 - DayBefore ) / ( DayAfter + 365 - DayBefore); // alert(FS.TPMBoundary); FS.WaterTemperature = MyTArray[MyDayArray.length-1] + ( MyTArray[i] - MyTArray[MyDayArray.length-1] ) * ( MyDay + 365 - DayBefore ) / ( DayAfter + 365 - DayBefore); // alert(FS.WaterTemperature); } break; } else // must be past the last value in the array if ( i == MyDayArray.length-1 ) { DayBefore = MyDayArray[i-1]; DayAfter = MyDayArray[0]; // first element FS.ChlBoundary = MyChlArray[i-1] + ( MyChlArray[0] - MyChlArray[i-1] ) * ( MyDay - DayBefore ) / ( DayAfter + 365 - DayBefore); FS.POMBoundary = MyPOMArray[i-1] + ( MyPOMArray[0] - MyPOMArray[i-1] ) * ( MyDay - DayBefore ) / ( DayAfter + 365 - DayBefore); FS.TPMBoundary = MyTPMArray[i-1] + ( MyTPMArray[0] - MyTPMArray[i-1] ) * ( MyDay - DayBefore ) / ( DayAfter + 365 - DayBefore); FS.WaterTemperature = MyTArray[i-1] + ( MyTArray[0] - MyTArray[i-1] ) * ( MyDay - DayBefore ) / ( DayAfter + 365 - DayBefore); break; } /* if ( ( MyDay > 0 ) && ( MyDay % 40 == 0 ) ) alert(MyDay); */ // if ( MyDay % 40 == 0 ) // alert(FS.ChlBoundary); // FS.ChlBoundary; // FS.POMBoundary; // FS.TPMBoundary; } // Round to x decimal places function DecimalPlaces(mynumber,mydp) { mydp = Math.pow(10,mydp); mynumber = Math.round(mynumber*mydp)/mydp; return mynumber; } // Calculate log10 (JavaScript only calculates ln) function Log10(x) { return Math.LOG10E * Math.log(x); } function GetOxygenSaturation(mytemperature,mysalinity) { var temperature = mytemperature * 1.00, // to make it a floating point type salinity = mysalinity; // From Benson, B.B., and Krause, D., Jr. 1984. The concentration and isotopic // fractionation of oxygen dissolved in freshwater and seawater in equilibrium // with the atmosphere. Limnology and Oceanography, 29: 620–632. // JGF fixed 2003.02.09 var Cs, lnCs, kelvin = 273.15; temperature = temperature + kelvin; // Sent in Celsius O2I = -135.90205; O2J = 1.575701 * Math.pow(10,5); O2K = -6.642308 * Math.pow(10,7); O2L = 1.243800 * Math.pow(10,10); O2M = -8.621949 * Math.pow(10,11); O2N = 0.017674; O2P = -10.754; O2Q = 2140.7; // Solubility in umol L-1 lnCs = O2I + O2J / temperature + O2K / Math.pow(temperature,2) + O2L / Math.pow(temperature,3) + O2M / Math.pow(temperature,4) - salinity * ( O2N + O2P / temperature + O2Q / Math.pow(temperature,2)); Cs = Math.exp(lnCs); var MolarMass = 31.9988, // One O2 molecule weighs 15.9994 * 2 g GasConversionFactor = MolarMass/1000; return Cs * GasConversionFactor; } //Riley & Skirrow - Page 391 function GetDensity(mytemperature,mysalinity) // Call Salinity in o/oo // and Temperature in oC { var temperature = mytemperature * 1.00, // to make it a floating point type salinity = mysalinity; var At,Bt,Et, SigmaT, Sigma0, Cl; //Use either Cox or Knudsen} if (salinity > 10) // Cox et al., 1970 - First coefficient is ten(-2) not ten(2) as Riley // indicates in the listed equation SigmaT = 8.009691 * Math.pow(10,-2) + 5.88194 * Math.pow(10,-2) * temperature + 0.7901864 * salinity - 8.114654 * Math.pow(10,-3) * Math.pow(temperature,2) - 3.253104 * Math.pow(10,-3) * salinity * temperature + 1.31708 * Math.pow(10,-4) * Math.pow(salinity,2) + 4.76004 * Math.pow(10,-5) * temperature * Math.pow(temperature,2) // FIX & TEST THIS ********** 23/06/2000 + 3.892875 * Math.pow(10,-5) * salinity * Math.pow(temperature,2) + 2.879715 * Math.pow(10,-6) * Math.pow(salinity,2) * temperature - 6.118315 * Math.pow(10,-8) * salinity * Math.pow(salinity,2); // FIX & TEST THIS ********** 23/06/2000 else { // Knudsen - 1901 Cl = salinity/1.80655; Sigma0 = -6.9 * Math.pow(10,-2) + 1.4708 * Cl - 1.570 * Math.pow(10,-3) * Math.pow(Cl,2) + 3.98 * Math.pow(10,-5) * Cl; At = 4.7867 * Math.pow(10,-3) * temperature - 9.8185 * Math.pow(10,-5) * Math.pow(temperature,2) + 1.0843 * Math.pow(10,-6) * temperature * Math.pow(temperature,2); Bt = 1.803 * Math.pow(10,-5) * temperature - 8.146 * Math.pow(10,-7) * Math.pow(temperature,2) + 1.667 * Math.pow(10,-8) * temperature * Math.pow(temperature,2); Et = -(Math.pow((temperature-3.98),2) * (temperature +283) /(503.57 * (temperature + 67.26))); SigmaT = (Sigma0 + 0.1324) * (1 - At + Bt * (Sigma0 - 0.1324)) + Et; } return SigmaT + 1000; // kg m-3 } // Riley & Skirrow - Page 576 - in centipoise function GetViscosity(mytemperature,mysalinity) // Call Salinity in o/oo // and Temperature in oC { var temperature = mytemperature * 1.00, // to make it a floating point type salinity = mysalinity, LocalGravity = FS.AccelerationOfGravity; // m s-2 var A5 = 0.000366, A25 = 0.001403, B5 = 0.002756, B25 = 0.003416; var viscosity_pureH20, A_t, B_t, A_slope, B_slope, A_intercept, B_intercept, Cl_vol; // Calculate viscosity of pure water for specified temperature viscosity_pureH20 = 1.0020 * Math.pow( 10, (1.1709 * (20 - temperature) - 0.001827 * Math.pow( (temperature - 20),2 )) / (temperature + 89.93)); // Calculate volume chlorinity = chlorinity * density Cl_vol = (salinity/1.80655) * FS.getDensity(temperature,salinity)/1000; // Linear interpolation/extrapolation to find A_t and B_t A_slope = (A25-A5)/20; B_slope = (B25-B5)/20; A_intercept = A5 - A_slope * 5; B_intercept = B5 - B_slope * 5; A_t = A_slope * temperature + A_intercept; B_t = B_slope * temperature + B_intercept; // Calculate viscosity return viscosity_pureH20 * (1+ A_t * Math.sqrt(Cl_vol) + B_t * Cl_vol); } function GetFallVelocity(grainsize,mytemperature) // Call grain size in mm // and temperature in oC { var temperature = mytemperature * 1.00, // to make it a floating point type two = 2, ninths = 9, WaterSalinity = 35.0, ParticleDensity = FS.SedimentParticleDensity, // kg m-3 LocalGravity = FS.AccelerationOfGravity, // m s-2 FallVelocity; // Stokes equation - results in m s-1 FallVelocity = two * LocalGravity * (ParticleDensity - FS.getDensity(temperature,WaterSalinity)) * Math.pow(Math.pow(10,grainsize * -FS.log10(2)) * 0.001/2,2) / (ninths * FS.getViscosity(temperature,WaterSalinity) / 1000); // m s-1 return FallVelocity; } function PrepareRun() { if ( FS.ModelRunning == 1 ) return; MyBar.showBar(); var OutputRunTime = Math.round(FS.RunTime); status = OutputRunTime + " day model run: 0% done..."; FS.clearElements(); FS.StopButton = 0; } function EndRun() { MyBar.hideBar(); if ( FS.StopButton == 0 ) status = "Model run complete (" + FS.RunTime + " days)"; else { if ( FS.DayString == 1 ) status = "Model run complete (" + FS.DayString + " days)"; else status = "Model run complete (" + FS.DayString + " days)"; } document.farm.calculatenow.innerText = "Simulate now"; FS.ModelRunning = 0; } function ShowDebugger() { alert("TPM (mg L-1) in box 1: " + FS.decimalPlaces(FS.TPM[0],2) + "\nPOM (mg L-1) in box 1: " + FS.decimalPlaces(FS.POM[0],2)); if ( document.farm.useshellfish.checked != 1 ) return; var factor, unit; if ( document.farm.usepopulation.checked == 1 ) { factor = 1.0; unit = "k"; } else { factor = 1000; unit = ""; } var NitrogenBalance = - FS.NitrogenRemoval + FS.NitrogenAddition + FS.NitrogenInFaeces; alert("Phytoplankton initial conc (ug L-1):" + FS.decimalPlaces(FS.ChlBoundary*1.0,2) + "\nPhytoplankton removal (" + unit + "g N): -" + FS.decimalPlaces(FS.ChlorophyllRemoval*factor,2) + "\nPOM removal (" + unit + "g N): -" + FS.decimalPlaces((FS.NitrogenRemoval-FS.ChlorophyllRemoval)*factor,2) + "\nNitrogen excretion (" + unit + "g N): " + FS.decimalPlaces(FS.NitrogenAddition*factor,2) + "\nNitrogen in faeces (" + unit + "g N): " + FS.decimalPlaces(FS.NitrogenInFaeces*factor,2) + "\nNitrogen mass balance (" + unit + "g N): " + FS.decimalPlaces(NitrogenBalance*factor,2)); // Calculate proportion of phytoplankton and detritus ingested var ProportionPhyto = FS.PhytoIngestion / FS.PhytoFiltration; var ProportionDetritus = FS.DetritusIngestion / FS.DetritusFitration; alert("Proportion of phytoplankton ingested: " + FS.decimalPlaces(ProportionPhyto,3) + "\nProportion of detritus ingested: " + FS.decimalPlaces(ProportionDetritus,3)); } function CalculateASSETS() { // Only proceed if there is a valid value if ( document.farm.chlaverage.value == "-" ) return; // Average chlorophyll var MeanChla = document.farm.chlaverage.value; if (MeanChla <= 5) document.assetschlreduction.src="/images/ASSETShigh.jpg"; else if (MeanChla > 5 && MeanChla <= 10) document.assetschlreduction.src="/images/ASSETSgood.jpg"; else if (MeanChla > 10 && MeanChla <= 20) document.assetschlreduction.src="/images/ASSETSmoderate.jpg"; else if (MeanChla > 20 && MeanChla <= 60) document.assetschlreduction.src="/images/ASSETSpoor.jpg"; else if (MeanChla > 60) document.assetschlreduction.src="/images/ASSETSbad.jpg"; else document.assetschlreduction.src="/images/ASSETSblank.jpg"; // Minimum oxygen var MinimumDO = document.farm.dominimum.value; if (MinimumDO == 0 ) document.assetsdoreduction.src="/images/ASSETSbad.jpg"; else if (MinimumDO > 0 && MinimumDO <= 2) document.assetsdoreduction.src="/images/ASSETSpoor.jpg"; else if (MinimumDO > 2 && MinimumDO <= 5) document.assetsdoreduction.src="/images/ASSETSmoderate.jpg"; else if (MinimumDO > 5 && MinimumDO <= 8) document.assetsdoreduction.src="/images/ASSETSgood.jpg"; else if (MinimumDO > 8) document.assetsdoreduction.src="/images/ASSETShigh.jpg"; else document.assetsdoreduction.src="/images/ASSETSblank.jpg"; // ASSETS scores // Average chlorophyll var PrimarySymptomScore; if (MeanChla <= 5) PrimarySymptomScore = 0.25; else if (MeanChla > 5 && MeanChla <= 10) PrimarySymptomScore = 0.5; else if (MeanChla > 10 && MeanChla <= 20) PrimarySymptomScore = 0.5; else if (MeanChla > 20 && MeanChla <= 60) PrimarySymptomScore = 1; else if (MeanChla > 60) PrimarySymptomScore = 1; // Minimum dissolved oxygen var SecondarySymptomScore; if (MinimumDO == 0 ) SecondarySymptomScore = 1; else if (MinimumDO > 0 && MinimumDO <= 2) SecondarySymptomScore = 1; else if (MinimumDO > 2 && MinimumDO <= 5) SecondarySymptomScore = 0.5; else if (MinimumDO > 5 && MinimumDO <= 8) SecondarySymptomScore = 0.25; else if (MinimumDO > 8) SecondarySymptomScore = 0.25; // Final score var FinalScore = 0; if (PrimarySymptomScore <= 0.3) if ( SecondarySymptomScore <= 0.3 ) FinalScore = 5; else if ( SecondarySymptomScore > 0.3 && SecondarySymptomScore <= 0.6 ) FinalScore = 4; else FinalScore = 2; else if (PrimarySymptomScore > 0.3 && PrimarySymptomScore <= 0.6) if ( SecondarySymptomScore <= 0.3 ) FinalScore = 4; else if ( SecondarySymptomScore > 0.3 && SecondarySymptomScore <= 0.6 ) FinalScore = 3; else FinalScore = 1; else if ( SecondarySymptomScore <= 0.3 ) FinalScore = 3; else if ( SecondarySymptomScore > 0.3 && SecondarySymptomScore <= 0.6 ) FinalScore = 2; else FinalScore = 1; switch (FinalScore) { case 1: document.assetsscoreafterrun.src="/images/ASSETSbad.jpg"; ASSETSAFTER.style.color = "red"; ASSETSAFTER.innerText = "Bad"; break; case 2: document.assetsscoreafterrun.src="/images/ASSETSpoor.jpg"; ASSETSAFTER.style.color = "orange"; // orange ASSETSAFTER.innerText = "Poor"; break; case 3: document.assetsscoreafterrun.src="/images/ASSETSmoderate.jpg"; ASSETSAFTER.style.color = "yellow"; // yellow ASSETSAFTER.innerText = "Moderate"; break; case 4: document.assetsscoreafterrun.src="/images/ASSETSgood.jpg"; ASSETSAFTER.style.color = "green"; ASSETSAFTER.innerText = "Good"; break; case 5: document.assetsscoreafterrun.src="/images/ASSETShigh.jpg"; ASSETSAFTER.style.color = "blue"; ASSETSAFTER.innerText = "High"; break; default: document.assetsscoreafterrun.src="/images/ASSETSblank.jpg"; ASSETSAFTER.innerText = ""; break; } } function ProcessFileData(MyCookie,MyCounter) { switch (MyCounter) { case 0: // alert(MyCookie); document.farm.filename.value = MyCookie; break; case 1: document.farm.width.value = MyCookie; break; case 2: document.farm.length.value = MyCookie; break; case 3: document.farm.depth.value = MyCookie; break; case 4: document.farm.boxes.value = MyCookie; break; case 5: if (MyCookie == "true") document.farm.usebottomculture.checked = 1 else document.farm.usebottomculture.checked = 0; break; case 6: document.farm.selectspecies.selectedIndex = MyCookie; break; case 7: document.farm.cultivationperiod.value = MyCookie; break; case 8: document.farm.densityfirst.value = MyCookie; break; case 9: document.farm.densitymiddle.value = MyCookie; break; case 10: document.farm.densitylast.value = MyCookie; break; case 11: if (MyCookie == "true") document.farm.useshellfish.checked = 1 else document.farm.useshellfish.checked = 0; break; case 12: if (MyCookie == "true") document.farm.usepopulation.checked = 1 else document.farm.usepopulation.checked = 0; break; case 13: document.farm.watertemperature.value = MyCookie; break; case 14: document.farm.currentspeed.value = MyCookie; break; case 15: document.farm.chlorophyll.value = MyCookie; break; case 16: document.farm.pom.value = MyCookie; break; case 17: document.farm.tpm.value = MyCookie; break; case 18: document.farm.dissolvedoxygen.value = MyCookie; FS.updateOutputs(); DefineModelSettings(); // Needed for runtime based on velocity break; // Outputs also stored case 19: // alert(MyCookie); document.farm.biomassfirst.value = MyCookie; break; case 20: document.farm.biomassmiddle.value = MyCookie; break; case 21: document.farm.biomasslast.value = MyCookie; break; case 22: document.farm.biomasstotal.value = MyCookie; break; case 23: document.farm.biomassratio.value = MyCookie; break; case 24: document.farm.adultsfirst.value = MyCookie; break; case 25: document.farm.adultsmiddle.value = MyCookie; break; case 26: document.farm.adultslast.value = MyCookie; break; case 27: document.farm.adultstotal.value = MyCookie; break; case 28: document.farm.adultsratio.value = MyCookie; break; case 29: document.farm.chlfirst.value = MyCookie; break; case 30: document.farm.chlmiddle.value = MyCookie; break; case 31: document.farm.chllast.value = MyCookie; break; case 32: document.farm.chlaverage.value = MyCookie; break; case 33: document.farm.chlreduction.value = MyCookie; break; case 34: document.farm.dominimum.value = MyCookie; break; case 35: document.farm.doreduction.value = MyCookie; FS.calculateASSETS(); break; default: // alert(MyCookie); break; } // FS.updateOutputs(); Moved to before output processing to avoid ClearElements() } function ListModels() { var FileList = document.farm.filelist; for (var i = 0; i < FileList.options.length; i++) FileList.options[i] = null; FileList.options.length = 0; var MyNewOption = new Option("Please select...", "nomodel", false, false); FileList.options[FileList.options.length] = MyNewOption; var MyNumberOfModels = FS.findModels(); // alert(MyNumberOfModels); if ( MyNumberOfModels == 0 ) return; else { for (var i = 0; i < MyNumberOfModels; i++) { MyNewOption = new Option(FS.ModelName[i], FS.ModelName[i], false, false); FileList.options[FileList.options.length] = MyNewOption; // alert(FS.ModelName[i]); // alert(FS.ModelFirst[i]); // alert(FS.ModelLast[i]); } } // document.farm.selectspecies.options[1] = null; // remove oysters } function FindModels() { // alert("FARM debugging enabled"); // if ( navigator.cookieEnabled == false ) // { // alert("Cookies turned off"); // return; // } // else // alert("Cookies turned on"); // p.270 JS guide var allcookies = document.cookie; var pos = allcookies.indexOf("FARM="); // alert(pos); if (pos != -1 ) { var start = pos + 5; var end = allcookies.indexOf(";", start); if (end == -1) end = allcookies.length; var value = allcookies.substring(start,end); value = unescape(value); var MyLength = value.length; // alert(value); var Separator = FS.Separator, Marks = FS.Fields, // Number of separators, depends on number of fields MyMark = 0; // Number of saved models for ( var i=1; i < MyLength; i++) { if ( value.substring(i-1,i) == Separator ) MyMark++; } var TotalModels = MyMark/Marks; // alert(TotalModels); FS.ModelName = new Array(TotalModels); FS.ModelValue = new Array(TotalModels); FS.ModelMark = new Array(TotalModels); // FS.ModelFirst = new Array(TotalModels); // FS.ModelLast = new Array(TotalModels); // Find models and fill array var FirstChar, LastChar; MyMark = 0; for ( var i=0; i < TotalModels; i++) { MyMark = 0; for ( var j=1; j <= MyLength; j++) { if ( value.substring(j-1,j) == Separator ) { if ( MyMark == i * Marks ) FirstChar = j; if (MyMark == i * Marks + 1 ) { LastChar = j-1; // alert(FirstChar); // alert(LastChar); FS.ModelName[i] = value.substring(FirstChar,LastChar); // FS.ModelFirst[i] = FirstChar; // FS.ModelLast[i] = LastChar; // alert(value.substring(FirstChar,LastChar)); break; } MyMark++; } } } var j = 0; MyMark = 0; for ( var i=1; i < MyLength; i++) { if ( value.substring(i-1,i) == Separator ) { if ( MyMark % Marks == 0 ) { FS.ModelMark[j] = i-1; // alert(FS.ModelMark[j]); j++; } MyMark++; } } for ( var i=0; i < TotalModels; i++) { if ( i < TotalModels-1 ) FS.ModelValue[i] = value.substring(FS.ModelMark[i],FS.ModelMark[i+1]); else FS.ModelValue[i] = value.substring(FS.ModelMark[i],MyLength); // alert(FS.ModelValue[i]); } return TotalModels; } else return 0; } function LoadModel() { var MyNumberOfModels = FS.findModels(); // alert(MyNumberOfModels); if ( MyNumberOfModels == 0 ) return; /* else { for (var i = 0; i < MyNumberOfModels; i++) { alert(FS.ModelName[i]); alert(FS.ModelFirst[i]); alert(FS.ModelLast[i]); } } */ var allcookies = document.cookie; var pos = allcookies.indexOf("FARM="); var start = pos + 5, end = allcookies.indexOf(";", start); if (end == -1) end = allcookies.length; var value = allcookies.substring(start,end); value = unescape(value); var MyLength = value.length; var Separator = FS.Separator, // "#" in hex Marks = FS.Fields, // Number of separators, depends on number of fields MyMark = 0; // Select chosen model here var FirstMark, FirstChar, LastChar, SelectedModel = document.getElementById('filelist').selectedIndex-1; // alert(SelectedModel); FirstMark = SelectedModel * Marks; // Fixed in delete function for ( var i=1; i <= MyLength; i++) { if (MyMark == FirstMark ) FirstChar = i-1; if (MyMark == FirstMark + Marks ) { if ( i < MyLength ) LastChar = i-1; else LastChar = i; } if ( value.substring(i-1,i) == Separator ) MyMark++; } // And then load it finalvalue = value.substring(FirstChar,LastChar); // 2006.04.30 - start at 1 because first char is # var i = 0, StartHash = 1, EndHash = 1, CookieField; var FinalValue = finalvalue + Separator; var FinalLength = FinalValue.length; // alert(FinalValue); do { EndHash = FinalValue.indexOf(Separator, StartHash); CookieField = FinalValue.substring(StartHash,EndHash); // call function here ProcessFileData(CookieField,i); // process then loop EndHash++; i++; StartHash = EndHash; } while (EndHash < FinalLength) // Moved to ProcessFileData, before output processing to avoid ClearElements() // DefineModelSettings(); // Needed for runtime based on velocity } function SaveModel() { // document.savethemodel.src="/images/diskdownfinal.jpg"; var Separator = FS.Separator; var allcookies = document.cookie; // Lengths // 45 No cookies // 150 1 cookie 108 length // 300 2 cookie 102 length // Average length = 150 + 45 initial overhead, 4K max is 4092bytes, gives about 25-26 cookies var maxcookielength = 3900; var ModelName = document.farm.filename.value; if ( ModelName == "" ) { alert("Please enter a name for your model."); return; } var MyNumberOfModels = FS.findModels(); var value = ""; // alert(MyNumberOfModels); if ( MyNumberOfModels != 0 ) { for (var i = 0; i < MyNumberOfModels; i++) { if ( ModelName == FS.ModelName[i] ) { var msg = "\nWarning!" + " Model \"" + ModelName + "\" already exists. Replace?"; if (!confirm(msg)) return; // abort save // alert("Warning! Duplicate name - model will be replaced.") } else { // Only here, to allow duplicate names without increased cookie size if (allcookies.length >maxcookielength) { alert("Warning! There is no storage space left, please delete some models."); return; } value = value + FS.ModelValue[i]; } } } var nextyear = new Date(); nextyear.setFullYear(nextyear.getFullYear() + 1); document.cookie = "FARM=" + escape(value) + escape(Separator) + escape(ModelName) + escape(Separator) + escape(document.farm.width.value) + escape(Separator) + escape(document.farm.length.value) + escape(Separator) + escape(document.farm.depth.value) + escape(Separator) + escape(document.farm.boxes.value) + escape(Separator) + escape(document.farm.usebottomculture.checked) + escape(Separator) + escape(document.farm.selectspecies.selectedIndex) + escape(Separator) + escape(document.farm.cultivationperiod.value) + escape(Separator) + escape(document.farm.densityfirst.value) + escape(Separator) + escape(document.farm.densitymiddle.value) + escape(Separator) + escape(document.farm.densitylast.value) + escape(Separator) + escape(document.farm.useshellfish.checked) + escape(Separator) + escape(document.farm.usepopulation.checked) + escape(Separator) + escape(document.farm.watertemperature.value) + escape(Separator) + escape(document.farm.currentspeed.value) + escape(Separator) + escape(document.farm.chlorophyll.value) + escape(Separator) + escape(document.farm.pom.value) + escape(Separator) + escape(document.farm.tpm.value) + escape(Separator) + escape(document.farm.dissolvedoxygen.value) + escape(Separator) + escape(document.farm.biomassfirst.value) + escape(Separator) + escape(document.farm.biomassmiddle.value) + escape(Separator) + escape(document.farm.biomasslast.value) + escape(Separator) + escape(document.farm.biomasstotal.value) + escape(Separator) + escape(document.farm.biomassratio.value) + escape(Separator) + escape(document.farm.adultsfirst.value) + escape(Separator) + escape(document.farm.adultsmiddle.value) + escape(Separator) + escape(document.farm.adultslast.value) + escape(Separator) + escape(document.farm.adultstotal.value) + escape(Separator) + escape(document.farm.adultsratio.value) + escape(Separator) + escape(document.farm.chlfirst.value) + escape(Separator) + escape(document.farm.chlmiddle.value) + escape(Separator) + escape(document.farm.chllast.value) + escape(Separator) + escape(document.farm.chlaverage.value) + escape(Separator) + escape(document.farm.chlreduction.value) + escape(Separator) + escape(document.farm.dominimum.value) + escape(Separator) + escape(document.farm.doreduction.value) + "; expires=" + nextyear.toGMTString(); FS.listModels(); } function LiveDisk() { document.savethemodel.src="/images/disklive.jpg"; } function DeadDisk() { document.savethemodel.src="/images/diskdeaddw.jpg"; } function DeleteModel() { var ModelName = document.farm.filename.value, MyNumberOfModels = FS.findModels(); if (( ModelName == "" ) || (MyNumberOfModels == 0)) return; FS.listModels(); var ModelNumber; // alert(MyNumberOfModels); if ( MyNumberOfModels == 0 ) return; for (var i = 0; i < MyNumberOfModels; i++) if ( FS.ModelName[i] == ModelName) { ModelNumber = i; break; } var allcookies = document.cookie; var pos = allcookies.indexOf("FARM="); var start = pos + 5, end = allcookies.indexOf(";", start); if (end == -1) end = allcookies.length; var value = allcookies.substring(start,end); value = unescape(value); var MyLength = value.length; var Separator = FS.Separator, // "#" in hex Marks = FS.Fields, // Number of separators, depends on number of fields MyMark = 0; // Select chosen model here var FirstMark, FirstChar, LastChar, SelectedModel = ModelNumber; // alert(SelectedModel); FirstMark = SelectedModel * Marks; for ( var i=1; i <= MyLength; i++) { if (MyMark == FirstMark ) FirstChar = i-1; if (MyMark == FirstMark + Marks ) { if ( i < MyLength ) LastChar = i-1; else LastChar = i; } if ( value.substring(i-1,i) == Separator ) MyMark++; } // And then delete it var firstpart = value.substring(0,FirstChar), lastpart = value.substring(LastChar,MyLength), finalstring = firstpart + lastpart; var msg = "\nWarning!" + " You are about to delete\n the \"" + ModelName + "\" model. Continue?"; if (!confirm(msg)) return; // abort delete var nextyear = new Date(); nextyear.setFullYear(nextyear.getFullYear() + 1); document.cookie = "FARM=" + escape(finalstring) + "; expires=" + nextyear.toGMTString(); document.farm.filename.value = ""; FS.listModels(); } function LiveDelete() { var MyNumberOfModels = FS.findModels(), ModelName = document.farm.filename.value; if (( ModelName == "" ) || (MyNumberOfModels == 0)) return; document.deletethemodel.src="/images/deletelive.jpg"; } function DeadDelete() { document.deletethemodel.src="/images/deletedead.jpg"; } function UpdatePopulation() { if ( document.farm.useshellfish.checked == 0 ) { document.farm.usepopulation.checked = 0; document.farm.usebottomculture.checked = 0; } else { document.farm.usepopulation.checked = 1; // Change labels NF1.innerText = "Adults (first box)"; NF2.innerText = "Adults (middle box)"; NF3.innerText = "Adults (last box)"; TotalAdults.innerText = "Adults (total)"; HarvestableAnimals.innerText = "Harvestable animals"; HarvestableBiomass.innerText = "Harvestable biomass"; TotalHarvest.innerText = "Total harvest (TPP)"; BiomassRatio.innerText = "Biomass ratio (APP)"; BF1.innerText = "tons"; BF2.innerText = "tons"; BF3.innerText = "tons"; BFA.innerText = "tons"; BRA.innerText = ""; } FS.clearElements(); } function UpdateOutputs() { if ( document.farm.useshellfish.checked == 0 ) { document.farm.usepopulation.checked = 0; return; } if ( document.farm.usepopulation.checked == 1 ) { // Change labels NF1.innerText = "Adults (first box)"; NF2.innerText = "Adults (middle box)"; NF3.innerText = "Adults (last box)"; TotalAdults.innerText = "Adults (total)"; HarvestableAnimals.innerText = "Harvestable animals"; HarvestableBiomass.innerText = "Harvestable biomass"; TotalHarvest.innerText = "Total harvest (TPP)"; BiomassRatio.innerText = "Biomass ratio (APP)"; BF1.innerText = "tons"; BF2.innerText = "tons"; BF3.innerText = "tons"; BFA.innerText = "tons"; BRA.innerText = ""; } else { // Change labels NF1.innerText = "Animals (first box)"; NF2.innerText = "Animals (middle box)"; NF3.innerText = "Animals (last box)"; TotalAdults.innerText = "Animals (total)"; HarvestableAnimals.innerText = "Individuals"; HarvestableBiomass.innerText = "Individual weight"; TotalHarvest.innerText = "Average weight"; BiomassRatio.innerText = "Shell length"; BF1.innerText = "g TFW"; BF2.innerText = "g TFW"; BF3.innerText = "g TFW"; BFA.innerText = "g TFW"; BRA.innerText = "cm"; } FS.clearElements(); } function UpdateBottomCulture() { if ( document.farm.useshellfish.checked == 0 ) { document.farm.usebottomculture.checked = 0; return; } } function UpdateOxygenSaturation() { FS.DOBoundary = FS.getOxygenSaturation(FS.WaterTemperature, FS.Salinity); document.farm.dissolvedoxygen.value = FS.decimalPlaces(FS.DOBoundary,2); // mg L-1 // ASSETS Dissolved oxygen if (FS.DOBoundary == 0) document.assetsDO.src="/images/ASSETSbad.jpg"; else if (FS.DOBoundary > 0 && FS.DOBoundary <= 2) document.assetsDO.src="/images/ASSETSpoor.jpg"; else if (FS.DOBoundary > 2 && FS.DOBoundary <= 5) document.assetsDO.src="/images/ASSETSmoderate.jpg"; else if (FS.DOBoundary > 5 && FS.DOBoundary <= 8) document.assetsDO.src="/images/ASSETSgood.jpg"; else if (FS.DOBoundary > 8) document.assetsDO.src="/images/ASSETShigh.jpg"; else document.assetsDO.src="/images/ASSETSblank.jpg"; } function SplitBoxes() { FS.Parts = Math.round(FS.Boxes/3); FS.P1 = FS.P2 = FS.P3 = FS.Parts; switch (FS.Boxes) { case 1: FS.P1 = 1; FS.P2 = 0; FS.P3 = 0; return; break; case 2: FS.P1 = 1; FS.P2 = 1; FS.P3 = 0; return; break; case 3: FS.P1 = 1; FS.P2 = 1; FS.P3 = 1; return; break; default: break; } // if less than number of boxes while ( FS.P1 + FS.P2 + FS.P3 < FS.Boxes ) { // 0.0-1.0 scaled to 0-30 MyPart = Math.round (Math.random() * 30); if (MyPart <= 10) FS.P1++; else if (MyPart > 10 && MyPart <= 20) FS.P2++; else FS.P3++; } // if more than number of boxes while ( FS.P1 + FS.P2 + FS.P3 > FS.Boxes ) { // 0.0-1.0 scaled to 0-30 MyPart = Math.round (Math.random() * 30); if (MyPart <= 10) FS.P1--; else if (MyPart > 10 && MyPart <= 20) FS.P2--; else FS.P3--; } // alert(FS.P1); // alert(FS.P2); // alert(FS.P3); } // Farm volume per segment function CalculateVolume() { return FS.decimalPlaces(FS.Volume,2); } // Advect food sources function Transport() { for ( var i = 0; i < FS.Boxes; i++ ) { if ( i == 0 ) { FS.ChlFlux[i] = FS.ChlFlux[i] + FS.Flow / FS.Volume * (FS.ChlBoundary - FS.Chl[i]); FS.OxygenFlux[i] = FS.OxygenFlux[i] + FS.Flow / FS.Volume * (FS.DOBoundary - FS.Oxygen[i]); FS.POMFlux[i] = FS.POMFlux[i] + FS.Flow / FS.Volume * (FS.POMBoundary - FS.POM[i]); FS.TPMFlux[i] = FS.TPMFlux[i] + FS.Flow / FS.Volume * (FS.TPMBoundary - FS.TPM[i]); } else { FS.ChlFlux[i] = FS.ChlFlux[i] + FS.Flow / FS.Volume * (FS.Chl[i-1] - FS.Chl[i]); FS.OxygenFlux[i] = FS.OxygenFlux[i] + FS.Flow / FS.Volume * (FS.Oxygen[i-1] - FS.Oxygen[i]); FS.POMFlux[i] = FS.POMFlux[i] + FS.Flow / FS.Volume * (FS.POM[i-1] - FS.POM[i]); FS.TPMFlux[i] = FS.TPMFlux[i] + FS.Flow / FS.Volume * (FS.TPM[i-1] - FS.TPM[i]); } } } // Sediment POM and SPM - function implemented also for sedimenting chl a, but presently commented - JGF 2006.07.28 function Sediment() { // Only process sedimentation if no culture or surface culture if ( document.farm.usebottomculture.checked == 1 ) return; // This function does not presently account for turbulence, which would allow deposition only over // part of the tidal cycle - JGF 2006.07.28 var MyFallVelocity, MyFatFallVelocity, MyWaterTemperature = FS.WaterTemperature, MyGrainSize = 6, // phi-wentworth = 6, silt = 0.0625-0.0039mm (phi 4-8) MyFatGrainSize = 4, // phi-wentworth = 4, very fine sand = 0.125-0.0625mm (phi 3-4) BoxSurfaceArea = FS.Length * FS.Width // Surface area in m2 BoxDepth = FS.Depth, // Depth in m BoxVolume = FS.Volume, // Volume in m3 DAYSTOSECONDS = FS.DaysToSeconds; MyFallVelocity = FS.getFallVelocity(MyGrainSize,MyWaterTemperature) // m s-1 * DAYSTOSECONDS // m d-1 * BoxSurfaceArea; // m3 d-1 MyFatFallVelocity = FS.getFallVelocity(MyFatGrainSize,MyWaterTemperature) // m s-1 * DAYSTOSECONDS // m d-1 * BoxSurfaceArea; // m3 d-1 // alert(FS.getFallVelocity(MyGrainSize,MyWaterTemperature)); // m s-1 // alert(FS.TPM[0] + ", " + BoxVolume + ", " + MyFallVelocity + ", " + FS.TPM[0] * MyFallVelocity / BoxVolume); // g m-3 d-1 for ( var i = 0; i < FS.Boxes; i++ ) { FS.TPMFlux[i] = FS.TPMFlux[i] // g m-3 d-1 - FS.TPM[i] // g m-3 * MyFallVelocity // to g d-1 * (1-FS.FATTPM[i]) // proportion fine sediment / BoxVolume; // to g m-3 d-1 FS.TPMFlux[i] = FS.TPMFlux[i] // g m-3 d-1 - FS.TPM[i] // g m-3 * MyFatFallVelocity // to g d-1 * FS.FATTPM[i] // proportion coarse sediment / BoxVolume; // to g m-3 d-1 FS.POMFlux[i] = FS.POMFlux[i] // g m-3 d-1 - FS.POM[i] // g m-3 * MyFallVelocity // to g d-1 * (1-FS.FATPOM[i]) // proportion fine sediment / BoxVolume; // to g m-3 d-1 FS.POMFlux[i] = FS.POMFlux[i] // g m-3 d-1 - FS.POM[i] // g m-3 * MyFatFallVelocity // to g d-1 * FS.FATPOM[i] // proportion coarse sediment / BoxVolume; // to g m-3 d-1 /* FS.ChlFlux[i] = FS.ChlFlux[i] // mg chl m-3 d-1 - FS.Chl[i] // mg chl m-3 * MyFallVelocity // to mg chl d-1 / BoxVolume; // to mg chl m-3 d-1 */ } } // Shellfish grazing // Generic function Graze() { for (i = 0; i < FS.Boxes; i++) { FS.MyBox = i; FS.NumberOfAnimals = 1; FS.genericFeed(); FS.genericRespire(); FS.genericAssimilate(); FS.IndividualBiomassFlux[i] = FS.IndividualBiomassFlux[i] // gTFW ind-1 d-1 + FS.ScopeForGrowth; } if (document.farm.usepopulation.checked == 0) return; for (k = 0; k < FS.Classes; k++) for (j = 0; j < FS.Boxes; j++) { FS.MyClass = k; FS.MyBox = j; FS.NumberOfAnimals = FS.ClassDensity[FS.MyClass * FS.Boxes + FS.MyBox]; FS.genericFeed(); FS.genericRespire(); FS.genericAssimilate(); FS.GrowthRate[k * FS.Boxes + j] = FS.ScopeForGrowth; // if ( FS.TimeNow == 2000 ) // alert(FS.GrowthRate[k * FS.Boxes + j]); } } function GenericFeed() { var PhytoFood = FS.Chl[FS.MyBox], // ug L-1 chl a POMFood = FS.POM[FS.MyBox], // mg L-1 POM NumberOfAnimals = FS.NumberOfAnimals, BoxVolume = FS.Volume, ChlToCarbon = 30, PhytoKs = 8, // ug L-1 chl a // 4-5 L per hour MaxPhytoRate = 1000, // CR per ind. 100 L d-1 with 10 ug L-1 chl a = ug chla ind-1 d-1 POMToCarbon = 3, POMKs = 5, MaxPOMRate = 500, // CR per ind. 100 L d-1 with 5 mg L-1 POM = mg POM ind-1 d-1 POMUptake; FS.FoodUptake = MaxPhytoRate * PhytoFood / (PhytoKs + PhytoFood); FS.FoodUptake = FS.FoodUptake // ug chl a ind-1 d-1 * ChlToCarbon // to ug C ind-1 d-1 / FS.CUBIC; // to mg C ind-1 d-1 // Balance method - per m-3 FS.ChlFlux[FS.MyBox] = FS.ChlFlux[FS.MyBox] // mg chl a m-3 d-1 - FS.FoodUptake // mg C ind-1 d-1 * NumberOfAnimals // to mg C total ind. d-1 / ChlToCarbon // mg chla total ind d-1 / BoxVolume; // mg chl a m-3 d-1 // ( FS.TimeNow == 2 ) // alert(FS.ClassDensity[FS.MyClass * FS.Boxes + FS.MyBox]); POMUptake = MaxPOMRate * POMFood / (POMKs + POMFood); POMUptake = POMUptake // mg POM ind-1 d-1 / POMToCarbon; // to mg C ind-1 d-1 // Balance method - per m-3 FS.POMFlux[FS.MyBox] = FS.POMFlux[FS.MyBox] // g POM m-3 d-1 - POMUptake // mg C ind-1 d-1 * NumberOfAnimals // to mg C total ind. d-1 * POMToCarbon // mg POM total ind d-1 / FS.CUBIC // g POM total ind d-1 / BoxVolume; // g POM m-3 d-1 FS.FoodUptake = FS.FoodUptake // mg C ind-1 d-1 + POMUptake; } function GenericRespire() { var CarbonToOxygen = 32/12, NumberOfAnimals = FS.NumberOfAnimals, BoxVolume = FS.Volume; FS.OxygenConsumption = FS.FoodUptake // mg C ind-1 d-1 * CarbonToOxygen; // mg O2 ind-1 d-1 FS.OxygenFlux[FS.MyBox] = FS.OxygenFlux[FS.MyBox] // g O2 m-3 d-1 - FS.OxygenConsumption // mg O2 ind-1 d-1 * NumberOfAnimals // to mg O2 total ind d-1 / FS.CUBIC // g O2 total ind d-1 / BoxVolume; // g O2 m-3 d-1 } function GenericAssimilate() { var CarbonToDW = 3, // C is 33.33% DW DWToFW = 5, // DW = 20% FW MetabolicLosses = 0.8; // 80% energy lost FS.ScopeForGrowth = (FS.FoodUptake - FS.FoodUptake * MetabolicLosses) // mg C ind-1 d-1 * CarbonToDW // to mg DW ind-1 d-1 * DWToFW // to mg FW ind-1 d-1 / FS.CUBIC; // g FW ind-1 d-1 } // Manila clam function ClamGraze() { for (i = 0; i < FS.Boxes; i++) { FS.MyBox = i; FS.NumberOfAnimals = 1; FS.IndividualWeight = FS.IndividualBiomass[i]; FS.clamAnabolism(); FS.clamCatabolism(); FS.IndividualBiomassFlux[i] = FS.IndividualBiomassFlux[i] // gTFW ind-1 d-1 + FS.ScopeForGrowth; } if (document.farm.usepopulation.checked == 0) return; for (k = 0; k < FS.Classes; k++) for (j = 0; j < FS.Boxes; j++) { FS.MyClass = k; FS.MyBox = j; FS.NumberOfAnimals = FS.ClassDensity[FS.MyClass * FS.Boxes + FS.MyBox]; FS.IndividualWeight = (FS.MyClass * FS.ClassAmplitude // Mid-interval + FS.SeedClassTFW); FS.clamAnabolism(); FS.clamCatabolism(); FS.GrowthRate[k * FS.Boxes + j] = FS.ScopeForGrowth; // if ( FS.TimeNow == 2000 ) // alert(FS.GrowthRate[k * FS.Boxes + j]); } } function ClamAnabolism() { var IndividualWeight = FS.IndividualWeight, // Model works in wet weight DAYSTOHOURS = FS.DaysToHours, MyWaterTemperature = FS.WaterTemperature, PhytoFood = FS.Chl[FS.MyBox], // ug L-1 chl a FgT, TmaxG = 32, // Maximum temperature for growth ToptG = 22.7, // Optimal temperature for growth betaG = 0.21, // Coefficient of temperature growth Tanabolism, FgV, TmaxV = 32, // Maximum temperature for filtration ToptV = 22.7, // Optimal temperature for filtration betaV = 0.21, // Coefficient of temperature filtration Tfood, Fstar, Ff, Gdmax = 0.014, // Maximum growth rate on DW basis vf = 2.035*DAYSTOHOURS, // Maximum filtration rate in L d-1 p = 1.26, // Coefficient of allometric equation relating DW to WW q = 0.32, // Coefficient of allometric filter velocity epsf = 47.65, // Energetic content of food - confirm units Pastres epsT = 19200, // Energetic content of Tapes Phillipinarum DryWeight, b = 0.0234, // Coefficient of allometric equation relating DW to WW // Nit represents the contribution to the diet which comes from // food sources other the phytoplankton. A field scientist told us the in the // lagoon Tapes takes 70/75% of their energy from phytoplankton. That is why // we choose .25 as an average value - Daniele niT = 0.25, Gwmax = 0.031, // Maximum growth rate on WW basis ChlorophyllToCarbon = 50; FS.ScopeForGrowth = 0; // Model uses C in mg L-1 PhytoFood = PhytoFood / FS.CUBIC // to mg chl a L-1 * ChlorophyllToCarbon; // mg C L-1 from Daniele // DryWeight DryWeight = b * Math.pow(IndividualWeight,p); // Growth if ( MyWaterTemperature <= TmaxG ) Tanabolism = MyWaterTemperature else Tanabolism = TmaxG; FgT = Math.pow((TmaxG-Tanabolism)/(TmaxG-ToptG),betaG*(TmaxG-ToptG)) * Math.exp(betaG*(Tanabolism-ToptG)); // Filtration if ( MyWaterTemperature <= TmaxV ) Tfood = MyWaterTemperature else Tfood = TmaxV; FvT = Math.pow((TmaxV-Tfood)/(TmaxV-ToptV),betaV*(TmaxV-ToptV)) * Math.exp(betaV*(Tfood-ToptV)); // Fstar and Ff Fstar = Gdmax * FgT * MyWaterTemperature * Math.pow(DryWeight,1-p/3) * epsT / ( vf * FvT * MyWaterTemperature * Math.pow(DryWeight,q) * epsf ); // Ff = IF (PhytoFood>Fstar,1,MIN(1.0,PhytoFood/Fstar+niT)) if ( PhytoFood > Fstar ) Ff = 1.0 else { if ( PhytoFood/Fstar+niT < 1.0 ) Ff = PhytoFood/Fstar+niT else Ff = 1.0; } // Ff*Gwmax*FgT*Wet_Weight^(2/3) FS.ScopeForGrowth = Ff * Gwmax * FgT * Math.pow(IndividualWeight,2/3); } function ClamCatabolism() { var IndividualWeight = FS.IndividualWeight, MyWaterTemperature = FS.WaterTemperature, FgR, TmaxR = 35, // Maximum temperatrure for respiration ToptR = 20.5, // Optimal temperature for respiration betaR = 0.17, // Coefficient of temperature respiration Tcatabolism, Rwmax = 0.0081; // Maximum respiration rate on WW basis if ( MyWaterTemperature <= TmaxR ) Tcatabolism = MyWaterTemperature else Tcatabolism = TmaxR; FgR = Math.pow((TmaxR-Tcatabolism)/(TmaxR-ToptR),betaR*(TmaxR-ToptR)) * Math.exp(betaR*(Tcatabolism-ToptR)); // Catabolism = Rwmax*FrT*Wet_Weight FS.ScopeForGrowth = FS.ScopeForGrowth - Rwmax * FgR * IndividualWeight; } // Cockle function CockleGraze() { var TotalFWtomeatDW = 0.026; // Rueda et al, 2005 for (i = 0; i < FS.Boxes; i++) { FS.MyBox = i; FS.NumberOfAnimals = 1; FS.IndividualWeight = FS.IndividualBiomass[i] * TotalFWtomeatDW; FS.cockleFeed(); FS.cockleRespire(); FS.cockleAssimilate(); // Converted to g TFW, so individual biomass is always in gTFW FS.IndividualBiomassFlux[i] = FS.IndividualBiomassFlux[i] + FS.ScopeForGrowth / TotalFWtomeatDW; } if (document.farm.usepopulation.checked == 0) return; for (k = 0; k < FS.Classes; k++) for (j = 0; j < FS.Boxes; j++) { FS.MyClass = k; FS.MyBox = j; FS.NumberOfAnimals = FS.ClassDensity[FS.MyClass * FS.Boxes + FS.MyBox]; FS.IndividualWeight = (FS.MyClass * FS.ClassAmplitude //Mid-interval + FS.SeedClassTFW) * TotalFWtomeatDW; FS.cockleFeed(); FS.cockleRespire(); FS.cockleAssimilate(); FS.GrowthRate[k * FS.Boxes + j] = FS.ScopeForGrowth / TotalFWtomeatDW; // if ( FS.TimeNow == 2000 ) // alert(FS.GrowthRate[k * FS.Boxes + j]); } } function CockleFeed() { var IndividualWeight = FS.IndividualWeight, // Model works in dry soft tissue weight NumberOfAnimals = FS.NumberOfAnimals, BoxVolume = FS.Volume, TimeStep = FS.DeltaT, TPM = 0, POM = 0, Phyorg = 0, FOOD, ChlorophyllCarbonRatio = 0.02, PhytoCarbonToDW = 0.38, // dry mass of organic matter in phytoplankton - mg L-1 DAYSTOHOURS = FS.DaysToHours, CR, CRdash, CRdoubledash, FR, // g ind-1 d-1 TPMFiltration, OFR, // g ind-1 d-1 IRmax, // g ind-1 d-1 IR, // g ind-1 d-1 RR, // g ind-1 d-1 OIR, // g ind-1 d-1 ORR, // g ind-1 d-1 ACR = 0.041, // m 3 gAFDW-1 d-1 Smaal et al, 1997 BCR = 0.61, // Allometric CR/Wt coef. Smaal et al, 1997 CD, CDmax = 0.8, // Maximum clearance depression Asest = 30, // Seston threshold for CD Klepper, 1989 Bsest = 150, // g m-3 Prins et al, 1991 SubmersionFactor = 0.7, // Fraction of time intertidal cockles are submerged FPOMSES, FPOMING, FPOMPSF, Bses = 0.389, SPFOODMASS = 0.001, // g food mm-3 Willows, 1992 Specific food mass GC, // Gut content AGC = 32.42, // mm3 g-BGC Hawkins et al, 1990 BGC = 0.714, // Hawkins et al, 1990 GPT, // Gut passage time GPTmin = 5.48, // h GPTmax = 15.81, // h SE, MUCUS, MUCUSCOEF = 0.000149, // Mucus fraction of pseudofaeces AE, // Absorption efficiency AEmax = 0.76; // Navarro et al, 1997 // Food supply // Phytoplankton food supply Phyorg = FS.Chl[FS.MyBox] // ug chl a L-1 / (ChlorophyllCarbonRatio * FS.CUBIC) // to mg C L-1 / PhytoCarbonToDW; // to mg DW L-1 POM = FS.POM[FS.MyBox]; TPM = FS.TPM[FS.MyBox]; FOOD = Phyorg + POM; // Filtration CR = ACR * Math.pow(IndividualWeight,BCR); CD = CDmax * (TPM-Asest) / (Bsest-Asest); // ignore the phaeocystis part CRdash = CR * (1-CD); CRdoubledash = CRdash * SubmersionFactor; FR = CRdoubledash * TPM; FPOMSES = FOOD/TPM; TPMFiltration = FR // g DW animal-1 d-1 * ( NumberOfAnimals / BoxVolume ); // to g DW total m-3 d-1 // 2001.08.26 JGF - Cockle growth is readjusted based on limitation of filtration rate // this avoids the error of maintaining high growth rates but filtering less seston // than that actually used for calculating growth, when the condition below is true. if ( TPMFiltration * TimeStep > TPM ) { MyTPMFiltration = TPM / TimeStep; GrowthReduction = MyTPMFiltration/TPMFiltration; // Temporary to allow animals to grow JGF 2006.04.04 // GrowthReduction = 1; FR = FR * GrowthReduction; // g d-1 TPMFiltration = FR // g DW animal-1 d-1 * ( NumberOfAnimals / BoxVolume ); // to g DW total m-3 d-1 } OFR = FR * FPOMSES; // Pre-ingestive selection and ingestion FPOMING = Math.pow(FPOMSES,Bses); GC = AGC * Math.pow(IndividualWeight, BGC); GPT = GPTmax + (GPTmin-GPTmax) * FPOMING; IRmax = GC * SPFOODMASS / GPT; IR = IRmax; // IR = FR if no pseudofaeces, otherwise IRmax limited by wt through GC RR = FR - IR; OIR = IR * FPOMING; ORR = OFR - OIR; FPOMPSF = ORR/RR; SE = 1 - FPOMPSF/FPOMSES; MUCUS = MUCUSCOEF * RR; // Absorption AE = AEmax * ( 1 - Math.exp(-GPT)); FS.AR = AE * OIR; // Absorption rate per cockle FS.OIR = OIR; // Needed for respiration // if ( FS.TimeNow == 5 ) // alert(RR); // Balance methods // TPM // alert(TPMFiltration); FS.TPMFlux[FS.MyBox] = FS.TPMFlux[FS.MyBox] - TPMFiltration; // g m-3 d-1 // if ( FS.TimeNow == 0 ) // alert(FS.TPMFlux[FS.MyBox]); // POM FS.POMFlux[FS.MyBox] = FS.POMFlux[FS.MyBox] - OFR // g DW animal-1 d-1 * ( POM / FOOD ) // Proportion which is POM * NumberOfAnimals // g DW d-1 / BoxVolume; // g DW m-3 d-1 // if ( FS.TimeNow == 0 ) // alert(FS.POMFlux[FS.MyBox]); // Chl a PhytoplanktonFiltration = OFR // g DW animal-1 d-1 * ( 1 - POM / FOOD ) // Proportion which is phytoplankton * PhytoCarbonToDW // to g C animal-1 d-1 * NumberOfAnimals * FS.CUBIC // to mg C animal-1 d-1 / BoxVolume; // to mgC total m-3 d-1 FS.ChlFlux[FS.MyBox] = FS.ChlFlux[FS.MyBox] - PhytoplanktonFiltration * ChlorophyllCarbonRatio; } function CockleRespire() { var CarbonToOxygen = 32/12, DryWeightToCarbon = 0.4, IndividualWeight = FS.IndividualWeight, // Model works in dry soft tissue weight NumberOfAnimals = FS.NumberOfAnimals, BoxVolume = FS.Volume, RESR, RESRbas, RESRrout, RESRact, Ares = 0.00409, Bres = 0.892, Tres, Q10res = 1.008, RESabsc = 0.056, RESspawnc = 0.097, SPAWNC = 0; // Ignore respiration due to gamete production at present // Get water temperature for respiration var MyWaterTemperature = FS.WaterTemperature; // default value Tres = Math.pow(Q10res, (MyWaterTemperature-10)/10); // JGF Converted DW to C - Rueda et al state RESR in gC ind-1 d-1 RESRbas = 0; // Ares * Math.pow(IndividualWeight*DryWeightToCarbon, Bres) * Tres; // JGF Converted DW to C - Rueda et al state RESR in gC ind-1 d-1 RESRout = RESabsc * FS.OIR * DryWeightToCarbon; // Ignore respiration due to gamete production at present RESRact = RESspawnc * SPAWNC; RESR = RESRbas + RESRout + RESRact; // gC ind-1 d-1 FS.OxygenConsumption = RESR // g C ind-1 d-1 * CarbonToOxygen; // g O2 ind-1 d-1 FS.OxygenFlux[FS.MyBox] = FS.OxygenFlux[FS.MyBox] // g O2 m-3 d-1 - FS.OxygenConsumption // g O2 ind-1 d-1 * NumberOfAnimals // to g O2 total ind d-1 / BoxVolume; // g O2 m-3 d-1 // JGF Converted C to DW- Rueda et al state RESR in gC ind-1 d-1 FS.RESR = RESR / DryWeightToCarbon; // g DW ind-1 d-1 } function CockleAssimilate() { FS.ScopeForGrowth = FS.AR - FS.RESR; // g dw ind-1 d-1 } // Polyculture of oysters and mussels function PolycultureGraze() { // Oysters var TotalFWToMeatDW = 63.237; for (i = 0; i < FS.Boxes; i++) { FS.MyBox = i; FS.NumberOfAnimals = 1; FS.IndividualWeight = FS.IndividualOysterBiomass[i]; FS.ShellDryWeight = FS.IndividualOysterShellDryWeight[i]; // if ( FS.TimeNow == 1 ) // alert(FS.IndividualWeight); FS.oysterFeed(); FS.oysterRespire(); FS.oysterExcrete(); FS.oysterReproduce(); FS.oysterAssimilate(); // Was converted to g TFW, so individual biomass was always in gTFW // from 2006.11.17 individual runs in g tissue DW FS.IndividualOysterBiomassFlux[i] = FS.IndividualOysterBiomassFlux[i] + FS.ScopeForGrowth; FS.IndividualOysterShellDryWeightFlux[i] = FS.IndividualOysterShellDryWeightFlux[i] + FS.ShellGrowth; } if (document.farm.usepopulation.checked == 0) return; for (k = 0; k < FS.Classes; k++) for (j = 0; j < FS.Boxes; j++) { FS.MyClass = k; FS.MyBox = j; FS.NumberOfAnimals = FS.OysterClassDensity[FS.MyClass * FS.Boxes + FS.MyBox]; // FS.IndividualWeight = (FS.MyClass * 10 + 5) // Mid-interval // / TotalFWToMeatDW; FS.IndividualWeight = (FS.MyClass * FS.ClassAmplitude // Mid-interval + FS.SeedClassTFW) / TotalFWToMeatDW; FS.oysterFeed(); FS.oysterRespire(); FS.oysterExcrete(); FS.oysterReproduce(); FS.oysterAssimilate(); FS.OysterGrowthRate[k * FS.Boxes + j] = FS.ScopeForGrowth // must be in TFW * TotalFWToMeatDW; // if ( FS.TimeNow == 2000 ) // alert(FS.OysterGrowthRate[k * FS.Boxes + j]); } // Mussels TotalFWToMeatDW = 15.06; for (i = 0; i < FS.Boxes; i++) { FS.MyBox = i; FS.NumberOfAnimals = 1; FS.IndividualWeight = FS.IndividualMusselBiomass[i]; FS.ShellDryWeight = FS.IndividualMusselShellDryWeight[i]; // if ( FS.TimeNow == 1 ) // alert(FS.IndividualWeight); FS.musselFeed(); FS.musselRespire(); FS.musselExcrete(); FS.musselReproduce(); FS.musselAssimilate(); // Was converted to g TFW, so individual biomass was always in gTFW // from 2006.11.17 individual runs in g tissue DW FS.IndividualMusselBiomassFlux[i] = FS.IndividualMusselBiomassFlux[i] + FS.ScopeForGrowth; FS.IndividualMusselShellDryWeightFlux[i] = FS.IndividualMusselShellDryWeightFlux[i] + FS.ShellGrowth; } if (document.farm.usepopulation.checked == 0) return; for (k = 0; k < FS.Classes; k++) for (j = 0; j < FS.Boxes; j++) { FS.MyClass = k; FS.MyBox = j; FS.NumberOfAnimals = FS.MusselClassDensity[FS.MyClass * FS.Boxes + FS.MyBox]; FS.IndividualWeight = (FS.MyClass * FS.ClassAmplitude // Mid-interval + FS.SeedClassTFW) / TotalFWToMeatDW; FS.musselFeed(); FS.musselRespire(); FS.musselExcrete(); FS.musselReproduce(); FS.musselAssimilate(); // Classes run in TFW FS.MusselGrowthRate[k * FS.Boxes + j] = FS.ScopeForGrowth // must be in TFW * TotalFWToMeatDW; // if ( FS.TimeNow == 2000 ) // alert(FS.MusselGrowthRate[k * FS.Boxes + j]); } } // Population dynamics function DemographicUpwind() { // Zero everything for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) { FS.OrganismGrowth[i] = 0; FS.OrganismScopeForGrowth[i] = 0; FS.OrganismMortality[i] = 0; } var ClassAmplitude = FS.ClassAmplitude; // g TFW // Eliminate -ve growth for 1st class, +ve for last for (k = 0; k < FS.Classes; k++) for (i = 0; i < FS.Boxes; i++) { if ( ( ( k==0 ) && (FS.GrowthRate[k * FS.Boxes + i] < 0)) || ( ( k==FS.Classes-1 ) && (FS.GrowthRate[k * FS.Boxes + i] > 0) ) ) FS.GrowthRate[k * FS.Boxes + i] = 0; FS.OrganismGrowth[k * FS.Boxes + i] = FS.GrowthRate[k * FS.Boxes + i] * FS.ClassDensity[k * FS.Boxes + i] / ClassAmplitude; FS.OrganismMortality[k * FS.Boxes + i] = FS.Mortality[k * FS.Boxes + i] * FS.ClassDensity[k * FS.Boxes + i]; } // Execute migrations for (k = 0; k < FS.Classes; k++) for (i = 0; i < FS.Boxes; i++) { if ( k == 0 ) // special case for first class { FS.OrganismScopeForGrowth[(k+1) * FS.Boxes + i] = FS.OrganismGrowth[k * FS.Boxes + i]; FS.OrganismScopeForGrowth[k * FS.Boxes + i] = FS.OrganismScopeForGrowth[k * FS.Boxes + i] - FS.OrganismGrowth[k * FS.Boxes + i] - FS.OrganismMortality[k * FS.Boxes + i]; } else { if ( FS.OrganismGrowth[k * FS.Boxes + i] <= 0) { FS.OrganismScopeForGrowth[(k-1) * FS.Boxes + i] = FS.OrganismScopeForGrowth[(k-1) * FS.Boxes + i] - FS.OrganismGrowth[k * FS.Boxes + i]; FS.OrganismScopeForGrowth[k * FS.Boxes + i] = FS.OrganismScopeForGrowth[k * FS.Boxes + i] + FS.OrganismGrowth[k * FS.Boxes + i] - FS.OrganismMortality[k * FS.Boxes + i]; } else { FS.OrganismScopeForGrowth[(k+1) * FS.Boxes + i] = FS.OrganismScopeForGrowth[(k+1) * FS.Boxes + i] + FS.OrganismGrowth[k * FS.Boxes + i]; FS.OrganismScopeForGrowth[k * FS.Boxes + i] = FS.OrganismScopeForGrowth[k * FS.Boxes + i] - FS.OrganismGrowth[k * FS.Boxes + i] - FS.OrganismMortality[k * FS.Boxes + i]; } } } } //=================================== function ExecuteModel() { FS.MyCounter++; var j = FS.MyCounter, Increment = 250; for ( var i = j; i < j + Increment; i++ ) { FS.TimeNow = i; if ( i >= FS.TheRunTime ) break; FS.go(); FS.integrate(); if (i % FS.StatusInterval == 0) { // window.setInterval(MyBar.togglePause(),1000); var rp = i*100/FS.TheRunTime; var OutputString = rp.toFixed(0); var ds = FS.OutputRunTime * rp / 100; FS.DayString = ds.toFixed(0); status = FS.OutputRunTime + " day model run: " + OutputString + "% done..."; // window.focus(); // MyBar.togglePause(); // alert("In loop"); } } FS.MyCounter = FS.MyCounter + Increment; if ( FS.MyCounter < FS.TheRunTime) setTimeout("FS.runModel()",1); else { // Outputs document.farm.chlfirst.value = FS.decimalPlaces(FS.Chl[0],2); if (FS.Boxes > 1 ) document.farm.chllast.value = FS.decimalPlaces(FS.Chl[FS.Boxes-1],2); if (FS.Boxes < 3 ) document.farm.chlmiddle.value = "-"; else if (FS.Boxes > 3 ) { var MyBox = Math.round(FS.Boxes/2)-1; // document.farm.chlmiddle.value = MyBox; document.farm.chlmiddle.value = FS.decimalPlaces(FS.Chl[MyBox],2); } else document.farm.chlmiddle.value = FS.decimalPlaces(FS.Chl[FS.Boxes-2],2); // Average chlorophyll var MeanChla = 0; for ( i = 0; i < FS.Boxes; i++ ) MeanChla = MeanChla + FS.Chl[i]; MeanChla = MeanChla/FS.Boxes; document.farm.chlaverage.value = FS.decimalPlaces(MeanChla,2); // Reduction document.farm.chlreduction.value = Math.round((FS.ChlBoundary-MeanChla)*100/FS.ChlBoundary); // Minimum oxygen var MinimumDO = FS.Oxygen[0]; // first box for ( i = 0; i < FS.Boxes; i++ ) if ( MinimumDO > FS.Oxygen[i] ) MinimumDO = FS.Oxygen[i]; document.farm.dominimum.value = FS.decimalPlaces(MinimumDO,2); // Reduction document.farm.doreduction.value = Math.round((FS.DOBoundary-MinimumDO)*100/FS.DOBoundary); FS.calculateASSETS(); // Default no shellfish document.farm.adultsfirst.value = "-"; document.farm.adultsmiddle.value = "-"; document.farm.adultslast.value = "-"; document.farm.biomassfirst.value = "-"; document.farm.biomassmiddle.value = "-"; document.farm.biomasslast.value = "-"; document.farm.biomasstotal.value = "-"; if ( document.farm.useshellfish.checked == 1 ) { if ( document.farm.usepopulation.checked == 1 ) { // Special case for polyculture /* if ( FS.MySpecies == 3 ) for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) { // alert(FS.OysterClassDensity[i]); // alert(FS.MusselClassDensity[i]); FS.ClassDensity[i] = FS.OysterClassDensity[i] + FS.MusselClassDensity[i]; } */ // for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) // alert(FS.ClassDensity[i]); var AdultClass = FS.Classes-1; /* document.farm.adultsfirst.value = Math.round(FS.ClassDensity[AdultClass * FS.Boxes]); document.farm.adultslast.value = Math.round(FS.ClassDensity[AdultClass * FS.Boxes + (FS.Boxes-1)]); if (FS.Boxes < 3 ) document.farm.adultsmiddle.value = "-"; else if (FS.Boxes > 3 ) { var MyBox = Math.round(FS.Boxes/2)-1; document.farm.adultsmiddle.value = Math.round(FS.ClassDensity[AdultClass * FS.Boxes + MyBox]); } else document.farm.adultsmiddle.value = Math.round(FS.ClassDensity[AdultClass * FS.Boxes + 1]); */ // This test to make sure categories fit if (FS.Boxes == 3) { FS.P1 = 1; FS.P2 = 1; } var NumberAdult1 = NumberAdult2 = NumberAdult3 = NumberAdultTotal = 0; for (k = 0; k < FS.Classes; k++) for (j = 0; j < FS.Boxes; j++) if ( k == AdultClass ) { if ( j < FS.P1 ) NumberAdult1 = NumberAdult1 + FS.ClassDensity[k * FS.Boxes + j]; else if ( ( FS.Boxes != 2 ) && ( j >= FS.P1 && j < (FS.P1 + FS.P2) ) ) NumberAdult2 = NumberAdult2 + FS.ClassDensity[k * FS.Boxes + j]; else NumberAdult3 = NumberAdult3 + FS.ClassDensity[k * FS.Boxes + j]; } NumberAdultTotal = NumberAdult1 + NumberAdult2 + NumberAdult3; document.farm.adultsfirst.value = Math.round(NumberAdult1); if ( FS.Boxes > 2 ) document.farm.adultsmiddle.value = Math.round(NumberAdult2); if ( FS.Boxes > 1 ) document.farm.adultslast.value = Math.round(NumberAdult3); document.farm.adultstotal.value = Math.round(NumberAdultTotal); document.farm.adultsratio.value = Math.round(NumberAdultTotal*100/FS.NumberSeed); var BiomassAdult1 = BiomassAdult2 = BiomassAdult3 = BiomassAdultTotal = BiomassTotal = 0, TonToGram = 1000000, SeedWeight = FS.SeedClassTFW, // gTFW first class mid-interval HarvestWeight = FS.Classes // gTFW last class mid-interval * FS.ClassAmplitude - FS.SeedClassTFW; for (k = 0; k < FS.Classes; k++) for (j = 0; j < FS.Boxes; j++) if ( k == AdultClass ) { if ( j < FS.P1 ) BiomassAdult1 = BiomassAdult1 + FS.ClassDensity[k * FS.Boxes + j]; else if ( ( FS.Boxes != 2 ) && ( j >= FS.P1 && j < (FS.P1 + FS.P2) ) ) BiomassAdult2 = BiomassAdult2 + FS.ClassDensity[k * FS.Boxes + j]; else BiomassAdult3 = BiomassAdult3 + FS.ClassDensity[k * FS.Boxes + j]; } BiomassAdult1 = BiomassAdult1 * HarvestWeight / TonToGram; BiomassAdult2 = BiomassAdult2 * HarvestWeight / TonToGram; BiomassAdult3 = BiomassAdult3 * HarvestWeight / TonToGram; BiomassAdultTotal = BiomassAdult1 + BiomassAdult2 + BiomassAdult3; document.farm.biomassfirst.value = FS.decimalPlaces(BiomassAdult1,1); if ( FS.Boxes > 2 ) document.farm.biomassmiddle.value = FS.decimalPlaces(BiomassAdult2,1); if ( FS.Boxes > 1 ) document.farm.biomasslast.value = FS.decimalPlaces(BiomassAdult3,1); document.farm.biomasstotal.value = FS.decimalPlaces(BiomassAdultTotal,1); document.farm.biomassratio.value = FS.decimalPlaces(BiomassAdultTotal /(FS.NumberSeed*SeedWeight/TonToGram),2); // document.farm.biomassratio.value = Math.round(BiomassAdultTotal // *100 // /(FS.NumberSeed*SeedWeight/TonToGram)); } else { switch ( Math.round(FS.Boxes) ) { case 1: document.farm.adultsfirst.value = 1; document.farm.adultsmiddle.value = "-"; document.farm.adultslast.value = "-"; FS.P1 = 1; break; case 2: document.farm.adultsfirst.value = 1; document.farm.adultsmiddle.value = "-"; document.farm.adultslast.value = 1; FS.P1 = 1; FS.P3 = 1; break; default: document.farm.adultsfirst.value = FS.P1; document.farm.adultsmiddle.value = FS.P2; document.farm.adultslast.value = FS.P3; break; } document.farm.adultstotal.value = FS.Boxes; var BiomassAdult1 = BiomassAdult2 = BiomassAdult3 = BiomassAdultTotal = BiomassTotal = 0; var ShellWeightAdult1 = ShellWeightAdult2 = ShellWeightAdult3 = ShellWeightAdultTotal = ShellWeightTotal = 0; for (i = 0; i < FS.Boxes; i++) { if ( i < FS.P1 ) { BiomassAdult1 = BiomassAdult1 + FS.IndividualBiomass[i]; ShellWeightAdult1 = ShellWeightAdult1 + FS.IndividualShellDryWeight[i]; } else if ( ( FS.Boxes != 2 ) && ( i >= FS.P1 && i < (FS.P1 + FS.P2) ) ) { BiomassAdult2 = BiomassAdult2 + FS.IndividualBiomass[i]; ShellWeightAdult2 = ShellWeightAdult2 + FS.IndividualShellDryWeight[i]; } else { BiomassAdult3 = BiomassAdult3 + FS.IndividualBiomass[i]; ShellWeightAdult3 = ShellWeightAdult3 + FS.IndividualShellDryWeight[i]; } } BiomassAdultTotal = BiomassAdult1 + BiomassAdult2 + BiomassAdult3; ShellWeightAdultTotal = ShellWeightAdult1 + ShellWeightAdult2 + ShellWeightAdult3; if ( FS.Boxes > 1 ) { BiomassAdult1 = BiomassAdult1/FS.P1; ShellWeightAdult1 = ShellWeightAdult1/FS.P1; BiomassAdult3 = BiomassAdult3/FS.P3; ShellWeightAdult3 = ShellWeightAdult3/FS.P3; document.farm.biomassfirst.value = FS.decimalPlaces(BiomassAdult1,1); document.farm.biomasslast.value = FS.decimalPlaces(BiomassAdult3,1); } else { BiomassAdult1 = BiomassAdult1/FS.P1; ShellWeightAdult1 = ShellWeightAdult1/FS.P1; document.farm.biomassfirst.value = FS.decimalPlaces(BiomassAdult1,1); } if ( FS.Boxes > 2 ) { BiomassAdult2 = BiomassAdult2/FS.P2; ShellWeightAdult2 = ShellWeightAdult2/FS.P2; document.farm.biomassmiddle.value = FS.decimalPlaces(BiomassAdult2,1); } BiomassAdultTotal = BiomassAdultTotal/FS.Boxes; ShellWeightAdultTotal = ShellWeightAdultTotal/FS.Boxes; document.farm.biomasstotal.value = FS.decimalPlaces(BiomassAdultTotal,1); // Shell length here (substitutes biomass ratio when running individual models) switch(FS.MySpecies) { case 0: // Generic shellfish document.farm.biomassratio.value = "-"; break; case 1: // Clams var a = 0.00026, // Coefficient of allometric equation relating WW to L ShellLength, y = document.farm.biomasstotal.value; // (Wet_Weight/a)^(1/3) ShellLength = Math.pow(y/a,1/3); document.farm.biomassratio.value = FS.decimalPlaces(ShellLength,0); break; default: break; } } } FS.endRun(); } } //=================================== function RunModel() { if ( FS.ModelRunning == 1 ) { // alert("running"); FS.MyCounter = FS.TheRunTime; FS.StopButton = 1; // Stop was pressed return; } // OldRunModel(); // return; // New version allowing windows message loop to operate FS.initialize(); try { 1/FS.Boxes; } catch ( Exception ) { return; } if (FS.Boxes <= 0) // No boxes, no run return; FS.TheRunTime = FS.RunTime/FS.DeltaT, FS.OutputRunTime = Math.round(FS.RunTime), FS.StatusInterval = Math.round(FS.TheRunTime/100); // update status FS.MyCounter = 0; // FS.TheRunTime = 10; // alert(FS.TheRunTime); // MyBar.showBar(); document.farm.calculatenow.innerText = "Stop model..."; FS.ModelRunning = 1; setTimeout("FS.runModel();",1); } //================================ // xp_progressbar // Copyright 2004 Brian Gosselin of ScriptAsylum.com // // v1.0 - Initial release // v1.1 - Added ability to pause the scrolling action (requires you to assign // the bar to a unique arbitrary variable). // - Added ability to specify an action to perform after a x amount of // - bar scrolls. This requires two added arguments. // v1.2 - Added ability to hide/show each bar (requires you to assign the bar // to a unique arbitrary variable). // var xyz = createBar( // total_width, // total_height, // background_color, // border_width, // border_color, // block_color, // scroll_speed, // block_count, // scroll_count, // action_to_perform_after_scrolled_n_times // ) var w3c=(document.getElementById)?true:false; var ie=(document.all)?true:false; var N=-1; function createBar(w,h,bgc,brdW,brdC,blkC,speed,blocks,count,action){ if(ie||w3c){ var t='
'; t+=''; for(i=0;it.w){ t.style.left=-(t.h*2+1)+'px'; t.ctr++; if(t.ctr>=t.count){ eval(t.action); t.ctr=0; }}else t.style.left=(parseInt(t.style.left)+t.h+1)+'px'; } function togglePause(){ if(this.tid==0){ this.tid=setInterval('startBar('+this.N+')',this.speed); }else{ clearInterval(this.tid); this.tid=0; }} //=================================== // Legacy code function OldGenericFeed() { // MaxRate = 5 / FS.YearsToDays; // 500% y-1 to d-1 // MaxRate = 0.1 * FS.DaysToSeconds; // d-1 var Food = FS.Chl[FS.MyBox], // ug L-1 chl a NumberOfAnimals = FS.NumberOfAnimals, BoxVolume = FS.Volume, ChlToCarbon = 30, Ks = 8, // ug L-1 chl a MaxRate =500; // CR per ind. 50 L d-1 with 10 ug L-1 chl a = ug chla ind-1 d-1 FS.FoodUptake = MaxRate * Food / (Ks + Food); FS.FoodUptake = FS.FoodUptake // ug chl a ind-1 d-1 * ChlToCarbon // to ug C ind-1 d-1 / FS.CUBIC; // to mg C ind-1 d-1 // Balance method - per m-3 FS.ChlFlux[FS.MyBox] = FS.ChlFlux[FS.MyBox] // mg chl a m-3 d-1 - FS.FoodUptake // mg C ind-1 d-1 * NumberOfAnimals // to mg C total ind. d-1 / ChlToCarbon // mg chla total ind d-1 / BoxVolume; // mg chl a m-3 d-1 // ( FS.TimeNow == 2 ) // alert(FS.ClassDensity[FS.MyClass * FS.Boxes + FS.MyBox]); } //================================ function OldRunModel() { FS.initialize(); try { 1/FS.Boxes; } catch ( Exception ) { return; } if (FS.Boxes <= 0) // No boxes, no run return; var i,j, RunTime = FS.RunTime/FS.DeltaT, OutputRunTime = Math.round(FS.RunTime), StatusInterval = Math.round(RunTime/100); // update status // window.setInterval(MyBar.togglePause(),1000); // window.setInterval(alert("In loop"),1000); // alert(RunTime); for ( j = 0; j < RunTime; j++ ) { FS.go(); FS.integrate(); FS.TimeNow = j; // j = j + FS.DeltaT; if (j % StatusInterval == 0) { var rp = j*100/RunTime; var OutputString = rp.toFixed(0); // status = "Running (" + OutputString + "% done...)"; status = OutputRunTime +" day model run (" + OutputString + "% done...)"; // window.focus(); // MyBar.togglePause(); // alert("In loop"); } } // window.clearInterval(1000); // alert("Out of loop"); // Outputs document.farm.chlfirst.value = FS.decimalPlaces(FS.Chl[0],2); if (FS.Boxes > 1 ) document.farm.chllast.value = FS.decimalPlaces(FS.Chl[FS.Boxes-1],2); if (FS.Boxes < 3 ) document.farm.chlmiddle.value = "-"; else if (FS.Boxes > 3 ) { var MyBox = Math.round(FS.Boxes/2)-1; // document.farm.chlmiddle.value = MyBox; document.farm.chlmiddle.value = FS.decimalPlaces(FS.Chl[MyBox],2); } else document.farm.chlmiddle.value = FS.decimalPlaces(FS.Chl[FS.Boxes-2],2); // Average chlorophyll var MeanChla = 0; for ( i = 0; i < FS.Boxes; i++ ) MeanChla = MeanChla + FS.Chl[i]; MeanChla = MeanChla/FS.Boxes; document.farm.chlaverage.value = FS.decimalPlaces(MeanChla,2); // Reduction document.farm.chlreduction.value = Math.round((FS.ChlBoundary-MeanChla)*100/FS.ChlBoundary); if (MeanChla <= 5) document.assetschlreduction.src="/images/ASSETShigh.jpg"; else if (MeanChla > 5 && MeanChla <= 10) document.assetschlreduction.src="/images/ASSETSgood.jpg"; else if (MeanChla > 10 && MeanChla <= 20) document.assetschlreduction.src="/images/ASSETSmoderate.jpg"; else if (MeanChla > 20 && MeanChla <= 60) document.assetschlreduction.src="/images/ASSETSpoor.jpg"; else if (MeanChla > 60) document.assetschlreduction.src="/images/ASSETSbad.jpg"; else document.assetschlreduction.src="/images/ASSETSblank.jpg"; // Minimum oxygen var MinimumDO = FS.Oxygen[0]; // first box for ( i = 0; i < FS.Boxes; i++ ) if ( MinimumDO > FS.Oxygen[i] ) MinimumDO = FS.Oxygen[i]; document.farm.dominimum.value = FS.decimalPlaces(MinimumDO,2); // Reduction document.farm.doreduction.value = Math.round((FS.DOBoundary-MinimumDO)*100/FS.DOBoundary); if (MinimumDO == 0 ) document.assetsdoreduction.src="/images/ASSETSbad.jpg"; else if (MinimumDO > 0 && MinimumDO <= 2) document.assetsdoreduction.src="/images/ASSETSpoor.jpg"; else if (MinimumDO > 2 && MinimumDO <= 5) document.assetsdoreduction.src="/images/ASSETSmoderate.jpg"; else if (MinimumDO > 5 && MinimumDO <= 8) document.assetsdoreduction.src="/images/ASSETSgood.jpg"; else if (MinimumDO > 8) document.assetsdoreduction.src="/images/ASSETShigh.jpg"; else document.assetsdoreduction.src="/images/ASSETSblank.jpg"; // ASSETS scores // Average chlorophyll var PrimarySymptomScore; if (MeanChla <= 5) PrimarySymptomScore = 0.25; else if (MeanChla > 5 && MeanChla <= 10) PrimarySymptomScore = 0.5; else if (MeanChla > 10 && MeanChla <= 20) PrimarySymptomScore = 0.5; else if (MeanChla > 20 && MeanChla <= 60) PrimarySymptomScore = 1; else if (MeanChla > 60) PrimarySymptomScore = 1; // Minimum dissolved oxygen var SecondarySymptomScore; if (MinimumDO == 0 ) SecondarySymptomScore = 1; else if (MinimumDO > 0 && MinimumDO <= 2) SecondarySymptomScore = 1; else if (MinimumDO > 2 && MinimumDO <= 5) SecondarySymptomScore = 0.5; else if (MinimumDO > 5 && MinimumDO <= 8) SecondarySymptomScore = 0.25; else if (MinimumDO > 8) SecondarySymptomScore = 0.25; // Final score var FinalScore = 0; if (PrimarySymptomScore <= 0.3) if ( SecondarySymptomScore <= 0.3 ) FinalScore = 5; else if ( SecondarySymptomScore > 0.3 && SecondarySymptomScore <= 0.6 ) FinalScore = 4; else FinalScore = 2; else if (PrimarySymptomScore > 0.3 && PrimarySymptomScore <= 0.6) if ( SecondarySymptomScore <= 0.3 ) FinalScore = 4; else if ( SecondarySymptomScore > 0.3 && SecondarySymptomScore <= 0.6 ) FinalScore = 3; else FinalScore = 1; else if ( SecondarySymptomScore <= 0.3 ) FinalScore = 3; else if ( SecondarySymptomScore > 0.3 && SecondarySymptomScore <= 0.6 ) FinalScore = 2; else FinalScore = 1; switch (FinalScore) { case 1: document.assetsscoreafterrun.src="/images/ASSETSbad.jpg"; ASSETS.style.color = "red"; ASSETS.innerText = "Bad"; break; case 2: document.assetsscoreafterrun.src="/images/ASSETSpoor.jpg"; ASSETS.style.color = "orange"; // orange ASSETS.innerText = "Poor"; break; case 3: document.assetsscoreafterrun.src="/images/ASSETSmoderate.jpg"; ASSETS.style.color = "yellow"; // yellow ASSETS.innerText = "Moderate"; break; case 4: document.assetsscoreafterrun.src="/images/ASSETSgood.jpg"; ASSETS.style.color = "green"; ASSETS.innerText = "Good"; break; case 5: document.assetsscoreafterrun.src="/images/ASSETShigh.jpg"; ASSETS.style.color = "blue"; ASSETS.innerText = "High"; break; default: document.assetsscoreafterrun.src="/images/ASSETSblank.jpg"; ASSETS.innerText = ""; break; } // Default no shellfish document.farm.adultsfirst.value = "-"; document.farm.adultsmiddle.value = "-"; document.farm.adultslast.value = "-"; document.farm.biomassfirst.value = "-"; document.farm.biomassmiddle.value = "-"; document.farm.biomasslast.value = "-"; document.farm.biomasstotal.value = "-"; if ( document.farm.useshellfish.checked == 1 ) { if ( document.farm.usepopulation.checked == 1 ) { // for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) // alert(FS.ClassDensity[i]); var AdultClass = FS.Classes-1; /* document.farm.adultsfirst.value = Math.round(FS.ClassDensity[AdultClass * FS.Boxes]); document.farm.adultslast.value = Math.round(FS.ClassDensity[AdultClass * FS.Boxes + (FS.Boxes-1)]); if (FS.Boxes < 3 ) document.farm.adultsmiddle.value = "-"; else if (FS.Boxes > 3 ) { var MyBox = Math.round(FS.Boxes/2)-1; document.farm.adultsmiddle.value = Math.round(FS.ClassDensity[AdultClass * FS.Boxes + MyBox]); } else document.farm.adultsmiddle.value = Math.round(FS.ClassDensity[AdultClass * FS.Boxes + 1]); */ // This test to make sure categories fit if (FS.Boxes == 3) { FS.P1 = 1; FS.P2 = 1; } var NumberAdult1 = NumberAdult2 = NumberAdult3 = NumberAdultTotal = 0; for (k = 0; k < FS.Classes; k++) for (j = 0; j < FS.Boxes; j++) if ( k == AdultClass ) { if ( j < FS.P1 ) NumberAdult1 = NumberAdult1 + FS.ClassDensity[k * FS.Boxes + j]; else if ( ( FS.Boxes != 2 ) && ( j >= FS.P1 && j < (FS.P1 + FS.P2) ) ) NumberAdult2 = NumberAdult2 + FS.ClassDensity[k * FS.Boxes + j]; else NumberAdult3 = NumberAdult3 + FS.ClassDensity[k * FS.Boxes + j]; } NumberAdultTotal = NumberAdult1 + NumberAdult2 + NumberAdult3; document.farm.adultsfirst.value = Math.round(NumberAdult1); if ( FS.Boxes > 2 ) document.farm.adultsmiddle.value = Math.round(NumberAdult2); if ( FS.Boxes > 1 ) document.farm.adultslast.value = Math.round(NumberAdult3); document.farm.adultstotal.value = Math.round(NumberAdultTotal); document.farm.adultsratio.value = Math.round(NumberAdultTotal*100/FS.NumberSeed); var BiomassAdult1 = BiomassAdult2 = BiomassAdult3 = BiomassAdultTotal = BiomassTotal = 0, TonToGram = 1000000, SeedWeight = 5, // gTFW HarvestWeight = 25; // gTFW for (k = 0; k < FS.Classes; k++) for (j = 0; j < FS.Boxes; j++) if ( k == AdultClass ) { if ( j < FS.P1 ) BiomassAdult1 = BiomassAdult1 + FS.ClassDensity[k * FS.Boxes + j]; else if ( ( FS.Boxes != 2 ) && ( j >= FS.P1 && j < (FS.P1 + FS.P2) ) ) BiomassAdult2 = BiomassAdult2 + FS.ClassDensity[k * FS.Boxes + j]; else BiomassAdult3 = BiomassAdult3 + FS.ClassDensity[k * FS.Boxes + j]; } BiomassAdult1 = BiomassAdult1 * HarvestWeight / TonToGram; BiomassAdult2 = BiomassAdult2 * HarvestWeight / TonToGram; BiomassAdult3 = BiomassAdult3 * HarvestWeight / TonToGram; BiomassAdultTotal = BiomassAdult1 + BiomassAdult2 + BiomassAdult3; document.farm.biomassfirst.value = FS.decimalPlaces(BiomassAdult1,1); if ( FS.Boxes > 2 ) document.farm.biomassmiddle.value = FS.decimalPlaces(BiomassAdult2,1); if ( FS.Boxes > 1 ) document.farm.biomasslast.value = FS.decimalPlaces(BiomassAdult3,1); document.farm.biomasstotal.value = FS.decimalPlaces(BiomassAdultTotal,1); document.farm.biomassratio.value = Math.round(BiomassAdultTotal *100 /(FS.NumberSeed*SeedWeight/TonToGram)); } else { switch ( Math.round(FS.Boxes) ) { case 1: document.farm.adultsfirst.value = 1; document.farm.adultsmiddle.value = "-"; document.farm.adultslast.value = "-"; FS.P1 = 1; break; case 2: document.farm.adultsfirst.value = 1; document.farm.adultsmiddle.value = "-"; document.farm.adultslast.value = 1; FS.P1 = 1; FS.P3 = 1; break; default: document.farm.adultsfirst.value = FS.P1; document.farm.adultsmiddle.value = FS.P2; document.farm.adultslast.value = FS.P3; break; } document.farm.adultstotal.value = FS.Boxes; var BiomassAdult1 = BiomassAdult2 = BiomassAdult3 = BiomassAdultTotal = BiomassTotal = 0; for (i = 0; i < FS.Boxes; i++) { if ( i < FS.P1 ) BiomassAdult1 = BiomassAdult1 + FS.IndividualBiomass[i]; else if ( ( FS.Boxes != 2 ) && ( i >= FS.P1 && i < (FS.P1 + FS.P2) ) ) BiomassAdult2 = BiomassAdult2 + FS.IndividualBiomass[i]; else BiomassAdult3 = BiomassAdult3 + FS.IndividualBiomass[i]; } BiomassAdultTotal = BiomassAdult1 + BiomassAdult2 + BiomassAdult3; if ( FS.Boxes > 1 ) { document.farm.biomassfirst.value = FS.decimalPlaces(BiomassAdult1/FS.P1,1); document.farm.biomasslast.value = FS.decimalPlaces(BiomassAdult3/FS.P3,1); } else document.farm.biomassfirst.value = FS.decimalPlaces(BiomassAdult1,1); if ( FS.Boxes > 2 ) document.farm.biomassmiddle.value = FS.decimalPlaces(BiomassAdult2/FS.P2,1); document.farm.biomasstotal.value = FS.decimalPlaces(BiomassAdultTotal/FS.Boxes,1); } } FS.endRun(); } //=================================== // test function function WriteData() { FS.getParameters(); // Get parameters of farm a = FS.Width; document.farm.chlfirst.value = a; if ( document.farm.useshellfish.checked == 1 ) alert("Use") else alert("Don't use"); } //=================================== // Test function function Print() { document.write("Hello"); }