// Prawn Aquaculture Management (LMPrawn) Model // Copyright notices // Copyright General modelling approach Longline Ltd. March 2007 // Copyright Individual models as below: // Shrimp: Longline Ltd May 2006 // Generic: Longline Ltd March 2006 // Blue Mussel: A.J.S. Hawkins, PML // Razor Clam: A.J.S. Hawkins, PML // V1 - J.G.Ferreira, Rev. A 2007/03/30 // All rates in the model are per day, regardless of whether // they are defined per second, hour etc in the inputs // Classes function Farmscale() { Farmscale.prototype.getParameters = GetParameters; Farmscale.prototype.decimalPlaces = DecimalPlaces; Farmscale.prototype.log10 = Log10; Farmscale.prototype.calculateArea = CalculateArea; Farmscale.prototype.calculateVolume = CalculateVolume; Farmscale.prototype.defineModelSettings = DefineModelSettings; Farmscale.prototype.showInitialStatusBar = ShowInitialStatusBar; Farmscale.prototype.updateShellfish = UpdateShellfish; Farmscale.prototype.updateOutputs = UpdateOutputs; Farmscale.prototype.updateShellfishPopulation = UpdateShellfishPopulation; Farmscale.prototype.initialize = Initialize; Farmscale.prototype.sediment = Sediment; Farmscale.prototype.shrimpGraze = ShrimpGraze; Farmscale.prototype.graze = Graze; Farmscale.prototype.razorClamGraze = RazorClamGraze; Farmscale.prototype.demographicUpwind = DemographicUpwind; 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; // Shrimp private methods // Generic shrimp Farmscale.prototype.shrimpFeed = ShrimpFeed; Farmscale.prototype.shrimpRespire = ShrimpRespire; Farmscale.prototype.shrimpAssimilate = ShrimpAssimilate; Farmscale.prototype.shrimpFaecesProduction=ShrimpFaecesProduction;//added by Changbo Farmscale.prototype.ShrimpScopeForGrowth=ShrimpScopeForGrowth;//by Changbo // Shellfish private methods // Generic Farmscale.prototype.genericFeed = GenericFeed; Farmscale.prototype.genericRespire = GenericRespire; Farmscale.prototype.genericAssimilate = GenericAssimilate; // Razor clam - Mytilus edulis Farmscale.prototype.razorClamFeed = RazorClamFeed; Farmscale.prototype.razorClamRespire = RazorClamRespire; Farmscale.prototype.razorClamExcrete = RazorClamExcrete; Farmscale.prototype.razorClamReproduce = RazorClamReproduce; Farmscale.prototype.razorClamAssimilate = RazorClamAssimilate; // 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; // 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 = 5; // 5 weight classes FS.ClassAmplitude = 4; // g TFW for tests FS.SeedClassTFW = FS.ClassAmplitude/2; // g TFW, 2g FS.getParameters(); // Get parameters of farm FS.DeltaT = 1.0/24.0; // For tests, one day / 24 i.e. one hour // FS.RunTime = 180; // days FS.TotalTimesteps = Math.round(FS.RunTime/FS.DeltaT); // alert(FS.TotalTimesteps); // For the time being, cutoff is a 2 year run FS.MaxRunTime = 730; 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(); document.farm.area.value = FS.calculateArea(); FS.TotalIndividuals = FS.Area * FS.Density;//=============changed form "FS.Volume" to "FS.Area" by Changbo--2007.04.13------- document.farm.totalindividuals.value = Math.round(FS.TotalIndividuals); // ind // FS.listModels(); // ENABLE WHEN OK FOR LMPRAWN JGF 2007.04.05 } // display initial status bar function ShowInitialStatusBar() { var ModelSpecies = ": "; if ( document.farm.useshellfish.checked == 1 ) { switch(FS.MySpecies) { case 0: // generic ModelSpecies = " for generic shellfish: "; break; case 1: // razor clams ModelSpecies = " for razor clams: "; 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); // 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); // General 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 ( 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; } // Shrimp arrays // For individual biomass of one animal FS.shrimpGutContent=new Array(FS.Boxes),//added by Changbo---------------------- FS.IndividualShrimpBiomass = new Array(FS.Boxes), FS.IndividualShrimpBiomassFlux = new Array(FS.Boxes); // For polyculture FS.ShrimpClassDensity = new Array(FS.Boxes * FS.Classes), FS.ShrimpClassDensityFlux = new Array(FS.Boxes * FS.Classes), FS.ShrimpGrowthRate = new Array(FS.Boxes * FS.Classes), FS.ShrimpMortality = new Array(FS.Boxes * FS.Classes); for ( i = 0; i < FS.Boxes; i++ ) { FS.shrimpGutContent[i]=0;//-------------------------------------------------- FS.IndividualShrimpBiomass[i] = 0.04;//Changed from 0 to 0.04, the shrimp seeding FW---Changbo,2007.04.13 FS.IndividualShrimpBiomassFlux[i] = 0; } for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) { // For polyculture FS.ShrimpClassDensity[i] = 0; FS.ShrimpClassDensityFlux[i] = 0; FS.ShrimpGrowthRate[i] = 0; FS.ShrimpMortality[i] = 0; } // Appropriate class amplitude // SORT THIS OUT TO ALLOW SHRIMP AND RAZORS TO BE DIFFERENT JGF 2007.04.06 FS.ClassAmplitude = 5; // g TFW // Set mortality for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) FS.ShrimpMortality[i] = 0.2 // 20% y-1 / FS.YearsToDays; // to d-1 for (k = 0; k < FS.Classes; k++) for (j = 0; j < FS.Boxes; j++ ) if ( k == 0 ) FS.ShrimpClassDensity[k * FS.Boxes + j] = FS.Density * FS.Area; // "FS.Volume" was changed to "FS.Area". Changbo, 2007.04.13 // For polyculture FS.RazorClassDensity = new Array(FS.Boxes * FS.Classes), FS.RazorClassDensityFlux = new Array(FS.Boxes * FS.Classes), FS.RazorGrowthRate = new Array(FS.Boxes * FS.Classes), FS.RazorMortality = 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 ( i = 0; i < FS.Boxes * FS.Classes; i++ ) { // For polyculture FS.RazorClassDensity[i] = 0; FS.RazorClassDensityFlux[i] = 0; FS.RazorGrowthRate[i] = 0; FS.RazorMortality[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; } if ( document.farm.useshellfish.checked == 1 ) { for (k = 0; k < FS.Classes; k++) for (j = 0; j < FS.Boxes; j++) if ( k == 0 ) FS.RazorClassDensity[k * FS.Boxes + j] = FS.ShellfishDensity * FS.Volume; FS.NumberSeed = 0; for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) FS.NumberSeed = FS.NumberSeed + FS.RazorClassDensity[i]; } if ( document.farm.useshellfish.checked == 1 ) { switch(FS.MySpecies) { case 0: // Generic shellfish // 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.RazorMortality[i] = 0.2 // 20% y-1 / FS.YearsToDays; // to d-1 break; case 1: // Razor clams //var RazorClamTotalFWToMeatDW = 14.1057, //15.06, Estimated from Garen et al 2004, NEEDS IMPROVING//updated, 2007.5.13 var RazorClamInitialTFW = 0.54 // g TFW The seeding weight of razorclam is 0.54 g TFW, Changbo, 2007.5.14 WetSoftTissueWaterContent = 0.8115, ShellCavityWaterCorrection = 1.4765, ShellProportion = 0.4447, WetShellWaterContent = 0.1513; // Appropriate class amplitude and seed weight FS.ClassAmplitude = 5; // g TFW FS.SeedClassTFW = FS.ClassAmplitude/2; // g TFW // Set all individual biomasses and individual shell DW for ( i = 0; i < FS.Boxes; i++ ) { FS.IndividualBiomass[i] = RazorClamInitialTFW // TFW to dry tissue weight / ShellCavityWaterCorrection * (1 - ShellProportion) * (1 - WetSoftTissueWaterContent); //FS.IndividualBiomass[i] = 0.046136; // For tests - based on energy budget from AJSH //var MyIndividualLength = Math.pow(10,FS.log10(FS.IndividualBiomass[i] // * RazorClamTotalFWToMeatDW / 0.0836)/2.9602); //FS.IndividualShellDryWeight[i] = 0.0562 * Math.pow ( MyIndividualLength, 2.9611 ); // FS.IndividualShellDryWeight[i] = 0.0562 * Math.pow ( 2, 2.9611 ); // For tests based on length from AJSH // With an exact match to the ShellSIM C++ code, rounding off errors still make a change re: the // assimilation, so that we are sometimes in the second part of the "EnergyRatio" (0.68) test FS.IndividualShellDryWeight[i] = FS.IndividualBiomass[i] //According to ShellSim code, Changbo, 2007.05.11 / (1 - WetSoftTissueWaterContent) / (1 - ShellProportion) * ShellProportion * (1 - WetShellWaterContent); } // Set mortality for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) FS.RazorMortality[i] = 0.2 // 20% y-1 / FS.YearsToDays; // to d-1 // FS.Mortality[i] = 0.001918; // 70% y-1 Only for SMILE CL FARM case study break; default: break; } } } function ClearElements() { 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.adultstotal.value = "-"; document.farm.adultsratio.value = "-"; document.farm.biomasstotal.value = "-"; document.farm.biomassratio.value = "-"; document.farm.shellfishadultstotal.value = "-"; document.farm.shellfishadultsratio.value = "-"; document.farm.shellfishbiomasstotal.value = "-"; document.farm.shellfishbiomassratio.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 = 1; // document.farm.boxes.value; FS.Area = FS.Width * FS.Length; FS.Volume = FS.Width * FS.Length * FS.Depth; 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.WaterTemperature = document.farm.watertemperature.value; // oC // Environmental parameters FS.Salinity = document.farm.watersalinity.value; // psu 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 ( document.farm.useshellfish.checked == 1 ) { var SCP = document.farm.shellfishcultivationperiod.value; // days if ( SCP > FS.CultivationPeriod ) FS.CultivationPeriod = SCP; } if ( FS.CultivationPeriod != 1 ) { CPE.innerText = "days"; SC6.innerText = "days"; } else { CPE.innerText = "day"; SC6.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.Density = document.farm.shrimpdensity.value; // ind FS.ShellfishDensity = document.farm.shellfishdensity.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; } FS.MyShrimpSpecies = document.getElementById('selectshrimpspecies').selectedIndex; FS.MySpecies = document.getElementById('selectshellfishspecies').selectedIndex; // document.farm.selectshrimpspecies.options.length = 0; // clear // document.farm.selectshrimpspecies.options[1] = null; // remove oysters // var FS.Species = document.selectshrimpspecies.selectedIndex; // breaks // alert(document.getElementById('selectshrimpspecies').selectedIndex); // New functions to hide shellfish on startup - JGF 2007.04.04 FS.updateShellfish(); } function Go() { // alert("Before canned"); FS.getCannedData(); // alert("After canned"); // "Private" calculation functions here // FS.sediment(); // alert("After T&S"); switch(FS.MySpecies) { case 0: // LV FS.shrimpGraze(); break; default: FS.shrimpGraze(); break; }// Graze shrimp // Graze if checked if ( document.farm.useshellfish.checked == 1 ) { switch(FS.MySpecies) { case 0: // generic FS.graze(); break; case 1: // razorClams FS.razorClamGraze(); break; default: FS.graze(); break; } } } function Integrate() { // integration functions here var EnforceZero = 1; // Zero negative values when switched on (on=1, off=0) // Shrimp if ( document.farm.usepopulation.checked == 1 ) { FS.ClassDensity = FS.ShrimpClassDensity; FS.GrowthRate = FS.ShrimpGrowthRate; FS.Mortality = FS.ShrimpMortality; FS.demographicUpwind(); for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) FS.ShrimpClassDensityFlux[i] = FS.ShrimpClassDensityFlux[i] + FS.OrganismScopeForGrowth[i]; for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) { FS.ShrimpClassDensity[i] = FS.ClassDensity[i] + FS.ShrimpClassDensityFlux[i] * FS.DeltaT; FS.ShrimpClassDensityFlux[i] = 0; } } // Single individual for ( i = 0; i < FS.Boxes; i++ )//------------------------------- shrimGutContent added by Changbo------------------ { //FS.shrimpGutContent[i]+=(FS.shrimpFeed()-FS.shrimpAssimilate()-FS.shrimpFaecesProduction())*FS.DeltaT; FS.IndividualShrimpBiomass[i] = FS.IndividualShrimpBiomass[i] + FS.IndividualShrimpBiomassFlux[i] * FS.DeltaT; FS.IndividualShrimpBiomassFlux[i] = 0; } // Shellfish if ( document.farm.useshellfish.checked == 1 ) { if ( document.farm.useshellfishpopulation.checked == 1 ) { // Razors FS.ClassDensity = FS.RazorClassDensity; FS.GrowthRate = FS.RazorGrowthRate; FS.Mortality = FS.RazorMortality; FS.demographicUpwind(); for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) FS.RazorClassDensityFlux[i] = FS.RazorClassDensityFlux[i] + FS.OrganismScopeForGrowth[i]; for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) { FS.RazorClassDensity[i] = FS.ClassDensity[i] + FS.RazorClassDensityFlux[i] * FS.DeltaT; FS.RazorClassDensityFlux[i] = 0; } /* 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; } */ } // Always do individual biomass code 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; } } // 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 // 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 % 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.useshellfishpopulation.checked = 1 else document.farm.useshellfishpopulation.checked = 0; break; case 6: document.farm.selectshrimpspecies.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.selectshrimpspecies.options[1] = null; // remove shrimp } 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("LMFARM="); // 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("LMFARM="); 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 = "LMFARM=" + 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.useshellfishpopulation.checked) + escape(Separator) + escape(document.farm.selectshrimpspecies.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("LMFARM="); 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 = "LMFARM=" + 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 UpdateShellfish() { if ( document.farm.useshellfish.checked == 0 ) { // New functions to hide shellfish on startup - JGF 2007.04.04 SC1.innerHTML = ""; SC2.innerText = ""; SC3.innerText = ""; SC4.innerText = ""; SC5.innerText = ""; SC6.innerText = ""; SC7.innerHTML = ""; SCR1.innerHTML = ""; SCR2.innerHTML = ""; SCR3.innerHTML = ""; SCR4.innerHTML = ""; SCR5.innerHTML = ""; SCR6.innerHTML = ""; SCR7.innerHTML = ""; SCR8.innerHTML = ""; TSH.innerText = ""; SBR.innerText = ""; SAT.innerText = ""; SIR.innerText = ""; document.farm.selectshellfishspecies.style.visibility = "hidden"; document.farm.shellfishcultivationperiod.style.visibility = "hidden"; document.farm.shellfishdensity.style.visibility = "hidden"; document.farm.useshellfishpopulation.style.visibility = "hidden"; document.farm.shellfishbiomasstotal.style.visibility = "hidden"; document.farm.shellfishadultstotal.style.visibility = "hidden"; document.farm.shellfishbiomassratio.style.visibility = "hidden"; document.farm.shellfishadultsratio.style.visibility = "hidden"; } else { // New functions to show shellfish on check - JGF 2007.04.04 SC1.innerHTML = "Shellfish cultivation"; SC2.innerText = "Species"; SC3.innerText = "Cultivation period"; SC4.innerText = "Density"; SC5.innerText = "Use population"; SC6.innerText = "days"; SC7.innerHTML = "ind m-2"; FS.updateShellfishPopulation(); /* SCR1.innerHTML = "Harvestable shellfish"; SCR2.innerHTML = "Biomass"; SCR3.innerHTML = "Harvestable shellfish"; SCR4.innerHTML = "Number of animals"; SCR5.innerHTML = "tons"; SCR6.innerHTML = "ind"; SCR7.innerHTML = "%"; TSH.innerText = "Total harvest (TPP)"; SBR.innerText = "Biomass ratio (APP)"; SAT.innerText = "Adults (total)"; SIR.innerText = "Individuals (ratio)"; */ document.farm.selectshellfishspecies.style.visibility = "visible"; document.farm.shellfishcultivationperiod.style.visibility = "visible"; document.farm.shellfishdensity.style.visibility = "visible"; document.farm.useshellfishpopulation.style.visibility = "visible"; document.farm.shellfishbiomasstotal.style.visibility = "visible"; document.farm.shellfishadultstotal.style.visibility = "visible"; document.farm.shellfishbiomassratio.style.visibility = "visible"; document.farm.shellfishadultsratio.style.visibility = "visible"; } FS.clearElements(); } function UpdateOutputs() { if ( document.farm.usepopulation.checked == 1 ) { // Change labels TotalAdults.innerText = "Adults (total)"; HarvestableAnimals.innerText = "Harvestable shrimp"; HarvestableBiomass.innerText = "Harvestable shrimp"; TotalHarvest.innerText = "Total harvest (TPP)"; BiomassRatio.innerText = "Biomass ratio (APP)"; BFA.innerText = "tons"; BRA.innerText = ""; } else { // Change labels TotalAdults.innerText = "Animals (total)"; HarvestableAnimals.innerText = "Individuals"; HarvestableBiomass.innerText = "Individual weight"; TotalHarvest.innerText = "Average weight"; BiomassRatio.innerText = "Total length"; BFA.innerText = "g TFW"; BRA.innerText = "cm"; } FS.clearElements(); } function UpdateShellfishPopulation() { if ( document.farm.useshellfish.checked == 0 ) { document.farm.useshellfishpopulation.checked = 0; return; } if ( document.farm.useshellfishpopulation.checked == 1 ) { // Change labels TSH.innerText = "Total harvest (TPP)"; SBR.innerText = "Biomass ratio (APP)"; SAT.innerText = "Adults (total)"; SCR1.innerText = "Harvestable shellfish"; SCR3.innerText = "Harvestable shellfish"; SCR5.innerText = "tons"; SCR8.innerText = ""; } else { // Change labels TSH.innerText = "Average weight"; SBR.innerText = "Shell length"; SAT.innerText = "Animals (total)"; SCR1.innerText = "Individual weight"; SCR3.innerText = "Individuals"; SCR5.innerText = "g TFW"; SCR8.innerText = "cm"; } FS.clearElements(); } 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"; } // Farm area function CalculateArea() { return FS.decimalPlaces(FS.Area,2); } // Farm volume function CalculateVolume() { return FS.decimalPlaces(FS.Volume,2); } // Sediment POM and SPM - function implemented also for sedimenting chl a, but presently commented - JGF 2006.07.28 function Sediment() { return; // Only process sedimentation if no culture or surface culture if ( document.farm.useshellfishpopulation.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 */ } } // Shrimp grazing // Generic shrimp function ShrimpGraze() { shrimpFW=FS.IndividualShrimpBiomass[FS.MyBox];//------------------------------//------------- shrimpGC=FS.shrimpGutContent[FS.MyBox];//-------------------------------------//============= for (i = 0; i < FS.Boxes; i++) { FS.MyBox = i; FS.NumberOfAnimals = 1; FS.shrimpFeed(); FS.shrimpRespire(); FS.shrimpAssimilate(); FS.shrimpFaecesProduction();// added by Changbo FS.shrimpGutContent[i]+=(FS.shrimpFeed()-FS.shrimpAssimilate()-FS.shrimpFaecesProduction())*FS.DeltaT;//added by Changbo FS.IndividualShrimpBiomassFlux[i] = FS.IndividualShrimpBiomassFlux[i] // gTFW ind-1 d-1 + FS.ShrimpScopeForGrowth();// add "()" by Changbo } 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.ShrimpClassDensity[FS.MyClass * FS.Boxes + FS.MyBox]; FS.shrimpFeed(); FS.shrimpRespire(); FS.shrimpAssimilate(); FS.shrimpFaecesProduction();// added by Changbo FS.ShrimpGrowthRate[k * FS.Boxes + j] = FS.ShrimpScopeForGrowth();//-----------------()------------------ // if ( FS.TimeNow == 2000 ) // alert(FS.GrowthRate[k * FS.Boxes + j]); } } //----------------------------------------------------------following by Changbo----------------------------------------------------------------------------------------------------- var DW_to_FW=4.089, O2toBiomass=3.09, ShrimpAssimilationEfficiency=0.85, shrimpFW=0,//Initialize just for temporary use---------------------------//==================== shrimpGC=0; //----------------------------------------------------------//================================= function ShrimpFeed() { //return 10; var R32=5.8236, //Ration at 32 C for shrimp Food=500, //DW mg*m-2 ConsumptionEfficiency=0.1, Rmax_R1=0.071, Rmax_R2=0.59, Temperature=FS.WaterTemperature; //Temperature=28; var Rmax=Rmax_R1*Math.pow(shrimpFW,Rmax_R2)* (-0.0225*Temperature*Temperature + 1.4463*Temperature-17.418)/R32/DW_to_FW*FS.DaysToHours; if((FS.TimeNow > 1) && ((FS.TimeNow % 24) < 4)) return Rmax*(1-Math.exp(-ConsumptionEfficiency*Food)); else return 0; } function ShrimpAssimilate() { if(FS.TimeNow > 1) return shrimpGC*ShrimpAssimilationEfficiency; else return 0; } function ShrimpFaecesProduction() { if(FS.TimeNow > 1) return shrimpGC*(1-ShrimpAssimilationEfficiency); else return 0; } function ShrimpRespire() { //return 6; var Temperature=FS.WaterTemperature; //28C, const temperature for test if(FS.TimeNow > 1) return 0.05*Math.exp(0.07*Temperature)*Math.pow(shrimpFW,-0.185)* shrimpFW*O2toBiomass*0.001*FS.DaysToHours; else return 0; } function ShrimpScopeForGrowth() { //return 0.1; if(FS.TimeNow > 1 && FS.WaterTemperature > 17 && FS.WaterTemperature < 40) return (FS.shrimpAssimilate()-FS.shrimpRespire())*DW_to_FW; else return 0; } //--------------------------------------------------------------------------End by Changbo----------------------------------------------- /* function ShrimpFeed() { return; 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 ShrimpRespire() { return; 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 ShrimpAssimilate() { FS.ShrimpScopeForGrowth = 0.1; return; 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 } */ // 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.useshellfishpopulation.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 } // Razor clams function RazorClamGraze() { //var TotalFWToMeatDW = 14.1057; // updated, 2007.5.13 var ShellCavityWaterCorrection = 1.4765, ShellProportion = 0.4447, WetSoftTissueWaterContent = 0.8115; for (i = 0; i < FS.Boxes; i++) { FS.MyBox = i; FS.NumberOfAnimals = 1; FS.IndividualWeight = FS.IndividualBiomass[i]; FS.ShellDryWeight = FS.IndividualShellDryWeight[i]; // if ( FS.TimeNow == 1 ) // alert(FS.IndividualWeight); FS.razorClamFeed(); FS.razorClamRespire(); FS.razorClamExcrete(); FS.razorClamReproduce(); FS.razorClamAssimilate(); // Was converted to g TFW, so individual biomass was always in gTFW // from 2006.11.17 individual runs in g tissue DW FS.IndividualBiomassFlux[i] = FS.IndividualBiomassFlux[i] + FS.ScopeForGrowth; FS.IndividualShellDryWeightFlux[i] = FS.IndividualShellDryWeightFlux[i] + FS.ShellGrowth; } if (document.farm.useshellfishpopulation.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.RazorClassDensity[FS.MyClass * FS.Boxes + FS.MyBox]; FS.IndividualWeight = (FS.MyClass * FS.ClassAmplitude // Mid-interval + FS.SeedClassTFW) / ShellCavityWaterCorrection * (1 - ShellProportion) * (1 - WetSoftTissueWaterContent); FS.razorClamFeed(); FS.razorClamRespire(); FS.razorClamExcrete(); FS.razorClamReproduce(); FS.razorClamAssimilate(); // Classes run in TFW FS.RazorGrowthRate[k * FS.Boxes + j] = FS.ScopeForGrowth // must be in TFW * ShellCavityWaterCorrection / (1 - ShellProportion) / (1 - WetSoftTissueWaterContent); // if ( FS.TimeNow == 2000 ) // alert(FS.GrowthRate[k * FS.Boxes + j]); } } function RazorClamFeed() { var PhytoCarbonToDW = 0.38, // dry mass of organic matter in phytoplankton - mg L-1 WeightExponentForFeeding = 0.62, // Hawkins et al. 2001, 2002 DAYSTOHOURS = FS.DaysToHours, BoxVolume = FS.Volume, NumberOfAnimals = FS.NumberOfAnimals, IndividualWeight = FS.IndividualWeight, TimeStep = FS.DeltaT, ChlorophyllCarbonRatio = 1.0/15.0, // Major change AJSH 2006.09.21 POMToNitrogen = 1/3 * 7/45, // Redfield C:N CarbonToNitrogen = 7/45; // Divide by 3 to C, Redfield C:N; var Phyorg = 0, // Phytoplankton as dry weight organic material Detorg = 0, // Organic detritus TPM = 0, // Suspended particulate matter POM = 0, // Particulate organic matter PIM = 0, // Particulate inorganic matter OCS = 0, // PIM feeding and rejection FRPIM, // FR - Filtration rate RRPIM, // RR - Rejection rate IRPIM, // IR - Ingestion rate CRPIM, // CR- Clearance rate RRFRPIM, // Fraction // Phytoplankton feeding and rejection FRPHY, RRPHY, IRPHY, RRFRPHY, // Detritus feeding and rejection FRDET, RRDET, IRDET, RRFRDET, EDET = 1.5, // J mg-1 EPHY = 23.5, // J mg-1 FRPOM, IRPOM, // TPM feeding and rejection FRTPM, RRTPM, IRTPM, RRFRTPM, CRTPM, // Post-filtration selection efficiency prior to ingestion PIMSEING, // PIM Selection efficiency prior to ingestion PHYSEING, DETSEING, REDET, REPHY, REPIM, // Ingestion OCI, NAEIO, BoundWaterFraction, CorrectedPOM, CorrectedTPM; // Biodeposition var PseudofaecesPIM, PseudofaecesPOM, TruefaecesPIM, TruefaecesPOM, TotalFaecesBiodeposition, TotalPseudofaecesBiodeposition, TotalTrueFaeces, TotalWeightSpecificBiodeposition, TotalPOMBiodeposition; // Get water temperature for feeding rate effects var MyWaterTemperature = FS.WaterTemperature, // default value MySalinity = FS.Salinity, //35.0, changed to current salinity, 2007.5.13 TemperatureEffectsOnFeedingRate, StandardWaterTemperature = 15.0, SalinityEffectsOnFeedingRate, SalinityThreshold = 12, FullStrengthSeaWater = 35.0; // if ( FS.TimeNow == 1 ) // alert(FS.IndividualWeight); // MyWaterTemperature = 15; // for tests // MySalinity = 33.23; // for tests TemperatureEffectsOnFeedingRate = (0.9758 + 2.1696 * Math.exp(-0.5*Math.pow((MyWaterTemperature-18.5816)/ 3.8081,2))) / (0.9758 + 2.1696 * Math.exp(-0.5*Math.pow((StandardWaterTemperature-18.5816)/3.8081,2))); if ( TemperatureEffectsOnFeedingRate <= 0 ) TemperatureEffectsOnFeedingRate = 0.01; // Almada Villela 1984 if ( MySalinity < SalinityThreshold ) SalinityEffectsOnFeedingRate = 0.01; else SalinityEffectsOnFeedingRate = (0.766 + (21.1/MySalinity) + (-516.3/Math.pow(MySalinity,2)) + (2253/Math.pow(MySalinity,3))) / (0.766 + (21.1/FullStrengthSeaWater) + (-516.3/Math.pow(FullStrengthSeaWater,2)) + (2253/Math.pow(FullStrengthSeaWater,3))); FS.SalinityEffectsOnFeedingRate = SalinityEffectsOnFeedingRate; // Phytoplankton food supply Phyorg = FS.Chl[FS.MyBox] // ug chl a L-1 / ChlorophyllCarbonRatio // to ug C L-1 / FS.CUBIC // to mg C L-1 / PhytoCarbonToDW; // to mg DW L-1 // For tests // Phyorg = 10 // ug chl a L-1 // / ChlorophyllCarbonRatio // to ug C L-1 // / FS.CUBIC // to mg C L-1 // / PhytoCarbonToDW; // to mg DW L-1 POM = FS.POM[FS.MyBox]; TPM = FS.TPM[FS.MyBox]; // POM = 20; // For tests // TPM = 50; // For tests if ( POM < 0 ) // POM must be zero or greater POM = 0.1 * TPM; // All preliminary calculations of derived parameters BoundWaterFraction = 0.0065 * Math.pow(Phyorg/POM,-1.0175); if ( BoundWaterFraction >= 0.1 ) BoundWaterFraction = 0.1; // Open water system correction // if ( OpenWaterSystem ) // BoundWaterFraction = 0.05; PIM = TPM-POM; CorrectedPOM = POM-(PIM*BoundWaterFraction); if ( CorrectedPOM < 0 ) CorrectedPOM = 0; // mg L-1 if ( PIM < 0 ) PIM = 0; CorrectedTPM = PIM + CorrectedPOM; Detorg = CorrectedPOM-Phyorg; // mg L-1 if ( Detorg < 0 ) Detorg = 0.1; if ( Detorg <= 0 ) Detorg = 0.01; if ( Phyorg <= 0 ) Phyorg = 0.01; try { OCS = POM/TPM; } catch ( exception ) { OCS = 0; } // First pass algorithm to limit growth as number of animals increases // 1. Calculate FRPIM, FRPHY and FRDET, and then FRTPM // PIM feeding and rejection // FRPIM = 463.964 * (1-Math.exp(-0.006 * PIM)); //FRPIM = 469.8 * (1-Math.exp(-0.005 * PIM)); FRPIM = 96.66 * (1-Math.exp(-0.015 * PIM)); if ( FRPIM < 0 ) FRPIM = 0; else FRPIM = FRPIM * TemperatureEffectsOnFeedingRate * SalinityEffectsOnFeedingRate * Math.pow(IndividualWeight,WeightExponentForFeeding); // mg h-1 // Phyto feeding and rejection // FRPHY = 3.825 * Phyorg; //FRPHY = 4.114 * Phyorg; FRPHY = 1.664 * Phyorg; if ( FRPHY < 0 ) FRPHY = 0; else FRPHY = FRPHY * TemperatureEffectsOnFeedingRate * SalinityEffectsOnFeedingRate * Math.pow(IndividualWeight,WeightExponentForFeeding); // mg h-1 // Detritus feeding and rejection try { // FRDET = 29.439 * (1-Math.exp(-0.129 * Detorg)); //FRDET = 30.299 * (1-Math.exp(-0.124 * Detorg)); FRDET = 81.265 * (1-Math.exp(-0.035 * Detorg)); } catch ( exception ) { FRDET = 0; } if ( FRDET < 0 ) FRDET = 0; else FRDET = FRDET * TemperatureEffectsOnFeedingRate * SalinityEffectsOnFeedingRate * Math.pow(IndividualWeight,WeightExponentForFeeding); // mg h-1 // TPM feeding and rejection FRTPM = FRPHY+FRPIM+FRDET; // mg h-1 // 2006.07.22 JGF - Razor clam growth is readjusted based on limitation of filtration rate // considering the most limiting factor out of phytoplankton, POM and TPM. // Both filtration and ingestion are reduced acording to the factor "GrowthReduction" // thus avoiding removal of resources beyond what is available. Tests with oyster density // 100 and FARM layout from mussels of 300 wrt EutroDK2006 slides show no difference in // results - older formulation below should be deleted after tests. PhytoplanktonFiltration = FRPHY // mg DW animal-1 h-1 * DAYSTOHOURS // to mg DW animal-1 d-1 / FS.CUBIC // to g DW animal-1 d-1 // Changed in FARMSCALE * ( NumberOfAnimals / BoxVolume ); // to g DW total m-3 d-1 // Phyorg mg DW L-1 i.e. g DW m-3 so we must compare identical units POMFiltration = FRDET // mg DW animal-1 h-1 * DAYSTOHOURS // to mg DW animal-1 d-1 / FS.CUBIC // to g DW animal-1 d-1 // Changed in FARMSCALE * ( NumberOfAnimals / BoxVolume ); // to g DW total m-3 d-1 TPMFiltration = FRTPM // mg DW animal-1 h-1 * DAYSTOHOURS // to mg DW animal-1 d-1 / FS.CUBIC // to g DW animal-1 d-1 // Changed in FARMSCALE * ( NumberOfAnimals / BoxVolume ); // to g DW total m-3 d-1 var GrowthReduction = 1.0; if ( PhytoplanktonFiltration * TimeStep > Phyorg ) { MaxFiltration = Phyorg / TimeStep; // g DW total m-3 d-1 GrowthReduction = MaxFiltration/PhytoplanktonFiltration; } if ( POMFiltration * TimeStep > Detorg ) { MaxFiltration = Detorg / TimeStep; // g DW total m-3 d-1 if ( MaxFiltration/POMFiltration < GrowthReduction ) GrowthReduction = MaxFiltration/POMFiltration; } if ( TPMFiltration * TimeStep > TPM ) { MaxFiltration = TPM / TimeStep; // g DW total m-3 d-1 if ( MaxFiltration/TPMFiltration < GrowthReduction ) GrowthReduction = MaxFiltration/TPMFiltration; } if ( GrowthReduction < 1.0 ) { FRPIM = FRPIM * GrowthReduction; // mg h-1 FRPHY = FRPHY * GrowthReduction; // mg h-1 FRDET = FRDET * GrowthReduction; // mg h-1 FRTPM = FRPHY+FRPIM+FRDET; // mg h-1 TPMFiltration = FRTPM // mg DW animal-1 h-1 * DAYSTOHOURS // to mg DW animal-1 d-1 / FS.CUBIC // to g DW animal-1 d-1 // Changed in FARMSCALE * ( NumberOfAnimals / BoxVolume ); // to g DW total m-3 d-1 } // PIM feeding and rejection //IRPIM = 7.567 * (1-Math.exp(-0.153 * PIM)); // AJSH flagged as changed, but unchanged IRPIM = 52.63 * (1-Math.exp(-0.016 * PIM)); if ( IRPIM < 0 ) IRPIM = 0; else IRPIM = IRPIM * TemperatureEffectsOnFeedingRate * SalinityEffectsOnFeedingRate * Math.pow(IndividualWeight,WeightExponentForFeeding) * GrowthReduction; // mg h-1 RRPIM = FRPIM-IRPIM; RRFRPIM = RRPIM/FRPIM; CRPIM = FRPIM/PIM; // L h-1 // Detritus feeding and rejection try { // IRDET = 5.922 * (1-Math.exp(-0.412 * Detorg)); //IRDET = 5.89 * (1-Math.exp(-0.461 * Detorg)); IRDET = 79.254 * (1-Math.exp(-0.034 * Detorg)); } catch ( exception ) { IRDET = 0; } if ( IRDET < 0 ) IRDET = 0; else IRDET = IRDET * TemperatureEffectsOnFeedingRate * SalinityEffectsOnFeedingRate * Math.pow(IndividualWeight,WeightExponentForFeeding) * GrowthReduction; // mg h-1 RRDET = FRDET-IRDET; RRFRDET = RRDET/FRDET; FRPOM = FRPHY + FRDET; // Phytoplankton ingestion // IRPHY = 3.447 * Phyorg; // IRPHY = 3.526 * Phyorg; IRPHY = 1.577 * Phyorg; if ( IRPHY < 0 ) IRPHY = 0; else IRPHY = IRPHY * TemperatureEffectsOnFeedingRate * SalinityEffectsOnFeedingRate * Math.pow(IndividualWeight,WeightExponentForFeeding) * GrowthReduction; // mg h-1 RRPHY = FRPHY-IRPHY; RRFRPHY = RRPHY/FRPHY; // Calculate proportion of phytoplankton and detritus ingested FS.DetritusFitration = FS.DetritusFitration + FRDET; FS.PhytoFiltration = FS.PhytoFiltration + FRPHY; FS.DetritusIngestion = FS.DetritusIngestion + IRDET; FS.PhytoIngestion = FS.PhytoIngestion + IRPHY; // For open water sites, EDET = 4, else EDET = 1.5 - Add boolean parameter to XLS // if ( OpenWaterSystem) // EDET = 4.0; // Debugger(EDET); // TPM feeding and rejection FRTPM = FRPHY+FRPIM+FRDET; // mg h-1 IRTPM = IRPHY+IRPIM+IRDET; RRTPM = FRTPM-IRTPM; RRFRTPM = RRTPM/FRTPM; CRTPM = FRTPM/TPM; // Use CRTPM to find filtered volume (clearance rate X time) ClearanceRate = CRTPM; // new 2002.07.16 to calculate clearance rate in L h-1 // Post-filtration selection efficiency prior to ingestion try // Exception handling for division by zero { DETSEING = (IRDET/IRTPM)/(FRDET/FRTPM); PHYSEING = (IRPHY/IRTPM)/(FRPHY/FRTPM); PIMSEING = (IRPIM/IRTPM)/(FRPIM/FRTPM); REDET = (FRDET/FRTPM)/(Detorg/TPM); REPHY = (FRPHY/FRTPM)/(Phyorg/TPM); REPIM = (FRPIM/FRTPM)/(PIM/TPM); } catch ( exception ) { return; } // Ingestion IRPOM = IRDET + IRPHY; OCI = IRPOM/IRTPM; var AlertTime = 5; //NAEIO = 0.940 // + (-0.047 / OCI) // + (-0.209 / ( IRPOM * DAYSTOHOURS)) // + (0.011 / Math.pow(IRPOM * DAYSTOHOURS,2)); NAEIO = 1.101 + (-0.101 / OCI) + (-0.537 / ( IRPOM * DAYSTOHOURS)) + (0.050 / Math.pow(IRPOM * DAYSTOHOURS,2)); // Debugger(NAEIO); FS.NEA = (EPHY*IRPHY + EDET*IRDET) * NAEIO; // J ind-1 h-1 /* if ( FS.TimeNow == AlertTime ) alert(IRPHY*24); if ( FS.TimeNow == AlertTime ) alert(IRDET*24); if ( FS.TimeNow == AlertTime ) alert(IRPIM*24); if ( FS.TimeNow == AlertTime ) alert(FS.NEA*24); */ // Balance methods // TPM // alert(TPMFiltration); FS.TPMFlux[FS.MyBox] = FS.TPMFlux[FS.MyBox] - TPMFiltration; // g m-3 d-1 // / FS.CUBIC; // to return in mg l-1 d-1 // if ( FS.TimeNow == 0 ) // alert(FS.TPMFlux[FS.MyBox]); // POM // alert(IRDET); FS.POMFlux[FS.MyBox] = FS.POMFlux[FS.MyBox] - IRDET // mg DW animal-1 h-1 * DAYSTOHOURS // mg DW animal-1 d-1 * NumberOfAnimals // mg DW d-1 / FS.CUBIC // g DW d-1 / BoxVolume; // g DW m-3 d-1 // if ( FS.TimeNow == 0 ) // alert(FS.POMFlux[FS.MyBox]); // Chl a PhytoplanktonFiltration = IRPHY // mg DW animal-1 h-1 * PhytoCarbonToDW // to mg C animal-1 h-1 * DAYSTOHOURS // to mg C animal-1 d-1 * ( NumberOfAnimals / BoxVolume ); // to mgC total m-3 d-1 FS.ChlFlux[FS.MyBox] = FS.ChlFlux[FS.MyBox] - PhytoplanktonFiltration * ChlorophyllCarbonRatio; // if ( FS.TimeNow == AlertTime ) // alert(FS.ChlFlux[FS.MyBox]); FS.ChlorophyllRemoval = FS.ChlorophyllRemoval // kg N timestep-1 + PhytoplanktonFiltration // mg C total m-3 d-1 * CarbonToNitrogen // mg N total m-3 d-1 * BoxVolume // to mg N total vol d-1 * FS.DeltaT // to mg N total vol timestep-1 / Math.pow(FS.CUBIC,2); // to kg N timestep-1 FS.NitrogenRemoval = FS.NitrogenRemoval // kg N timestep-1 + (PhytoplanktonFiltration // mg C total m-3 d-1 * CarbonToNitrogen // mg N total m-3 d-1 + IRDET // mg DW animal-1 h-1 * DAYSTOHOURS // mg DW animal-1 d-1 * NumberOfAnimals / BoxVolume // mg DW total m-3 d-1 * POMToNitrogen) // mg N total m-3 d-1 * BoxVolume // to mg N total vol d-1 * FS.DeltaT // to mg N total vol timestep-1 / Math.pow(FS.CUBIC,2); // to kg N timestep-1 // New biodeposition code PseudofaecesPIM = RRPIM; // mg ind-1 h-1 PseudofaecesPOM = RRTPM-RRPIM; // mg ind-1 h-1 TotalPseudofaecesBiodeposition = RRTPM; TruefaecesPIM = IRPIM; // mg ind-1 h-1 if ( NAEIO > 0 ) TruefaecesPOM = (IRDET+IRPHY) * (1-NAEIO) // mg ind-1 h-1 else TruefaecesPOM = 0; // mg ind-1 h-1 TotalTrueFaeces = TruefaecesPIM + TruefaecesPOM; // mg ind-1 h-1 TotalFaecesBiodeposition = TotalTrueFaeces // mg ind-1 h-1 + TotalPseudofaecesBiodeposition; TotalPOMBiodeposition = PseudofaecesPOM + TruefaecesPOM; // mg ind-1 h-1 TotalWeightSpecificBiodeposition = TotalFaecesBiodeposition // L g-1 soft tissue h-1 * Math.pow(1/IndividualWeight, WeightExponentForFeeding); // JGF 2006.06.25 - Used TruefaecesPOM rather than TotalPOMBiodeposition because // N removal is based on IRPHY and IRDET, so already excludes pseudofaeces // however some material is lost to water due to mucopolysaccharides binding // PF, these are produced by the animal FS.NitrogenInFaeces = FS.NitrogenInFaeces // kg N d-1 // + TotalPOMBiodeposition // mg DW animal-1 h-1 + TruefaecesPOM // mg DW animal-1 h-1 * DAYSTOHOURS // to mg DW animal-1 d-1 * NumberOfAnimals // to mg DW total vol d-1 * POMToNitrogen // to mg N total vol d-1 * FS.DeltaT // to mg N total vol timestep-1 / Math.pow(FS.CUBIC,2); // to kg N total vol timestep-1 // if POM is returned mussels do not grow CHECK! - TPM seems indifferent // Tests, POM returned increases concentration at high number of animals // grow well at 25-100 ind m-3 density, high densities no growth // 2006.06.25 JGF // 180 days, 6000 is 96% // if ( FS.TimeNow == 6000 ) // { // alert(FS.POM[FS.MyBox]); // alert(FS.TPM[FS.MyBox]); // } // Allow POM and TPM feedback for mussel layout slide from EutroDK to work // return; // test effect of no feedback // Balance for pseudofaeces and faeces // TPM addition FS.TPMFlux[FS.MyBox] = FS.TPMFlux[FS.MyBox] + TotalFaecesBiodeposition // mg animal-1 h-1 * DAYSTOHOURS // mg DW animal-1 d-1 * NumberOfAnimals // mg DW d-1 / FS.CUBIC // g DW d-1 / BoxVolume; // g DW m-3 d-1 // if ( FS.TimeNow == 1 ) // alert(FS.TPMFlux[FS.MyBox]); // POM addition FS.POMFlux[FS.MyBox] = FS.POMFlux[FS.MyBox] + TotalPOMBiodeposition // mg DW animal-1 h-1 * DAYSTOHOURS // mg DW animal-1 d-1 * NumberOfAnimals // mg DW d-1 / FS.CUBIC // g DW d-1 / BoxVolume; // g DW m-3 d-1 // if ( FS.TimeNow == 1 ) // alert(FS.POMFlux[FS.MyBox]); } function RazorClamRespire() { var OXYGENATOMICWEIGHT = 16, // Checked correct with AJSH 2006.05.04 NITROGENATOMICWEIGHT = 14, // 14.01; DAYSTOHOURS = FS.DaysToHours, THLToOxygen = 14.06, // 1 mg O2 = 14.06 J - Gnaiger (1983) NumberOfAnimals = FS.NumberOfAnimals, BoxVolume = FS.Volume, IndividualWeight = FS.IndividualWeight, MyWaterTemperature = FS.WaterTemperature, WeightExponentForFeeding = 0.62, // Hawkins et al. 2001, 2002 WeightExponentForMetabolism = 0.72, // According to theoretical expectations; Hawkins et al 2002, JEMBE TemperatureEffectsOnMaintenanceMetabolism, // measured in M. edulis as described by Hawkins el al. 2002 JEMBE SalinityEffectsOnMaintenanceMetabolism = FS.SalinityEffectsOnFeedingRate, MaintenanceHeatLoss, TotalHeatLosses, TotalWeightSpecificHeatLosses, OxygenUptakeMass, OxygenUptakeVolume, WeightSpecificOxygenUptakeVolume, WeightStandardNEA, WeightSpecificNitrogenExcretion, EnergyExcretedAsNitrogen, OxygenToNitrogenRatio, StandardWaterTemperature = 15.0; var AlertTime = 1; TemperatureEffectsOnMaintenanceMetabolism = Math.exp(0.074*MyWaterTemperature) /Math.exp(0.074*StandardWaterTemperature); // SalinityEffectsOnMaintenanceMetabolism = SalinityEffectsOnFeedingRate; MaintenanceHeatLoss = 4.1 * TemperatureEffectsOnMaintenanceMetabolism * SalinityEffectsOnMaintenanceMetabolism * Math.pow(IndividualWeight, WeightExponentForMetabolism); // J ind-1 h-1 TotalHeatLosses = 0.23 * FS.NEA + MaintenanceHeatLoss; // J ind-1 h-1 TotalWeightSpecificHeatLosses = TotalHeatLosses // J g-1 h-1 * Math.pow(1/IndividualWeight,WeightExponentForMetabolism); OxygenUptakeMass = TotalHeatLosses / THLToOxygen; // mg O2 ind-1 h-1 OxygenUptakeVolume = OxygenUptakeMass / 1.428; // ml O2 ind-1 h-1 WeightSpecificOxygenUptakeVolume = OxygenUptakeVolume // ml O2 g-1 h-1 * Math.pow(1/IndividualWeight,WeightExponentForMetabolism); // Only used for calculating OxygenToNitrogenRatio WeightStandardNEA = Math.pow(1/IndividualWeight,WeightExponentForFeeding) // J ind-1 h-1 * FS.NEA * DAYSTOHOURS; // to J ind-1 d-1 for IF test below // Ratio can change between 10 and 200, as a function of WeightStandardNEA //Ratio can change between 10 and 50 2007.5.13 if (10 + 0.04 * WeightStandardNEA < 10) OxygenToNitrogenRatio = 10; else if (10 + 0.152 * WeightStandardNEA > 50) OxygenToNitrogenRatio = 50; else OxygenToNitrogenRatio = 10 + 0.04 * WeightStandardNEA; TotalExcretoryLosses = TotalHeatLosses // ug NH4 h-1 / THLToOxygen / OXYGENATOMICWEIGHT / OxygenToNitrogenRatio * NITROGENATOMICWEIGHT * FS.CUBIC; WeightSpecificNitrogenExcretion = TotalExcretoryLosses // ug g-1 h-1 * Math.pow(1/IndividualWeight,WeightExponentForMetabolism); EnergyExcretedAsNitrogen = TotalExcretoryLosses * 0.02428; // J ind-1 h-1 FS.NEB = FS.NEA - TotalHeatLosses - EnergyExcretedAsNitrogen; // J ind-1 h-1 // if ( FS.TimeNow == AlertTime ) // alert(FS.NEB*24); FS.TotalExcretoryLosses = TotalExcretoryLosses; FS.OxygenConsumption = TotalHeatLosses // J ind-1 h-1 / THLToOxygen // mg O2 ind-1 h-1 / FS.CUBIC // g O2 ind-1 h-1 * DAYSTOHOURS; // 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 FS.NitrogenAddition = FS.NitrogenAddition + TotalExcretoryLosses // ug N ind-1 h-1 * NumberOfAnimals // to ug N in box h-1 * DAYSTOHOURS // to ug N in box d-1 * FS.DeltaT // to ug N timestep-1 / Math.pow(FS.CUBIC,3); // to kg N timestep-1 } function RazorClamExcrete() { var BoxVolume = FS.Volume, NumberOfAnimals = FS.NumberOfAnimals, AmmoniaExcretion; // Upscaling to population for nutrient balance AmmoniaExcretion = FS.TotalExcretoryLosses * ( NumberOfAnimals / BoxVolume ); } function RazorClamReproduce() { FS.EnergyLostAsReproductiveOutput = 0; return; //for test var SoftTissueEnergeticConversion = 20300, //20500, J g-1 Dare and Edwards, 1975 ShellEnergeticConversion = 440, JulianDay = Math.round(FS.TimeNow * FS.DeltaT), DAYSTOHOURS = FS.DaysToHours, Reproduction = 0, //TotalFWToMeatDW = 14.1057, // Estimated from Garen et al 2004, NEEDS IMPROVING//updated, 2007.5.13 IndividualWeight = FS.IndividualWeight, IndividualShellWeight = FS.ShellDryWeight, //ShellLength = Math.pow(10,FS.log10(IndividualWeight * TotalFWToMeatDW / 0.0836)/2.9602), //cm //ShellLength = Math.exp((FS.log10(IndividualShellWeight) - FS.log10(0.0365))/2.4525), //cm ShellLength = Math.exp((Math.log(IndividualShellWeight) - Math.log(0.0365))/2.4525), SizeOfMaturation = 2.5, // cm EnergyRatio = 0.9354, //added on 14th May, 2007 ZCB EnergyLostAsReproductiveOutput = 0; //Complementary variables: according to ShellSim C++ code var MyThresholdTemperature = 19, MyWaterTemperature = FS.WaterTemperature, AlreadySpawned = false, INFINITY = 1000000, SpawningDay = INFINITY, SoftTissueEnergeticContents, ShellEnergeticContents, MyCriticalEnergyRatio, MyMaximumDrySomaticTissueWeight = 1.25, MyProprtionDSTLostOnSpawning = 0.08, MyMaximumDSTWeight; if (JulianDay == 365 ) AlreadySpawned = false; // reset for new year if ( ( MyWaterTemperature > MyThresholdTemperature ) && ( AlreadySpawned == false ) && ( SpawningDay == INFINITY ) ) { // Define spawning day SpawningDay = ++JulianDay; AlreadySpawned = true; } if ( JulianDay > SpawningDay ) SpawningDay = INFINITY; // Spawn here if ( SpawningDay != JulianDay ) return; FS.EnergyLostAsReproductiveOutput = 0; /*if ( ShellLength <= SizeOfMaturation ) return; if ( ( JulianDay == 90 ) || ( JulianDay == 308 ) ) { // AJSH uses 107 and divides by 20.5 - changed below since this // must be in identical units as NEB (spawning loss in J h-1) Reproduction = 0.107 // Converted per hour * Math.pow(IndividualWeight, 1.25) * SoftTissueEnergeticConversion / DAYSTOHOURS; EnergyLostAsReproductiveOutput = Reproduction; FS.EnergyLostAsReproductiveOutput = EnergyLostAsReproductiveOutput; } */ MyMaximumDSTWeight = MyMaximumDrySomaticTissueWeight / (1-MyProportionDSTLostOnSpawning); SoftTissueEnergeticContents = IndividualWeight // g to J * SoftTissueEnergeticConversion; ShellEnergeticContents = IndividualShellWeight // g to J * ShellEnergeticConversion; MyCriticalEnergyRatio = SoftTissueEnergeticContents / ( SoftTissueEnergeticContents + ShellEnergeticContents ); if ( ( ShellLength > SizeOfMaturation ) && ( MyCriticalEnergyRatio >= 0.95 * EnergyRatio ) ) { if ( ( IndividualWeight < MyMaximumDrySomaticTissueWeight ) || ( ( IndividualWeight > MyMaximumDrySomaticTissueWeight ) && // >= then line can be removed ( IndividualWeight >= MyMaximumDSTWeight ) ) ) { // Must be in identical units to NEB (spawning loss in J h-1) Reproduction = IndividualWeight * MyProportionDSTLostOnSpawning * SoftTissueEnergeticConversion / DAYSTOHOURS; // Converted per hour EnergyLostAsReproductiveOutput = Reproduction; FS.EnergyLostAsReproductiveOutput = EnergyLostAsReproductiveOutput; } } } function RazorClamAssimilate() { // AJSH uses four state variables, I only retain two: Dry Tissue Weight and Dry Shell Weight var SoftTissueEnergeticConversion = 20300, // J g-1 Dare and Edwards, 1975 // Changed the variables below to object variables for individual hierarchy // computed for M edulis from Cameron et al 1979 and Price et al 1976 ShellEnergeticConversion = 440, // J g-1 - PML Loch Creran 2006 EnergyRatio = 0.9354, // Energy ratio between soft tissue and soft tissue plus shell energy // Calculated from Seed 1983 SoftTissueEnergeticContents, ShellEnergeticContents, EnergyLostAsReproductiveOutput = FS.EnergyLostAsReproductiveOutput, DAYSTOHOURS = FS.DaysToHours, IndividualWeight = FS.IndividualWeight, IndividualShellWeight = FS.ShellDryWeight, TissueGrowth = 0, ShellGrowth = 0; FS.ScopeForGrowth = 0; FS.ShellGrowth = 0; // Eliminates first state variable (Soft tissue energy) from AJSH by calculating from individual weight SoftTissueEnergeticContents = IndividualWeight // g to J * SoftTissueEnergeticConversion; ShellEnergeticContents = IndividualShellWeight // g to J * ShellEnergeticConversion; // alert(FS.NEB); // alert(EnergyLostAsReproductiveOutput); if ( FS.NEB > 0 ) { if ( SoftTissueEnergeticContents / ( SoftTissueEnergeticContents + ShellEnergeticContents ) >= EnergyRatio ) { TissueGrowth = EnergyRatio * FS.NEB; ShellGrowth = (1-EnergyRatio) * FS.NEB; } else { TissueGrowth = FS.NEB; } } // Converted to gDW ind-1 d-1 FS.ScopeForGrowth += TissueGrowth / SoftTissueEnergeticConversion // J ind-1 d-1// Convert "=" to "+=" by Changbo, 2007.5.14 * DAYSTOHOURS; // Converted to gDW ind-1 d-1 if ( FS.NEB <= 0 ) EnergyLostAsReproductiveOutput = Math.abs(FS.NEB) + EnergyLostAsReproductiveOutput; // alert(EnergyLostAsReproductiveOutput); FS.ScopeForGrowth = FS.ScopeForGrowth // J ind-1 d-1 - EnergyLostAsReproductiveOutput / SoftTissueEnergeticConversion * DAYSTOHOURS; FS.ShellGrowth = ShellGrowth / ShellEnergeticConversion * DAYSTOHOURS; // alert(FS.ScopeForGrowth); // alert(FS.ShellGrowth); } // 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"); } /*------------------------------------------------------================= if(FS.TimeNow==60) { //For test alert("FS.TimeNow:"+FS.TimeNow); alert("FS.MyBox:"+FS.MyBox); alert("SFG:"+ FS.ShrimpScopeForGrowth()); alert("Feed:"+ FS.shrimpFeed()); alert("Respire:"+ FS.shrimpRespire()); alert("Gutcontent:"+ FS.shrimpGutContent[FS.MyBox]); alert("FW:" + FS.IndividualShrimpBiomass[0]); }*/ } FS.MyCounter = FS.MyCounter + Increment; if ( FS.MyCounter < FS.TheRunTime) setTimeout("FS.runModel()",1); else { // Outputs // 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(); // Shrimp outputs if ( document.farm.usepopulation.checked == 1 ) { // document.farm.biomasstotal.value = 5; // Tests // document.farm.biomassratio.value = 1; // Tests // for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) // alert(FS.ShrimpClassDensity[i]); //var AdultClass = FS.Classes-1; var AdultClass=FS.Classes-1;//Marketable size of shrimp is 13-18 g, over 18 g is too big, var NumberShrimpAdults = 0;// need to change this in the future. Changbo,2007.04.15 for (k = 0; k < FS.Classes; k++) for (j = 0; j < FS.Boxes; j++) if ( k == AdultClass ) //if(k >= AdultClass) NumberShrimpAdults += FS.ShrimpClassDensity[k * FS.Boxes + j]; //Change "=" to "+ =" by Changbo, 2007.04.15 document.farm.adultstotal.value = Math.round(NumberShrimpAdults); // document.farm.adultsratio.value = Math.round(NumberAdultTotal*100/FS.NumberShrimpSeed); var BiomassShrimpAdults = BiomassShrimps = 0, TonToGram = 1000000, SeedWeight = FS.SeedClassTFW, // gTFW first class mid-interval HarvestWeight = FS.Classes // gTFW last class mid-interval * FS.ClassAmplitude - FS.SeedClassTFW; //Final harvest weight need not to detract the seed weight??? Changbo,2007.04.15 BiomassShrimpAdults = NumberShrimpAdults*HarvestWeight/TonToGram;// tons, Added "*HarvestWeight/TonToGram",change from //number of individuals to biomass, by Changbo,2007.04.13 document.farm.biomasstotal.value = FS.decimalPlaces(BiomassShrimpAdults,1); /* document.farm.biomassratio.value = FS.decimalPlaces(BiomassShrimpAdults /(FS.NumberSeed*SeedWeight/TonToGram),2); */ } else { var BiomassShellfishIndividual = FS.IndividualShrimpBiomass[FS.Boxes-1]; // Only one box var ShrimpBodyLength=5.4906*Math.pow(BiomassShellfishIndividual, 0.3321);// TotalLength, cm------------by Changbo,2007.04.13 document.farm.biomasstotal.value = FS.decimalPlaces(BiomassShellfishIndividual,1); document.farm.biomassratio.value = FS.decimalPlaces(ShrimpBodyLength,1); } // Default no shellfish document.farm.shellfishbiomasstotal.value = "-"; if ( document.farm.useshellfish.checked == 1 ) { if ( document.farm.useshellfishpopulation.checked == 1 ) { // for ( i = 0; i < FS.Boxes * FS.Classes; i++ ) // alert(FS.ClassDensity[i]); var AdultClass = FS.Classes-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.shellfishadultstotal.value = Math.round(NumberAdultTotal); document.farm.shellfishadultsratio.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.shellfishbiomasstotal.value = FS.decimalPlaces(BiomassAdultTotal,1); document.farm.shellfishbiomassratio.value = FS.decimalPlaces(BiomassAdultTotal /(FS.NumberSeed*SeedWeight/TonToGram),2); // document.farm.biomassratio.value = Math.round(BiomassAdultTotal // *100 // /(FS.NumberSeed*SeedWeight/TonToGram)); } else { document.farm.shellfishadultstotal.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; BiomassAdultTotal = BiomassAdultTotal/FS.Boxes; ShellWeightAdultTotal = ShellWeightAdultTotal/FS.Boxes; document.farm.shellfishbiomasstotal.value = FS.decimalPlaces(BiomassAdultTotal,1); // Shell length here (substitutes biomass ratio when running individual models) switch(FS.MySpecies) { case 0: // Generic shellfish document.farm.shellfishbiomassratio.value = "-"; break; case 1: // Razor clams var WetShellWaterContent = 0.1513, WetSoftTissueWaterContent = 0.8115, //TotalFWToMeatDW = 14.1057, ShellCavityWaterCorrection = 1.4765; //added by Changbo, 2007.5.14 BiomassAdult1 = BiomassAdult1 / ( 1 - WetSoftTissueWaterContent ) + ShellWeightAdult1 / ( 1 - WetShellWaterContent ); BiomassAdult2 = BiomassAdult2 / ( 1 - WetSoftTissueWaterContent ) + ShellWeightAdult2 / ( 1 - WetShellWaterContent ); BiomassAdult3 = BiomassAdult3 / ( 1 - WetSoftTissueWaterContent ) + ShellWeightAdult3 / ( 1 - WetShellWaterContent ); //BiomassAdultTotal = BiomassAdult1 + BiomassAdult2 + BiomassAdult3; //=========//============The biomass does not include shell cavity water content, it may need to be changed as below??? 2007.5.14 BiomassAdultTotal = (BiomassAdult1 + BiomassAdult2 + BiomassAdult3) * ShellCavityWaterCorrection; //BiomassAdultTotal = BiomassAdultTotal/3; // Now in TFW based on dry tissue + dry shell BiomassAdultTotal = BiomassAdultTotal/FS.Boxes; // Now in TFW based on dry tissue + dry shell if ( ShellWeightAdultTotal != 0 ) //ShellLength = Math.exp((Math.log(ShellWeightAdultTotal)-Math.log(0.0562))/2.9611); //ShellLength = Math.exp((FS.log10(ShellWeightAdultTotal)-FS.log10(0.0365))/2.4525); ShellLength = Math.exp((Math.log(ShellWeightAdultTotal)-Math.log(0.0365))/2.4525); else ShellLength = 0; document.farm.shellfishbiomasstotal.value = FS.decimalPlaces(BiomassAdultTotal,1); document.farm.shellfishbiomassratio.value = FS.decimalPlaces(ShellLength,1); // document.farm.biomassratio.value = "-"; break; default: break; } } } FS.endRun(); } } //=================================== function RunModel() { if ( FS.ModelRunning == 1 ) { // alert("running"); FS.MyCounter = FS.TheRunTime; FS.StopButton = 1; // Stop was pressed 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; }} // 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"); }