コード例 #1
0
        public void EndRun()
        {
            MadingleyModelInitialisation initialisation = this.ModelInitialisation;

            // Temporary
            Boolean varExists;
#endif
            if (TrackGlobalProcesses.TrackProcesses) TrackGlobalProcesses.CloseNPPFile();

            // Loop over cells and close process trackers
            for (int i = 0; i < _CellList.Count; i++)
            {
                if (ProcessTrackers[i].TrackProcesses) ProcessTrackers[i].CloseStreams(SpecificLocations);
            }

            // Write the final global outputs
            GlobalOutputs.FinalOutputs();

            if (SpecificLocations)
            {
                // Loop over grid cells and write the final grid cell outputs
                for (int i = 0; i < _CellList.Count; i++)
                {
                    CellOutputs[i].FinalOutputs(EcosystemModelGrid, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions,
                        _CellList, i, GlobalDiagnosticVariables, initialisation, CurrentMonth, EcosystemModelGrid.GetEnviroLayer("Realm", 0, _CellList[i][0], _CellList[i][1], out varExists) == 2.0);
                }
            }
            else
            {
                // Write the final grid outputs
                GridOutputs.FinalOutputs();
            }
        }
コード例 #2
0
ファイル: Converters.cs プロジェクト: mikeharfoot/Madingley
        public static MadingleyModelInitialisation ConvertInitialisation(
            Madingley.Common.ModelState m,
            Madingley.Common.Configuration d,
            Madingley.Common.Environment e)
        {
            var i = new MadingleyModelInitialisation("", "", "", "");

            i.GlobalModelTimeStepUnit = d.GlobalModelTimeStepUnit;
            i.NumTimeSteps            = (uint)d.NumTimeSteps;
            i.BurninTimeSteps         = (uint)d.BurninTimeSteps;
            i.ImpactTimeSteps         = (uint)d.ImpactTimeSteps;
            i.RecoveryTimeSteps       = (uint)d.RecoveryTimeSteps;
            i.CellSize                   = e.CellSize;
            i.BottomLatitude             = (float)e.BottomLatitude;
            i.TopLatitude                = (float)e.TopLatitude;
            i.LeftmostLongitude          = (float)e.LeftmostLongitude;
            i.RightmostLongitude         = (float)e.RightmostLongitude;
            i.RunCellsInParallel         = d.RunCellsInParallel;
            i.RunSimulationsInParallel   = d.RunSimulationsInParallel;
            i.RunRealm                   = d.RunRealm;
            i.DrawRandomly               = d.DrawRandomly;
            i.ExtinctionThreshold        = d.ExtinctionThreshold;
            i.MaxNumberOfCohorts         = d.MaxNumberOfCohorts;
            i.DispersalOnly              = d.DispersalOnly;
            i.PlanktonDispersalThreshold = d.PlanktonDispersalThreshold;
            i.SpecificLocations          = e.SpecificLocations;
            i.InitialisationFileStrings  = new SortedList <string, string>();
            i.InitialisationFileStrings["OutputDetail"]      = "high";
            i.InitialisationFileStrings["DispersalOnlyType"] = d.DispersalOnlyType;
            i.CohortFunctionalGroupDefinitions = ConvertFunctionalGroupDefinitions(d.CohortFunctionalGroupDefinitions);
            i.StockFunctionalGroupDefinitions  = ConvertFunctionalGroupDefinitions(d.StockFunctionalGroupDefinitions);
            if (m != null)
            {
                i.EnviroStack = ConvertEnvironment(m.GridCells);
            }
            else
            {
                i.EnviroStack = ConvertEnvironment(e.CellEnvironment);
            }
            i.CellList                = e.FocusCells.Select(a => new UInt32[] { (uint)a.Item1, (uint)a.Item2 }).ToList();
            i.TrackProcesses          = true;
            i.TrackCrossCellProcesses = true;
            i.TrackGlobalProcesses    = true;
            i.Units             = new SortedList <string, string>(e.Units);
            i.ImpactCellIndices = d.ImpactCellIndices.Select(ii => (uint)ii).ToList();
            i.ImpactAll         = d.ImpactAll;
            if (m != null)
            {
                i.ModelStates = ConvertModelStates(m, d, e);
                i.InputState  = true;
                i.InputGlobalDiagnosticVariables = new SortedList <string, double>(m.GlobalDiagnosticVariables);
            }
            else
            {
                i.ModelStates = null;
                i.InputState  = false;
            }

            return(i);
        }
        /// <summary>
        /// Constructor for process tracker: Initialises the trackers for individual processes
        /// </summary>
        /// <param name="numTimesteps">The number of time steps in the model</param>
        /// <param name="lats">The latitudes of active grid cells in the model</param>
        /// <param name="lons">The longitudes of active grid cells in the model</param>
        /// <param name="cellIndices">List of indices of active cells in the model grid</param>
        /// <param name="Filenames">The filenames of the output files to write the tracking results to</param>
        /// <param name="trackProcesses">Whether to track processes</param>
        /// <param name="cohortDefinitions">The definitions for cohort functional groups in the model</param>
        /// <param name="missingValue">The missing value to use in process tracking output files</param>
        /// <param name="outputFileSuffix">The suffix to be applied to output files from process tracking</param>
        /// <param name="outputPath">The path to the folder to be used for process tracking outputs</param>
        /// <param name="trackerMassBins">The mass bins to use for categorising output data in the process trackers</param>
        /// <param name="specificLocations">Whether the model is being run for specific locations</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        /// <param name="latCellSize">The size of grid cells latitudinally</param>
        /// <param name="lonCellSize">The size of grid cells longitudinally</param>
        public GlobalProcessTracker(uint numTimesteps,
            float[] lats, float[] lons,
            List<uint[]> cellIndices,
            SortedList<string, string> Filenames,
            Boolean trackProcesses,
            FunctionalGroupDefinitions cohortDefinitions,
            FunctionalGroupDefinitions stockDefinitions,
            double missingValue,
            string outputFileSuffix,
            string outputPath, MassBinsHandler trackerMassBins,
            Boolean specificLocations,
            MadingleyModelInitialisation initialisation,
            float latCellSize,
            float lonCellSize)
        {
            // Initialise trackers for ecological processes
            _TrackProcesses = trackProcesses;

            if (_TrackProcesses)
            {
                _TrackNPP = new GlobalNPPTracker(outputPath, lats.Length, lons.Length, lats, lons, latCellSize, lonCellSize,
                    (int)numTimesteps,stockDefinitions.GetNumberOfFunctionalGroups(),outputFileSuffix);

            }
        }
コード例 #4
0
        /// <summary>
        /// Constructor for the global output class
        /// </summary>
        /// <param name="outputDetail">The level of detail to be used in model outputs</param>
        /// <param name="modelInitialisation">Model intialisation object</param>
        public OutputGlobal(string outputDetail, MadingleyModelInitialisation modelInitialisation)
        {
            // Set the output path
            _OutputPath = modelInitialisation.OutputPath;

            // Set the output detail level
            if (outputDetail == "low")
            {
                ModelOutputDetail = OutputDetailLevel.Low;
            }
            else if (outputDetail == "medium")
            {
                ModelOutputDetail = OutputDetailLevel.Medium;
            }
            else if (outputDetail == "high")
            {
                ModelOutputDetail = OutputDetailLevel.High;
            }
            else
            {
                Debug.Fail("Specified output detail level is not valid, must be 'low', 'medium' or 'high'");
            }

            // Initialise the data converter
            DataConverter = new ArraySDSConvert();

            // Initialise the SDS object creator
            SDSCreator = new CreateSDSObject();
        }
コード例 #5
0
 /// <summary>
 /// Track the flow of mass between trophic levels during a herbivory event
 /// </summary>
 /// <param name="latitudeIndex">The latitudinal index of the current grid cell</param>
 /// <param name="longitudeIndex">The longitudinal index of the current grid cell</param>
 /// <param name="toFunctionalGroup">The index of the functional group that the predator belongs to</param>
 /// <param name="cohortFunctionalGroupDefinitions">The functional group definitions of cohorts in the model</param>
 /// <param name="massEaten">The mass eaten during the herbivory event</param>
 /// <param name="predatorBodyMass">The body mass of the predator doing the eating</param>
 /// <param name="initialisation">The Madingley Model initialisation</param>
 /// <param name="marineCell">Whether the current cell is a marine cell</param>
 public void TrackHerbivoryTrophicFlow(uint latitudeIndex, uint longitudeIndex, int toFunctionalGroup,
                                       FunctionalGroupDefinitions cohortFunctionalGroupDefinitions, double massEaten, double predatorBodyMass,
                                       MadingleyModelInitialisation initialisation, Boolean marineCell)
 {
     foreach (var o in this.ProcessTrackers)
     {
         o.TrackHerbivoryTrophicFlow((int)latitudeIndex, (int)longitudeIndex, toFunctionalGroup, massEaten, predatorBodyMass, marineCell);
     }
 }
コード例 #6
0
 /// <summary>
 /// Track the flow of mass between trophic levels during a predation event
 /// </summary>
 /// <param name="latitudeIndex">The latitudinal index of the current grid cell</param>
 /// <param name="longitudeIndex">The longitudinal index of the current grid cell</param>
 /// <param name="fromFunctionalGroup">The index of the functional group being eaten</param>
 /// <param name="toFunctionalGroup">The index of the functional group that the predator belongs to</param>
 /// <param name="cohortFunctionalGroupDefinitions">The functional group definitions of cohorts in the model</param>
 /// <param name="massEaten">The mass eaten during the predation event</param>
 /// <param name="predatorBodyMass">The body mass of the predator doing the eating</param>
 /// <param name="preyBodyMass">The body mass of the prey doing the eating</param>
 /// <param name="initialisation">The Madingley Model initialisation</param>
 /// <param name="marineCell">Whether the current cell is a marine cell</param>
 public void TrackPredationTrophicFlow(uint latitudeIndex, uint longitudeIndex, int fromFunctionalGroup, int toFunctionalGroup,
     FunctionalGroupDefinitions cohortFunctionalGroupDefinitions, double massEaten, double predatorBodyMass, double preyBodyMass,
     MadingleyModelInitialisation initialisation, Boolean marineCell)
 {
     foreach (var o in this.ProcessTrackers)
     {
         o.TrackPredationTrophicFlow((int)latitudeIndex, (int)longitudeIndex, fromFunctionalGroup, toFunctionalGroup, massEaten, predatorBodyMass, preyBodyMass, marineCell);
     }
 }
コード例 #7
0
        /// <summary>
        /// Sets up the model grid within a Madingley model run
        /// </summary>
        /// <param name="initialisation">An instance of the model initialisation class</param> 
        /// <param name="scenarioParameters">The parameters for the scenarios to run</param>
        /// <param name="scenarioIndex">The index of the scenario that this model is to run</param>
        public void SetUpModelGrid(MadingleyModelInitialisation initialisation,
            ScenarioParameterInitialisation scenarioParameters, int scenarioIndex, int simulation)
#endif
        {
            // If the intialisation file contains a column pointing to another file of specific locations, and if this column is not blank then read the 
            // file indicated
            if (SpecificLocations)
            {
                // Set up the model grid using these locations
#if true
                EcosystemModelGrid = new ModelGrid(BottomLatitude, LeftmostLongitude, TopLatitude, RightmostLongitude,
                    CellSize, CellSize, _CellList, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions,
                    GlobalDiagnosticVariables, initialisation.TrackProcesses, SpecificLocations, RunGridCellsInParallel);
#else
                EcosystemModelGrid = new ModelGrid(BottomLatitude, LeftmostLongitude, TopLatitude, RightmostLongitude,
                    CellSize, CellSize, _CellList, EnviroStack, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions,
                    GlobalDiagnosticVariables, initialisation.TrackProcesses, SpecificLocations,RunGridCellsInParallel);
#endif

            }
            else
            {
                EcologyTimer = new StopWatch();
                EcologyTimer.Start();

                // Set up a full model grid (i.e. not for specific locations)
                // Set up the model grid using these locations
#if true
                EcosystemModelGrid = new ModelGrid(BottomLatitude, LeftmostLongitude, TopLatitude, RightmostLongitude,
                    CellSize, CellSize, _CellList, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions,
                    GlobalDiagnosticVariables, initialisation.TrackProcesses, SpecificLocations, RunGridCellsInParallel);
#else
                EcosystemModelGrid = new ModelGrid(BottomLatitude, LeftmostLongitude, TopLatitude, RightmostLongitude,
                    CellSize, CellSize, _CellList, EnviroStack, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions,
                    GlobalDiagnosticVariables, initialisation.TrackProcesses, SpecificLocations, RunGridCellsInParallel);
#endif

                EcologyTimer.Stop();
                Console.WriteLine("Time to initialise cells: {0}", EcologyTimer.GetElapsedTimeSecs());

                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Madingley Model memory usage post grid cell seed: {0}", GC.GetTotalMemory(true) / 1E9, " (G Bytes)\n");
                Console.ForegroundColor = ConsoleColor.White;

            }

            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("Madingley Model memory usage pre Collect: {0}", Math.Round(GC.GetTotalMemory(true) / 1E9, 2), " (GBytes)");
            Console.ForegroundColor = ConsoleColor.White;
            GC.Collect();

            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("Madingley Model memory usage post Collect: {0}", Math.Round(GC.GetTotalMemory(true) / 1E9, 5), " (GBytes)\n");
            Console.ForegroundColor = ConsoleColor.White;

        }
        /// <summary>
        /// Initalise the ecological processes
        /// </summary>
        public void InitializeCrossGridCellEcology(string globalModelTimeStepUnit, Boolean drawRandomly, MadingleyModelInitialisation modelInitialisation)
        {
            // Initialise dispersal formulations
            _DispersalFormulations = new SortedList<string, IEcologicalProcessAcrossGridCells>();

            // Declare and attach dispersal formulations
            Dispersal DispersalFormulation = new Dispersal(drawRandomly, globalModelTimeStepUnit, modelInitialisation);
            _DispersalFormulations.Add("Basic dispersal", DispersalFormulation);

            // Initialise apply ecology
            ApplyCrossGridCellEcologicalProcessResults = new ApplyCrossGridCellEcology();
        }
コード例 #9
0
ファイル: ModelGrid.cs プロジェクト: mikeharfoot/Madingley
        /// <summary>
        /// Get the total of a state variable for specific cells
        /// </summary>
        /// <param name="variableName">The name of the variable</param>
        /// <param name="traitValue">The functional group trait value to get data for</param>
        /// <param name="functionalGroups">A vector of functional group indices to consider</param>
        /// <param name="cellIndices">List of indices of active cells in the model grid</param>
        /// <param name="stateVariableType">A string indicating the type of state variable; 'cohort' or 'stock'</param>
        /// <param name="initialisation">The Madingley Model intialisation</param>
        /// <returns>Summed value of variable over whole grid</returns>
        /// <todo>Overload to work with vector and array state variables</todo>
        public double StateVariableGridTotal(string variableName, string traitValue, int[] functionalGroups, List <uint[]> cellIndices,
                                             string stateVariableType, MadingleyModelInitialisation initialisation)
        {
            double tempVal = 0;

            double[,] TempStateVariable = this.GetStateVariableGrid(variableName, traitValue, functionalGroups, cellIndices, stateVariableType, initialisation);

            // Loop through and sum values across a grid, excluding missing values
            for (int ii = 0; ii < cellIndices.Count; ii++)
            {
                tempVal += TempStateVariable[cellIndices[ii][0], cellIndices[ii][1]];
            }

            return(tempVal);
        }
コード例 #10
0
        /// <summary>
        /// Initializes the ecosystem model
        /// </summary>
        /// <param name="initialisation">An instance of the model initialisation class</param> 
        /// <param name="outputFilesSuffix">The suffix to be applied to all outputs from this model run</param>
        /// <param name="simulation">The index of the simulation being run</param>
        /// <param name="modelState">Existing model state or null</param>
        public MadingleyModel(
            MadingleyModelInitialisation initialisation,
            string outputFilesSuffix,
            int simulation,
            Madingley.Common.ModelState modelState)
        {
            this.ModelInitialisation = initialisation;

            var scenarioIndex = 0;
            var globalModelTimeStepUnit = initialisation.GlobalModelTimeStepUnit;

            this.GlobalDiagnosticVariables = new SortedList<string, double>(modelState.GlobalDiagnosticVariables);
            var gridCells = Converters.ConvertGridCells(modelState.GridCells);

            // Assign the properties for this model run
            AssignModelRunProperties(initialisation, outputFilesSuffix);
コード例 #11
0
        public OutputGrid(string outputDetail, MadingleyModelInitialisation modelInitialisation)
        {
            // Set the output path
            _OutputPath = modelInitialisation.OutputPath;

            // Initialise the grid viewer
            GridViewer = new ViewGrid();

            // Set the output detail level
            if (outputDetail == "low")
            {
                ModelOutputDetail = OutputDetailLevel.Low;
            }
            else if (outputDetail == "medium")
            {
                ModelOutputDetail = OutputDetailLevel.Medium;
            }
            else if (outputDetail == "high")
            {
                ModelOutputDetail = OutputDetailLevel.High;
            }
            else
            {
                Debug.Fail("Specified output detail level is not valid, must be 'low', 'medium' or 'high'");
            }


            // Get whether to track marine specifics
            OutputMetrics = modelInitialisation.OutputMetrics;

            //Initialise the EcosystemMetrics class
            Metrics = new EcosytemMetrics();

            // Initialise the data converter
            DataConverter = new ArraySDSConvert();

            // Initialise the SDS object creator
            SDSCreator = new CreateSDSObject();

            // Set the local variable designating whether to display live outputs during this model run
            if (modelInitialisation.LiveOutputs)
            {
                LiveOutputs = true;
            }

            Utils = new UtilityFunctions();
        }
コード例 #12
0
        /// <summary>
        /// Set up the tracker for outputing properties of the eating process
        /// </summary>
        /// <param name="numLats">The number of latitudes in the model grid</param>
        /// <param name="numLons">The number of longitudes in the model grid</param>
        /// <param name="trophicFlowsFilename">The filename to write data on trophic flows to</param>
        /// <param name="outputFilesSuffix">The suffix to apply to output files from this simulation</param>
        /// <param name="outputPath">The file path to write all outputs to</param>
        /// <param name="cellIndex">The index of the current cell within the list of all grid cells in this simulation</param>
        /// <param name="initialisation">The instance of the MadingleyModelInitialisation class for this simulation</param>
        /// <param name="MarineCell">Whether the current cell is a marine cell</param>
        public EatingTracker(uint numLats, uint numLons, string trophicFlowsFilename, string outputFilesSuffix, string outputPath,
            int cellIndex, MadingleyModelInitialisation initialisation, Boolean MarineCell)
        {
            this.FileName = outputPath + trophicFlowsFilename + outputFilesSuffix + "_Cell" + cellIndex + ".txt";

            using (var TrophicFlowsWriter = new StreamWriter(this.FileName))
            {
                TrophicFlowsWriter.WriteLine("Latitude\tLongitude\ttime_step\tfromIndex\ttoIndex\tmass_eaten_g");
            }

            // Initialise array to hold mass flows among trophic levels
            if (initialisation.TrackMarineSpecifics && MarineCell)
                // 0 = autotrophs, 1 = non-planktonic herbivores, 2 = non-planktonic omnivores, 3 = non-planktonic carnivores, 4 = obligate zooplankton, 5 = non-obligate zooplankton, 6 = baleen whales
                TrophicMassFlows = new double[numLats, numLons, 7, 7];
            else
                TrophicMassFlows = new double[numLats, numLons, 4, 4];
        }
コード例 #13
0
        /// <summary>
        /// Run reproduction
        /// </summary>
        /// <param name="gridCellCohorts">The cohorts in the current grid cell</param>
        /// <param name="gridCellStocks">The stocks in the current grid cell</param>
        /// <param name="actingCohort">The position of the acting cohort in the jagged array of grid cell cohorts</param>
        /// <param name="cellEnvironment">The environment in the current grid cell</param>
        /// <param name="deltas">The sorted list to track changes in biomass and abundance of the acting cohort in this grid cell</param>
        /// <param name="madingleyCohortDefinitions">The definitions for cohort functional groups in the model</param>
        /// <param name="madingleyStockDefinitions">The definitions for stock functional groups in the model</param>
        /// <param name="currentTimeStep">The current model time step</param>
        /// <param name="processTracker">An instance of ProcessTracker to hold diagnostics for eating</param>
        /// <param name="partial">Thread-locked variables for the parallelised version</param>
        /// <param name="specificLocations">Whether the model is being run for specific locations</param>
        /// <param name="outputDetail">The level of output detail being used for this model run</param>
        /// <param name="currentMonth">The current model month</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        public void RunEcologicalProcess(GridCellCohortHandler gridCellCohorts, GridCellStockHandler gridCellStocks, 
            int[] actingCohort, SortedList<string, double[]> cellEnvironment, Dictionary<string,Dictionary<string,double>> deltas , 
            FunctionalGroupDefinitions madingleyCohortDefinitions, FunctionalGroupDefinitions madingleyStockDefinitions,
            uint currentTimeStep, ProcessTracker processTracker, ref ThreadLockedParallelVariables partial,
            Boolean specificLocations, string outputDetail, uint currentMonth, MadingleyModelInitialisation initialisation)
        {
            // Holds the reproductive strategy of a cohort
            bool _Iteroparous = madingleyCohortDefinitions.GetTraitNames("reproductive strategy", actingCohort[0])=="iteroparity";

            // Assign mass to reproductive potential
            Implementations["reproduction basic"].RunReproductiveMassAssignment(gridCellCohorts, gridCellStocks, actingCohort, cellEnvironment, deltas,
                madingleyCohortDefinitions, madingleyStockDefinitions, currentTimeStep, processTracker);

            // Run reproductive events. Note that we can't skip juveniles here as they could conceivably grow to adulthood and get enough biomass to reproduce in a single time step
            // due to other ecological processes
            Implementations["reproduction basic"].RunReproductionEvents(gridCellCohorts, gridCellStocks, actingCohort, cellEnvironment,
                    deltas, madingleyCohortDefinitions, madingleyStockDefinitions, currentTimeStep, processTracker, ref partial, _Iteroparous, currentMonth);
        }
