/// <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);
        }
        /// <summary>
        /// Apply all updates from the ecological processes to the properties of the acting cohort and to the environment
        /// </summary>
        public void UpdateAllCrossGridCellEcology(ModelGrid madingleyModelGrid, ref uint dispersalCounter, CrossCellProcessTracker trackCrossCellProcesses, uint currentTimeStep)
        {
            // Create an array to hold the number of cohorts dispersing in each direction from each grid cell
            uint[, ,] InboundCohorts = new uint[madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(0), madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(1), 8];

            // Create an array to hold the number of cohorts dispersing in each direction to each grid cell
            uint[, ,] OutboundCohorts = new uint[madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(0), madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(1), 8];

            // Create an list array to hold the weights of cohorts dispersing from grid cell. Dimensions are: num grid cells lon, num grid cells lat, num cohorts dispersing
            List <double>[,] OutboundCohortWeights = new List <double> [madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(0), madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(1)];

            for (uint ii = 0; ii < madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(0); ii++)
            {
                for (uint jj = 0; jj < madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(1); jj++)
                {
                    OutboundCohortWeights[ii, jj] = new List <double>();
                }
            }

            // Loop through the delta array that holds the grid cells of the cohorts that are flagged as needing to be moved
            for (uint ii = 0; ii < madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(0); ii++)
            {
                for (uint jj = 0; jj < madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(1); jj++)
                {
                    // No cohorts to move if there are none in the delta dispersal array
                    if (madingleyModelGrid.DeltaFunctionalGroupDispersalArray[ii, jj].Count == 0)
                    {
                    }
                    // Otherwise, loop through the cohorts and change the pointers/references to them one-by-one
                    else
                    {
                        for (int kk = 0; kk < madingleyModelGrid.DeltaFunctionalGroupDispersalArray[ii, jj].Count; kk++)
                        {
                            // Find out which grid cell it is going to
                            uint[] CellToDisperseTo = madingleyModelGrid.DeltaCellToDisperseToArray[ii, jj].ElementAt(kk);

                            // Functional group is identified by the first array
                            uint CohortToDisperseFG = madingleyModelGrid.DeltaFunctionalGroupDispersalArray[ii, jj].ElementAt(kk);

                            // Cohort number is identified by the second array
                            uint CohortToDisperseNum = madingleyModelGrid.DeltaCohortNumberDispersalArray[ii, jj].ElementAt(kk);

                            // If track processes is on, add this to the list of inbound and outbound cohorts
                            if (trackCrossCellProcesses.TrackCrossCellProcesses)
                            {
                                WriteOutCrossGridCell(madingleyModelGrid, CellToDisperseTo, InboundCohorts, OutboundCohorts, OutboundCohortWeights, ii, jj,
                                                      CohortToDisperseFG, CohortToDisperseNum, madingleyModelGrid.DeltaCellExitDirection[ii, jj].ElementAt(kk),
                                                      madingleyModelGrid.DeltaCellEntryDirection[ii, jj].ElementAt(kk));
                            }

                            // Simmply add it to the existing cohorts in that FG in the grid cell to disperse to
                            madingleyModelGrid.AddNewCohortToGridCell(CellToDisperseTo[0], CellToDisperseTo[1], (int)CohortToDisperseFG, madingleyModelGrid.GetGridCellIndividualCohort(ii, jj, (int)CohortToDisperseFG, (int)CohortToDisperseNum));

                            // Update the dispersal counter
                            dispersalCounter++;

                            // So now there is a pointer in the grid cell to which it is going. We have to delete the pointers in the original cell and in the
                            // delta array, but we need to do this without messing with the list structure; i.e. wait until all cohorts have been moved
                        }
                    }
                }
            }

            // Reset the delta arrays and remove the pointers to the cohorts in the original list
            for (uint ii = 0; ii < madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(0); ii++)
            {
                for (uint jj = 0; jj < madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(1); jj++)
                {
                    // No cohorts to move if there are none in the delta dispersal array
                    if (madingleyModelGrid.DeltaFunctionalGroupDispersalArray[ii, jj].Count == 0)
                    {
                    }
                    // Otherwise, loop through the cohorts and change the pointers/references to them one-by-one
                    else
                    {
                        // Delete the cohorts from the original grid cell. Note that this needs to be done carefully to ensure that the correct ones
                        // are deleted (lists shift about when an internal element is deleted.
                        madingleyModelGrid.DeleteGridCellIndividualCohorts(ii, jj, madingleyModelGrid.DeltaFunctionalGroupDispersalArray[ii, jj], madingleyModelGrid.DeltaCohortNumberDispersalArray[ii, jj]);

                        // Reset the lists in the delta dispersal arrays
                        madingleyModelGrid.DeltaFunctionalGroupDispersalArray[ii, jj] = new List <uint>();
                        madingleyModelGrid.DeltaCohortNumberDispersalArray[ii, jj]    = new List <uint>();

                        // Reset the list in the grid cells to disperse to array
                        madingleyModelGrid.DeltaCellToDisperseToArray[ii, jj] = new List <uint[]>();

                        // Reset the lists in the delta dispersal arrays
                        madingleyModelGrid.DeltaCellExitDirection[ii, jj]  = new List <uint>();
                        madingleyModelGrid.DeltaCellEntryDirection[ii, jj] = new List <uint>();
                    }
                }
            }

            if (trackCrossCellProcesses.TrackCrossCellProcesses)
            {
                // If we are tracking dispersal, then write out how many cohorts have moved to a file
                trackCrossCellProcesses.RecordDispersalForACell(InboundCohorts, OutboundCohorts, OutboundCohortWeights, currentTimeStep, madingleyModelGrid);
            }
        }
        /// <summary>
        /// Apply all updates from the ecological processes to the properties of the acting cohort and to the environment
        /// </summary>
        public void UpdateAllCrossGridCellEcology(ModelGrid madingleyModelGrid, ref uint dispersalCounter, CrossCellProcessTracker trackCrossCellProcesses, uint currentTimeStep)
        {
            // Create an array to hold the number of cohorts dispersing in each direction from each grid cell
                uint[, ,] InboundCohorts = new uint[madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(0), madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(1), 8];

                // Create an array to hold the number of cohorts dispersing in each direction to each grid cell
                uint[, ,] OutboundCohorts = new uint[madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(0), madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(1), 8];

                // Create an list array to hold the weights of cohorts dispersing from grid cell. Dimensions are: num grid cells lon, num grid cells lat, num cohorts dispersing
                List<double>[,] OutboundCohortWeights = new List<double>[madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(0), madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(1)];

                for (uint ii = 0; ii < madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(0); ii++)
                {
                    for (uint jj = 0; jj < madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(1); jj++)
                    {
                        OutboundCohortWeights[ii,jj] = new List<double>();
                    }
                }

            // Loop through the delta array that holds the grid cells of the cohorts that are flagged as needing to be moved
            for (uint ii = 0; ii < madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(0) ; ii++)
            {
                for (uint jj = 0; jj < madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(1); jj++)
                {
                    if (madingleyModelGrid.DeltaFunctionalGroupDispersalArray[ii, jj] != null)
                    {

                        // No cohorts to move if there are none in the delta dispersal array
                        if (madingleyModelGrid.DeltaFunctionalGroupDispersalArray[ii, jj].Count == 0)
                        {
                        }
                        // Otherwise, loop through the cohorts and change the pointers/references to them one-by-one
                        else
                        {

                            for (int kk = 0; kk < madingleyModelGrid.DeltaFunctionalGroupDispersalArray[ii, jj].Count; kk++)
                            {
                                // Find out which grid cell it is going to
                                uint[] CellToDisperseTo = madingleyModelGrid.DeltaCellToDisperseToArray[ii, jj].ElementAt(kk);

                                // Functional group is identified by the first array
                                uint CohortToDisperseFG = madingleyModelGrid.DeltaFunctionalGroupDispersalArray[ii, jj].ElementAt(kk);

                                // Cohort number is identified by the second array
                                uint CohortToDisperseNum = madingleyModelGrid.DeltaCohortNumberDispersalArray[ii, jj].ElementAt(kk);

                                // If track processes is on, add this to the list of inbound and outbound cohorts
                                if (trackCrossCellProcesses.TrackCrossCellProcesses)
                                {
                                    WriteOutCrossGridCell(madingleyModelGrid, CellToDisperseTo, InboundCohorts, OutboundCohorts, OutboundCohortWeights, ii, jj,
                                        CohortToDisperseFG, CohortToDisperseNum, madingleyModelGrid.DeltaCellExitDirection[ii, jj].ElementAt(kk),
                                        madingleyModelGrid.DeltaCellEntryDirection[ii, jj].ElementAt(kk));
                                }

                                // Simmply add it to the existing cohorts in that FG in the grid cell to disperse to
                                madingleyModelGrid.AddNewCohortToGridCell(CellToDisperseTo[0], CellToDisperseTo[1], (int)CohortToDisperseFG, madingleyModelGrid.GetGridCellIndividualCohort(ii, jj, (int)CohortToDisperseFG, (int)CohortToDisperseNum));

                                // Update the dispersal counter
                                dispersalCounter++;

                                // So now there is a pointer in the grid cell to which it is going. We have to delete the pointers in the original cell and in the
                                // delta array, but we need to do this without messing with the list structure; i.e. wait until all cohorts have been moved
                            }
                        }
                    }

                }
            }

            // Reset the delta arrays and remove the pointers to the cohorts in the original list
            for (uint ii = 0; ii < madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(0); ii++)
            {
                for (uint jj = 0; jj < madingleyModelGrid.DeltaFunctionalGroupDispersalArray.GetLength(1); jj++)
                {
                    if (madingleyModelGrid.DeltaFunctionalGroupDispersalArray[ii, jj] != null)
                    {
                        // No cohorts to move if there are none in the delta dispersal array
                        if (madingleyModelGrid.DeltaFunctionalGroupDispersalArray[ii, jj].Count == 0)
                        {
                        }
                        // Otherwise, loop through the cohorts and change the pointers/references to them one-by-one
                        else
                        {
                            // Delete the cohorts from the original grid cell. Note that this needs to be done carefully to ensure that the correct ones
                            // are deleted (lists shift about when an internal element is deleted.
                            madingleyModelGrid.DeleteGridCellIndividualCohorts(ii, jj, madingleyModelGrid.DeltaFunctionalGroupDispersalArray[ii, jj], madingleyModelGrid.DeltaCohortNumberDispersalArray[ii, jj]);

                            // Reset the lists in the delta dispersal arrays
                            madingleyModelGrid.DeltaFunctionalGroupDispersalArray[ii, jj] = new List<uint>();
                            madingleyModelGrid.DeltaCohortNumberDispersalArray[ii, jj] = new List<uint>();

                            // Reset the list in the grid cells to disperse to array
                            madingleyModelGrid.DeltaCellToDisperseToArray[ii, jj] = new List<uint[]>();

                            // Reset the lists in the delta dispersal arrays
                            madingleyModelGrid.DeltaCellExitDirection[ii, jj] = new List<uint>();
                            madingleyModelGrid.DeltaCellEntryDirection[ii, jj] = new List<uint>();
                        }
                    }

                }
            }

            if (trackCrossCellProcesses.TrackCrossCellProcesses)
            {
                // If we are tracking dispersal, then write out how many cohorts have moved to a file
                trackCrossCellProcesses.RecordDispersalForACell(InboundCohorts, OutboundCohorts, OutboundCohortWeights, currentTimeStep, madingleyModelGrid);
            }
        }
Ejemplo n.º 4
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);
#endif

            // Set up the model grid
#if true
            this._CellList = initialisation.CellList.ToList();
            SetUpModelGrid(initialisation);
            EcosystemModelGrid.SetGridCells(gridCells, this._CellList);
#else
            SetUpModelGrid(initialisation, scenarioParameters, scenarioIndex, simulation);
#endif

            // 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 time step timer
            TimeStepTimer = new StopWatch();
            EcologyTimer = new StopWatch();
            OutputTimer = new StopWatch();

            // Set the global model time step unit
            _GlobalModelTimeStepUnit = globalModelTimeStepUnit;
        }
 /// <summary>
 /// Update the properties of all cohorts across all grid cells
 /// </summary>
 public void UpdateCrossGridCellEcology(ModelGrid madingleyModelGrid, ref uint dispersalCounter, CrossCellProcessTracker trackCrossCellProcesses, uint currentTimeStep)
 {
     // Apply the results of cross-cell ecological processes
     ApplyCrossGridCellEcologicalProcessResults.UpdateAllCrossGridCellEcology(madingleyModelGrid, ref dispersalCounter, trackCrossCellProcesses, currentTimeStep);
 }