/// <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); } }
/// <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); }