コード例 #14
0
        /// <summary>
        /// Sets up the model outputs
        /// </summary>
        /// <param name="initialisation">An instance of the model initialisation class</param>
        /// <param name="simulation">The index of the simulation being run</param>
        /// <param name="scenarioIndex">The index of the scenario being run</param>
        public void SetUpOutputs(MadingleyModelInitialisation initialisation, int simulation, int scenarioIndex)
        {
            // Initialise the global outputs
            GlobalOutputs = new OutputGlobal(InitialisationFileStrings["OutputDetail"], initialisation);

            // Create new outputs class instances (if the model is run for the whold model grid then select the grid view for the live output,
            // if the model is run for specific locations then use the graph view)
            if (SpecificLocations)
            {

                // Initialise the vector of outputs instances
                CellOutputs = new OutputCell[_CellList.Count];

                for (int i = 0; i < _CellList.Count; i++)
                {
                    CellOutputs[i] = new OutputCell(InitialisationFileStrings["OutputDetail"], initialisation, i);
                }

#if false
                // Spawn a dataset viewer instance for each cell to display live model results
                if (initialisation.LiveOutputs)
                {
                    for (int i = 0; i < _CellList.Count; i++)
                    {
                        CellOutputs[i].SpawnDatasetViewer(NumTimeSteps);
                    }
                }
#endif

            }
            else
            {
                GridOutputs = new OutputGrid(InitialisationFileStrings["OutputDetail"], initialisation);

#if false
                // Spawn dataset viewer to display live grid results
                if (initialisation.LiveOutputs)
                {
                    GridOutputs.SpawnDatasetViewer();
                }
#endif
            }
        }
コード例 #15
0
        /// <summary>
        /// Run reproduction
        /// </summary>
        /// <param name="gridCellCohorts">The cohorts in the current grid cell</param>
        /// <param name="gridCellStocks">The stocks in the current grid cell</param>
        /// <param name="actingCohort">The position of the acting cohort in the jagged array of grid cell cohorts</param>
        /// <param name="cellEnvironment">The environment in the current grid cell</param>
        /// <param name="deltas">The sorted list to track changes in biomass and abundance of the acting cohort in this grid cell</param>
        /// <param name="madingleyCohortDefinitions">The definitions for cohort functional groups in the model</param>
        /// <param name="madingleyStockDefinitions">The definitions for stock functional groups in the model</param>
        /// <param name="currentTimeStep">The current model time step</param>
        /// <param name="processTracker">An instance of ProcessTracker to hold diagnostics for eating</param>
        /// <param name="partial">Thread-locked variables for the parallelised version</param>
        /// <param name="specificLocations">Whether the model is being run for specific locations</param>
        /// <param name="outputDetail">The level of output detail being used for this model run</param>
        /// <param name="currentMonth">The current model month</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        public void RunEcologicalProcess(GridCellCohortHandler gridCellCohorts, GridCellStockHandler gridCellStocks, 
            int[] actingCohort, SortedList<string, double[]> cellEnvironment, Dictionary<string,Dictionary<string,double>> deltas , 
            FunctionalGroupDefinitions madingleyCohortDefinitions, FunctionalGroupDefinitions madingleyStockDefinitions,
            uint currentTimeStep, ProcessTracker processTracker, ref ThreadLockedParallelVariables partial,
            Boolean specificLocations, string outputDetail, uint currentMonth, MadingleyModelInitialisation initialisation)
        {

                    // Holds the reproductive strategy of a cohort
        bool _Iteroparous = madingleyCohortDefinitions.GetTraitNames("reproductive strategy", actingCohort[0])=="iteroparity";

            // Assign mass to reproductive potential
            Implementations["reproduction basic"].RunReproductiveMassAssignment(gridCellCohorts, gridCellStocks, actingCohort, cellEnvironment, deltas,
                madingleyCohortDefinitions, madingleyStockDefinitions, currentTimeStep, processTracker);

            // Run reproductive events. Note that we can't skip juveniles here as they could conceivably grow to adulthood and get enough biomass to reproduce in a single time step
            // due to other ecological processes
            Implementations["reproduction basic"].RunReproductionEvents(gridCellCohorts, gridCellStocks, actingCohort, cellEnvironment,
                    deltas, madingleyCohortDefinitions, madingleyStockDefinitions, currentTimeStep, processTracker, ref partial, _Iteroparous, currentMonth);
        }
コード例 #16
0
        /// <summary>
        /// Calculates the variables to output
        /// </summary>
        /// <param name="cohortFunctionalGroupDefinitions">The functional group definitions of cohorts in the model</param>
        /// <param name="stockFunctionalGroupDefinitions">The functional group definitions of stocks in the model</param>
        /// <param name="ecosystemModelGrid">The model grid</param>
        /// <param name="cellIndices">The list of indices of active cells in the model grid</param>
        /// <param name="globalDiagnosticVariables">Global diagnostic variables</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        public void CalculateOutputs(FunctionalGroupDefinitions cohortFunctionalGroupDefinitions, FunctionalGroupDefinitions
                                     stockFunctionalGroupDefinitions, ModelGrid ecosystemModelGrid, List <uint[]> cellIndices, SortedList <string, double>
                                     globalDiagnosticVariables, MadingleyModelInitialisation initialisation)
        {
            // Get all cohort functional group indices in the model
            int[] CohortFunctionalGroupIndices = cohortFunctionalGroupDefinitions.AllFunctionalGroupsIndex;

            // Get all stock functional group indices in the model
            int[] StockFunctionalGroupIndices = stockFunctionalGroupDefinitions.AllFunctionalGroupsIndex;

            // Reset total abundance, biomass and pool biomasses
            TotalAbundance     = 0.0;
            TotalBiomass       = 0.0;
            TotalLivingBiomass = 0.0;
            OrganicPoolOut     = 0.0;
            RespiratoryPoolOut = 0.0;

            // Add total cohort biomass and total stock biomass to the total biomass tracker
            TotalLivingBiomass += ecosystemModelGrid.StateVariableGridTotal("Biomass", "NA", CohortFunctionalGroupIndices, cellIndices, "cohort", initialisation);
            TotalLivingBiomass += ecosystemModelGrid.StateVariableGridTotal("Biomass", "NA", StockFunctionalGroupIndices, cellIndices, "stock", initialisation);

            // Add total cohort abundance to the total abundance tracker
            TotalAbundance += ecosystemModelGrid.StateVariableGridTotal("Abundance", "NA", CohortFunctionalGroupIndices, cellIndices, "cohort", initialisation);

            // Get total organic pool biomass
            OrganicPoolOut = ecosystemModelGrid.GetEnviroGridTotal("Organic Pool", 0, cellIndices);

            // Get total respiratory pool biomass
            RespiratoryPoolOut = ecosystemModelGrid.GetEnviroGridTotal("Respiratory CO2 Pool", 0, cellIndices);

            // Get total of all biomass
            TotalBiomass = TotalLivingBiomass + RespiratoryPoolOut + OrganicPoolOut;

            // Get number of cohorts and stocks
            TotalNumberOfCohorts = globalDiagnosticVariables["NumberOfCohortsInModel"];
            TotalNumberOfStocks  = globalDiagnosticVariables["NumberOfStocksInModel"];

            // Get numbers of cohort extinctions and productions
            NumberOfCohortsExtinct  = globalDiagnosticVariables["NumberOfCohortsExtinct"];
            NumberOfCohortsProduced = globalDiagnosticVariables["NumberOfCohortsProduced"];
            NumberOfCohortsCombined = globalDiagnosticVariables["NumberOfCohortsCombined"];
        }
        /// <summary>
        /// Constructor for Dispersal: fills the list of available implementations of dispersal
        /// </summary>
        public Dispersal(Boolean DrawRandomly, string globalModelTimeStepUnit, MadingleyModelInitialisation modelInitialisation)
        {
            // Initialise the list of dispersal implementations
            Implementations = new SortedList<string, IDispersalImplementation>();

            // Add the basic advective dispersal implementation to the list of implementations
            AdvectiveDispersal AdvectiveDispersalImplementation = new AdvectiveDispersal(globalModelTimeStepUnit, DrawRandomly);
            Implementations.Add("basic advective dispersal", AdvectiveDispersalImplementation);

            // Add the basic advective dispersal implementation to the list of implementations
            DiffusiveDispersal DiffusiveDispersalImplementation = new DiffusiveDispersal(globalModelTimeStepUnit, DrawRandomly);
            Implementations.Add("basic diffusive dispersal", DiffusiveDispersalImplementation);

            // Add the basic advective dispersal implementation to the list of implementations
            ResponsiveDispersal ResponsiveDispersalImplementation = new ResponsiveDispersal(globalModelTimeStepUnit, DrawRandomly);
            Implementations.Add("basic responsive dispersal", ResponsiveDispersalImplementation);

            // Get the weight threshold below which organisms are dispersed planktonically
            PlanktonThreshold = modelInitialisation.PlanktonDispersalThreshold;
        }
        public OutputModelState(MadingleyModelInitialisation modelInitialisation, string suffix, int simulation)
        {
            //Initialise output path and variables
            // Set the output path
            _OutputPath = modelInitialisation.OutputPath;

            // Initialise the data converter
            DataConverter = new ArraySDSConvert();

            // Initialise the SDS object creator
            SDSCreator = new CreateSDSObject();

            StateWriter = new StreamWriter(_OutputPath + "State" + suffix + simulation.ToString() + ".txt");
            // Create a threadsafe textwriter to write outputs to the Maturity stream
            SyncStateWriter = TextWriter.Synchronized(StateWriter);
            SyncStateWriter.WriteLine("TimeStep\tLatitude\tLongitude\tID" +
            "\tFunctionalGroup\tJuvenileMass\tAdultMass\tIndividualBodyMass\tCohortAbundance\tBirthTimeStep" +
                "\tMaturityTimeStep\tLogOptimalPreyBodySizeRatio\tMaximumAchievedBodyMass\tTrophicIndex\tProportionTimeActive");

            Simulation = simulation;
        }
コード例 #19
0
        /// <summary>
        /// Set up the tracker for outputing properties of the eating process
        /// </summary>
        /// <param name="numLats">The number of latitudes in the model grid</param>
        /// <param name="numLons">The number of longitudes in the model grid</param>
        /// <param name="trophicFlowsFilename">The filename to write data on trophic flows to</param>
        /// <param name="outputFilesSuffix">The suffix to apply to output files from this simulation</param>
        /// <param name="outputPath">The file path to write all outputs to</param>
        /// <param name="cellIndex">The index of the current cell within the list of all grid cells in this simulation</param>
        /// <param name="initialisation">The instance of the MadingleyModelInitialisation class for this simulation</param>
        /// <param name="MarineCell">Whether the current cell is a marine cell</param>
        public EatingTracker(uint numLats, uint numLons, string trophicFlowsFilename, string outputFilesSuffix, string outputPath,
                             int cellIndex, MadingleyModelInitialisation initialisation, Boolean MarineCell)
        {
            this.FileName = outputPath + trophicFlowsFilename + outputFilesSuffix + "_Cell" + cellIndex + ".txt";

            using (var TrophicFlowsWriter = new StreamWriter(this.FileName))
            {
                TrophicFlowsWriter.WriteLine("Latitude\tLongitude\ttime_step\tfromIndex\ttoIndex\tmass_eaten_g");
            }

            // Initialise array to hold mass flows among trophic levels
            if (initialisation.TrackMarineSpecifics && MarineCell)
            {
                // 0 = autotrophs, 1 = non-planktonic herbivores, 2 = non-planktonic omnivores, 3 = non-planktonic carnivores, 4 = obligate zooplankton, 5 = non-obligate zooplankton, 6 = baleen whales
                TrophicMassFlows = new double[numLats, numLons, 7, 7];
            }
            else
            {
                TrophicMassFlows = new double[numLats, numLons, 4, 4];
            }
        }
コード例 #20
0
        public OutputModelState(MadingleyModelInitialisation modelInitialisation, string suffix, int simulation)
        {
            //Initialise output path and variables
            // Set the output path
            _OutputPath = modelInitialisation.OutputPath;

            // Initialise the data converter
            DataConverter = new ArraySDSConvert();

            // Initialise the SDS object creator
            SDSCreator = new CreateSDSObject();

            StateWriter = new StreamWriter(_OutputPath + "State" + suffix + simulation.ToString() + ".txt");
            // Create a threadsafe textwriter to write outputs to the Maturity stream
            SyncStateWriter = TextWriter.Synchronized(StateWriter);
            SyncStateWriter.WriteLine("TimeStep\tLatitude\tLongitude\tID" +
                                      "\tFunctionalGroup\tJuvenileMass\tAdultMass\tIndividualBodyMass\tCohortAbundance\tReproductiveMass\tBirthTimeStep" +
                                      "\tMaturityTimeStep\tLogOptimalPreyBodySizeRatio\tMaximumAchievedBodyMass\tTrophicIndex\tProportionTimeActive");

            Simulation = simulation;
        }
コード例 #21
0
        /// <summary>
        /// Assigns the properties of the current model run
        /// </summary>
        /// <param name="initialisation">An instance of the model initialisation class</param> 
        /// <param name="scenarioParameters">The parameters for the scenarios to run</param>
        /// <param name="scenarioIndex">The index of the scenario that this model is to run</param>
        /// <param name="outputFilesSuffix">The suffix to be applied to all outputs from this model run</param>
        public void AssignModelRunProperties(MadingleyModelInitialisation initialisation, 
            ScenarioParameterInitialisation scenarioParameters, int scenarioIndex,
            string outputFilesSuffix)
#endif
        {
            // Assign the properties of this model run from the same properties in the specified model initialisation
            _GlobalModelTimeStepUnit = initialisation.GlobalModelTimeStepUnit;
            NumTimeSteps = initialisation.NumTimeSteps;
            CellSize = (float)initialisation.CellSize;
            _CellList = initialisation.CellList;
            BottomLatitude = initialisation.BottomLatitude;
            TopLatitude = initialisation.TopLatitude;
            LeftmostLongitude = initialisation.LeftmostLongitude;
            RightmostLongitude = initialisation.RightmostLongitude;
            InitialisationFileStrings = initialisation.InitialisationFileStrings;
            CohortFunctionalGroupDefinitions = initialisation.CohortFunctionalGroupDefinitions;
            StockFunctionalGroupDefinitions = initialisation.StockFunctionalGroupDefinitions;
            EnviroStack = initialisation.EnviroStack;
            OutputFilesSuffix = outputFilesSuffix;
            OutputModelStateTimestep = initialisation.OutputStateTimestep;
            SpecificLocations = initialisation.SpecificLocations;
        }
コード例 #22
0
ファイル: Dispersal.cs プロジェクト: mikeharfoot/Madingley
        /// <summary>
        /// Constructor for Dispersal: fills the list of available implementations of dispersal
        /// </summary>
        public Dispersal(Boolean DrawRandomly, string globalModelTimeStepUnit, MadingleyModelInitialisation modelInitialisation)
        {
            // Initialise the list of dispersal implementations
            Implementations = new SortedList <string, IDispersalImplementation>();

            // Add the basic advective dispersal implementation to the list of implementations
            AdvectiveDispersal AdvectiveDispersalImplementation = new AdvectiveDispersal(globalModelTimeStepUnit, DrawRandomly);

            Implementations.Add("basic advective dispersal", AdvectiveDispersalImplementation);

            // Add the basic advective dispersal implementation to the list of implementations
            DiffusiveDispersal DiffusiveDispersalImplementation = new DiffusiveDispersal(globalModelTimeStepUnit, DrawRandomly);

            Implementations.Add("basic diffusive dispersal", DiffusiveDispersalImplementation);

            // Add the basic advective dispersal implementation to the list of implementations
            ResponsiveDispersal ResponsiveDispersalImplementation = new ResponsiveDispersal(globalModelTimeStepUnit, DrawRandomly);

            Implementations.Add("basic responsive dispersal", ResponsiveDispersalImplementation);

            // Get the weight threshold below which organisms are dispersed planktonically
            PlanktonThreshold = modelInitialisation.PlanktonDispersalThreshold;
        }
コード例 #23
0
        public OutputModelState(MadingleyModelInitialisation modelInitialisation, string suffix, int simulation)
        {
            //Initialise output path and variables
            // Set the output path
            _OutputPath = modelInitialisation.OutputPath;

            // Initialise the data converter
            DataConverter = new ArraySDSConvert();

            // Initialise the SDS object creator
            SDSCreator = new CreateSDSObject();

            this.FileName = _OutputPath + "State" + suffix + simulation.ToString() + ".txt";

            using (var StateWriter = new StreamWriter(this.FileName))
            {
                StateWriter.WriteLine("TimeStep\tLatitude\tLongitude\tID" +
                                      "\tFunctionalGroup\tJuvenileMass\tAdultMass\tIndividualBodyMass\tCohortAbundance\tBirthTimeStep" +
                                      "\tMaturityTimeStep\tLogOptimalPreyBodySizeRatio\tMaximumAchievedBodyMass\tTrophicIndex\tProportionTimeActive");
            }

            Simulation = simulation;
        }
コード例 #24
0
        /// <summary>
        /// Constructor for process tracker: Initialises the trackers for individual processes
        /// </summary>
        /// <param name="numTimesteps">The number of time steps in the model</param>
        /// <param name="lats">The latitudes of active grid cells in the model</param>
        /// <param name="lons">The longitudes of active grid cells in the model</param>
        /// <param name="cellIndices">List of indices of active cells in the model grid</param>
        /// <param name="Filenames">The filenames of the output files to write the tracking results to</param>
        /// <param name="trackProcesses">Whether to track processes</param>
        /// <param name="cohortDefinitions">The definitions for cohort functional groups in the model</param>
        /// <param name="missingValue">The missing value to use in process tracking output files</param>
        /// <param name="outputFileSuffix">The suffix to be applied to output files from process tracking</param>
        /// <param name="outputPath">The path to the folder to be used for process tracking outputs</param>
        /// <param name="trackerMassBins">The mass bins to use for categorising output data in the process trackers</param>
        /// <param name="specificLocations">Whether the model is being run for specific locations</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        /// <param name="latCellSize">The size of grid cells latitudinally</param>
        /// <param name="lonCellSize">The size of grid cells longitudinally</param>
        public GlobalProcessTracker(uint numTimesteps,
                                    float[] lats, float[] lons,
                                    List <uint[]> cellIndices,
                                    SortedList <string, string> Filenames,
                                    Boolean trackProcesses,
                                    FunctionalGroupDefinitions cohortDefinitions,
                                    FunctionalGroupDefinitions stockDefinitions,
                                    double missingValue,
                                    string outputFileSuffix,
                                    string outputPath, MassBinsHandler trackerMassBins,
                                    Boolean specificLocations,
                                    MadingleyModelInitialisation initialisation,
                                    float latCellSize,
                                    float lonCellSize)
        {
            // Initialise trackers for ecological processes
            _TrackProcesses = trackProcesses;

            if (_TrackProcesses)
            {
                _TrackNPP = new GlobalNPPTracker(outputPath, lats.Length, lons.Length, lats, lons, latCellSize, lonCellSize, (int)numTimesteps, stockDefinitions.GetNumberOfFunctionalGroups());
            }
        }
        /// <summary>
        /// Run metabolism
        /// </summary>
        /// <param name="gridCellCohorts">The cohorts in the current grid cell</param>
        /// <param name="gridCellStocks">The stocks in the current grid cell</param>
        /// <param name="actingCohort">The position of the acting cohort in the jagged array of grid cell cohorts</param>
        /// <param name="cellEnvironment">The environment in the current grid cell</param>
        /// <param name="deltas">The sorted list to track changes in biomass and abundance of the acting cohort in this grid cell</param>
        /// <param name="madingleyCohortDefinitions">The definitions for cohort functional groups in the model</param>
        /// <param name="madingleyStockDefinitions">The definitions for stock functional groups in the model</param>
        /// <param name="currentTimestep">The current model time step</param>
        /// <param name="trackProcesses">An instance of ProcessTracker to hold diagnostics for metabolism</param>
        /// <param name="partial">Thread-locked variables</param>
        /// <param name="specificLocations">Whether the model is being run for specific locations</param>
        /// <param name="outputDetail">The level of output detail being used for the current model run</param>
        /// <param name="currentMonth">The current model month</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        public void RunEcologicalProcess(GridCellCohortHandler gridCellCohorts, GridCellStockHandler gridCellStocks, 
            int[] actingCohort, SortedList<string, double[]> cellEnvironment, Dictionary<string, Dictionary<string, double>> deltas, 
            FunctionalGroupDefinitions madingleyCohortDefinitions, FunctionalGroupDefinitions madingleyStockDefinitions, 
            uint currentTimestep, ProcessTracker trackProcesses, ref ThreadLockedParallelVariables partial,
            Boolean specificLocations, string outputDetail, uint currentMonth, MadingleyModelInitialisation initialisation)
        {
            double Realm = cellEnvironment["Realm"][0];
            if (madingleyCohortDefinitions.GetTraitNames("Heterotroph/Autotroph", gridCellCohorts[actingCohort].FunctionalGroupIndex) == "heterotroph")
            {
                if (madingleyCohortDefinitions.GetTraitNames("Endo/Ectotherm", gridCellCohorts[actingCohort].FunctionalGroupIndex) == "endotherm")
                {

                        Implementations["basic endotherm"].RunMetabolism(gridCellCohorts, gridCellStocks, actingCohort, cellEnvironment, deltas, madingleyCohortDefinitions, madingleyStockDefinitions, currentTimestep, currentMonth);
                }
                else
                {
                        Implementations["basic ectotherm"].RunMetabolism(gridCellCohorts, gridCellStocks, actingCohort, cellEnvironment, deltas, madingleyCohortDefinitions, madingleyStockDefinitions, currentTimestep, currentMonth);

                }

            }

            // If the process tracker is on and output detail is set to high and this cohort has not been merged yet, then record
            // the number of individuals that have died
            if (trackProcesses.TrackProcesses && (outputDetail == "high"))
            {

                trackProcesses.TrackTimestepMetabolism((uint)cellEnvironment["LatIndex"][0],
                                                (uint)cellEnvironment["LonIndex"][0],
                                                currentTimestep,
                                                gridCellCohorts[actingCohort].IndividualBodyMass,
                                                actingCohort[0],
                                                cellEnvironment["Temperature"][currentMonth],
                                                deltas["biomass"]["metabolism"]);

            }
        }
コード例 #26
0
        /// <summary>
        /// Constructor for process tracker: Initialises the trackers for individual processes
        /// </summary>
        /// <param name="numTimesteps">The number of time steps in the model</param>
        /// <param name="lats">The latitudes of active grid cells in the model</param>
        /// <param name="lons">The longitudes of active grid cells in the model</param>
        /// <param name="cellIndices">List of indices of active cells in the model grid</param>
        /// <param name="Filenames">The filenames of the output files to write the tracking results to</param>
        /// <param name="trackProcesses">Whether to track processes</param>
        /// <param name="cohortDefinitions">The definitions for cohort functional groups in the model</param>
        /// <param name="missingValue">The missing value to use in process tracking output files</param>
        /// <param name="outputFileSuffix">The suffix to be applied to output files from process tracking</param>
        /// <param name="outputPath">The path to the folder to be used for process tracking outputs</param>
        /// <param name="trackerMassBins">The mass bins to use for categorising output data in the process trackers</param>
        /// <param name="specificLocations">Whether the model is being run for specific locations</param>
        /// <param name="cellIndex">The index of the current cell in the list of all cells to run the model for</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        /// <param name="marineCell">Whether the current cell is a marine cell</param>
        /// <param name="latCellSize">The size of grid cells in the latitudinal direction</param>
        /// <param name="lonCellSize">The size of grid cells in the longitudinal direction</param>
        public ProcessTracker(uint numTimesteps,
                              float[] lats, float[] lons,
                              List <uint[]> cellIndices,
                              SortedList <string, string> Filenames,
                              Boolean trackProcesses,
                              FunctionalGroupDefinitions cohortDefinitions,
                              double missingValue,
                              string outputFileSuffix,
                              string outputPath, MassBinsHandler trackerMassBins,
                              Boolean specificLocations,
                              int cellIndex,
                              MadingleyModelInitialisation initialisation,
                              bool marineCell,
                              float latCellSize,
                              float lonCellSize)
        {
            // Initialise trackers for ecological processes
            _TrackProcesses = trackProcesses;

            if (_TrackProcesses)
            {
                _TrackReproduction = new ReproductionTracker(numTimesteps, (uint)lats.Length, (uint)lons.Length, cellIndices, Filenames["NewCohortsOutput"], Filenames["MaturityOutput"], outputFileSuffix, outputPath, cellIndex);
                _TrackEating       = new EatingTracker((uint)lats.Length, (uint)lons.Length, Filenames["TrophicFlowsOutput"], outputFileSuffix, outputPath, cellIndex, initialisation, marineCell);
                _TrackGrowth       = new GrowthTracker(numTimesteps, (uint)lats.Length, (uint)lons.Length, cellIndices, Filenames["GrowthOutput"], outputFileSuffix, outputPath, cellIndex);
                _TrackMortality    = new MortalityTracker(numTimesteps, (uint)lats.Length, (uint)lons.Length, cellIndices, Filenames["MortalityOutput"], outputFileSuffix, outputPath, cellIndex);
                _TrackExtinction   = new ExtinctionTracker(Filenames["ExtinctionOutput"], outputPath, outputFileSuffix, cellIndex);
                _TrackMetabolism   = new MetabolismTracker(Filenames["MetabolismOutput"], outputPath, outputFileSuffix, cellIndex);

                // Initialise the predation and herbivory trackers only for runs with specific locations
                if (specificLocations == true)
                {
                    _TrackPredation = new PredationTracker(numTimesteps, cellIndices, Filenames["PredationFlowsOutput"], cohortDefinitions,
                                                           missingValue, outputFileSuffix, outputPath, trackerMassBins, cellIndex);
                }
            }
        }
コード例 #27
0
        /// <summary>
        /// Generates the initial outputs for this model run
        /// </summary>
        /// <param name="outputFilesSuffix">The suffix to be applied to all outputs from this model run</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        /// <param name="month">The current month in the model run</param>
        public void InitialOutputs(string outputFilesSuffix, MadingleyModelInitialisation initialisation, uint month)
        {
            // Set up global outputs for all model runs
            GlobalOutputs.SetupOutputs(NumTimeSteps, EcosystemModelGrid, OutputFilesSuffix);

            // Create initial global outputs
            GlobalOutputs.InitialOutputs(EcosystemModelGrid, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions, _CellList,
                GlobalDiagnosticVariables, initialisation);

            // Temporary
            Boolean varExists;

            if (SpecificLocations)
            {
                for (int i = 0; i < _CellList.Count; i++)
                {
                    // Set up grid cell outputs
                    CellOutputs[i].SetUpOutputs(EcosystemModelGrid, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions,
                        NumTimeSteps, OutputFilesSuffix, _CellList, i, EcosystemModelGrid.GetEnviroLayer("Realm", 0, _CellList[i][0], _CellList[i][1], out varExists) == 2.0);

                    // Create initial grid cell outputs
                    CellOutputs[i].InitialOutputs(EcosystemModelGrid, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions,
                        _CellList, i, GlobalDiagnosticVariables, NumTimeSteps, initialisation, month, EcosystemModelGrid.GetEnviroLayer("Realm", 0, _CellList[i][0], _CellList[i][1], out varExists) == 2.0);
                }
            }
            else
            {
                // Set up grid outputs
                GridOutputs.SetupOutputs(EcosystemModelGrid, OutputFilesSuffix, NumTimeSteps,
                    CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions);

                // Create initial grid outputs
                GridOutputs.InitialOutputs(EcosystemModelGrid, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions, _CellList, initialisation);
            }

        }
コード例 #28
0
        /// <summary>
        /// Runs a single simulation of the Madingley model
        /// </summary>
        /// <param name="scenarios">Parameter information and simulation number for all scenarios to be run</param>
        /// <param name="scenarioIndex">The index of the scenario to be run in this simulation</param>
        /// <param name="initialiseMadingley">Model initialization information for all simulations</param>
        /// <param name="outputFileSuffix">Suffix to be applied to the names of files written out by this simulation</param>
        /// <param name="simulation">The index of the simulation being run</param>
        public void RunSimulation(ScenarioParameterInitialisation scenarios, int scenarioIndex, MadingleyModelInitialisation initialiseMadingley,
                                  string outputFileSuffix, int simulation)
        {
            // Declare an instance of the class that runs a Madingley model simulation
            MadingleyModel MadingleyEcosystemModel;

            // Declare and start a timer
            StopWatch s = new StopWatch();

            s.Start();
            StopWatch t = new StopWatch();

            t.Start();

            // Initialize the instance of MadingleyModel
            MadingleyEcosystemModel = new MadingleyModel(initialiseMadingley, scenarios, scenarioIndex, outputFileSuffix,
                                                         initialiseMadingley.GlobalModelTimeStepUnit, simulation);
            t.Stop();

            // Run the simulation
            MadingleyEcosystemModel.RunMadingley(initialiseMadingley);

            // Stop the timer and write out the time taken to run this simulation
            s.Stop();
            Console.WriteLine("Model run finished");
            Console.WriteLine("Total elapsed time was {0} seconds", s.GetElapsedTimeSecs());
            Console.WriteLine("Model setup time was {0} seconds", t.GetElapsedTimeSecs());
            Console.WriteLine("Model run time was {0} seconds", s.GetElapsedTimeSecs() - t.GetElapsedTimeSecs());
        }
        /// <summary>
        /// Calculate the actual amount eaten in herbivory, apply the changes to the eaten autotroph stocks, and update deltas for the herbivore cohort
        /// </summary>
        /// <param name="gridCellCohorts">The cohorts in this grid cell</param>
        /// <param name="gridCellStocks">The stocks in this grid cell</param>
        /// <param name="actingCohort">The acting cohort</param>
        /// <param name="cellEnvironment">The environmental conditions in this grid cell</param>
        /// <param name="deltas">The sorted list to track changes in biomass and abundance of the acting cohort in this grid cell</param>
        /// <param name="madingleyCohortDefinitions">The functional group definitions for cohorts in the model</param>
        /// <param name="madingleyStockDefinitions">The functional group definitions for stocks in the model</param>
        /// <param name="trackProcesses">An instance of ProcessTracker to hold diagnostics for herbivory</param>
        /// <param name="currentTimestep">The current model time step</param>
        /// <param name="specificLocations">Whether the model is being run for specific locations</param>
        /// <param name="outputDetail">The level of output detail being used in this model run</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        public void RunEating(GridCellCohortHandler gridCellCohorts, GridCellStockHandler gridCellStocks, int[] actingCohort, SortedList <string, double[]>
                              cellEnvironment, Dictionary <string, Dictionary <string, double> > deltas, FunctionalGroupDefinitions madingleyCohortDefinitions,
                              FunctionalGroupDefinitions madingleyStockDefinitions, ProcessTracker trackProcesses, uint currentTimestep, Boolean specificLocations,
                              string outputDetail, MadingleyModelInitialisation initialisation)
        {
            EdibleScaling = 1.0;
            if (cellEnvironment["Realm"][0] == 1.0)
            {
                EdibleScaling = 0.1;
            }

            // Loop over autotroph functional groups that can be eaten
            foreach (int FunctionalGroup in _FunctionalGroupIndicesToEat)
            {
                // Loop over stocks within the functional groups
                for (int i = 0; i < gridCellStocks[FunctionalGroup].Count; i++)
                {
                    // Get the mass from this stock that is available for eating (assumes only 10% is edible in the terrestrial realm)
                    EdibleMass = gridCellStocks[FunctionalGroup][i].TotalBiomass * EdibleScaling;

                    // Calculate the biomass actually eaten from this stock by the acting cohort
                    _BiomassesEaten[FunctionalGroup][i] = CalculateBiomassesEaten(_PotentialBiomassesEaten[FunctionalGroup][i],
                                                                                  _TimeUnitsToHandlePotentialFoodItems, gridCellCohorts[actingCohort].CohortAbundance, EdibleMass);

                    gridCellCohorts[actingCohort].TrophicIndex += _BiomassesEaten[FunctionalGroup][i];

                    // Remove the biomass eaten from the autotroph stock
                    gridCellStocks[FunctionalGroup][i].TotalBiomass -= _BiomassesEaten[FunctionalGroup][i];

                    // If the model is being run for specific locations and if track processes has been specified, then track the mass flow between
                    // primary producer and herbivore
                    if (specificLocations && trackProcesses.TrackProcesses)
                    {
                        trackProcesses.RecordHerbivoryMassFlow(currentTimestep, _BodyMassHerbivore, _BiomassesEaten[FunctionalGroup][i]);
                    }

                    // If track processes has been specified and the output detail level is set to high and the model is being run for specific locations,
                    // then track the flow of mass between trophic levels
                    if (trackProcesses.TrackProcesses && (outputDetail == "high") && specificLocations)
                    {
                        trackProcesses.TrackHerbivoryTrophicFlow((uint)cellEnvironment["LatIndex"][0], (uint)cellEnvironment["LonIndex"][0],
                                                                 gridCellCohorts[actingCohort].FunctionalGroupIndex, madingleyCohortDefinitions, _BiomassesEaten[FunctionalGroup][i], _BodyMassHerbivore, initialisation, cellEnvironment["Realm"][0] == 2.0);
                    }


                    // Check that the biomass eaten is not a negative value
                    // Commented out for purposes of speed
                    //Debug.Assert(_BiomassesEaten[FunctionalGroup][i] >= 0,
                    //    "Herbivory negative for this herbivore cohort" + actingCohort);

                    // Add the biomass eaten and assimilated by an individual to the delta biomass for the acting cohort
                    deltas["biomass"]["herbivory"] += _BiomassesEaten[FunctionalGroup][i] * AssimilationEfficiency / gridCellCohorts[actingCohort].CohortAbundance;

                    // Move the biomass eaten but not assimilated by an individual into the organic matter pool
                    deltas["organicpool"]["herbivory"] += _BiomassesEaten[FunctionalGroup][i] * (1 - AssimilationEfficiency);
                }

                // Check that the delta biomass from eating for the acting cohort is not negative
                // Commented out for the purposes of speed
                //Debug.Assert(deltas["biomass"]["herbivory"] >= 0, "Delta biomass from herbviory is negative");

                // Calculate the total biomass eaten by the acting (herbivore) cohort
                _TotalBiomassEatenByCohort = deltas["biomass"]["herbivory"] * gridCellCohorts[actingCohort].CohortAbundance;
            }
        }
コード例 #30
0
        /// <summary>
        /// Run ecological processes for stocks in a specified grid cell
        /// </summary>
        /// <param name="latCellIndex">The latitudinal index of the cell to run stock ecology for</param>
        /// <param name="lonCellIndex">The longitudinal index of the cell to run stock ecology for</param>
        /// <param name="workingGridCellStocks">A copy of the cohorts in the current grid cell</param>
        /// <param name="cellIndex">The index of the current cell in the list of all cells to run the model for</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        private void RunWithinCellStockEcology(uint latCellIndex, uint lonCellIndex, 
            GridCellStockHandler workingGridCellStocks, int cellIndex, MadingleyModelInitialisation initialisation)
        {
            // Create a local instance of the stock ecology class
            EcologyStock MadingleyEcologyStock = new EcologyStock();

            // Initialise stock ecology
            MadingleyEcologyStock.InitializeEcology();

            //The location of the acting stock
            int[] ActingStock = new int[2];

            // Get the list of functional group indices for autotroph stocks
            int[] AutotrophStockFunctionalGroups = StockFunctionalGroupDefinitions.GetFunctionalGroupIndex("Heterotroph/Autotroph", "Autotroph", false).
                ToArray();

            // Loop over autotroph functional groups
            foreach (int FunctionalGroup in AutotrophStockFunctionalGroups)
            {
                for (int ll = 0; ll < workingGridCellStocks[FunctionalGroup].Count; ll++)
                {
                    // Get the position of the acting stock
                    ActingStock[0] = FunctionalGroup;
                    ActingStock[1] = ll;

                    // Run stock ecology
                    MadingleyEcologyStock.RunWithinCellEcology(workingGridCellStocks, ActingStock, EcosystemModelGrid.GetCellEnvironment(
                        latCellIndex, lonCellIndex), EnvironmentalDataUnits, _HumanNPPScenario, StockFunctionalGroupDefinitions,
                        CurrentTimeStep, NumBurninSteps, NumImpactSteps, initialisation.RecoveryTimeSteps, initialisation.InstantaneousTimeStep, initialisation.NumInstantaneousTimeStep, _GlobalModelTimeStepUnit, ProcessTrackers[cellIndex].TrackProcesses, ProcessTrackers[cellIndex],
                        TrackGlobalProcesses, CurrentMonth,
                        InitialisationFileStrings["OutputDetail"],SpecificLocations,((initialisation.ImpactCellIndices.Contains((uint)cellIndex) || (initialisation.ImpactAll))));

                }
            }
        }
コード例 #31
0
        /// <summary>
        /// Sets up the model outputs
        /// </summary>
        /// <param name="initialisation">An instance of the model initialisation class</param>
        /// <param name="simulation">The index of the simulation being run</param>
        /// <param name="scenarioIndex">The index of the scenario being run</param>
        public void SetUpOutputs(MadingleyModelInitialisation initialisation, int simulation, int scenarioIndex)
        {
            // Initialise the global outputs
            GlobalOutputs = new OutputGlobal(InitialisationFileStrings["OutputDetail"], initialisation);

            // Create new outputs class instances (if the model is run for the whold model grid then select the grid view for the live output,
            // if the model is run for specific locations then use the graph view)
            if (SpecificLocations)
            {

                // Initialise the vector of outputs instances
                CellOutputs = new OutputCell[_CellList.Count];

                for (int i = 0; i < _CellList.Count; i++)
                {
                    CellOutputs[i] = new OutputCell(InitialisationFileStrings["OutputDetail"], initialisation, i);
                }

                // Spawn a dataset viewer instance for each cell to display live model results
                if (initialisation.LiveOutputs)
                {
                    for (int i = 0; i < _CellList.Count; i++)
                    {
                        CellOutputs[i].SpawnDatasetViewer(NumTimeSteps);
                    }
                }

            }
            else
            {
                GridOutputs = new OutputGrid(InitialisationFileStrings["OutputDetail"], initialisation);

                // Spawn dataset viewer to display live grid results
                if (initialisation.LiveOutputs)
                {
                    GridOutputs.SpawnDatasetViewer();
                }
            }
        }
        /// <summary>
        /// Calculates the variables to output
        /// </summary>
        /// <param name="ecosystemModelGrid">The model grid to get output data from</param>
        /// <param name="cohortFunctionalGroupDefinitions">Definitions of the cohort functional groups in the model</param>
        /// <param name="stockFunctionalGroupDefinitions">Definitions of the stock functional groups in the model</param>
        /// <param name="cellIndices">List of indices of active cells in the model grid</param>
        /// <param name="cellNumber">The number of the current cell in the list of indices of active cells</param>
        /// <param name="globalDiagnosticVariables">The sorted list of global diagnostic variables in the model</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        /// <param name="month">The current month in the model run</param>
        /// <param name="marineCell">Whether the current cell is a marine cell</param>
        private void CalculateOutputs(ModelGrid ecosystemModelGrid, FunctionalGroupDefinitions cohortFunctionalGroupDefinitions,
            FunctionalGroupDefinitions stockFunctionalGroupDefinitions, List<uint[]> cellIndices, int cellNumber, SortedList<string, double>
            globalDiagnosticVariables, MadingleyModelInitialisation initialisation, uint month, Boolean marineCell)
        {
            // Calculate low-level outputs
            CalculateLowLevelOutputs(ecosystemModelGrid, cellIndices, cellNumber, globalDiagnosticVariables, cohortFunctionalGroupDefinitions,
                stockFunctionalGroupDefinitions, initialisation, month, marineCell);

            if (ModelOutputDetail == OutputDetailLevel.High)
            {
                // Calculate high-level outputs
                CalculateHighLevelOutputs(ecosystemModelGrid, cellIndices, cellNumber, marineCell);
            }
        }
コード例 #33
0
        /// <summary>
        /// Record the flow of biomass between trophic levels during predation
        /// </summary>
        /// <param name="latIndex">The latitudinal index of the current grid cell</param>
        /// <param name="lonIndex">The longitudinal index of the current grid cell</param>
        /// <param name="fromFunctionalGroup">The index of the functional group that the biomass is flowing from (i.e. the prey)</param>
        /// <param name="toFunctionalGroup">The index of the functional group that the biomass is flowing to (i.e. the predator)</param>
        /// <param name="cohortFunctionalGroupDefinitions">The functional group definitions of cohorts in the model</param>
        /// <param name="massEaten">The total biomass eaten by the predator cohort</param>
        /// <param name="predatorBodyMass">The body mass of the predator doing the eating</param>
        /// <param name="preyBodyMass">The body mass of the prey being eaten</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        /// <param name="MarineCell">Whether the current cell is a marine cell</param>
        public void RecordPredationTrophicFlow(uint latIndex, uint lonIndex, int fromFunctionalGroup, int toFunctionalGroup,
                                               FunctionalGroupDefinitions cohortFunctionalGroupDefinitions, double massEaten, double predatorBodyMass, double preyBodyMass,
                                               MadingleyModelInitialisation initialisation, Boolean MarineCell)
        {
            int fromIndex = 0;
            int toIndex   = 0;

            if (initialisation.TrackMarineSpecifics && MarineCell)
            {
                // Get the trophic level index of the functional group that mass is flowing from
                switch (cohortFunctionalGroupDefinitions.GetTraitNames("nutrition source", fromFunctionalGroup))
                {
                case "herbivore":
                    switch (cohortFunctionalGroupDefinitions.GetTraitNames("mobility", fromFunctionalGroup))
                    {
                    case "planktonic":
                        fromIndex = 4;
                        break;

                    default:
                        switch (cohortFunctionalGroupDefinitions.GetTraitNames("endo/ectotherm", fromFunctionalGroup))
                        {
                        case "endotherm":
                            switch (cohortFunctionalGroupDefinitions.GetTraitNames("diet", fromFunctionalGroup))
                            {
                            case "allspecial":
                                fromIndex = 6;
                                break;

                            default:
                                fromIndex = 1;
                                break;
                            }
                            break;

                        default:
                            if (preyBodyMass <= initialisation.PlanktonDispersalThreshold)
                            {
                                fromIndex = 5;
                            }
                            else
                            {
                                fromIndex = 1;
                            }
                            break;
                        }
                        break;
                    }
                    break;

                case "omnivore":
                    switch (cohortFunctionalGroupDefinitions.GetTraitNames("mobility", fromFunctionalGroup))
                    {
                    case "planktonic":
                        fromIndex = 4;
                        break;

                    default:
                        switch (cohortFunctionalGroupDefinitions.GetTraitNames("endo/ectotherm", fromFunctionalGroup))
                        {
                        case "endotherm":
                            switch (cohortFunctionalGroupDefinitions.GetTraitNames("diet", fromFunctionalGroup))
                            {
                            case "allspecial":
                                fromIndex = 6;
                                break;

                            default:
                                fromIndex = 2;
                                break;
                            }
                            break;

                        default:
                            if (preyBodyMass <= initialisation.PlanktonDispersalThreshold)
                            {
                                fromIndex = 5;
                            }
                            else
                            {
                                fromIndex = 2;
                            }
                            break;
                        }
                        break;
                    }
                    break;

                case "carnivore":
                    switch (cohortFunctionalGroupDefinitions.GetTraitNames("mobility", fromFunctionalGroup))
                    {
                    case "planktonic":
                        fromIndex = 4;
                        break;

                    default:
                        switch (cohortFunctionalGroupDefinitions.GetTraitNames("endo/ectotherm", fromFunctionalGroup))
                        {
                        case "endotherm":
                            switch (cohortFunctionalGroupDefinitions.GetTraitNames("diet", fromFunctionalGroup))
                            {
                            case "allspecial":
                                fromIndex = 6;
                                break;

                            default:
                                fromIndex = 3;
                                break;
                            }
                            break;

                        default:
                            if (preyBodyMass <= initialisation.PlanktonDispersalThreshold)
                            {
                                fromIndex = 5;
                            }
                            else
                            {
                                fromIndex = 3;
                            }
                            break;
                        }
                        break;
                    }
                    break;

                default:
                    Debug.Fail("Specified nutrition source is not supported");
                    break;
                }

                // Get the trophic level index of the functional group that mass is flowing to
                switch (cohortFunctionalGroupDefinitions.GetTraitNames("nutrition source", toFunctionalGroup))
                {
                case "omnivore":
                    switch (cohortFunctionalGroupDefinitions.GetTraitNames("mobility", toFunctionalGroup))
                    {
                    case "planktonic":
                        toIndex = 4;
                        break;

                    default:
                        switch (cohortFunctionalGroupDefinitions.GetTraitNames("endo/ectotherm", toFunctionalGroup))
                        {
                        case "endotherm":
                            switch (cohortFunctionalGroupDefinitions.GetTraitNames("diet", toFunctionalGroup))
                            {
                            case "allspecial":
                                toIndex = 6;
                                break;

                            default:
                                toIndex = 2;
                                break;
                            }
                            break;

                        default:
                            if (predatorBodyMass <= initialisation.PlanktonDispersalThreshold)
                            {
                                toIndex = 5;
                            }
                            else
                            {
                                toIndex = 2;
                            }
                            break;
                        }
                        break;
                    }
                    break;

                case "carnivore":
                    switch (cohortFunctionalGroupDefinitions.GetTraitNames("mobility", toFunctionalGroup))
                    {
                    case "planktonic":
                        toIndex = 4;
                        break;

                    default:
                        switch (cohortFunctionalGroupDefinitions.GetTraitNames("endo/ectotherm", toFunctionalGroup))
                        {
                        case "endotherm":
                            switch (cohortFunctionalGroupDefinitions.GetTraitNames("diet", toFunctionalGroup))
                            {
                            case "allspecial":
                                toIndex = 6;
                                break;

                            default:
                                toIndex = 3;
                                break;
                            }
                            break;

                        default:
                            if (predatorBodyMass <= initialisation.PlanktonDispersalThreshold)
                            {
                                toIndex = 5;
                            }
                            else
                            {
                                toIndex = 3;
                            }
                            break;
                        }
                        break;
                    }
                    break;

                default:
                    Debug.Fail("Specified nutrition source is not supported");
                    break;
                }
            }
            else
            {
                // Get the trophic level index of the functional group that mass is flowing from
                switch (cohortFunctionalGroupDefinitions.GetTraitNames("nutrition source", fromFunctionalGroup))
                {
                case "herbivore":
                    fromIndex = 1;
                    break;

                case "omnivore":
                    fromIndex = 2;
                    break;

                case "carnivore":
                    fromIndex = 3;
                    break;

                default:
                    Debug.Fail("Specified nutrition source is not supported");
                    break;
                }

                // Get the trophic level index of the functional group that mass is flowing to
                switch (cohortFunctionalGroupDefinitions.GetTraitNames("nutrition source", toFunctionalGroup))
                {
                case "herbivore":
                    toIndex = 1;
                    break;

                case "omnivore":
                    toIndex = 2;
                    break;

                case "carnivore":
                    toIndex = 3;
                    break;

                default:
                    Debug.Fail("Specified nutrition source is not supported");
                    break;
                }
            }

            // Add the flow of matter to the matrix of mass flows
            TrophicMassFlows[latIndex, lonIndex, fromIndex, toIndex] += massEaten;
        }
コード例 #34
0
        /// <summary>
        /// Write flows of matter among trophic levels to the output file at the end of the time step
        /// </summary>
        /// <param name="currentTimeStep">The current time step</param>
        /// <param name="numLats">The latitudinal dimension of the model grid in number of cells</param>
        /// <param name="numLons">The longitudinal dimension of the model grid in number of cells</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        /// <param name="MarineCell">Whether the current cell is a marine cell</param>
        public void WriteTrophicFlows(uint currentTimeStep, uint numLats, uint numLons, MadingleyModelInitialisation initialisation,
                                      Boolean MarineCell)
        {
            using (var TrophicFlowsWriter = File.AppendText(this.FileName))
            {
                for (int lat = 0; lat < numLats; lat++)
                {
                    for (int lon = 0; lon < numLons; lon++)
                    {
                        for (int i = 0; i < TrophicMassFlows.GetLength(2); i++)
                        {
                            for (int j = 0; j < TrophicMassFlows.GetLength(3); j++)
                            {
                                if (TrophicMassFlows[lat, lon, i, j] > 0)
                                {
                                    TrophicFlowsWriter.WriteLine(Convert.ToString(lat) + '\t' + Convert.ToString(lon) + '\t' + Convert.ToString(currentTimeStep) +
                                                                 '\t' + Convert.ToString(i) + '\t' + Convert.ToString(j) + '\t' + Convert.ToString(TrophicMassFlows[lat, lon, i, j]));
                                }
                            }
                        }
                    }
                }
            }

            // Initialise array to hold mass flows among trophic levels
            if (initialisation.TrackMarineSpecifics && MarineCell)
            {
                TrophicMassFlows = new double[numLats, numLons, 7, 7];
            }
            else
            {
                TrophicMassFlows = new double[numLats, numLons, 4, 4];
            }
        }
コード例 #35
0
        /// <summary>
        /// Runs the specified number of simulations for each of the specified scenarios
        /// </summary>
        /// <param name="simulationInitialisationFilename">Filename of the file from which to read initialisation information</param>
        /// <param name="scenarios">Contains scenario information for this set of simulations</param>
        /// <param name="outputPath">The path to which outputs should be written</param>
        public void RunAllSimulations(string simulationInitialisationFilename, string definitionsFilename, string outputsFilename, ScenarioParameterInitialisation scenarios, string outputPath)
        {
            // Declare an instance of the class for initializing the Madingley model
            MadingleyModelInitialisation InitialiseMadingley = new MadingleyModelInitialisation(simulationInitialisationFilename, definitionsFilename, outputsFilename, outputPath);

            // Specify the output path in this instance
            InitialiseMadingley.OutputPath = outputPath;

            // List to hold the names of the scenarios to run
            List <string> ScenarioNames = new List <string>();
            // String variable to hold the index suffix to apply to output files for a given simulation
            string OutputFilesSuffix;

            // Loop over scenario names and add the name of the scenario to the list of scenarion names
            foreach (var scenario in scenarios.scenarioParameters)
            {
                ScenarioNames.Add(scenario.Item1);
            }

            // Check whether there is only one simulation to run
            if (scenarios.scenarioNumber == 1 && scenarios.scenarioParameters.ElementAt(scenarios.scenarioNumber - 1).Item2 == 1)
            {
                // For a single simulation

                // Set-up the suffix for the output files
                OutputFilesSuffix = "_";

                // Loop over the parameters for this scenario
                for (int i = 0; i < ScenarioNames.Count; i++)
                {
                    // Add the parameter information to the suffix for this simulation
                    OutputFilesSuffix += ScenarioNames[0] + "_";
                }
                // Add a zero index to the end of the suffix
                OutputFilesSuffix += "0";

                //Run the simulation
                RunSimulation(scenarios, 0, InitialiseMadingley, OutputFilesSuffix, 0);
            }
            else
            {
                if (InitialiseMadingley.RunSimulationsInParallel)
                {
                    // Loop over specified scenarios iteratively
                    for (int ScenarioIndex = 0; ScenarioIndex < scenarios.scenarioNumber; ScenarioIndex++)
                    {
                        //Create an array of new MadingleyModel instances for simulations under this scenario combination
                        MadingleyModel[] MadingleyEcosystemModels = new MadingleyModel
                                                                    [scenarios.scenarioParameters.ElementAt(ScenarioIndex).Item2];

                        for (int simulation = 0; simulation < scenarios.scenarioParameters.ElementAt(ScenarioIndex).Item2; simulation++)
                        {
                            // Set up the suffix for the output files
                            OutputFilesSuffix = "_";

                            // Add the scenario label to the suffix for the output files
                            OutputFilesSuffix += ScenarioNames[ScenarioIndex] + "_";

                            // Add the simulation index number to the suffix
                            OutputFilesSuffix += simulation.ToString();

                            // Initialize the instance of MadingleyModel
                            MadingleyEcosystemModels[simulation] = new MadingleyModel(InitialiseMadingley, scenarios, ScenarioIndex, OutputFilesSuffix,
                                                                                      InitialiseMadingley.GlobalModelTimeStepUnit, simulation);
                        }

                        // Loop over the specified number of simulations for each scenario
                        //for (int simulation = 0; simulation<  scenarios.scenarioSimulationsNumber[ScenarioIndex]; simulation++)
                        Parallel.For(0, scenarios.scenarioParameters.ElementAt(ScenarioIndex).Item2, simulation =>
                        {
                            // Declare and start a timer
                            StopWatch s = new StopWatch();
                            s.Start();

                            // Run the simulation
                            MadingleyEcosystemModels[simulation].RunMadingley(InitialiseMadingley);

                            // Stop the timer and write out the time taken to run this simulation
                            s.Stop();
                            Console.WriteLine("Model run finished");
                            Console.WriteLine("Total elapsed time was {0} seconds", s.GetElapsedTimeSecs());
                        });
                    }
                }
                else
                {
                    //Run simulations sequentially

                    // Loop over specified scenarios
                    for (int ScenarioIndex = 0; ScenarioIndex < scenarios.scenarioNumber; ScenarioIndex++)
                    {
                        // Loop over the specified number of simulations for each scenario
                        for (int simulation = 0; simulation < scenarios.scenarioParameters.ElementAt(ScenarioIndex).Item2; simulation++)
                        {
                            // Set up the suffix for the output files
                            OutputFilesSuffix = "_";

                            // Add the scenario label to the suffix for the output files
                            OutputFilesSuffix += ScenarioNames[ScenarioIndex] + "_";

                            // Add the simulation index number to the suffix
                            OutputFilesSuffix += simulation.ToString();

                            // Run the current simulation
                            RunSimulation(scenarios, ScenarioIndex, InitialiseMadingley, OutputFilesSuffix, simulation);
                        }
                    }
                }
            }
        }
コード例 #36
0
 /// <summary>
 /// Write trophic flow data from the current time step to file 
 /// </summary>
 /// <param name="currentTimeStep">The current model time step</param>
 /// <param name="numLats">The number of grid cells, latitudinally, in the simulation</param>
 /// <param name="numLons">The number of grid cells, longitudinally, in the simulation</param>
 /// <param name="initialisation">The Madingley Model initialisation</param>
 /// <param name="marineCell">Whether the current cell is a marine cell</param>
 public void WriteTimeStepTrophicFlows(uint currentTimeStep, uint numLats, uint numLons, MadingleyModelInitialisation initialisation,
     Boolean marineCell)
 {
     _TrackEating.WriteTrophicFlows(currentTimeStep, numLats, numLons, initialisation, marineCell);
 }
コード例 #37
0
 /// <summary>
 /// Track the flow of mass between trophic levels during a herbivory event
 /// </summary>
 /// <param name="latIndex">The latitudinal index of the current grid cell</param>
 /// <param name="lonIndex">The longitudinal index of the current grid cell</param>
 /// <param name="toFunctionalGroup">The index of the functional group that the predator belongs to</param>
 /// <param name="cohortFunctionalGroupDefinitions">The functional group definitions of cohorts in the model</param>
 /// <param name="massEaten">The mass eaten during the herbivory event</param>
 /// <param name="predatorBodyMass">The body mass of the predator doing the eating</param>
 /// <param name="initialisation">The Madingley Model initialisation</param>
 /// <param name="marineCell">Whether the current cell is a marine cell</param>
 public void TrackHerbivoryTrophicFlow(uint latIndex, uint lonIndex, int toFunctionalGroup,
     FunctionalGroupDefinitions cohortFunctionalGroupDefinitions, double massEaten, double predatorBodyMass,
     MadingleyModelInitialisation initialisation, Boolean marineCell)
 {
     _TrackEating.RecordHerbivoryTrophicFlow(latIndex, lonIndex, toFunctionalGroup, cohortFunctionalGroupDefinitions, massEaten, predatorBodyMass, initialisation, marineCell);
 }
コード例 #38
0
        /// <summary>
        /// Constructor for process tracker: Initialises the trackers for individual processes
        /// </summary>
        /// <param name="numTimesteps">The number of time steps in the model</param>
        /// <param name="lats">The latitudes of active grid cells in the model</param>
        /// <param name="lons">The longitudes of active grid cells in the model</param>
        /// <param name="cellIndices">List of indices of active cells in the model grid</param>
        /// <param name="Filenames">The filenames of the output files to write the tracking results to</param>
        /// <param name="trackProcesses">Whether to track processes</param>
        /// <param name="cohortDefinitions">The definitions for cohort functional groups in the model</param>
        /// <param name="missingValue">The missing value to use in process tracking output files</param>
        /// <param name="outputFileSuffix">The suffix to be applied to output files from process tracking</param>
        /// <param name="outputPath">The path to the folder to be used for process tracking outputs</param>
        /// <param name="trackerMassBins">The mass bins to use for categorising output data in the process trackers</param>
        /// <param name="specificLocations">Whether the model is being run for specific locations</param>
        /// <param name="cellIndex">The index of the current cell in the list of all cells to run the model for</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        /// <param name="marineCell">Whether the current cell is a marine cell</param>
        /// <param name="latCellSize">The size of grid cells in the latitudinal direction</param>
        /// <param name="lonCellSize">The size of grid cells in the longitudinal direction</param>
        public ProcessTracker(uint numTimesteps,
            float[] lats, float[] lons,
            List<uint[]> cellIndices,
            SortedList<string, string> Filenames,
            Boolean trackProcesses,
            FunctionalGroupDefinitions cohortDefinitions,
            double missingValue,
            string outputFileSuffix,
            string outputPath, MassBinsHandler trackerMassBins,
            Boolean specificLocations,
            int cellIndex,
            MadingleyModelInitialisation initialisation,
            bool marineCell,
            float latCellSize,
            float lonCellSize)
        {
            // Initialise trackers for ecological processes
            _TrackProcesses = trackProcesses;

            if (_TrackProcesses)
            {
                _TrackReproduction = new ReproductionTracker(numTimesteps, (uint)lats.Length, (uint)lons.Length, cellIndices, Filenames["NewCohortsOutput"], Filenames["MaturityOutput"], outputFileSuffix, outputPath, cellIndex);
                _TrackEating = new EatingTracker((uint)lats.Length, (uint)lons.Length, Filenames["TrophicFlowsOutput"], outputFileSuffix, outputPath, cellIndex, initialisation, marineCell);
                _TrackGrowth = new GrowthTracker(numTimesteps, (uint)lats.Length, (uint)lons.Length, cellIndices, Filenames["GrowthOutput"], outputFileSuffix, outputPath, cellIndex);
                _TrackMortality = new MortalityTracker(numTimesteps, (uint)lats.Length, (uint)lons.Length, cellIndices, Filenames["MortalityOutput"], outputFileSuffix, outputPath, cellIndex);
                _TrackExtinction = new ExtinctionTracker(Filenames["ExtinctionOutput"], outputPath, outputFileSuffix, cellIndex);
                _TrackMetabolism = new MetabolismTracker(Filenames["MetabolismOutput"], outputPath, outputFileSuffix, cellIndex);

                // Initialise the predation and herbivory trackers only for runs with specific locations
                if (specificLocations == true)
                {
                    _TrackPredation = new PredationTracker(numTimesteps, cellIndices, Filenames["PredationFlowsOutput"], cohortDefinitions,
                        missingValue, outputFileSuffix, outputPath, trackerMassBins, cellIndex);
                }
            }
        }
コード例 #39
0
        /// <summary>
        /// Apply the changes from predation to prey cohorts, and update deltas for the predator cohort
        /// </summary>
        /// <param name="gridCellCohorts">The cohorts in the current grid cell</param>
        /// <param name="gridCellStocks">The stocks in the current grid cell</param>
        /// <param name="actingCohort">The acting cohort</param>
        /// <param name="cellEnvironment">The environment in the current grid cell</param>
        /// <param name="deltas">The sorted list to track changes in biomass and abundance of the acting cohort in this grid cell</param>
        /// <param name="madingleyCohortDefinitions">The functional group definitions for cohorts in the model</param>
        /// <param name="madingleyStockDefinitions">The functional group definitions for stocks in the model</param>
        /// <param name="trackProcesses">An instance of ProcessTracker to hold diagnostics for predation</param>
        /// <param name="currentTimestep">The current model time step</param>
        /// <param name="specificLocations">Whether the model is being run for specific locations</param>
        /// <param name="outputDetail">The level of output detail used in this model run</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        public void RunEating(GridCellCohortHandler gridCellCohorts, GridCellStockHandler gridCellStocks, int[] actingCohort, SortedList <string, double[]>
                              cellEnvironment, Dictionary <string, Dictionary <string, double> > deltas, FunctionalGroupDefinitions madingleyCohortDefinitions,
                              FunctionalGroupDefinitions madingleyStockDefinitions, ProcessTracker trackProcesses, uint currentTimestep, Boolean specificLocations,
                              string outputDetail, MadingleyModelInitialisation initialisation)
        {
            if (trackProcesses.TrackProcesses)
            {
                Track = (RandomNumberGenerator.GetUniform() > 0.975) ? true : false;
            }


            TempDouble = 0.0;

            // Temporary variable to hold the total time spent eating + 1. Saves an extra calculation in CalculateAbundanceEaten
            double TotalTimeUnitsToHandlePlusOne = TimeUnitsToHandlePotentialFoodItems + 1;

            // Loop over potential prey functional groups
            foreach (int FunctionalGroup in _FunctionalGroupIndicesToEat)
            {
                // Loop over cohorts within the functional group
                for (int i = 0; i < NumberCohortsPerFunctionalGroupNoNewCohorts[FunctionalGroup]; i++)
                {
                    // Get the individual body mass of this cohort
                    _BodyMassPrey = gridCellCohorts[FunctionalGroup][i].IndividualBodyMass;

                    // Calculate the actual abundance of prey eaten from this cohort
                    if (gridCellCohorts[FunctionalGroup][i].CohortAbundance > 0)
                    {
                        // Calculate the actual abundance of prey eaten from this cohort
                        _AbundancesEaten[FunctionalGroup][i] = CalculateAbundanceEaten(_PotentialAbundanceEaten[FunctionalGroup][i], _PredatorAbundanceMultipliedByTimeEating,
                                                                                       TotalTimeUnitsToHandlePlusOne, gridCellCohorts[FunctionalGroup][i].CohortAbundance);
                    }
                    else
                    {
                        _AbundancesEaten[FunctionalGroup][i] = 0;
                    }

                    // Remove number of prey eaten from the prey cohort
                    gridCellCohorts[FunctionalGroup][i].CohortAbundance -= _AbundancesEaten[FunctionalGroup][i];

                    gridCellCohorts[actingCohort].TrophicIndex += (_BodyMassPrey + gridCellCohorts[FunctionalGroup][i].IndividualReproductivePotentialMass) * _AbundancesEaten[FunctionalGroup][i] * gridCellCohorts[FunctionalGroup][i].TrophicIndex;

                    // If the process tracker is set and output detail is set to high and the prey cohort has never been merged,
                    // then track its mortality owing to predation
                    if (trackProcesses.TrackProcesses)
                    {
                        if ((outputDetail == "high") && (gridCellCohorts[FunctionalGroup][i].CohortID.Count == 1) &&
                            AbundancesEaten[FunctionalGroup][i] > 0)
                        {
                            trackProcesses.RecordMortality((uint)cellEnvironment["LatIndex"][0], (uint)cellEnvironment["LonIndex"][0], gridCellCohorts
                                                           [FunctionalGroup][i].BirthTimeStep, currentTimestep, gridCellCohorts[FunctionalGroup][i].IndividualBodyMass,
                                                           gridCellCohorts[FunctionalGroup][i].AdultMass, gridCellCohorts[FunctionalGroup][i].FunctionalGroupIndex,
                                                           gridCellCohorts[FunctionalGroup][i].CohortID[0], AbundancesEaten[FunctionalGroup][i], "predation");
                        }

                        // If the model is being run for specific locations and if track processes has been specified, then track the mass flow between
                        // prey and predator
                        if (specificLocations)
                        {
                            trackProcesses.RecordPredationMassFlow(currentTimestep, _BodyMassPrey, _BodyMassPredator, _BodyMassPrey *
                                                                   _AbundancesEaten[FunctionalGroup][i]);

                            if (outputDetail == "high")
                            {
                                trackProcesses.TrackPredationTrophicFlow((uint)cellEnvironment["LatIndex"][0], (uint)cellEnvironment["LonIndex"][0],
                                                                         gridCellCohorts[FunctionalGroup][i].FunctionalGroupIndex, gridCellCohorts[actingCohort].FunctionalGroupIndex,
                                                                         madingleyCohortDefinitions, (_AbundancesEaten[FunctionalGroup][i] * _BodyMassPrey), _BodyMassPredator, _BodyMassPrey,
                                                                         initialisation, cellEnvironment["Realm"][0] == 2.0);
                            }
                        }
                    }


                    // Check that the abundance eaten from this cohort is not negative
                    // Commented out for the purposes of speed
                    //Debug.Assert( _AbundancesEaten[FunctionalGroup][i].CompareTo(0.0) >= 0,
                    //     "Predation negative for this prey cohort" + actingCohort);

                    // Create a temporary value to speed up the predation function
                    // This is equivalent to the body mass of the prey cohort including reproductive potential mass, times the abundance eaten of the prey cohort,
                    // divided by the abundance of the predator
                    TempDouble += (_BodyMassPrey + gridCellCohorts[FunctionalGroup][i].IndividualReproductivePotentialMass) * _AbundancesEaten[FunctionalGroup][i] / _AbundancePredator;
                }
            }



            // Add the biomass eaten and assimilated by an individual to the delta biomass for the acting (predator) cohort
            deltas["biomass"]["predation"] = TempDouble * _PredatorAssimilationEfficiency;

            // Move the biomass eaten but not assimilated by an individual into the organic matter pool
            deltas["organicpool"]["predation"] = TempDouble * _PredatorNonAssimilation * _AbundancePredator;

            // Check that the delta biomass from eating for the acting cohort is not negative
            //Debug.Assert(deltas["biomass"]["predation"] >= 0, "Predation yields negative biomass");

            // Calculate the total biomass eaten by the acting (predator) cohort
            _TotalBiomassEatenByCohort = deltas["biomass"]["predation"] * _AbundancePredator;
        }
        /// <summary>
        /// Write to the output file values of the output variables during the model time steps
        /// </summary>
        /// <param name="ecosystemModelGrid">The model grid to get data from</param>
        /// <param name="cohortFunctionalGroupDefinitions">The definitions of the cohort functional groups in the model</param>
        /// <param name="stockFunctionalGroupDefinitions">The definitions of the stock  functional groups in the model</param>
        /// <param name="cellIndices">List of indices of active cells in the model grid</param>
        /// <param name="cellNumber">The number of the current cell in the list of indices of active cells</param>
        /// <param name="globalDiagnosticVariables">List of global diagnostic variables</param>
        /// <param name="timeStepTimer">The timer for the current time step</param>
        /// <param name="numTimeSteps">The number of time steps in the model run</param>
        /// <param name="currentTimestep">The current model time step</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        /// <param name="month">The current month in the model run</param>
        /// <param name="marineCell">Whether the current cell is a marine cell</param>
        public void TimeStepOutputs(ModelGrid ecosystemModelGrid, FunctionalGroupDefinitions cohortFunctionalGroupDefinitions, 
            FunctionalGroupDefinitions stockFunctionalGroupDefinitions, List<uint[]> cellIndices, int cellNumber,
            SortedList<string, double> globalDiagnosticVariables, StopWatch timeStepTimer, uint numTimeSteps, uint currentTimestep, 
            MadingleyModelInitialisation initialisation, uint month, Boolean marineCell)
        {
            // Calculate values of the output variables to be used
            CalculateOutputs(ecosystemModelGrid, cohortFunctionalGroupDefinitions, stockFunctionalGroupDefinitions, cellIndices, cellNumber, globalDiagnosticVariables, initialisation, month, marineCell);

            // Generate the live outputs for this time step
            if (LiveOutputs)
            {
                TimeStepLiveOutputs(numTimeSteps, currentTimestep, ecosystemModelGrid, marineCell);
            }

            // Generate the console outputs for the current time step
            TimeStepConsoleOutputs(currentTimestep, timeStepTimer);

            // Generate the file outputs for the current time step
            TimeStepFileOutputs(ecosystemModelGrid, cohortFunctionalGroupDefinitions, currentTimestep, marineCell, cellIndices,cellNumber);
        }
        /// <summary>
        /// Calculate outputs associated with low-level outputs
        /// </summary>
        /// <param name="ecosystemModelGrid">The model grid</param>
        /// <param name="cellIndices">The list of indices of active cells in the model grid</param>
        /// <param name="cellIndex">The position of the current cell in the list of active cells</param>
        /// <param name="globalDiagnosticVariables">The global diagnostic variables for this model run</param>
        /// <param name="cohortFunctionalGroupDefinitions">The functional group definitions of cohorts in the model</param>
        /// <param name="stockFunctionalGroupDefinitions">The functional group definitions of stocks in the model</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        /// <param name="month">The current month in the model run</param>
        /// <param name="MarineCell">Whether the current cell is a marine cell</param>
        private void CalculateLowLevelOutputs(ModelGrid ecosystemModelGrid, List<uint[]> cellIndices, int cellIndex, 
            SortedList<string,double> globalDiagnosticVariables, FunctionalGroupDefinitions cohortFunctionalGroupDefinitions,
            FunctionalGroupDefinitions stockFunctionalGroupDefinitions, MadingleyModelInitialisation initialisation, uint month, 
            Boolean MarineCell)
        {
            // Reset the total living biomass
            TotalLivingBiomass = 0.0;

            string[] Keys;

            if (MarineCell)
            {
                // Get the list of cohort trait combinations to consider
                Keys = CohortTraitIndicesMarine.Keys.ToArray();

                // Get biomass, abundance and densities for each of the trait combinations. Note that the GetStateVariableDensity function deals with the assessment of whether cohorts contain individuals
                // of low enough mass to be considered zooplankton in the marine realm
                foreach (string TraitValue in Keys)
                {
                    // Biomass density
                    TotalBiomassDensitiesOut[TraitValue] = ecosystemModelGrid.GetStateVariableDensity("Biomass", TraitValue, CohortTraitIndicesMarine[TraitValue], cellIndices[cellIndex][0], cellIndices[cellIndex][1], "cohort", initialisation) / 1000.0;

                    // Density
                    TotalDensitiesOut[TraitValue] = ecosystemModelGrid.GetStateVariableDensity("Abundance", TraitValue, CohortTraitIndicesMarine[TraitValue], cellIndices[cellIndex][0], cellIndices[cellIndex][1], "cohort", initialisation);
                }
            }
            else
            {
                // Get the list of cohort trait combinations to consider
                Keys = CohortTraitIndices.Keys.ToArray();

                // Get biomass, abundance and densities for each of the trait combinations
                foreach (string TraitValue in Keys)
                {
                    // Biomass density
                    TotalBiomassDensitiesOut[TraitValue] = ecosystemModelGrid.GetStateVariableDensity("Biomass", TraitValue, CohortTraitIndices[TraitValue], cellIndices[cellIndex][0], cellIndices[cellIndex][1], "cohort", initialisation) / 1000.0;

                    // Density
                    TotalDensitiesOut[TraitValue] = ecosystemModelGrid.GetStateVariableDensity("Abundance", TraitValue, CohortTraitIndices[TraitValue], cellIndices[cellIndex][0], cellIndices[cellIndex][1], "cohort", initialisation);
                }
            }

            // Add the total biomass of all cohorts to the total living biomass variable
            TotalLivingBiomass += ecosystemModelGrid.GetStateVariable("Biomass", "NA", cohortFunctionalGroupDefinitions.AllFunctionalGroupsIndex,
                cellIndices[cellIndex][0], cellIndices[cellIndex][1], "cohort", initialisation);
            TotalLivingBiomassDensity = ecosystemModelGrid.GetStateVariableDensity("Biomass", "NA", cohortFunctionalGroupDefinitions.AllFunctionalGroupsIndex, cellIndices[cellIndex][0], cellIndices[cellIndex][1], "cohort", initialisation) / 1000.0;
            TotalHeterotrophAbundanceDensity = ecosystemModelGrid.GetStateVariableDensity("Abundance", "NA", cohortFunctionalGroupDefinitions.AllFunctionalGroupsIndex, cellIndices[cellIndex][0], cellIndices[cellIndex][1], "cohort", initialisation);
            TotalHeterotrophBiomassDensity = TotalLivingBiomassDensity;

            if (MarineCell)
            {
                // Get the list of stock trait combinations to consider
                Keys = StockTraitIndicesMarine.Keys.ToArray();

                // Get biomass and biomass density for each of the trait combinations
                foreach (string TraitValue in Keys)
                {
                    // Density
                    TotalBiomassDensitiesOut[TraitValue] = ecosystemModelGrid.GetStateVariableDensity("Biomass", TraitValue, StockTraitIndicesMarine[TraitValue], cellIndices[cellIndex][0], cellIndices[cellIndex][1], "stock", initialisation) / 1000.0;
                }
            }
            else
            {
                // Get the list of stock trait combinations to consider
                Keys = StockTraitIndices.Keys.ToArray();

                // Get biomass and biomass density for each of the trait combinations
                foreach (string TraitValue in Keys)
                {
                    // Density
                    TotalBiomassDensitiesOut[TraitValue] = ecosystemModelGrid.GetStateVariableDensity("Biomass", TraitValue, StockTraitIndices[TraitValue], cellIndices[cellIndex][0], cellIndices[cellIndex][1], "stock", initialisation) / 1000.0;
                }
            }

            // Add the total biomass of all stocks to the total living biomass variable
            TotalLivingBiomass += ecosystemModelGrid.GetStateVariable("Biomass", "NA", stockFunctionalGroupDefinitions.AllFunctionalGroupsIndex,
                cellIndices[cellIndex][0], cellIndices[cellIndex][1], "stock", initialisation);
            TotalLivingBiomassDensity += ecosystemModelGrid.GetStateVariableDensity("Biomass", "NA", stockFunctionalGroupDefinitions.AllFunctionalGroupsIndex, cellIndices[cellIndex][0], cellIndices[cellIndex][1], "stock", initialisation) / 1000.0;

            if (TrackMarineSpecifics && MarineCell)
            {
                bool varExists;
                TotalIncomingNPP = ecosystemModelGrid.GetEnviroLayer("NPP", month, cellIndices[cellIndex][0], cellIndices[cellIndex][1], out varExists);
            }
        }
コード例 #42
0
        /// <summary>
        /// Assigns the properties of the current model run
        /// </summary>
        /// <param name="initialisation">An instance of the model initialisation class</param> 
        /// <param name="scenarioParameters">The parameters for the scenarios to run</param>
        /// <param name="scenarioIndex">The index of the scenario that this model is to run</param>
        /// <param name="outputFilesSuffix">The suffix to be applied to all outputs from this model run</param>
        public void AssignModelRunProperties(MadingleyModelInitialisation initialisation, 
            ScenarioParameterInitialisation scenarioParameters, int scenarioIndex,
            string outputFilesSuffix)
        {
            // Assign the properties of this model run from the same properties in the specified model initialisation
            _GlobalModelTimeStepUnit = initialisation.GlobalModelTimeStepUnit;
            NumTimeSteps = initialisation.NumTimeSteps;
            NumBurninSteps = initialisation.BurninTimeSteps;
            NumImpactSteps = initialisation.ImpactTimeSteps;
            NumRecoverySteps = initialisation.RecoveryTimeSteps;
            CellSize = (float)initialisation.CellSize;
            _CellList = initialisation.CellList;
            BottomLatitude = initialisation.BottomLatitude;
            TopLatitude = initialisation.TopLatitude;
            LeftmostLongitude = initialisation.LeftmostLongitude;
            RightmostLongitude = initialisation.RightmostLongitude;
            RunGridCellsInParallel = initialisation.RunCellsInParallel;
            DrawRandomly = initialisation.DrawRandomly;
            _ExtinctionThreshold = initialisation.ExtinctionThreshold;
            MergeDifference = initialisation.MergeDifference;
            InitialisationFileStrings = initialisation.InitialisationFileStrings;
            CohortFunctionalGroupDefinitions = initialisation.CohortFunctionalGroupDefinitions;
            StockFunctionalGroupDefinitions = initialisation.StockFunctionalGroupDefinitions;
            EnviroStack = initialisation.EnviroStack;
            _HumanNPPScenario = scenarioParameters.scenarioParameters.ElementAt(scenarioIndex).Item3["npp"];
            _TemperatureScenario = scenarioParameters.scenarioParameters.ElementAt(scenarioIndex).Item3["temperature"];
            _HarvestingScenario = scenarioParameters.scenarioParameters.ElementAt(scenarioIndex).Item3["harvesting"];
            OutputFilesSuffix = outputFilesSuffix;
            EnvironmentalDataUnits = initialisation.Units;
            OutputModelStateTimestep = initialisation.OutputStateTimestep;
            SpecificLocations = initialisation.SpecificLocations;

            // Initialise the cohort ID to zero
            NextCohortID = 0;
        }
コード例 #43
0
        /// <summary>
        /// A method to run the main ecosystem model loop in parallel (latitudinal strips)
        /// </summary>
        /// <param name="cellIndex">The index of the current cell in the list of all cells to run the model for</param>
        /// <param name="partial">A threadlockedparallelvariable that is used to pass global diagnostic information back with locking or race conditions</param>
        /// <param name="dispersalOnly">Whether to run dispersal only (i.e. to turn all other ecological processes off</param>
        /// <param name="initialisation">The Madingley Model intialisation</param>
        /// <remarks>Note that variables and instances of classes that are written to within this method MUST be local within this method to prevent 
        /// race issues and multiple threads attempting to write to the same variable when running the program in parallel</remarks>
        public void RunCell(int cellIndex, ThreadLockedParallelVariables partial, Boolean dispersalOnly, 
            MadingleyModelInitialisation initialisation)
        {
            // Apply any climate change impacts
            ClimateChangeSimulator.ApplyTemperatureScenario(
                EcosystemModelGrid.GetCellEnvironment(_CellList[cellIndex][0], _CellList[cellIndex][1]),
                _TemperatureScenario,CurrentTimeStep,CurrentMonth,NumBurninSteps,NumImpactSteps,
                ((initialisation.ImpactCellIndices.Contains((uint)cellIndex) || initialisation.ImpactAll)));

            // Create a temporary internal copy of the grid cell cohorts
            GridCellCohortHandler WorkingGridCellCohorts = EcosystemModelGrid.GetGridCellCohorts(_CellList[cellIndex][0], _CellList[cellIndex][1]);

            // Create a temporary internal copy of the grid cell stocks
            GridCellStockHandler WorkingGridCellStocks = EcosystemModelGrid.GetGridCellStocks(_CellList[cellIndex][0], _CellList[cellIndex][1]);

            // Run stock ecology
            RunWithinCellStockEcology(_CellList[cellIndex][0], _CellList[cellIndex][1], WorkingGridCellStocks, cellIndex,
                initialisation);

            // Run within cell ecology if we are not doing dispersal only
            if (dispersalOnly)
            {
                // Run cohort ecology
                RunWithinCellDispersalOnly(_CellList[cellIndex][0], _CellList[cellIndex][1], partial, WorkingGridCellCohorts, WorkingGridCellStocks);
            }
            else
            {
                // Run cohort ecology
                RunWithinCellCohortEcology(_CellList[cellIndex][0], _CellList[cellIndex][1], partial, WorkingGridCellCohorts, WorkingGridCellStocks, InitialisationFileStrings["OutputDetail"], cellIndex, initialisation);

            }

            // Apply any direct harvesting impacts
            HarvestingSimulator.RemoveHarvestedIndividuals(WorkingGridCellCohorts, _HarvestingScenario, CurrentTimeStep, NumBurninSteps,
                NumImpactSteps,NumTimeSteps, EcosystemModelGrid.GetCellEnvironment(_CellList[cellIndex][0], _CellList[cellIndex][1]),
                (initialisation.ImpactCellIndices.Contains((uint)cellIndex) || initialisation.ImpactAll), _GlobalModelTimeStepUnit, CohortFunctionalGroupDefinitions);

            // For runs with specific locations and where track processes has been specified, write out mass flows data and reset the mass flow tracker
            // for the next time step
            if (SpecificLocations && ProcessTrackers[cellIndex].TrackProcesses)
            {
                ProcessTrackers[cellIndex].EndTimeStepPredationTracking(CurrentTimeStep);
                ProcessTrackers[cellIndex].EndTimeStepHerbvioryTracking(CurrentTimeStep);
            }
        }
コード例 #44
0
        /// <summary>
        /// Run processes for cells sequentially
        /// </summary>
        public void RunCellsSequentially(MadingleyModelInitialisation initialisation)
        {
            // Instantiate a class to hold thread locked global diagnostic variables
            ThreadLockedParallelVariables singleThreadDiagnostics = new ThreadLockedParallelVariables { Extinctions = 0, Productions = 0, NextCohortIDThreadLocked = NextCohortID };

            if (initialisation.RunRealm == "")
            {

                for (int ii = 0; ii < _CellList.Count; ii++)
                {
                    RunCell(ii, singleThreadDiagnostics, initialisation.DispersalOnly, initialisation);
                }
            }

            else
            {

                if (initialisation.RunRealm == "marine")
                {
                    for (int ii = 0; ii < _CellList.Count; ii++)
                    {
                        if (EcosystemModelGrid.GetCellEnvironment(_CellList[ii][0], _CellList[ii][1])["Realm"][0] == 2.0) RunCell(ii, singleThreadDiagnostics, initialisation.DispersalOnly, initialisation);
                    }
                }
                else if (initialisation.RunRealm == "terrestrial")
                {
                    for (int ii = 0; ii < _CellList.Count; ii++)
                    {
                        if (EcosystemModelGrid.GetCellEnvironment(_CellList[ii][0], _CellList[ii][1])["Realm"][0] == 1.0) RunCell(ii, singleThreadDiagnostics, initialisation.DispersalOnly, initialisation);
                    }
                }
                else
                {
                    Console.WriteLine("Run Single Realm needs to be 'marine', 'terrestrial', or blank");
                    Console.ReadKey();
                }
            }

            // Update the variable tracking cohort unique IDs
            NextCohortID = singleThreadDiagnostics.NextCohortIDThreadLocked;

            // Take the results from the thread local variables and apply to the global diagnostic variables
            GlobalDiagnosticVariables["NumberOfCohortsExtinct"] = singleThreadDiagnostics.Extinctions - singleThreadDiagnostics.Combinations;
            GlobalDiagnosticVariables["NumberOfCohortsProduced"] = singleThreadDiagnostics.Productions;
            GlobalDiagnosticVariables["NumberOfCohortsInModel"] = GlobalDiagnosticVariables["NumberOfCohortsInModel"] + singleThreadDiagnostics.Productions - singleThreadDiagnostics.Extinctions;
            GlobalDiagnosticVariables["NumberOfCohortsCombined"] = singleThreadDiagnostics.Combinations;
        }
コード例 #45
0
        private void RunWithinCellCohortEcology(uint latCellIndex, uint lonCellIndex, ThreadLockedParallelVariables partial, 
            GridCellCohortHandler workingGridCellCohorts, GridCellStockHandler workingGridCellStocks,string outputDetail, int cellIndex, MadingleyModelInitialisation initialisation)
        {
            // Local instances of classes
            EcologyCohort MadingleyEcologyCohort = new EcologyCohort();
            Activity CohortActivity = new Activity();
            CohortMerge CohortMerger = new CohortMerge(DrawRandomly);

            // A list of the original cohorts inside a particular grid cell
            int[] OriginalGridCellCohortsNumbers;
            // A vector to hold the order in which cohorts will act
            uint[] RandomCohortOrder;
            // A jagged array to keep track of cohorts that are being worked on
            uint[][] CohortIndices;
            // The location of the acting cohort
            int[] ActingCohort = new int[2];
            // Temporary local variables
            int EcosystemModelParallelTempval1;
            int EcosystemModelParallelTempval2;
            // Boolean to pass into function to get cell environmental data to check if the specified variable exists
            bool VarExists;
            // variable to track cohort number
            uint TotalCohortNumber = 0;

            // Fill in the array with the number of cohorts per functional group before ecological processes are run
            OriginalGridCellCohortsNumbers = new int[workingGridCellCohorts.Count];

            for (int i = 0; i < workingGridCellCohorts.Count; i++)
            {
                OriginalGridCellCohortsNumbers[i] = workingGridCellCohorts[i].Count;
            }

            // Initialize ecology for stocks and cohorts
            MadingleyEcologyCohort.InitializeEcology(EcosystemModelGrid.GetCellEnvironment(latCellIndex, lonCellIndex)["Cell Area"][0],
                _GlobalModelTimeStepUnit, DrawRandomly);

            // Create a jagged array indexed by functional groups to hold cohort indices
            CohortIndices = new uint[CohortFunctionalGroupDefinitions.GetNumberOfFunctionalGroups()][];

            // Loop over functional groups
            for (int ll = 0; ll < CohortFunctionalGroupDefinitions.GetNumberOfFunctionalGroups(); ll++)
            {
                // Dimension the number of columns in each row of the jagged array to equal number of gridCellCohorts in each functional group
                if (workingGridCellCohorts[ll] == null)
                {
                    CohortIndices[ll] = new uint[0];
                }
                else
                {
                    CohortIndices[ll] = new uint[workingGridCellCohorts[ll].Count()];
                }
                // Loop over gridCellCohorts in the functional group
                for (int kk = 0; kk < CohortIndices[ll].Count(); kk++)
                {
                    // Fill jagged array with indices for each cohort
                    CohortIndices[ll][kk] = TotalCohortNumber;
                    TotalCohortNumber += 1;
                }

            }

            if (DrawRandomly)
            {
                // Randomly order the cohort indices
                RandomCohortOrder = Utilities.RandomlyOrderedIndices(TotalCohortNumber);
            }
            else
            {
                RandomCohortOrder = Utilities.NonRandomlyOrderedCohorts(TotalCohortNumber, CurrentTimeStep);
            }

            // Diagnostic biological variables don't need to be reset every cohort, but rather every grid cell
            EcosystemModelParallelTempval2 = 0;

            // Initialise eating formulations
            MadingleyEcologyCohort.EatingFormulations["Basic eating"].InitializeEcologicalProcess(workingGridCellCohorts, workingGridCellStocks,
                CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions, "revised predation");
            MadingleyEcologyCohort.EatingFormulations["Basic eating"].InitializeEcologicalProcess(workingGridCellCohorts, workingGridCellStocks
                , CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions, "revised herbivory");

            // Loop over randomly ordered gridCellCohorts to implement biological functions
            for (int ll = 0; ll < RandomCohortOrder.Length; ll++)
            {

                // Locate the randomly chosen cohort within the array of lists of gridCellCohorts in the grid cell
                ActingCohort = Utilities.FindJaggedArrayIndex(RandomCohortOrder[ll], CohortIndices, TotalCohortNumber);

                // Perform all biological functions except dispersal (which is cross grid cell)
                if (workingGridCellCohorts[ActingCohort].CohortAbundance.CompareTo(_ExtinctionThreshold) > 0)
                {
                    // Calculate number of cohorts in this functional group in this grid cell before running ecology
                    EcosystemModelParallelTempval1 = workingGridCellCohorts[ActingCohort[0]].Count;

                    CohortActivity.AssignProportionTimeActive(workingGridCellCohorts[ActingCohort], EcosystemModelGrid.GetCellEnvironment(latCellIndex, lonCellIndex), CohortFunctionalGroupDefinitions, CurrentTimeStep, CurrentMonth);

                    // Run ecology
                    MadingleyEcologyCohort.RunWithinCellEcology(workingGridCellCohorts, workingGridCellStocks,
                        ActingCohort, EcosystemModelGrid.GetCellEnvironment(latCellIndex, lonCellIndex),
                        EcosystemModelGrid.GetCellDeltas(latCellIndex, lonCellIndex),
                        CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions, CurrentTimeStep,
                        ProcessTrackers[cellIndex], ref partial, SpecificLocations,outputDetail, CurrentMonth, initialisation);

                    // Update the properties of the acting cohort
                    MadingleyEcologyCohort.UpdateEcology(workingGridCellCohorts, workingGridCellStocks, ActingCohort,
                        EcosystemModelGrid.GetCellEnvironment(latCellIndex, lonCellIndex), EcosystemModelGrid.GetCellDeltas(
                        latCellIndex, lonCellIndex), CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions, CurrentTimeStep,
                        ProcessTrackers[cellIndex]);

                    // Add newly produced cohorts to the tracking variable
                    EcosystemModelParallelTempval2 += workingGridCellCohorts[ActingCohort[0]].Count - EcosystemModelParallelTempval1;

                    // Check that the mass of individuals in this cohort is still >= 0 after running ecology
                    Debug.Assert(workingGridCellCohorts[ActingCohort].IndividualBodyMass >= 0.0, "Biomass < 0 for this cohort");
                }

                // Check that the mass of individuals in this cohort is still >= 0 after running ecology
                Debug.Assert(workingGridCellCohorts[ActingCohort].IndividualBodyMass >= 0.0, "Biomass < 0 for this cohort");
            }

            // Update diagnostics of productions
            partial.Productions += EcosystemModelParallelTempval2;

            RunExtinction(latCellIndex, lonCellIndex, partial, workingGridCellCohorts, cellIndex);

            // Merge cohorts, if necessary
            if (workingGridCellCohorts.GetNumberOfCohorts() > initialisation.MaxNumberOfCohorts)
            {
                partial.Combinations = CohortMerger.MergeToReachThresholdFast(workingGridCellCohorts, workingGridCellCohorts.GetNumberOfCohorts(), initialisation.MaxNumberOfCohorts);

                //Run extinction a second time to remove those cohorts that have been set to zero abundance when merging
                RunExtinction(latCellIndex, lonCellIndex, partial, workingGridCellCohorts, cellIndex);
            }
            else
                partial.Combinations = 0;

            // Write out the updated cohort numbers after all ecological processes have occured
            EcosystemModelGrid.SetGridCellCohorts(workingGridCellCohorts, latCellIndex, lonCellIndex);
        }
コード例 #46
0
        /// <summary>
        /// Run the global ecosystem model
        /// </summary>
        /// <param name="initialisation">The initialization details for the current set of model simulations</param>
        public void RunMadingley(MadingleyModelInitialisation initialisation)
        {
            // Write out model run details to the console
            Console.WriteLine("Running model");
            Console.WriteLine("Number of time steps is: {0}", NumTimeSteps);
            Console.WriteLine(" ");
            Console.WriteLine(" ");

            // Temporary variable
            Boolean varExists;

             // Run the model
             for (UInt32 hh = 0; hh < NumTimeSteps; hh += 1)
             {
                 Console.WriteLine("Running time step {0}...",hh + 1);

                 // Start the timer
                 TimeStepTimer.Start();

                 // Get current time step and month
                 CurrentTimeStep = hh;
                 CurrentMonth = Utilities.GetCurrentMonth(hh,_GlobalModelTimeStepUnit);

                 // Initialise cross grid cell ecology
                 MadingleyEcologyCrossGridCell.InitializeCrossGridCellEcology(_GlobalModelTimeStepUnit, DrawRandomly, initialisation);

                 EcologyTimer.Start();

                 // Loop over grid cells and run biological processes
                 if (RunGridCellsInParallel)
                 {
                     // Run cells in parallel
                     RunCellsInParallel(initialisation);
                 }
                 else
                 {
                     // Run cells in sequence
                     RunCellsSequentially(initialisation);
                 }

                 EcologyTimer.Stop();
                 Console.WriteLine("Within grid ecology took: {0}" ,EcologyTimer.GetElapsedTimeSecs());
                 // Run the garbage collector. Note that it works in the background so may take a little while
                 // Needs to be done to ensure cohorts are deleted properly
                 GC.Collect();

                 if (TrackGlobalProcesses.TrackProcesses)
                 {
                     for (uint ii = 0; ii < StockFunctionalGroupDefinitions.GetNumberOfFunctionalGroups(); ii++)
                     {
                         TrackGlobalProcesses.StoreNPPGrid(hh, ii);
                         TrackGlobalProcesses.StoreHANPPGrid(hh, ii);
                     }
                 }

                 EcologyTimer.Start();

                 // Run cross grid cell ecology
                 RunCrossGridCellEcology(ref Dispersals, initialisation.DispersalOnly, initialisation);

                 EcologyTimer.Stop();
                 Console.WriteLine("Across grid ecology took: {0}", EcologyTimer.GetElapsedTimeSecs());

                 // Run the garbage collector. Note that it works in the background so may take a little while
                 // Needs to be done here to ensure cohorts are deleted properly
                 GC.Collect();

                 // Stop the timer
                 TimeStepTimer.Stop();

                 OutputTimer.Start();

                 // Write the global outputs for this time step
                 GlobalOutputs.TimeStepOutputs(EcosystemModelGrid, CurrentTimeStep, CurrentMonth, TimeStepTimer,CohortFunctionalGroupDefinitions,
                     StockFunctionalGroupDefinitions,_CellList,GlobalDiagnosticVariables, initialisation);

                 OutputTimer.Stop();
                 Console.WriteLine("Global Outputs took: {0}", OutputTimer.GetElapsedTimeSecs());

                 OutputTimer.Start();

                 if (SpecificLocations)
                 {
                     // Loop over grid cells and write (a) time step outputs, and (b) trophic flow data (if process tracking is on)
                     for (int i = 0; i < _CellList.Count; i++)
                     {
                         // Write out the grid cell outputs for this time step
                         CellOutputs[i].TimeStepOutputs(EcosystemModelGrid, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions,
                             _CellList, i, GlobalDiagnosticVariables, TimeStepTimer, NumTimeSteps, CurrentTimeStep, initialisation, CurrentMonth, EcosystemModelGrid.GetEnviroLayer("Realm", 0, _CellList[i][0], _CellList[i][1], out varExists) == 2.0);

                         // Write out trophic flow data for this time step
                         if(ProcessTrackers[i].TrackProcesses) ProcessTrackers[i].WriteTimeStepTrophicFlows(CurrentTimeStep, EcosystemModelGrid.NumLatCells, EcosystemModelGrid.NumLonCells, initialisation,
                             EcosystemModelGrid.GetEnviroLayer("Realm", 0, _CellList[i][0], _CellList[i][1], out varExists) == 2.0);

                     }
                 }
                 else
                 {
                     // Write out grid outputs for this time step
                     GridOutputs.TimeStepOutputs(EcosystemModelGrid, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions, _CellList,
                         CurrentTimeStep, initialisation);
                 }

                 OutputTimer.Stop();
                 Console.WriteLine("Cell/Grid Outputs took: {0}", OutputTimer.GetElapsedTimeSecs());

                 // Write the results of dispersal to the console
                 Console.ForegroundColor = ConsoleColor.Green;
                 Console.WriteLine("Number of cohorts that dispersed this time step: {0}\n", Dispersals);
                 Console.ForegroundColor = ConsoleColor.White;
                 Dispersals = 0;

                 if (OutputModelStateTimestep.Contains(hh))
                 {
                     OutputTimer.Start();
                     Console.WriteLine("Outputting model state");

                     //Writing to text based output
                     WriteModelState.OutputCurrentModelState( EcosystemModelGrid, _CellList, hh);
                     //WriteModelState.OutputCurrentModelState(EcosystemModelGrid,CohortFunctionalGroupDefinitions, _CellList, CurrentTimeStep, initialisation.MaxNumberOfCohorts,"ModelState");

                     OutputTimer.Stop();
                     // Write the results of dispersal to the console
                     Console.ForegroundColor = ConsoleColor.Green;
                     Console.WriteLine("Writing model state took: {0}", OutputTimer.GetElapsedTimeSecs());
                     Console.ForegroundColor = ConsoleColor.White;

                 }

             }

             if (TrackGlobalProcesses.TrackProcesses) TrackGlobalProcesses.CloseNPPFile();

            // Loop over cells and close process trackers
             for (int i = 0; i < _CellList.Count; i++)
             {
                 if (ProcessTrackers[i].TrackProcesses) ProcessTrackers[i].CloseStreams(SpecificLocations);
             }

            // Write the final global outputs
            GlobalOutputs.FinalOutputs();

            WriteModelState.CloseStreams();

            if (SpecificLocations)
            {
                // Loop over grid cells and write the final grid cell outputs
                for (int i = 0; i < _CellList.Count; i++)
                {
                    CellOutputs[i].FinalOutputs(EcosystemModelGrid, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions,
                        _CellList, i, GlobalDiagnosticVariables, initialisation, CurrentMonth, EcosystemModelGrid.GetEnviroLayer("Realm", 0, _CellList[i][0], _CellList[i][1], out varExists) == 2.0);
                }
            }
            else
            {
                // Write the final grid outputs
                GridOutputs.FinalOutputs();
            }
        }
コード例 #47
0
        /// <summary>
        /// Initializes the ecosystem model
        /// </summary>
        /// <param name="initialisation">An instance of the model initialisation class</param> 
        /// <param name="scenarioParameters">The parameters for the scenarios to run</param>
        /// <param name="scenarioIndex">The index of the scenario being run</param>
        /// <param name="outputFilesSuffix">The suffix to be applied to all outputs from this model run</param>
        /// <param name="globalModelTimeStepUnit">The time step unit used in the model</param>
        /// <param name="simulation">The index of the simulation being run</param>
        public MadingleyModel(MadingleyModelInitialisation initialisation, ScenarioParameterInitialisation scenarioParameters, int scenarioIndex,
            string outputFilesSuffix, string globalModelTimeStepUnit, int simulation)
        {
            // Assign the properties for this model run
            AssignModelRunProperties(initialisation, scenarioParameters, scenarioIndex, outputFilesSuffix);

            // Set up list of global diagnostics
            SetUpGlobalDiagnosticsList();

            // Set up the model grid
            SetUpModelGrid(initialisation, scenarioParameters, scenarioIndex, simulation);

            // Set up model outputs
            SetUpOutputs(initialisation, simulation, scenarioIndex);

            // Make the initial outputs
            InitialOutputs(outputFilesSuffix, initialisation, CurrentMonth);

            // Instance the array of process trackers
            ProcessTrackers = new ProcessTracker[_CellList.Count];

            // Temporary variables
            Boolean varExists;

            // Set up process trackers for each grid cell
            for (int i = 0; i < _CellList.Count; i++)
            {
                ProcessTrackers[i] = new ProcessTracker(NumTimeSteps,
                EcosystemModelGrid.Lats, EcosystemModelGrid.Lons,
                _CellList,
                initialisation.ProcessTrackingOutputs,
                initialisation.TrackProcesses,
                CohortFunctionalGroupDefinitions,
                EcosystemModelGrid.GlobalMissingValue,
                outputFilesSuffix,
                initialisation.OutputPath, initialisation.ModelMassBins,
                SpecificLocations, i, initialisation,
                EcosystemModelGrid.GetEnviroLayer("Realm", 0, _CellList[i][0], _CellList[i][1], out varExists) == 2.0,
                EcosystemModelGrid.LatCellSize,
                EcosystemModelGrid.LonCellSize);
            }

            // Set up a cross cell process tracker
            TrackCrossCellProcesses = new CrossCellProcessTracker(initialisation.TrackCrossCellProcesses, "DispersalData", initialisation.OutputPath, outputFilesSuffix);

            //Set up a global process tracker
            if (SpecificLocations) initialisation.TrackGlobalProcesses = false;

            TrackGlobalProcesses = new GlobalProcessTracker(NumTimeSteps,
                EcosystemModelGrid.Lats, EcosystemModelGrid.Lons,
                _CellList,
                initialisation.ProcessTrackingOutputs,
                initialisation.TrackGlobalProcesses,
                CohortFunctionalGroupDefinitions,
                StockFunctionalGroupDefinitions,
                EcosystemModelGrid.GlobalMissingValue,
                outputFilesSuffix,
                initialisation.OutputPath, initialisation.ModelMassBins,
                SpecificLocations, initialisation,
                EcosystemModelGrid.LatCellSize,
                EcosystemModelGrid.LonCellSize);

            //Set-up the instance of OutputModelState
            WriteModelState = new OutputModelState(initialisation, outputFilesSuffix, simulation);

            if (SpecificLocations) initialisation.RunRealm = "";

            // Record the initial cohorts in the process trackers
            RecordInitialCohorts();

            // Initialise the class for cross-grid-cell ecology
            MadingleyEcologyCrossGridCell = new EcologyCrossGridCell();

            // Initialise the time step timer
            TimeStepTimer = new StopWatch();
            EcologyTimer = new StopWatch();
            OutputTimer = new StopWatch();

            // Set the global model time step unit
            _GlobalModelTimeStepUnit = globalModelTimeStepUnit;

            // Initialise the utility functions
            Utilities = new UtilityFunctions();

            // Initialise the climate change impacts class
            ClimateChangeSimulator = new ClimateChange();

            // Initialise the harvesting impacts class
            HarvestingSimulator = new Harvesting(EcosystemModelGrid.Lats, EcosystemModelGrid.Lons, (float)EcosystemModelGrid.LatCellSize);
        }
コード例 #48
0
        /// <summary>
        /// Run eating
        /// </summary>
        /// <param name="gridCellCohorts">The cohorts in the current grid cell</param>
        /// <param name="gridCellStocks">The stocks in the current grid cell</param>
        /// <param name="actingCohort">The position of the acting cohort in the jagged array of grid cell cohorts</param>
        /// <param name="cellEnvironment">The environment in the current grid cell</param>
        /// <param name="deltas">The sorted list to track changes in biomass and abundance of the acting cohort in this grid cell</param>
        /// <param name="madingleyCohortDefinitions">The definitions for cohort functional groups in the model</param>
        /// <param name="madingleyStockDefinitions">The definitions for stock functional groups in the model</param>
        /// <param name="currentTimestep">The current model time step</param>
        /// <param name="trackProcesses">An instance of ProcessTracker to hold diagnostics for eating</param>
        /// <param name="partial">Thread-locked variables</param>
        /// <param name="specificLocations">Whether the model is being run for specific locations</param>
        /// <param name="outputDetail">The level of output detail being used for the current model run</param>
        /// <param name="currentMonth">The current model month</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        public void RunEcologicalProcess(GridCellCohortHandler gridCellCohorts,
                                         GridCellStockHandler gridCellStocks, int[] actingCohort,
                                         SortedList <string, double[]> cellEnvironment,
                                         Dictionary <string, Dictionary <string, double> > deltas,
                                         FunctionalGroupDefinitions madingleyCohortDefinitions,
                                         FunctionalGroupDefinitions madingleyStockDefinitions,
                                         uint currentTimestep, ProcessTracker trackProcesses,
                                         ref ThreadLockedParallelVariables partial, Boolean specificLocations,
                                         string outputDetail, uint currentMonth, MadingleyModelInitialisation initialisation)
        {
            PreviousTrophicIndex = gridCellCohorts[actingCohort].TrophicIndex;
            //Reset this cohort's trohic index ready for calculation across its feeding this timetsstep
            gridCellCohorts[actingCohort].TrophicIndex = 0.0;

            // Get the nutrition source (herbivory, carnivory or omnivory) of the acting cohort
            string NutritionSource = madingleyCohortDefinitions.GetTraitNames("Nutrition source", gridCellCohorts[actingCohort].FunctionalGroupIndex);

            // Switch to the appropriate eating process(es) given the cohort's nutrition source
            switch (NutritionSource)
            {
            case "herbivore":

                // Get the assimilation efficiency for herbivory for this cohort from the functional group definitions
                Implementations["revised herbivory"].AssimilationEfficiency =
                    madingleyCohortDefinitions.GetBiologicalPropertyOneFunctionalGroup
                        ("herbivory assimilation", gridCellCohorts[actingCohort].FunctionalGroupIndex);

                // Get the proportion of time spent eating for this cohort from the functional group definitions
                Implementations["revised herbivory"].ProportionTimeEating = gridCellCohorts[actingCohort].ProportionTimeActive;

                // Calculate the potential biomass available from herbivory
                if (cellEnvironment["Realm"][0] == 2.0)
                {
                    Implementations["revised herbivory"].GetEatingPotentialMarine
                        (gridCellCohorts, gridCellStocks, actingCohort,
                        cellEnvironment, madingleyCohortDefinitions, madingleyStockDefinitions);
                }
                else
                {
                    Implementations["revised herbivory"].GetEatingPotentialTerrestrial
                        (gridCellCohorts, gridCellStocks, actingCohort,
                        cellEnvironment, madingleyCohortDefinitions, madingleyStockDefinitions);
                }

                // Run herbivory to apply changes in autotroph biomass from herbivory and add biomass eaten to the delta arrays
                Implementations["revised herbivory"].RunEating
                    (gridCellCohorts, gridCellStocks, actingCohort,
                    cellEnvironment, deltas, madingleyCohortDefinitions,
                    madingleyStockDefinitions, trackProcesses,
                    currentTimestep, specificLocations, outputDetail, initialisation);

                break;

            case "carnivore":

                // Get the assimilation efficiency for predation for this cohort from the functional group definitions
                Implementations["revised predation"].AssimilationEfficiency =
                    madingleyCohortDefinitions.GetBiologicalPropertyOneFunctionalGroup
                        ("carnivory assimilation", gridCellCohorts[actingCohort].FunctionalGroupIndex);

                Implementations["revised predation"].ProportionTimeEating = gridCellCohorts[actingCohort].ProportionTimeActive;

                // Calculate the potential biomass available from predation
                if (cellEnvironment["Realm"][0] == 2.0)
                {
                    Implementations["revised predation"].GetEatingPotentialMarine
                        (gridCellCohorts, gridCellStocks, actingCohort,
                        cellEnvironment, madingleyCohortDefinitions, madingleyStockDefinitions);
                }
                else
                {
                    Implementations["revised predation"].GetEatingPotentialTerrestrial
                        (gridCellCohorts, gridCellStocks, actingCohort,
                        cellEnvironment, madingleyCohortDefinitions, madingleyStockDefinitions);
                }
                // Run predation to apply changes in prey biomass from predation and add biomass eaten to the delta arrays
                Implementations["revised predation"].RunEating
                    (gridCellCohorts, gridCellStocks, actingCohort, cellEnvironment, deltas,
                    madingleyCohortDefinitions, madingleyStockDefinitions, trackProcesses,
                    currentTimestep, specificLocations, outputDetail, initialisation);


                break;

            case "omnivore":

                // Get the assimilation efficiency for predation for this cohort from the functional group definitions
                Implementations["revised predation"].AssimilationEfficiency =
                    madingleyCohortDefinitions.GetBiologicalPropertyOneFunctionalGroup
                        ("carnivory assimilation", gridCellCohorts[actingCohort].FunctionalGroupIndex);

                // Get the assimilation efficiency for herbivory for this cohort from the functional group definitions
                Implementations["revised herbivory"].AssimilationEfficiency =
                    madingleyCohortDefinitions.GetBiologicalPropertyOneFunctionalGroup
                        ("herbivory assimilation", gridCellCohorts[actingCohort].FunctionalGroupIndex);

                // Get the proportion of time spent eating and assign to both the herbivory and predation implementations
                double ProportionTimeEating = gridCellCohorts[actingCohort].ProportionTimeActive;
                Implementations["revised predation"].ProportionTimeEating = ProportionTimeEating;
                Implementations["revised herbivory"].ProportionTimeEating = ProportionTimeEating;

                // Calculate the potential biomass available from herbivory
                if (cellEnvironment["Realm"][0] == 2.0)
                {
                    Implementations["revised herbivory"].GetEatingPotentialMarine
                        (gridCellCohorts, gridCellStocks, actingCohort,
                        cellEnvironment, madingleyCohortDefinitions,
                        madingleyStockDefinitions);
                }
                else
                {
                    Implementations["revised herbivory"].GetEatingPotentialTerrestrial
                        (gridCellCohorts, gridCellStocks, actingCohort,
                        cellEnvironment, madingleyCohortDefinitions,
                        madingleyStockDefinitions);
                }

                // Calculate the potential biomass available from predation
                if (cellEnvironment["Realm"][0] == 2.0)
                {
                    Implementations["revised predation"].GetEatingPotentialMarine
                        (gridCellCohorts, gridCellStocks, actingCohort,
                        cellEnvironment, madingleyCohortDefinitions,
                        madingleyStockDefinitions);
                }
                else
                {
                    Implementations["revised predation"].GetEatingPotentialTerrestrial
                        (gridCellCohorts, gridCellStocks, actingCohort,
                        cellEnvironment, madingleyCohortDefinitions,
                        madingleyStockDefinitions);
                }

                // Calculate the total handling time for all expected kills from predation and expected plant matter eaten in herbivory
                TotalTimeToEatForOmnivores =
                    Implementations["revised herbivory"].TimeUnitsToHandlePotentialFoodItems +
                    Implementations["revised predation"].TimeUnitsToHandlePotentialFoodItems;

                // Assign this total time to the relevant variables in both herbviory and predation, so that actual amounts eaten are calculated correctly
                Implementations["revised herbivory"].TimeUnitsToHandlePotentialFoodItems = TotalTimeToEatForOmnivores;
                Implementations["revised predation"].TimeUnitsToHandlePotentialFoodItems = TotalTimeToEatForOmnivores;

                // Run predation to update prey cohorts and delta biomasses for the acting cohort
                Implementations["revised predation"].RunEating
                    (gridCellCohorts, gridCellStocks, actingCohort,
                    cellEnvironment, deltas, madingleyCohortDefinitions,
                    madingleyStockDefinitions, trackProcesses,
                    currentTimestep, specificLocations, outputDetail, initialisation);

                // Run herbivory to update autotroph biomass and delta biomasses for the acting cohort
                Implementations["revised herbivory"].RunEating
                    (gridCellCohorts, gridCellStocks, actingCohort,
                    cellEnvironment, deltas, madingleyCohortDefinitions,
                    madingleyStockDefinitions, trackProcesses,
                    currentTimestep, specificLocations, outputDetail, initialisation);

                break;

            default:

                // For nutrition source that are not supported, throw an error
                Debug.Fail("The model currently does not contain an eating model for nutrition source:" + NutritionSource);

                break;
            }

            // Check that the biomasses from predation and herbivory in the deltas is a number
            Debug.Assert(!double.IsNaN(deltas["biomass"]["predation"]), "BiomassFromEating is NaN");
            Debug.Assert(!double.IsNaN(deltas["biomass"]["herbivory"]), "BiomassFromEating is NaN");

            double biomassEaten = 0.0;

            if (madingleyCohortDefinitions.GetBiologicalPropertyOneFunctionalGroup("carnivory assimilation",
                                                                                   gridCellCohorts[actingCohort].FunctionalGroupIndex) > 0)
            {
                biomassEaten += (deltas["biomass"]["predation"] / madingleyCohortDefinitions.GetBiologicalPropertyOneFunctionalGroup("carnivory assimilation",
                                                                                                                                     gridCellCohorts[actingCohort].FunctionalGroupIndex));
            }
            if (madingleyCohortDefinitions.GetBiologicalPropertyOneFunctionalGroup("herbivory assimilation",
                                                                                   gridCellCohorts[actingCohort].FunctionalGroupIndex) > 0)
            {
                biomassEaten += (deltas["biomass"]["herbivory"] / madingleyCohortDefinitions.GetBiologicalPropertyOneFunctionalGroup("herbivory assimilation",
                                                                                                                                     gridCellCohorts[actingCohort].FunctionalGroupIndex));
            }

            if (biomassEaten > 0.0)
            {
                gridCellCohorts[actingCohort].TrophicIndex = 1 +
                                                             (gridCellCohorts[actingCohort].TrophicIndex / (biomassEaten * gridCellCohorts[actingCohort].CohortAbundance));
            }
            else
            {
                gridCellCohorts[actingCohort].TrophicIndex = PreviousTrophicIndex;
            }
        }
コード例 #49
0
        /// <summary>
        /// Generates the initial outputs for this model run
        /// </summary>
        /// <param name="outputFilesSuffix">The suffix to be applied to all outputs from this model run</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        /// <param name="month">The current month in the model run</param>
        public void InitialOutputs(string outputFilesSuffix, MadingleyModelInitialisation initialisation, uint month)
        {
            // Set up global outputs for all model runs
            GlobalOutputs.SetupOutputs(NumTimeSteps, EcosystemModelGrid, OutputFilesSuffix);

            // Create initial global outputs
            GlobalOutputs.InitialOutputs(EcosystemModelGrid,CohortFunctionalGroupDefinitions,StockFunctionalGroupDefinitions,_CellList,
                GlobalDiagnosticVariables, initialisation);

            // Temporary
            Boolean varExists;

            if (SpecificLocations)
            {
                for (int i = 0; i < _CellList.Count; i++)
                {
                    // Set up grid cell outputs
                    CellOutputs[i].SetUpOutputs(EcosystemModelGrid, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions,
                        NumTimeSteps, OutputFilesSuffix, _CellList, i, EcosystemModelGrid.GetEnviroLayer("Realm", 0, _CellList[i][0], _CellList[i][1], out varExists) == 2.0);

                    // Create initial grid cell outputs
                    CellOutputs[i].InitialOutputs(EcosystemModelGrid, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions,
                        _CellList, i, GlobalDiagnosticVariables, NumTimeSteps, initialisation, month, EcosystemModelGrid.GetEnviroLayer("Realm", 0, _CellList[i][0], _CellList[i][1], out varExists) == 2.0);
                }
            }
            else
            {
                // Set up grid outputs
                GridOutputs.SetupOutputs(EcosystemModelGrid, OutputFilesSuffix, NumTimeSteps,
                    CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions);

                // Create initial grid outputs
                GridOutputs.InitialOutputs(EcosystemModelGrid, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions, _CellList, initialisation);
            }
        }
コード例 #50
0
ファイル: ModelGrid.cs プロジェクト: mikeharfoot/Madingley
        /// <summary>
        /// Gets a state variable density for specified functional groups of specified entity types in a specified grid cell
        /// </summary>
        /// <param name="variableName">The name of the variable to get: 'biomass' or 'abundance'</param>
        /// <param name="traitValue">The functional group trait value to get data for</param>
        /// <param name="functionalGroups">The functional group indices to get the state variable for</param>
        /// <param name="latCellIndex">The latitudinal index of the cell</param>
        /// <param name="lonCellIndex">The longitudinal index of the cell</param>
        /// <param name="stateVariableType">The type of entity to return the state variable for: 'stock' or 'cohort'</param>
        /// <param name="modelInitialisation">The Madingley Model initialisation</param>
        /// <returns>The state variable density for specified functional groups of specified entity types in a specified grid cell</returns>
        public double GetStateVariableDensity(string variableName, string traitValue, int[] functionalGroups, uint latCellIndex,
                                              uint lonCellIndex, string stateVariableType, MadingleyModelInitialisation modelInitialisation)
        {
            double returnValue = 0.0;

            switch (stateVariableType.ToLower())
            {
            case "cohort":

                GridCellCohortHandler TempCohorts = InternalGrid[latCellIndex, lonCellIndex].GridCellCohorts;

                switch (variableName.ToLower())
                {
                case "biomass":
                    if (traitValue != "Zooplankton (all)")
                    {
                        foreach (int f in functionalGroups)
                        {
                            foreach (var item in TempCohorts[f])
                            {
                                returnValue += ((item.IndividualBodyMass + item.IndividualReproductivePotentialMass) * item.CohortAbundance);
                            }
                        }
                    }
                    else
                    {
                        foreach (int f in functionalGroups)
                        {
                            foreach (var item in TempCohorts[f])
                            {
                                if (item.IndividualBodyMass <= modelInitialisation.PlanktonDispersalThreshold)
                                {
                                    returnValue += ((item.IndividualBodyMass + item.IndividualReproductivePotentialMass) * item.CohortAbundance);
                                }
                            }
                        }
                    }
                    break;

                case "abundance":
                    if (traitValue != "Zooplankton (all)")
                    {
                        foreach (int f in functionalGroups)
                        {
                            foreach (var item in TempCohorts[f])
                            {
                                returnValue += item.CohortAbundance;
                            }
                        }
                    }
                    else
                    {
                        foreach (int f in functionalGroups)
                        {
                            foreach (var item in TempCohorts[f])
                            {
                                if (item.IndividualBodyMass <= modelInitialisation.PlanktonDispersalThreshold)
                                {
                                    returnValue += item.CohortAbundance;
                                }
                            }
                        }
                    }
                    break;

                default:
                    Debug.Fail("For cohorts, state variable name must be either 'biomass' or 'abundance'");
                    break;
                }
                break;

            case "stock":
                GridCellStockHandler TempStocks = InternalGrid[latCellIndex, lonCellIndex].GridCellStocks;

                switch (variableName.ToLower())
                {
                case "biomass":
                    foreach (int f in functionalGroups)
                    {
                        foreach (var item in TempStocks[f])
                        {
                            returnValue += item.TotalBiomass;
                        }
                    }
                    break;

                default:
                    Debug.Fail("For stocks, state variable name must be 'biomass'");
                    break;
                }
                break;

            default:
                Debug.Fail("State variable type must be either 'cohort' or 'stock'");
                break;
            }

            return(returnValue / (InternalGrid[latCellIndex, lonCellIndex].CellEnvironment["Cell Area"][0]));
        }
コード例 #51
0
        /// <summary>
        /// Run processes for cells in parallel
        /// </summary>
        public void RunCellsInParallel(MadingleyModelInitialisation initialisation)
        {
            // Create temporary variables to hold extinctions and productions in the parallel loop;
            int extinctions = 0, productions = 0, combinations = 0;

            if (initialisation.RunRealm == "")
            {
                // Run a parallel loop over rows
                Parallel.For(0, _CellList.Count, () => new ThreadLockedParallelVariables { Extinctions = 0, Productions = 0, Combinations = 0, NextCohortIDThreadLocked = NextCohortID }, (ii, loop, threadTrackedDiagnostics) =>
                {
                    RunCell(ii, threadTrackedDiagnostics, initialisation.DispersalOnly, initialisation);
                    return threadTrackedDiagnostics;
                },
                 (threadTrackedDiagnostics) =>
                 {
                     Interlocked.Add(ref extinctions, threadTrackedDiagnostics.Extinctions);
                     Interlocked.Add(ref productions, threadTrackedDiagnostics.Productions);
                     Interlocked.Add(ref combinations, threadTrackedDiagnostics.Combinations);
                     Interlocked.Exchange(ref NextCohortID, threadTrackedDiagnostics.NextCohortIDThreadLocked);
                 }
                 );

            }
            else
            {

                if (initialisation.RunRealm == "marine")
                {

                    // Run a parallel loop over rows
                    Parallel.For(0, _CellList.Count, () => new ThreadLockedParallelVariables { Extinctions = 0, Productions = 0, Combinations = 0, NextCohortIDThreadLocked = NextCohortID }, (ii, loop, threadTrackedDiagnostics) =>
                    {
                        if (EcosystemModelGrid.GetCellEnvironment(_CellList[ii][0], _CellList[ii][1])["Realm"][0] == 2.0) RunCell(ii, threadTrackedDiagnostics, initialisation.DispersalOnly, initialisation);
                        return threadTrackedDiagnostics;
                    },
                     (threadTrackedDiagnostics) =>
                     {
                         Interlocked.Add(ref extinctions, threadTrackedDiagnostics.Extinctions);
                         Interlocked.Add(ref productions, threadTrackedDiagnostics.Productions);
                         Interlocked.Add(ref combinations, threadTrackedDiagnostics.Combinations);
                         Interlocked.Exchange(ref NextCohortID, threadTrackedDiagnostics.NextCohortIDThreadLocked);
                     }
                     );
                }
                else if (initialisation.RunRealm == "terrestrial")
                {

                    // Run a parallel loop over rows
                    Parallel.For(0, _CellList.Count, () => new ThreadLockedParallelVariables { Extinctions = 0, Productions = 0, Combinations = 0, NextCohortIDThreadLocked = NextCohortID }, (ii, loop, threadTrackedDiagnostics) =>
                    {
                        if (EcosystemModelGrid.GetCellEnvironment(_CellList[ii][0], _CellList[ii][1])["Realm"][0] == 1.0) RunCell(ii, threadTrackedDiagnostics, initialisation.DispersalOnly, initialisation);
                        return threadTrackedDiagnostics;
                    },
                     (threadTrackedDiagnostics) =>
                     {
                         Interlocked.Add(ref extinctions, threadTrackedDiagnostics.Extinctions);
                         Interlocked.Add(ref productions, threadTrackedDiagnostics.Productions);
                         Interlocked.Add(ref combinations, threadTrackedDiagnostics.Combinations);
                         Interlocked.Exchange(ref NextCohortID, threadTrackedDiagnostics.NextCohortIDThreadLocked);
                     }
                     );
                }
                else
                {
                    Console.WriteLine("Run single realm needs to be 'marine', 'terrestrial', or blank");
                    Console.ReadKey();
                }
            }

            Console.WriteLine("\n");

            // Take the results from the thread local variables and apply to the global diagnostic variables
            GlobalDiagnosticVariables["NumberOfCohortsExtinct"] = extinctions - combinations;
            GlobalDiagnosticVariables["NumberOfCohortsProduced"] = productions;
            GlobalDiagnosticVariables["NumberOfCohortsInModel"] = GlobalDiagnosticVariables["NumberOfCohortsInModel"] + productions - extinctions;
            GlobalDiagnosticVariables["NumberOfCohortsCombined"] = combinations;
        }
コード例 #52
0
ファイル: ModelGrid.cs プロジェクト: mikeharfoot/Madingley
        /// <summary>
        /// Return an array of values for a single state variable over specific cells
        /// </summary>
        /// <param name="variableName">Variable name</param>
        /// <param name="traitValue">The trait values of functional groups to get data for</param>
        /// <param name="functionalGroups">A vector of functional group indices to consider</param>
        /// <param name="cellIndices">List of indices of active cells in the model grid</param>
        /// <param name="stateVariableType">A string indicating the type of state variable; 'cohort' or 'stock'</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        /// <returns>Array of state variable values for each grid cell</returns>
        public double[,] GetStateVariableGrid(string variableName, string traitValue, int[] functionalGroups, List <uint[]> cellIndices,
                                              string stateVariableType, MadingleyModelInitialisation initialisation)
        {
            double[,] TempStateVariable = new double[this.NumLatCells, this.NumLonCells];

            switch (variableName.ToLower())
            {
            case "biomass":
                for (int ii = 0; ii < cellIndices.Count; ii++)
                {
                    // Check whether the state variable concerns cohorts or stocks
                    if (stateVariableType.ToLower() == "cohort")
                    {
                        if (traitValue != "Zooplankton")
                        {
                            // Check to make sure that the cell has at least one cohort
                            if (InternalGrid[cellIndices[ii][0], cellIndices[ii][1]].GridCellCohorts != null)
                            {
                                for (int nn = 0; nn < functionalGroups.Length; nn++)
                                {
                                    if (InternalGrid[cellIndices[ii][0], cellIndices[ii][1]].GridCellCohorts[functionalGroups[nn]] != null)
                                    {
                                        foreach (Cohort item in InternalGrid[cellIndices[ii][0], cellIndices[ii][1]].GridCellCohorts[functionalGroups[nn]].ToArray())
                                        {
                                            TempStateVariable[cellIndices[ii][0], cellIndices[ii][1]] += ((item.IndividualBodyMass + item.IndividualReproductivePotentialMass) * item.CohortAbundance);
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            // Check to make sure that the cell has at least one cohort
                            if (InternalGrid[cellIndices[ii][0], cellIndices[ii][1]].GridCellCohorts != null)
                            {
                                for (int nn = 0; nn < functionalGroups.Length; nn++)
                                {
                                    if (InternalGrid[cellIndices[ii][0], cellIndices[ii][1]].GridCellCohorts[functionalGroups[nn]] != null)
                                    {
                                        foreach (Cohort item in InternalGrid[cellIndices[ii][0], cellIndices[ii][1]].GridCellCohorts[functionalGroups[nn]].ToArray())
                                        {
                                            if (item.IndividualBodyMass <= initialisation.PlanktonDispersalThreshold)
                                            {
                                                TempStateVariable[cellIndices[ii][0], cellIndices[ii][1]] += ((item.IndividualBodyMass + item.IndividualReproductivePotentialMass) * item.CohortAbundance);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else if (stateVariableType.ToLower() == "stock")
                    {
                        // Check to make sure that the cell has at least one stock
                        if (InternalGrid[cellIndices[ii][0], cellIndices[ii][1]].GridCellStocks != null)
                        {
                            for (int nn = 0; nn < functionalGroups.Length; nn++)
                            {
                                if (InternalGrid[cellIndices[ii][0], cellIndices[ii][1]].GridCellStocks[functionalGroups[nn]] != null)
                                {
                                    foreach (Stock item in InternalGrid[cellIndices[ii][0], cellIndices[ii][1]].GridCellStocks[functionalGroups[nn]].ToArray())
                                    {
                                        TempStateVariable[cellIndices[ii][0], cellIndices[ii][1]] += (item.TotalBiomass);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        Debug.Fail("Variable 'state variable type' must be either 'stock' 'or 'cohort'");
                    }
                }
                break;

            case "abundance":
                for (int ii = 0; ii < cellIndices.Count; ii++)
                {
                    // Check whether the state variable concerns cohorts or stocks
                    if (stateVariableType.ToLower() == "cohort")
                    {
                        if (traitValue != "Zooplankton")
                        {
                            // Check to make sure that the cell has at least one cohort
                            if (InternalGrid[cellIndices[ii][0], cellIndices[ii][1]].GridCellCohorts != null)
                            {
                                for (int nn = 0; nn < functionalGroups.Length; nn++)
                                {
                                    if (InternalGrid[cellIndices[ii][0], cellIndices[ii][1]].GridCellCohorts[functionalGroups[nn]] != null)
                                    {
                                        foreach (Cohort item in InternalGrid[cellIndices[ii][0], cellIndices[ii][1]].GridCellCohorts[functionalGroups[nn]].ToArray())
                                        {
                                            TempStateVariable[cellIndices[ii][0], cellIndices[ii][1]] += item.CohortAbundance;
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            // Check to make sure that the cell has at least one cohort
                            if (InternalGrid[cellIndices[ii][0], cellIndices[ii][1]].GridCellCohorts != null)
                            {
                                for (int nn = 0; nn < functionalGroups.Length; nn++)
                                {
                                    if (InternalGrid[cellIndices[ii][0], cellIndices[ii][1]].GridCellCohorts[functionalGroups[nn]] != null)
                                    {
                                        foreach (Cohort item in InternalGrid[cellIndices[ii][0], cellIndices[ii][1]].GridCellCohorts[functionalGroups[nn]].ToArray())
                                        {
                                            if (item.IndividualBodyMass <= initialisation.PlanktonDispersalThreshold)
                                            {
                                                TempStateVariable[cellIndices[ii][0], cellIndices[ii][1]] += item.CohortAbundance;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        Debug.Fail("Currently abundance cannot be calculated for grid cell stocks");
                    }
                }
                break;

            default:
                Debug.Fail("Invalid search string passed for cohort property");
                break;
            }

            return(TempStateVariable);
        }
コード例 #53
0
        /// <summary>
        /// Run ecological processes that operate across grid cells
        /// </summary>
        public void RunCrossGridCellEcology(ref uint dispersals, bool dispersalOnly, MadingleyModelInitialisation modelInitialisation)
        {
            // If we are running specific locations, then we do not run dispersal
            if (SpecificLocations != true)
            {
                if (RunGridCellsInParallel)
                {
                    // Loop through each grid cell, and run dispersal for each. Note that because cells essentially run independently, we do not need to thread-lock variables
                    // as they do not exchange information until they are all completed (they basically just build up delta arrays of cohorts to move). However, if cells
                    // should start to exchange information for dispersal, or all contribute to a single centralised variable, then thread-locked parallel variables would
                    // have to be used.
                     Parallel.For(0, _CellList.Count, ii =>
                    {
                        EcologyCrossGridCell TempMadingleyEcologyCrossGridCell = new EcologyCrossGridCell();
                        // Initialise cross grid cell ecology
                        TempMadingleyEcologyCrossGridCell.InitializeCrossGridCellEcology(_GlobalModelTimeStepUnit, DrawRandomly, modelInitialisation);

                        //Initialise the delta for dispersal lists for this grid cell
                        EcosystemModelGrid.DeltaFunctionalGroupDispersalArray[_CellList[ii][0], _CellList[ii][1]] = new List<uint>();
                        EcosystemModelGrid.DeltaCohortNumberDispersalArray[_CellList[ii][0], _CellList[ii][1]] = new List<uint>();
                        EcosystemModelGrid.DeltaCellToDisperseToArray[_CellList[ii][0], _CellList[ii][1]] = new List<uint[]>();

                        EcosystemModelGrid.DeltaCellExitDirection[_CellList[ii][0], _CellList[ii][1]] = new List<uint>();
                        EcosystemModelGrid.DeltaCellEntryDirection[_CellList[ii][0], _CellList[ii][1]] = new List<uint>();

                        // We have looped through individal cells and calculated ecological processes for each. Now do this for cross grid cell processes
                        TempMadingleyEcologyCrossGridCell.RunCrossGridCellEcology(_CellList[ii], EcosystemModelGrid, dispersalOnly,
                            CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions, CurrentMonth);
                    });
                }
                else
                {
                    // Loop through each grid cell, and run dispersal for each.
                    // Note that currently dispersal is not parallelised, although it could be (though care would need to be taken to ensure that necessary variables are thread-locked
                    for (int ii = 0; ii < _CellList.Count; ii++)
                    {
                        //Initialise the delta for dispersal lists for this grid cell
                        EcosystemModelGrid.DeltaFunctionalGroupDispersalArray[_CellList[ii][0], _CellList[ii][1]] = new List<uint>();
                        EcosystemModelGrid.DeltaCohortNumberDispersalArray[_CellList[ii][0], _CellList[ii][1]] = new List<uint>();
                        EcosystemModelGrid.DeltaCellToDisperseToArray[_CellList[ii][0], _CellList[ii][1]] = new List<uint[]>();

                        EcosystemModelGrid.DeltaCellExitDirection[_CellList[ii][0], _CellList[ii][1]] = new List<uint>();
                        EcosystemModelGrid.DeltaCellEntryDirection[_CellList[ii][0], _CellList[ii][1]] = new List<uint>();

                        // We have looped through individal cells and calculated ecological processes for each. Now do this for cross grid cell processes
                        MadingleyEcologyCrossGridCell.RunCrossGridCellEcology(_CellList[ii], EcosystemModelGrid, dispersalOnly,
                            CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions, CurrentMonth);
                    }
                }
                // Apply the changes in the delta arrays from dispersal
                MadingleyEcologyCrossGridCell.UpdateCrossGridCellEcology(EcosystemModelGrid, ref dispersals, TrackCrossCellProcesses, CurrentTimeStep);
            }
        }
コード例 #54
0
ファイル: ModelGrid.cs プロジェクト: mikeharfoot/Madingley
        /// <summary>
        /// Return an array of log(values + 1) for a state variable for particular functional groups over specific cells. State variable (currently only biomass or abundance) must be >= 0 in all grid cells
        /// </summary>
        /// <param name="variableName">The name of the variable</param>
        /// <param name="traitValue">The functional group trait value to get data for</param>
        /// <param name="functionalGroups">A vector of functional group indices to consider</param>
        /// <param name="cellIndices">List of indices of active cells in the model grid</param>
        /// <param name="stateVariableType">A string indicating the type of state variable; 'cohort' or 'stock'</param>
        /// <param name="initialisation">The Madingley Model intialisation</param>
        /// <returns>Array of log(state variable values +1 ) for each grid cell</returns>
        public double[,] GetStateVariableGridLogDensityPerSqKm(string variableName, string traitValue, int[] functionalGroups,
                                                               List <uint[]> cellIndices, string stateVariableType, MadingleyModelInitialisation initialisation)
        {
            double[,] TempStateVariable = new double[this.NumLatCells, this.NumLonCells];
            double CellArea;

            TempStateVariable = this.GetStateVariableGrid(variableName, traitValue, functionalGroups, cellIndices, stateVariableType, initialisation);

            for (int ii = 0; ii < cellIndices.Count; ii++)
            {
                CellArea = GetCellEnvironment(cellIndices[ii][0], cellIndices[ii][1])["Cell Area"][0];
                TempStateVariable[cellIndices[ii][0], cellIndices[ii][1]] /= CellArea;
                TempStateVariable[cellIndices[ii][0], cellIndices[ii][1]]  = Math.Log(TempStateVariable[cellIndices[ii][0], cellIndices[ii][1]] + 1);
            }

            return(TempStateVariable);
        }
コード例 #55
0
        /// <summary>
        /// Sets up the model grid within a Madingley model run
        /// </summary>
        /// <param name="initialisation">An instance of the model initialisation class</param> 
        /// <param name="scenarioParameters">The parameters for the scenarios to run</param>
        /// <param name="scenarioIndex">The index of the scenario that this model is to run</param>
        public void SetUpModelGrid(MadingleyModelInitialisation initialisation,
            ScenarioParameterInitialisation scenarioParameters, int scenarioIndex, int simulation)
        {
            // If the intialisation file contains a column pointing to another file of specific locations, and if this column is not blank then read the
            // file indicated
            if (SpecificLocations)
            {
                // Set up the model grid using these locations
                EcosystemModelGrid = new ModelGrid(BottomLatitude, LeftmostLongitude, TopLatitude, RightmostLongitude,
                    CellSize, CellSize, _CellList, EnviroStack, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions,
                    GlobalDiagnosticVariables, initialisation.TrackProcesses, SpecificLocations, RunGridCellsInParallel,GlobalModelTimeStepUnit);
            }
            else
            {
                _CellList = new List<uint[]>();
                //Switched order so we create cell list first then initialise cells using list rather than grid.

                uint NumLatCells = (uint)((TopLatitude - BottomLatitude) / CellSize);
                uint NumLonCells = (uint)((RightmostLongitude - LeftmostLongitude) / CellSize);

                // Loop over all cells in the model
                for (uint ii = 0; ii < NumLatCells; ii += 1)
                {
                    for (uint jj = 0; jj < NumLonCells; jj += 1)
                    {
                        // Define a vector to hold the pair of latitude and longitude indices for this grid cell
                        uint[] cellIndices = new uint[2];

                        // Add the latitude and longitude indices to this vector
                        cellIndices[0] = ii;
                        cellIndices[1] = jj;

                        // Add the vector to the list of all active grid cells
                        _CellList.Add(cellIndices);

                    }
                }

                EcologyTimer = new StopWatch();
                EcologyTimer.Start();

                // Set up a full model grid (i.e. not for specific locations)
                // Set up the model grid using these locations
                EcosystemModelGrid = new ModelGrid(BottomLatitude, LeftmostLongitude, TopLatitude, RightmostLongitude,
                    CellSize, CellSize, _CellList, EnviroStack, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions,
                    GlobalDiagnosticVariables, initialisation.TrackProcesses, SpecificLocations, RunGridCellsInParallel, GlobalModelTimeStepUnit);

                List<int> cellsToRemove = new List<int>();
                if (initialisation.RunRealm == "terrestrial")
                {
                    for (int ii = 0; ii < _CellList.Count; ii += 1)
                    {
                        if ((EcosystemModelGrid.GetCellEnvironment(_CellList[ii][0], _CellList[ii][1])["Realm"][0] == 2.0) ||
                            (EcosystemModelGrid.GetCellEnvironment(_CellList[ii][0], _CellList[ii][1])["LandSeaMask"][0] == 0.0))
                        {
                            cellsToRemove.Add(ii);
                        }
                    }
                }
                else if (initialisation.RunRealm == "marine")
                {
                    for (int ii = 0; ii < _CellList.Count; ii += 1)
                    {
                        if (EcosystemModelGrid.GetCellEnvironment(_CellList[ii][0], _CellList[ii][1])["Realm"][0] == 1.0)
                        {
                            cellsToRemove.Add(ii);
                        }
                    }
                }

                for (int ii = (cellsToRemove.Count - 1); ii >= 0; ii--)
                {
                    _CellList.RemoveAt(cellsToRemove[ii]);
                }

                EcologyTimer.Stop();
                Console.WriteLine("Time to initialise cells: {0}", EcologyTimer.GetElapsedTimeSecs());

                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Madingley Model memory usage post grid cell seed: {0}", GC.GetTotalMemory(true) / 1E9, " (G Bytes)\n");
                Console.ForegroundColor = ConsoleColor.White;

            }

            if (initialisation.InputState)
            {
                InputModelState = new InputModelState(initialisation.ModelStatePath[simulation],
                    initialisation.ModelStateFilename[simulation],EcosystemModelGrid, _CellList);
            }

            // When the last simulation for the current scenario
            // if ((scenarioParameters.scenarioSimulationsNumber.Count == 1) && (scenarioIndex == scenarioParameters.scenarioSimulationsNumber[scenarioIndex] - 1)) EnviroStack.Clear();
            // Seed stocks and cohorts in the grid cells
            // If input state from output from a previous simulation
            if (initialisation.InputState)
            {
                // Seed grid cell cohort and stocks
                EcosystemModelGrid.SeedGridCellStocksAndCohorts(_CellList, InputModelState, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions);

                //remove cohorts that do not contain any biomass
                foreach (uint[] CellPair in _CellList)
                {

                    GridCellCohortHandler workingGridCellCohorts = EcosystemModelGrid.GetGridCellCohorts(CellPair[0], CellPair[1]);

                    for (int kk = 0; kk < CohortFunctionalGroupDefinitions.GetNumberOfFunctionalGroups(); kk++)
                    {
                        // Loop through each cohort in the functional group
                        for (int ll = (workingGridCellCohorts[kk].Count - 1); ll >= 0; ll--)
                        {
                            // If cohort abundance is less than the extinction threshold then add to the list for extinction
                            if (workingGridCellCohorts[kk][ll].CohortAbundance.CompareTo(0) <= 0 || workingGridCellCohorts[kk][ll].IndividualBodyMass.CompareTo(0.0) == 0)
                            {
                                // Remove the extinct cohort from the list of cohorts
                                workingGridCellCohorts[kk].RemoveAt(ll);
                            }
                        }

                    }
                }

            }
            else
            {
                EcosystemModelGrid.SeedGridCellStocksAndCohorts(_CellList, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions,
                    GlobalDiagnosticVariables, ref NextCohortID, InitialisationFileStrings["OutputDetail"] == "high", DrawRandomly,
                    initialisation.DispersalOnly, InitialisationFileStrings["DispersalOnlyType"], RunGridCellsInParallel);
            }

            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("Madingley Model memory usage pre Collect: {0}", Math.Round(GC.GetTotalMemory(true) / 1E9, 2), " (GBytes)");
            Console.ForegroundColor = ConsoleColor.White;
            GC.Collect();

            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("Madingley Model memory usage post Collect: {0}", Math.Round(GC.GetTotalMemory(true) / 1E9, 5), " (GBytes)\n");
            Console.ForegroundColor = ConsoleColor.White;
        }
        /// <summary>
        /// Constructor for the cell output class
        /// </summary>
        /// <param name="outputDetail">The level of detail to include in the ouputs: 'low', 'medium' or 'high'</param>
        /// <param name="modelInitialisation">Model initialisation object</param>
        /// <param name="cellIndex">The index of the current cell in the list of all cells to run the model for</param>
        public OutputCell(string outputDetail, MadingleyModelInitialisation modelInitialisation, 
            int cellIndex)
        {
            // Set the output path
            _OutputPath = modelInitialisation.OutputPath;

            // Set the initial maximum value for the y-axis of the live display
            MaximumYValue = 1000000;

            // Set the local copy of the mass bin handler from the model initialisation
            _MassBinHandler = modelInitialisation.ModelMassBins;

            // Get the number of mass bins to be used
            MassBinNumber = _MassBinHandler.NumMassBins;

            // Get the specified mass bins
            MassBins = modelInitialisation.ModelMassBins.GetSpecifiedMassBins();

            // Set the output detail level
            if (outputDetail == "low")
                ModelOutputDetail = OutputDetailLevel.Low;
            else if (outputDetail == "medium")
                ModelOutputDetail = OutputDetailLevel.Medium;
            else if (outputDetail == "high")
                ModelOutputDetail = OutputDetailLevel.High;
            else
                Debug.Fail("Specified output detail level is not valid, must be 'low', 'medium' or 'high'");

            // Get whether to track marine specifics
            TrackMarineSpecifics = modelInitialisation.TrackMarineSpecifics;

            // Get whether to track marine specifics
            OutputMetrics = modelInitialisation.OutputMetrics;

            //Initialise the EcosystemMetrics class
            Metrics = new EcosytemMetrics();

            // Initialise the data converter
            DataConverter = new ArraySDSConvert();

            // Initialise the SDS object creator
            SDSCreator = new CreateSDSObject();

            // Initialise the grid viewer
            GridViewer = new ViewGrid();

            // Set the local variable designating whether to display live outputs
            if (modelInitialisation.LiveOutputs)
                LiveOutputs = true;
        }
コード例 #57
0
        /// <summary>
        /// Apply the changes from predation to prey cohorts, and update deltas for the predator cohort
        /// </summary>
        /// <param name="gridCellCohorts">The cohorts in the current grid cell</param>
        /// <param name="gridCellStocks">The stocks in the current grid cell</param>
        /// <param name="actingCohort">The acting cohort</param>
        /// <param name="cellEnvironment">The environment in the current grid cell</param>
        /// <param name="deltas">The sorted list to track changes in biomass and abundance of the acting cohort in this grid cell</param>
        /// <param name="madingleyCohortDefinitions">The functional group definitions for cohorts in the model</param>
        /// <param name="madingleyStockDefinitions">The functional group definitions for stocks in the model</param>
        /// <param name="trackProcesses">An instance of ProcessTracker to hold diagnostics for predation</param>
        /// <param name="currentTimestep">The current model time step</param>
        /// <param name="specificLocations">Whether the model is being run for specific locations</param>
        /// <param name="outputDetail">The level of output detail used in this model run</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        public void RunEating(GridCellCohortHandler gridCellCohorts, GridCellStockHandler gridCellStocks, int[] actingCohort, SortedList<string, double[]>
            cellEnvironment, Dictionary<string, Dictionary<string, double>> deltas, FunctionalGroupDefinitions madingleyCohortDefinitions,
            FunctionalGroupDefinitions madingleyStockDefinitions, ProcessTracker trackProcesses, uint currentTimestep, Boolean specificLocations,
            string outputDetail, MadingleyModelInitialisation initialisation)
        {
            if (trackProcesses.TrackProcesses)
            {
                Track = (RandomNumberGenerator.GetUniform() > 0.975) ? true : false;
            }

            TempDouble = 0.0;

            // Temporary variable to hold the total time spent eating + 1. Saves an extra calculation in CalculateAbundanceEaten
            double TotalTimeUnitsToHandlePlusOne = TimeUnitsToHandlePotentialFoodItems + 1;

            // Loop over potential prey functional groups
            foreach (int FunctionalGroup in _FunctionalGroupIndicesToEat)
            {

                // Loop over cohorts within the functional group
                for (int i = 0; i < NumberCohortsPerFunctionalGroupNoNewCohorts[FunctionalGroup]; i++)
                {
                    // Get the individual body mass of this cohort
                    _BodyMassPrey = gridCellCohorts[FunctionalGroup][i].IndividualBodyMass;

                     // Calculate the actual abundance of prey eaten from this cohort
                    if (gridCellCohorts[FunctionalGroup][i].CohortAbundance > 0)
                    {

                     // Calculate the actual abundance of prey eaten from this cohort
                    _AbundancesEaten[FunctionalGroup][i] = CalculateAbundanceEaten(_PotentialAbundanceEaten[FunctionalGroup][i], _PredatorAbundanceMultipliedByTimeEating,
                        TotalTimeUnitsToHandlePlusOne, gridCellCohorts[FunctionalGroup][i].CohortAbundance);

                    }
                    else
                        _AbundancesEaten[FunctionalGroup][i] = 0;

                    // Remove number of prey eaten from the prey cohort
                    gridCellCohorts[FunctionalGroup][i].CohortAbundance -= _AbundancesEaten[FunctionalGroup][i];

                    gridCellCohorts[actingCohort].TrophicIndex += (_BodyMassPrey + gridCellCohorts[FunctionalGroup][i].IndividualReproductivePotentialMass) * _AbundancesEaten[FunctionalGroup][i] * gridCellCohorts[FunctionalGroup][i].TrophicIndex;

                    // If the process tracker is set and output detail is set to high and the prey cohort has never been merged,
                    // then track its mortality owing to predation
                    if (trackProcesses.TrackProcesses)
                    {
                        if ((outputDetail == "high") && (gridCellCohorts[FunctionalGroup][i].CohortID.Count == 1)
                        && AbundancesEaten[FunctionalGroup][i] > 0)
                        {
                            trackProcesses.RecordMortality((uint)cellEnvironment["LatIndex"][0], (uint)cellEnvironment["LonIndex"][0], gridCellCohorts
                                [FunctionalGroup][i].BirthTimeStep, currentTimestep, gridCellCohorts[FunctionalGroup][i].IndividualBodyMass,
                                gridCellCohorts[FunctionalGroup][i].AdultMass, gridCellCohorts[FunctionalGroup][i].FunctionalGroupIndex,
                                gridCellCohorts[FunctionalGroup][i].CohortID[0], AbundancesEaten[FunctionalGroup][i], "predation");
                        }

                        // If the model is being run for specific locations and if track processes has been specified, then track the mass flow between
                        // prey and predator
                        if (specificLocations)
                        {
                            trackProcesses.RecordPredationMassFlow(currentTimestep, _BodyMassPrey, _BodyMassPredator, _BodyMassPrey *
                                _AbundancesEaten[FunctionalGroup][i]);

                        if (outputDetail == "high")
                            trackProcesses.TrackPredationTrophicFlow((uint)cellEnvironment["LatIndex"][0], (uint)cellEnvironment["LonIndex"][0],
                                gridCellCohorts[FunctionalGroup][i].FunctionalGroupIndex, gridCellCohorts[actingCohort].FunctionalGroupIndex,
                                madingleyCohortDefinitions, (_AbundancesEaten[FunctionalGroup][i] * _BodyMassPrey), _BodyMassPredator, _BodyMassPrey,
                                initialisation, cellEnvironment["Realm"][0] == 2.0);

                        }

                    }

                    // Check that the abundance eaten from this cohort is not negative
                    // Commented out for the purposes of speed
                    //Debug.Assert( _AbundancesEaten[FunctionalGroup][i].CompareTo(0.0) >= 0,
                    //     "Predation negative for this prey cohort" + actingCohort);

                    // Create a temporary value to speed up the predation function
                    // This is equivalent to the body mass of the prey cohort including reproductive potential mass, times the abundance eaten of the prey cohort,
                    // divided by the abundance of the predator
                    TempDouble += (_BodyMassPrey + gridCellCohorts[FunctionalGroup][i].IndividualReproductivePotentialMass) * _AbundancesEaten[FunctionalGroup][i] / _AbundancePredator;

                }
            }

            // Add the biomass eaten and assimilated by an individual to the delta biomass for the acting (predator) cohort
            deltas["biomass"]["predation"] = TempDouble * _PredatorAssimilationEfficiency;

            // Move the biomass eaten but not assimilated by an individual into the organic matter pool
            deltas["organicpool"]["predation"] = TempDouble * _PredatorNonAssimilation * _AbundancePredator;

            // Check that the delta biomass from eating for the acting cohort is not negative
            //Debug.Assert(deltas["biomass"]["predation"] >= 0, "Predation yields negative biomass");

            // Calculate the total biomass eaten by the acting (predator) cohort
            _TotalBiomassEatenByCohort = deltas["biomass"]["predation"] * _AbundancePredator;
        }
        /// <summary>
        /// Write to the output file values of the output variables at the end of the model run
        /// </summary>
        /// <param name="EcosystemModelGrid">The model grid to get data from</param>
        /// <param name="CohortFunctionalGroupDefinitions">Definitions of the cohort functional groups in the model</param>
        /// <param name="StockFunctionalGroupDefinitions">Definitions of the stock functional groups in the model</param>
        /// <param name="cellIndices">List of indices of active cells in the model grid</param>
        /// <param name="cellNumber">The number of the current cell in the list of indices of active cells</param>
        /// <param name="GlobalDiagnosticVariables">List of global diagnostic variables</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        /// <param name="month">The current month in the model run</param>
        /// <param name="marineCell">Whether the current cell is a marine cell</param>
        public void FinalOutputs(ModelGrid EcosystemModelGrid, FunctionalGroupDefinitions CohortFunctionalGroupDefinitions, 
            FunctionalGroupDefinitions StockFunctionalGroupDefinitions, List<uint[]> cellIndices, int cellNumber, 
            SortedList<string, double> GlobalDiagnosticVariables, MadingleyModelInitialisation initialisation, uint month, Boolean marineCell)
        {
            // Calculate output variables
            CalculateOutputs(EcosystemModelGrid, CohortFunctionalGroupDefinitions, StockFunctionalGroupDefinitions, cellIndices,cellNumber, GlobalDiagnosticVariables, initialisation, month, marineCell);

            // Dispose of the dataset objects
            BasicOutputMemory.Clone("msds:nc?file="+ _OutputPath + "BasicOutputs" + _OutputSuffix + ".nc&openMode=create");
            BasicOutputMemory.Dispose();

            if (LiveOutputs)
            {
                DataSetToViewLive.Dispose();
            }

            if (ModelOutputDetail == OutputDetailLevel.High)
            {
                // Dispose of the dataset objects for high detail level outputs
                MassBinsOutputMemory.Clone("msds:nc?file="+ _OutputPath + "MassBinsOutputs" + _OutputSuffix + ".nc&openMode=create");
                MassBinsOutputMemory.Dispose();

                TrackedCohortsOutputMemory.Clone("msds:nc?file="+ _OutputPath + "TrackedCohortsOutputs" + _OutputSuffix + ".nc&openMode=create");
                TrackedCohortsOutputMemory.Dispose();

            }

            Metrics.CloseRserve();
        }
        /// <summary>
        /// Write to the output file values of the output variables before the first time step
        /// </summary>
        /// <param name="ecosystemModelGrid">The model grid to get data from</param>C:\madingley-ecosystem-model\Madingley\Output and tracking\PredationTracker.cs
        /// <param name="cohortFunctionalGroupDefinitions">The definitions of cohort functional groups in the model</param>
        /// <param name="stockFunctionalGroupDefinitions">The definitions of stock functional groups in the model</param>
        /// <param name="cellIndices">List of indices of active cells in the model grid</param>
        /// <param name="cellNumber">The number of the current cell in the list of indices of active cells</param>
        /// <param name="globalDiagnosticVariables">List of global diagnostic variables</param>
        /// <param name="numTimeSteps">The number of time steps in the model run</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        /// <param name="month">The current month in the model run</param>
        /// <param name="marineCell">Whether the current cell is a marine cell</param>
        public void InitialOutputs(ModelGrid ecosystemModelGrid, FunctionalGroupDefinitions cohortFunctionalGroupDefinitions,
            FunctionalGroupDefinitions stockFunctionalGroupDefinitions, List<uint[]> cellIndices, int cellNumber,
            SortedList<string, double> globalDiagnosticVariables, uint numTimeSteps, MadingleyModelInitialisation initialisation, 
            uint month, Boolean marineCell)
        {
            // Calculate values of the output variables to be used
            CalculateOutputs(ecosystemModelGrid, cohortFunctionalGroupDefinitions, stockFunctionalGroupDefinitions, cellIndices, cellNumber, globalDiagnosticVariables, initialisation, month, marineCell);

            // Generate the intial live outputs
            if (LiveOutputs)
            {
                InitialLiveOutputs(ecosystemModelGrid, marineCell);
            }
            // Generate the intial file outputs
            InitialFileOutputs(ecosystemModelGrid, cohortFunctionalGroupDefinitions, marineCell,cellIndices,cellNumber);
        }
        /// <summary>
        /// Run mortality
        /// </summary>
        /// <param name="gridCellCohorts">The cohorts in the current grid cell</param>
        /// <param name="gridCellStocks">The stocks in the current grid cell</param>
        /// <param name="actingCohort">The position of the acting cohort in the jagged array of grid cell cohorts</param>
        /// <param name="cellEnvironment">The environment in the current grid cell</param>
        /// <param name="deltas">The sorted list to track changes in biomass and abundance of the acting cohort in this grid cell</param>
        /// <param name="madingleyCohortDefinitions">The definitions for cohort functional groups in the model</param>
        /// <param name="madingleyStockDefinitions">The definitions for stock functional groups in the model</param>
        /// <param name="currentTimestep">The current model time step</param>
        /// <param name="trackProcesses">An instance of ProcessTracker to hold diagnostics for mortality</param>
        /// <param name="partial">Thread-locked variables</param>
        /// <param name="specificLocations">Whether the model is being run for specific locations</param>
        /// <param name="outputDetail">The level output detail being used for the current model run</param>
        /// <param name="currentMonth">The current model month</param>
        /// <param name="initialisation">The Madingley Model initialisation</param>
        public void RunEcologicalProcess(GridCellCohortHandler gridCellCohorts, GridCellStockHandler gridCellStocks,
                                         int[] actingCohort, SortedList <string, double[]> cellEnvironment, Dictionary <string, Dictionary <string, double> > deltas,
                                         FunctionalGroupDefinitions madingleyCohortDefinitions, FunctionalGroupDefinitions madingleyStockDefinitions,
                                         uint currentTimestep, ProcessTracker trackProcesses, ref ThreadLockedParallelVariables partial,
                                         Boolean specificLocations, string outputDetail, uint currentMonth, MadingleyModelInitialisation initialisation)
        {
            // Variables to hold the mortality rates
            double MortalityRateBackground;
            double MortalityRateSenescence;
            double MortalityRateStarvation;

            // Variable to hold the total abundance lost to all forms of mortality
            double MortalityTotal;

            // Individual body mass including change this time step as a result of other ecological processes
            double BodyMassIncludingChangeThisTimeStep;

            // Individual reproductive mass including change this time step as a result of other ecological processes
            double ReproductiveMassIncludingChangeThisTimeStep;

            // Calculate the body mass of individuals in this cohort including mass gained through eating this time step, up to but not exceeding adult body mass for this cohort.
            // Should be fine because these deductions are made in the reproduction implementation, but use Math.Min to double check.

            BodyMassIncludingChangeThisTimeStep = 0.0;

            // Loop over all items in the biomass deltas
            foreach (var Biomass in deltas["biomass"])
            {
                // Add the delta biomass to net biomass
                BodyMassIncludingChangeThisTimeStep += Biomass.Value;
            }
            BodyMassIncludingChangeThisTimeStep = Math.Min(gridCellCohorts[actingCohort].AdultMass, BodyMassIncludingChangeThisTimeStep + gridCellCohorts[actingCohort].IndividualBodyMass);

            // Temporary variable to hold net reproductive biomass change of individuals in this cohort as a result of other ecological processes
            ReproductiveMassIncludingChangeThisTimeStep = 0.0;

            // Loop over all items in the biomass deltas
            foreach (var Biomass in deltas["reproductivebiomass"])
            {
                // Add the delta biomass to net biomass
                ReproductiveMassIncludingChangeThisTimeStep += Biomass.Value;
            }

            ReproductiveMassIncludingChangeThisTimeStep += gridCellCohorts[actingCohort].IndividualReproductivePotentialMass;

            // Check to see if the cohort has already been killed by predation etc
            if ((BodyMassIncludingChangeThisTimeStep).CompareTo(0.0) <= 0)
            {
                // If individual body mass is not greater than zero, then all individuals become extinct
                MortalityTotal = gridCellCohorts[actingCohort].CohortAbundance;
            }
            else
            {
                // Calculate background mortality rate
                MortalityRateBackground = Implementations["basic background mortality"].CalculateMortalityRate(gridCellCohorts,
                                                                                                               actingCohort, BodyMassIncludingChangeThisTimeStep, deltas, currentTimestep);

                // If the cohort has matured, then calculate senescence mortality rate, otherwise set rate to zero
                if (gridCellCohorts[actingCohort].MaturityTimeStep != uint.MaxValue)
                {
                    MortalityRateSenescence = Implementations["basic senescence mortality"].CalculateMortalityRate(gridCellCohorts,
                                                                                                                   actingCohort, BodyMassIncludingChangeThisTimeStep, deltas, currentTimestep);
                }
                else
                {
                    MortalityRateSenescence = 0.0;
                }

                // Calculate the starvation mortality rate based on individual body mass and maximum body mass ever
                // achieved by this cohort
                MortalityRateStarvation = Implementations["basic starvation mortality"].CalculateMortalityRate(gridCellCohorts, actingCohort, BodyMassIncludingChangeThisTimeStep, deltas, currentTimestep);

                // Calculate the number of individuals that suffer mortality this time step from all sources of mortality
                MortalityTotal = (1 - Math.Exp(-MortalityRateBackground - MortalityRateSenescence -
                                               MortalityRateStarvation)) * gridCellCohorts[actingCohort].CohortAbundance;
            }

            // If the process tracker is on and output detail is set to high and this cohort has not been merged yet, then record
            // the number of individuals that have died
            if (trackProcesses.TrackProcesses && (outputDetail == "high") && (!gridCellCohorts[actingCohort].Merged))
            {
                trackProcesses.RecordMortality((uint)cellEnvironment["LatIndex"][0], (uint)cellEnvironment["LonIndex"][0], gridCellCohorts[actingCohort].BirthTimeStep,
                                               currentTimestep, gridCellCohorts[actingCohort].IndividualBodyMass, gridCellCohorts[actingCohort].AdultMass,
                                               gridCellCohorts[actingCohort].FunctionalGroupIndex,
                                               gridCellCohorts[actingCohort].CohortID[0], MortalityTotal, "sen/bg/starv");
            }

            // Remove individuals that have died from the delta abundance for this cohort
            deltas["abundance"]["mortality"] = -MortalityTotal;

            // Add the biomass of individuals that have died to the delta biomass in the organic pool (including reproductive
            // potential mass, and mass gained through eating, and excluding mass lost through metabolism)
            deltas["organicpool"]["mortality"] = MortalityTotal * (BodyMassIncludingChangeThisTimeStep + ReproductiveMassIncludingChangeThisTimeStep);
        }