private void CheckDensityDrivenDispersal(ModelGrid gridForDispersal, uint latIndex, uint lonIndex, Cohort cohortToDisperse, int functionalGroup, int cohortNumber)
        {
            // Check the population density
            double NumberOfIndividuals = cohortToDisperse.CohortAbundance;

            // Get the cell area, in kilometres squared
            double CellArea = gridForDispersal.GetCellEnvironment(latIndex, lonIndex)["Cell Area"][0];

            // If below the density threshold
            if ((NumberOfIndividuals / CellArea) < _DensityThresholdScaling / cohortToDisperse.AdultMass)
            {
                // Temporary variables to keep track of directions in which cohorts enter/exit cells during the multiple advection steps per time step
                uint ExitDirection  = new uint();
                uint EntryDirection = new uint();
                ExitDirection = 9999;

                // Check to see if it disperses (based on the same movement scaling as used in diffusive movement)
                // Calculate dispersal speed for that cohort
                double DispersalSpeed = CalculateDispersalSpeed(cohortToDisperse.IndividualBodyMass);

                // Cohort tries to disperse
                double[] DispersalArray = CalculateDispersalProbability(gridForDispersal, latIndex, lonIndex, CalculateDispersalSpeed(cohortToDisperse.AdultMass));

                double CohortDispersed = CheckForDispersal(DispersalArray[0]);

                if (CohortDispersed > 0)
                {
                    uint[] DestinationCell = CellToDisperseTo(gridForDispersal, latIndex, lonIndex, DispersalArray, DispersalArray[0], DispersalArray[4], DispersalArray[5], ref ExitDirection, ref EntryDirection);

                    // Update the delta array of cells to disperse to, if the cohort moves
                    if (DestinationCell[0] < 999999)
                    {
                        // Update the delta array of cohorts
                        gridForDispersal.DeltaFunctionalGroupDispersalArray[latIndex, lonIndex].Add((uint)functionalGroup);
                        gridForDispersal.DeltaCohortNumberDispersalArray[latIndex, lonIndex].Add((uint)cohortNumber);

                        // Update the delta array of cells to disperse to
                        gridForDispersal.DeltaCellToDisperseToArray[latIndex, lonIndex].Add(DestinationCell);

                        // Update the delta array of exit and entry directions
                        gridForDispersal.DeltaCellExitDirection[latIndex, lonIndex].Add(ExitDirection);
                        gridForDispersal.DeltaCellEntryDirection[latIndex, lonIndex].Add(EntryDirection);
                    }
                }
            }
        }
        /// <summary>
        /// Calculates the probability of responsive dispersal given average individual dispersal speed and grid cell
        /// </summary>
        /// <param name="madingleyGrid">The model grid</param>
        /// <param name="latIndex">The latitude index of the grid cell to check for dispersal</param>
        /// <param name="lonIndex">The longitude index of the grid cell to check for dispersal</param>
        /// <param name="dispersalSpeed">The average dispersal speed of individuals in the acting cohort</param>
        /// <returns>A six element array.
        /// The first element is the probability of dispersal.
        /// The second element is the probability of dispersing in the u (longitudinal) direction
        /// The third element is the probability of dispersing in the v (latitudinal) direction
        /// The fourth element is the probability of dispersing in the diagonal direction
        /// The fifth element is the u velocity
        /// The sixth element is the v velocity
        /// Note that the second, third, and fourth elements are always positive; thus, they do not indicate 'direction' in terms of dispersal.</returns>
        protected double[] CalculateDispersalProbability(ModelGrid madingleyGrid, uint latIndex, uint lonIndex, double dispersalSpeed)
        {
            double LatCellLength = madingleyGrid.CellHeightsKm[latIndex];
            double LonCellLength = madingleyGrid.CellWidthsKm[latIndex];

            // Pick a direction at random
            double RandomDirection = RandomNumberGenerator.GetUniform() * 2 * Math.PI;

            // Calculate the u and v components given the dispersal speed
            double uSpeed = dispersalSpeed * Math.Cos(RandomDirection);
            double vSpeed = dispersalSpeed * Math.Sin(RandomDirection);

            // Check that the whole cell hasn't moved out (i.e. that dispersal speed is not greater than cell length).
            // This could happen if dispersal speed was high enough; indicates a need to adjust the time step, or to slow dispersal
            if ((uSpeed > LonCellLength) || (vSpeed > LatCellLength))
            {
                Debug.Fail("Dispersal probability should always be <= 1");
            }

            // Calculate the area of the grid cell that is now outside in the diagonal direction
            double AreaOutsideBoth = Math.Abs(uSpeed * vSpeed);

            // Calculate the area of the grid cell that is now outside in the u direction (not including the diagonal)
            double AreaOutsideU = Math.Abs(uSpeed * LatCellLength) - AreaOutsideBoth;

            // Calculate the proportion of the grid cell that is outside in the v direction (not including the diagonal
            double AreaOutsideV = Math.Abs(vSpeed * LonCellLength) - AreaOutsideBoth;

            // Get the cell area, in kilometres squared
            double CellArea = madingleyGrid.GetCellEnvironment(latIndex, lonIndex)["Cell Area"][0];

            // Convert areas to a probability
            double DispersalProbability = (AreaOutsideU + AreaOutsideV + AreaOutsideBoth) / CellArea;

            // Check that we don't have any issues
            if (DispersalProbability > 1)
            {
                //Debug.Fail("Dispersal probability should always be <= 1");
                DispersalProbability = 1.0;
            }

            double[] NewArray = { DispersalProbability, AreaOutsideU / CellArea, AreaOutsideV / CellArea, AreaOutsideBoth / CellArea, uSpeed, vSpeed };

            return(NewArray);
        }
コード例 #3
0
        /// <summary>
        /// Initializes the ecosystem model
        /// </summary>
        /// <param name="mmi">An instance of the model initialisation class</param> 
        public static void Load(Tuple<Madingley.Common.Environment, SortedList<string, EnviroData>> mmi, bool readData)
        {
            var e = mmi.Item1;

            if (e.SpecificLocations == false)
            {
                var CellList = new List<Tuple<int, int>>();

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

                // Loop over all cells in the model
                for (int latitudeIndex = 0; latitudeIndex < NumLatCells; latitudeIndex++)
                {
                    for (int longitudeIndex = 0; longitudeIndex < NumLonCells; longitudeIndex++)
                    {
                        // Add the vector to the list of all active grid cells
                        CellList.Add(Tuple.Create(latitudeIndex, longitudeIndex));
                    }
                }

                e.FocusCells = CellList;
            }

            if (readData)
            {
                var cellList = e.FocusCells.Select(a => new UInt32[] { (uint)a.Item1, (uint)a.Item2 }).ToList();

                var EcosystemModelGrid = new ModelGrid((float)e.BottomLatitude, (float)e.LeftmostLongitude, (float)e.TopLatitude, (float)e.RightmostLongitude,
                    (float)e.CellSize, (float)e.CellSize, cellList, mmi.Item2,
                    e.SpecificLocations);

                Func<Tuple<int, int>, IDictionary<string, double[]>> convertCellEnvironment =
                    cell =>
                    {
                        var env = EcosystemModelGrid.GetCellEnvironment((uint)cell.Item1, (uint)cell.Item2);

                        return env.ToDictionary(kv => kv.Key, kv => kv.Value.ToArray());
                    };

                e.CellEnvironment = e.FocusCells.Select(convertCellEnvironment).ToList();
            }
        }
コード例 #4
0
        /// <summary>
        /// Initializes the ecosystem model
        /// </summary>
        /// <param name="mmi">An instance of the model initialisation class</param>
        public static void Load(Tuple <Madingley.Common.Environment, SortedList <string, EnviroData> > mmi)
        {
            var e = mmi.Item1;

            if (e.SpecificLocations == false)
            {
                var CellList = new List <Tuple <int, int> >();

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

                // Loop over all cells in the model
                for (int latitudeIndex = 0; latitudeIndex < NumLatCells; latitudeIndex++)
                {
                    for (int longitudeIndex = 0; longitudeIndex < NumLonCells; longitudeIndex++)
                    {
                        // Add the vector to the list of all active grid cells
                        CellList.Add(Tuple.Create(latitudeIndex, longitudeIndex));
                    }
                }

                e.FocusCells = CellList;
            }

            var cellList = e.FocusCells.Select(a => new UInt32[] { (uint)a.Item1, (uint)a.Item2 }).ToList();

            var EcosystemModelGrid = new ModelGrid((float)e.BottomLatitude, (float)e.LeftmostLongitude, (float)e.TopLatitude, (float)e.RightmostLongitude,
                                                   (float)e.CellSize, (float)e.CellSize, cellList, mmi.Item2,
                                                   e.SpecificLocations);

            Func <Tuple <int, int>, IDictionary <string, double[]> > convertCellEnvironment =
                cell =>
            {
                var env = EcosystemModelGrid.GetCellEnvironment((uint)cell.Item1, (uint)cell.Item2);

                return(env.ToDictionary(kv => kv.Key, kv => kv.Value.ToArray()));
            };

            e.CellEnvironment = e.FocusCells.Select(convertCellEnvironment).ToList();
        }
コード例 #5
0
        /// <summary>
        /// Calculates the probability of diffusive dispersal given average individual dispersal speed
        /// </summary>
        /// <param name="madingleyGrid">The model grid</param>
        /// <param name="latIndex">The latitude index of the grid cell to check for dispersal</param>
        /// <param name="lonIndex">The longitude index of the grid cell to check for dispersal</param>
        /// <param name="dispersalSpeed">The average speed at which individuals in this cohort move around their environment, in km per month</param>
        /// <returns>A six element array.
        /// The first element is the probability of dispersal.
        /// The second element is the probability of dispersing in the u (longitudinal) direction
        /// The third element is the probability of dispersing in the v (latitudinal) direction
        /// The fourth element is the probability of dispersing in the diagonal direction
        /// The fifth element is the u velocity modified by the random diffusion component
        /// The sixth element is the v velocity modified by the random diffusion component
        /// Note that the second, third, and fourth elements are always positive; thus, they do not indicate 'direction' in terms of dispersal.</returns>
        private double[] CalculateDispersalProbability(ModelGrid madingleyGrid, uint latIndex, uint lonIndex, double dispersalSpeed)
        {
            // Check that the u speed and v speed are not greater than the cell length. If they are, then rescale them; this limits the max velocity
            // so that cohorts cannot be advected more than one grid cell per time step
            double LatCellLength = madingleyGrid.CellHeightsKm[latIndex];
            double LonCellLength = madingleyGrid.CellWidthsKm[latIndex];

            // Pick a direction at random
            double RandomDirection = RandomNumberGenerator.GetUniform() * 2 * Math.PI;

            // Calculate the u and v components given the dispersal speed
            double uSpeed = dispersalSpeed * Math.Cos(RandomDirection);
            double vSpeed = dispersalSpeed * Math.Sin(RandomDirection);

            // Calculate the area of the grid cell that is now outside in the diagonal direction
            double AreaOutsideBoth = Math.Abs(uSpeed * vSpeed);

            // Calculate the area of the grid cell that is now outside in the u direction (not including the diagonal)
            double AreaOutsideU = Math.Abs(uSpeed * LatCellLength) - AreaOutsideBoth;

            // Calculate the proportion of the grid cell that is outside in the v direction (not including the diagonal
            double AreaOutsideV = Math.Abs(vSpeed * LonCellLength) - AreaOutsideBoth;

            // Get the cell area, in kilometres squared
            double CellArea = madingleyGrid.GetCellEnvironment(latIndex, lonIndex)["Cell Area"][0];

            // Convert areas to a probability
            double DispersalProbability = (AreaOutsideU + AreaOutsideV + AreaOutsideBoth) / CellArea;

            // Check that the whole cell hasn't moved out. This could happen if dispersal speed was high enough
            if (DispersalProbability >= 1)
            {
                Debug.Fail("Dispersal probability in diffusion should always be <= 1");
            }

            double[] NewArray = { DispersalProbability, AreaOutsideU / CellArea, AreaOutsideV / CellArea, AreaOutsideBoth / CellArea, uSpeed, vSpeed };

            return(NewArray);
        }
コード例 #6
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;
        }
コード例 #7
0
        /// <summary>
        /// Calculates the probability of advective dispersal given the grid cell
        /// </summary>
        /// <param name="madingleyGrid">The model grid</param>
        /// <param name="latIndex">The latitude index of the grid cell to check for dispersal</param>
        /// <param name="lonIndex">The longitude index of the grid cell to check for dispersal</param>
        /// <param name="currentMonth">The current model month</param>
        /// <returns>A six element array.
        /// The first element is the probability of dispersal.
        /// The second element is the probability of dispersing in the u (longitudinal) direction
        /// The third element is the probability of dispersing in the v (latitudinal) direction
        /// The fourth element is the probability of dispersing in the diagonal direction
        /// The fifth element is the distance travelled in the u direction (u velocity modified by the random diffusion component)
        /// The sixth element is the distance travelled in the v direction (v velocity modified by the random diffusion component)
        /// Note that the second, third, and fourth elements are always positive; thus, they do not indicate 'direction' in terms of dispersal.</returns>
        private double[] CalculateDispersalProbability(ModelGrid madingleyGrid, uint latIndex, uint lonIndex, uint currentMonth, double rescaleduSpeed, double rescaledvSpeed)
        {
            // Distance travelled in u (longitudinal) direction
            double uDistanceTravelled;

            // Distance travelled in v (latitudinal) direction
            double vDistanceTravelled;

            // U and V components of the diffusive velocity
            double[] DiffusiveUandVComponents = new double[2];

            // Length in km of a cell boundary latitudinally
            double LatCellLength;

            // Length in km of a cell boundary longitudinally
            double LonCellLength;

            // Area of the grid cell that is outside in the diagonal direction after dispersal, in kilometres squared
            double AreaOutsideBoth;

            // Area of the grid cell that is  outside in the u (longitudinal) direction after dispersal, in kilometres squared
            double AreaOutsideU;

            // Area of the grid cell that is  outside in the v (latitudinal) direction after dispersal, in kilometres squared
            double AreaOutsideV;

            // Cell area, in kilometres squared
            double CellArea;

            // Probability of dispersal
            double DispersalProbability;

            // Calculate the diffusive movement speed, with a direction chosen at random
            DiffusiveUandVComponents = CalculateDiffusion();

            // Calculate the distance travelled in this dispersal (not global) time step. both advective and diffusive speeds need to have been converted to km / advective model time step
            uDistanceTravelled = rescaleduSpeed + DiffusiveUandVComponents[0];
            vDistanceTravelled = rescaledvSpeed + DiffusiveUandVComponents[1];

            // Check that the u distance travelled and v distance travelled are not greater than the cell length
            LatCellLength = madingleyGrid.CellHeightsKm[latIndex];
            LonCellLength = madingleyGrid.CellWidthsKm[latIndex];

            if (Math.Abs(uDistanceTravelled) >= LonCellLength)
            {
                Debug.Fail("u velocity greater than cell width");
            }
            if (Math.Abs(vDistanceTravelled) >= LatCellLength)
            {
                Debug.Fail("v velocity greater than cell width");
            }

            // We assume that the whole grid cell moves at the given velocity and calculate the area that is then outside the original grid cell location.
            // This then becomes the probability of dispersal

            // Calculate the area of the grid cell that is now outside in the diagonal direction.
            AreaOutsideBoth = Math.Abs(uDistanceTravelled * vDistanceTravelled);

            // Calculate the area of the grid cell that is now outside in the u (longitudinal) direction (not including the diagonal)
            AreaOutsideU = Math.Abs(uDistanceTravelled * LatCellLength) - AreaOutsideBoth;

            // Calculate the proportion of the grid cell that is outside in the v (latitudinal) direction (not including the diagonal)
            AreaOutsideV = Math.Abs(vDistanceTravelled * LonCellLength) - AreaOutsideBoth;

            // Get the cell area, in kilometres squared
            CellArea = madingleyGrid.GetCellEnvironment(latIndex, lonIndex)["Cell Area"][0];

            // Convert areas to a probability
            DispersalProbability = (AreaOutsideU + AreaOutsideV + AreaOutsideBoth) / CellArea;

            // Check that the whole cell hasn't moved out. Could this happen for the fastest currents in a month? Definitely,
            // if current speeds were not constrained
            if (DispersalProbability >= 1)
            {
                Debug.Fail("Dispersal probability in advection should always be <= 1");
            }

            double[] NewArray = { DispersalProbability, AreaOutsideU / CellArea, AreaOutsideV / CellArea, AreaOutsideBoth / CellArea, uDistanceTravelled, vDistanceTravelled };
            return(NewArray);
        }
        /// <summary>
        /// Calculates the probability of diffusive dispersal given average individual dispersal speed
        /// </summary>
        /// <param name="madingleyGrid">The model grid</param>
        /// <param name="latIndex">The latitude index of the grid cell to check for dispersal</param>
        /// <param name="lonIndex">The longitude index of the grid cell to check for dispersal</param>
        /// <param name="dispersalSpeed">The average speed at which individuals in this cohort move around their environment, in km per month</param>
        /// <returns>A six element array. 
        /// The first element is the probability of dispersal.
        /// The second element is the probability of dispersing in the u (longitudinal) direction
        /// The third element is the probability of dispersing in the v (latitudinal) direction
        /// The fourth element is the probability of dispersing in the diagonal direction
        /// The fifth element is the u velocity modified by the random diffusion component
        /// The sixth element is the v velocity modified by the random diffusion component
        /// Note that the second, third, and fourth elements are always positive; thus, they do not indicate 'direction' in terms of dispersal.</returns>
        private double[] CalculateDispersalProbability(ModelGrid madingleyGrid, uint latIndex, uint lonIndex, double dispersalSpeed)
        {
            // Check that the u speed and v speed are not greater than the cell length. If they are, then rescale them; this limits the max velocity
            // so that cohorts cannot be advected more than one grid cell per time step
            double LatCellLength = madingleyGrid.CellHeightsKm[latIndex];
            double LonCellLength = madingleyGrid.CellWidthsKm[latIndex];

            // Pick a direction at random
            double RandomDirection = RandomNumberGenerator.GetUniform() * 2 * Math.PI;

            // Calculate the u and v components given the dispersal speed
            double uSpeed = dispersalSpeed * Math.Cos(RandomDirection);
            double vSpeed = dispersalSpeed * Math.Sin(RandomDirection);

            // Calculate the area of the grid cell that is now outside in the diagonal direction
            double AreaOutsideBoth = Math.Abs(uSpeed * vSpeed);

            // Calculate the area of the grid cell that is now outside in the u direction (not including the diagonal)
            double AreaOutsideU = Math.Abs(uSpeed * LatCellLength) - AreaOutsideBoth;

            // Calculate the proportion of the grid cell that is outside in the v direction (not including the diagonal
            double AreaOutsideV = Math.Abs(vSpeed * LonCellLength) - AreaOutsideBoth;

            // Get the cell area, in kilometres squared
            double CellArea = madingleyGrid.GetCellEnvironment(latIndex, lonIndex)["Cell Area"][0];

            // Convert areas to a probability
            double DispersalProbability = (AreaOutsideU + AreaOutsideV + AreaOutsideBoth) / CellArea;

            // Check that the whole cell hasn't moved out. This could happen if dispersal speed was high enough
            if (DispersalProbability >= 1)
            {
                Debug.Fail("Dispersal probability in diffusion should always be <= 1");
            }

            double[] NewArray = { DispersalProbability, AreaOutsideU / CellArea, AreaOutsideV / CellArea, AreaOutsideBoth / CellArea, uSpeed, vSpeed };

            return NewArray;
        }
        public InputModelState(string outputPath, string filename, ModelGrid ecosystemModelGrid, List<uint[]> cellList)
        {
            //Set the input state flag to be true
            _InputState = true;

            // Construct the string required to access the file using Scientific Dataset
            string _ReadFileString = "msds:nc?file=input/ModelStates/" + filename +".nc&openMode=readOnly";

            // Open the data file using Scientific Dataset
            DataSet StateDataSet = DataSet.Open(_ReadFileString);

            float[] Latitude = StateDataSet.GetData<float[]>("Latitude");
            float[] Longitude = StateDataSet.GetData<float[]>("Longitude");
            float[] CohortFunctionalGroup = StateDataSet.GetData<float[]>("Cohort Functional Group");
            float[] Cohort = StateDataSet.GetData<float[]>("Cohort");

            float[] StockFunctionalGroup = StateDataSet.GetData<float[]>("Stock Functional Group");
            float[] Stock = StateDataSet.GetData<float[]>("Stock");

            // Check that the longitudes and latitudes in the input state match the cell environment
            for (int la = 0; la < Latitude.Length; la++)
            {
                Debug.Assert(ecosystemModelGrid.GetCellEnvironment((uint)la, 0)["Latitude"][0] == Latitude[la],
                    "Error: input-state grid doesn't match current model grid");
            }
            for (int lo = 0; lo < Longitude.Length; lo++)
            {
                Debug.Assert(ecosystemModelGrid.GetCellEnvironment(0, (uint)lo)["Longitude"][0] == Longitude[lo],
                    "Error: input-state grid doesn't match current model grid");
            }

            List<double[,,]> CohortJuvenileMass = new List<double[,,]>();
            List<double[,,]> CohortAdultMass = new List<double[,,]>();
            List<double[,,]> CohortIndividualBodyMass = new List<double[,,]>();
            List<double[,,]> CohortCohortAbundance = new List<double[,,]>();
            List<double[,,]> CohortLogOptimalPreyBodySizeRatio = new List<double[,,]>();
            List<double[,,]> CohortBirthTimeStep = new List<double[,,]>();
            List<double[,,]> CohortProportionTimeActive = new List<double[,,]>();
            List<double[,,]> CohortTrophicIndex = new List<double[,,]>();

            double[,,,] tempData = new double[Latitude.Length, Longitude.Length,
                CohortFunctionalGroup.Length, Cohort.Length];

            tempData = StateDataSet.GetData<double[,,,]>("CohortJuvenileMass");

            for (int la = 0; la < Latitude.Length; la++)
            {
                CohortJuvenileMass.Add(new double[Longitude.Length, CohortFunctionalGroup.Length, Cohort.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < CohortFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Cohort.Length; c++)
                    {
                        CohortJuvenileMass[(int)cell[0]][cell[1], fg, c] = tempData[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            tempData = StateDataSet.GetData<double[,,,]>("CohortAdultMass");

            for (int la = 0; la < Latitude.Length; la++)
            {
                CohortAdultMass.Add(new double[Longitude.Length, CohortFunctionalGroup.Length, Cohort.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < CohortFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Cohort.Length; c++)
                    {
                        CohortAdultMass[(int)cell[0]][cell[1], fg, c] = tempData[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            tempData = StateDataSet.GetData<double[,,,]>("CohortIndividualBodyMass");

            for (int la = 0; la < Latitude.Length; la++)
            {
                CohortIndividualBodyMass.Add(new double[Longitude.Length, CohortFunctionalGroup.Length, Cohort.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < CohortFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Cohort.Length; c++)
                    {
                        CohortIndividualBodyMass[(int)cell[0]][cell[1], fg, c] = tempData[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            tempData = StateDataSet.GetData<double[,,,]>("CohortCohortAbundance");

            for (int la = 0; la < Latitude.Length; la++)
            {
                CohortCohortAbundance.Add(new double[Longitude.Length, CohortFunctionalGroup.Length, Cohort.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < CohortFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Cohort.Length; c++)
                    {
                        CohortCohortAbundance[(int)cell[0]][cell[1], fg, c] = tempData[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            tempData = StateDataSet.GetData<double[,,,]>("CohortLogOptimalPreyBodySizeRatio");

            for (int la = 0; la < Latitude.Length; la++)
            {
                CohortLogOptimalPreyBodySizeRatio.Add(new double[Longitude.Length, CohortFunctionalGroup.Length, Cohort.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < CohortFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Cohort.Length; c++)
                    {
                        CohortLogOptimalPreyBodySizeRatio[(int)cell[0]][cell[1], fg, c] = tempData[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            tempData = StateDataSet.GetData<double[,,,]>("CohortBirthTimeStep");

            for (int la = 0; la < Latitude.Length; la++)
            {
                CohortBirthTimeStep.Add(new double[Longitude.Length, CohortFunctionalGroup.Length, Cohort.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < CohortFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Cohort.Length; c++)
                    {
                        CohortBirthTimeStep[(int)cell[0]][cell[1], fg, c] = tempData[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            tempData = StateDataSet.GetData<double[,,,]>("CohortProportionTimeActive");

            for (int la = 0; la < Latitude.Length; la++)
            {
                CohortProportionTimeActive.Add(new double[Longitude.Length, CohortFunctionalGroup.Length, Cohort.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < CohortFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Cohort.Length; c++)
                    {
                        CohortProportionTimeActive[(int)cell[0]][cell[1], fg, c] = tempData[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            tempData = StateDataSet.GetData<double[,,,]>("CohortTrophicIndex");

            for (int la = 0; la < Latitude.Length; la++)
            {
                CohortTrophicIndex.Add(new double[Longitude.Length, CohortFunctionalGroup.Length, Cohort.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < CohortFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Cohort.Length; c++)
                    {
                        CohortTrophicIndex[(int)cell[0]][cell[1], fg, c] = tempData[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            _GridCellCohorts = new GridCellCohortHandler[Latitude.Length, Longitude.Length];

            long temp = 0;

            for (int cell = 0; cell < cellList.Count; cell++)
            {
                _GridCellCohorts[cellList[cell][0], cellList[cell][1]] = new GridCellCohortHandler(CohortFunctionalGroup.Length);

                for (int fg = 0; fg < CohortFunctionalGroup.Length; fg++)
                {
                    _GridCellCohorts[cellList[cell][0], cellList[cell][1]][fg] = new List<Cohort>();
                    for (int c = 0; c < Cohort.Length; c++)
                    {
                        if (CohortCohortAbundance[(int)cellList[cell][0]][cellList[cell][1],fg,c] > 0.0)
                        {
                            Cohort TempCohort = new Cohort(
                                (byte)fg,
                                CohortJuvenileMass[(int)cellList[cell][0]][cellList[cell][1], fg, c],
                                CohortAdultMass[(int)cellList[cell][0]][cellList[cell][1], fg, c],
                                CohortIndividualBodyMass[(int)cellList[cell][0]][cellList[cell][1], fg, c],
                                CohortCohortAbundance[(int)cellList[cell][0]][cellList[cell][1], fg, c],
                                Math.Exp(CohortLogOptimalPreyBodySizeRatio[(int)cellList[cell][0]][cellList[cell][1], fg, c]),
                                Convert.ToUInt16(CohortBirthTimeStep[(int)cellList[cell][0]][cellList[cell][1], fg, c]),
                                CohortProportionTimeActive[(int)cellList[cell][0]][cellList[cell][1], fg, c], ref temp,
                                CohortTrophicIndex[(int)cellList[cell][0]][cellList[cell][1], fg, c],
                                false);

                            _GridCellCohorts[cellList[cell][0], cellList[cell][1]][fg].Add(TempCohort);
                        }
                    }
                }

            }

            CohortJuvenileMass.RemoveRange(0, CohortJuvenileMass.Count);
            CohortAdultMass.RemoveRange(0, CohortAdultMass.Count);
            CohortIndividualBodyMass.RemoveRange(0, CohortIndividualBodyMass.Count);
            CohortCohortAbundance.RemoveRange(0, CohortCohortAbundance.Count);
            CohortLogOptimalPreyBodySizeRatio.RemoveRange(0, CohortLogOptimalPreyBodySizeRatio.Count);
            CohortBirthTimeStep.RemoveRange(0, CohortBirthTimeStep.Count);
            CohortProportionTimeActive.RemoveRange(0, CohortProportionTimeActive.Count);
            CohortTrophicIndex.RemoveRange(0, CohortTrophicIndex.Count);

            List<double[,,]> StockIndividualBodyMass = new List<double[,,]>();
            List<double[,,]> StockTotalBiomass = new List<double[,,]>();

            double[,,,] tempData2 = new double[Latitude.Length, Longitude.Length,
                StockFunctionalGroup.Length,Stock.Length];

            tempData2 = StateDataSet.GetData<double[,,,]>("StockIndividualBodyMass");

            for (int la = 0; la < Latitude.Length; la++)
            {
                StockIndividualBodyMass.Add(new double[Longitude.Length, StockFunctionalGroup.Length, Stock.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < StockFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Stock.Length; c++)
                    {
                        StockIndividualBodyMass[(int)cell[0]][cell[1], fg, c] = tempData2[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            tempData2 = StateDataSet.GetData<double[,,,]>("StockTotalBiomass");

            for (int la = 0; la < Latitude.Length; la++)
            {
                StockTotalBiomass.Add(new double[Longitude.Length, StockFunctionalGroup.Length, Stock.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < StockFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Stock.Length; c++)
                    {
                        StockTotalBiomass[(int)cell[0]][cell[1], fg, c] = tempData2[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            _GridCellStocks = new GridCellStockHandler[Latitude.Length, Longitude.Length];

            for (int cell = 0; cell < cellList.Count; cell++)
            {
                _GridCellStocks[cellList[cell][0], cellList[cell][1]] = new GridCellStockHandler(StockFunctionalGroup.Length);

                for (int fg = 0; fg < StockFunctionalGroup.Length; fg++)
                {
                    _GridCellStocks[cellList[cell][0], cellList[cell][1]][fg] = new List<Stock>();
                    for (int c = 0; c < Stock.Length; c++)
                    {
                        if (StockTotalBiomass[(int)cellList[cell][0]][cellList[cell][1], fg, c] > 0.0)
                        {
                            Stock TempStock = new Stock(
                                (byte)fg,
                                StockIndividualBodyMass[(int)cellList[cell][0]][cellList[cell][1], fg, c],
                                StockTotalBiomass[(int)cellList[cell][0]][cellList[cell][1], fg, c]);

                            _GridCellStocks[cellList[cell][0], cellList[cell][1]][fg].Add(TempStock);
                        }
                    }
                }

            }
        }
        /// <summary>
        /// Calculates the probability of advective dispersal given the grid cell
        /// </summary>
        /// <param name="madingleyGrid">The model grid</param>
        /// <param name="latIndex">The latitude index of the grid cell to check for dispersal</param>
        /// <param name="lonIndex">The longitude index of the grid cell to check for dispersal</param>
        /// <param name="currentMonth">The current model month</param>
        /// <returns>A six element array. 
        /// The first element is the probability of dispersal.
        /// The second element is the probability of dispersing in the u (longitudinal) direction
        /// The third element is the probability of dispersing in the v (latitudinal) direction
        /// The fourth element is the probability of dispersing in the diagonal direction
        /// The fifth element is the distance travelled in the u direction (u velocity modified by the random diffusion component)
        /// The sixth element is the distance travelled in the v direction (v velocity modified by the random diffusion component)
        /// Note that the second, third, and fourth elements are always positive; thus, they do not indicate 'direction' in terms of dispersal.</returns>
        private double[] CalculateDispersalProbability(ModelGrid madingleyGrid, uint latIndex, uint lonIndex, uint currentMonth, double rescaleduSpeed, double rescaledvSpeed)
        {
            // Distance travelled in u (longitudinal) direction
             double uDistanceTravelled;

            // Distance travelled in v (latitudinal) direction
             double vDistanceTravelled;

            // U and V components of the diffusive velocity
            double[] DiffusiveUandVComponents = new double[2];

             // Length in km of a cell boundary latitudinally
             double LatCellLength;

             // Length in km of a cell boundary longitudinally
             double LonCellLength;

             // Area of the grid cell that is outside in the diagonal direction after dispersal, in kilometres squared
             double AreaOutsideBoth;

             // Area of the grid cell that is  outside in the u (longitudinal) direction after dispersal, in kilometres squared
             double AreaOutsideU;

             // Area of the grid cell that is  outside in the v (latitudinal) direction after dispersal, in kilometres squared
             double AreaOutsideV;

             // Cell area, in kilometres squared
             double CellArea;

            // Probability of dispersal
             double DispersalProbability;

            // Calculate the diffusive movement speed, with a direction chosen at random
            DiffusiveUandVComponents = CalculateDiffusion();

            // Calculate the distance travelled in this dispersal (not global) time step. both advective and diffusive speeds need to have been converted to km / advective model time step
            uDistanceTravelled = rescaleduSpeed + DiffusiveUandVComponents[0];
            vDistanceTravelled = rescaledvSpeed + DiffusiveUandVComponents[1];

            // Check that the u distance travelled and v distance travelled are not greater than the cell length
            LatCellLength = madingleyGrid.CellHeightsKm[latIndex];
            LonCellLength = madingleyGrid.CellWidthsKm[latIndex];

            if (Math.Abs(uDistanceTravelled) >= LonCellLength)
            {
                Debug.Fail("u velocity greater than cell width");

            }
            if (Math.Abs(vDistanceTravelled) >= LatCellLength)
            {
                Debug.Fail("v velocity greater than cell width");
            }

            // We assume that the whole grid cell moves at the given velocity and calculate the area that is then outside the original grid cell location.
            // This then becomes the probability of dispersal

            // Calculate the area of the grid cell that is now outside in the diagonal direction.
            AreaOutsideBoth = Math.Abs(uDistanceTravelled * vDistanceTravelled);

            // Calculate the area of the grid cell that is now outside in the u (longitudinal) direction (not including the diagonal)
            AreaOutsideU = Math.Abs(uDistanceTravelled * LatCellLength) - AreaOutsideBoth;

            // Calculate the proportion of the grid cell that is outside in the v (latitudinal) direction (not including the diagonal)
            AreaOutsideV = Math.Abs(vDistanceTravelled * LonCellLength) - AreaOutsideBoth;

            // Get the cell area, in kilometres squared
            CellArea = madingleyGrid.GetCellEnvironment(latIndex, lonIndex)["Cell Area"][0];

            // Convert areas to a probability
            DispersalProbability = (AreaOutsideU + AreaOutsideV + AreaOutsideBoth) / CellArea;

            // Check that the whole cell hasn't moved out. Could this happen for the fastest currents in a month? Definitely,
            // if current speeds were not constrained
            if (DispersalProbability >= 1)
            {
                Debug.Fail("Dispersal probability in advection should always be <= 1");
            }

            double[] NewArray = { DispersalProbability, AreaOutsideU / CellArea, AreaOutsideV / CellArea, AreaOutsideBoth / CellArea, uDistanceTravelled, vDistanceTravelled };
            return NewArray;
        }
コード例 #11
0
        public InputModelState(string outputPath, string filename, ModelGrid ecosystemModelGrid, List <uint[]> cellList)
        {
            //Set the input state flag to be true
            _InputState = true;

            // Construct the string required to access the file using Scientific Dataset
            string _ReadFileString = "msds:nc?file=input/ModelStates/" + filename + ".nc&openMode=readOnly";

            // Open the data file using Scientific Dataset
            DataSet StateDataSet = DataSet.Open(_ReadFileString);


            float[] Latitude              = StateDataSet.GetData <float[]>("Latitude");
            float[] Longitude             = StateDataSet.GetData <float[]>("Longitude");
            float[] CohortFunctionalGroup = StateDataSet.GetData <float[]>("Cohort Functional Group");
            float[] Cohort = StateDataSet.GetData <float[]>("Cohort");

            float[] StockFunctionalGroup = StateDataSet.GetData <float[]>("Stock Functional Group");
            float[] Stock = StateDataSet.GetData <float[]>("Stock");


            // Check that the longitudes and latitudes in the input state match the cell environment
            for (int la = 0; la < Latitude.Length; la++)
            {
                Debug.Assert(ecosystemModelGrid.GetCellEnvironment((uint)la, 0)["Latitude"][0] == Latitude[la],
                             "Error: input-state grid doesn't match current model grid");
            }
            for (int lo = 0; lo < Longitude.Length; lo++)
            {
                Debug.Assert(ecosystemModelGrid.GetCellEnvironment(0, (uint)lo)["Longitude"][0] == Longitude[lo],
                             "Error: input-state grid doesn't match current model grid");
            }

            List <double[, , ]> CohortJuvenileMass                = new List <double[, , ]>();
            List <double[, , ]> CohortAdultMass                   = new List <double[, , ]>();
            List <double[, , ]> CohortIndividualBodyMass          = new List <double[, , ]>();
            List <double[, , ]> CohortCohortAbundance             = new List <double[, , ]>();
            List <double[, , ]> CohortLogOptimalPreyBodySizeRatio = new List <double[, , ]>();
            List <double[, , ]> CohortBirthTimeStep               = new List <double[, , ]>();
            List <double[, , ]> CohortProportionTimeActive        = new List <double[, , ]>();
            List <double[, , ]> CohortTrophicIndex                = new List <double[, , ]>();

            double[,,,] tempData = new double[Latitude.Length, Longitude.Length,
                                              CohortFunctionalGroup.Length, Cohort.Length];

            tempData = StateDataSet.GetData <double[, , , ]>("CohortJuvenileMass");


            for (int la = 0; la < Latitude.Length; la++)
            {
                CohortJuvenileMass.Add(new double[Longitude.Length, CohortFunctionalGroup.Length, Cohort.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < CohortFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Cohort.Length; c++)
                    {
                        CohortJuvenileMass[(int)cell[0]][cell[1], fg, c] = tempData[
                            cell[0], cell[1], fg, c];
                    }
                }
            }


            tempData = StateDataSet.GetData <double[, , , ]>("CohortAdultMass");

            for (int la = 0; la < Latitude.Length; la++)
            {
                CohortAdultMass.Add(new double[Longitude.Length, CohortFunctionalGroup.Length, Cohort.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < CohortFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Cohort.Length; c++)
                    {
                        CohortAdultMass[(int)cell[0]][cell[1], fg, c] = tempData[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            tempData = StateDataSet.GetData <double[, , , ]>("CohortIndividualBodyMass");

            for (int la = 0; la < Latitude.Length; la++)
            {
                CohortIndividualBodyMass.Add(new double[Longitude.Length, CohortFunctionalGroup.Length, Cohort.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < CohortFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Cohort.Length; c++)
                    {
                        CohortIndividualBodyMass[(int)cell[0]][cell[1], fg, c] = tempData[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            tempData = StateDataSet.GetData <double[, , , ]>("CohortCohortAbundance");

            for (int la = 0; la < Latitude.Length; la++)
            {
                CohortCohortAbundance.Add(new double[Longitude.Length, CohortFunctionalGroup.Length, Cohort.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < CohortFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Cohort.Length; c++)
                    {
                        CohortCohortAbundance[(int)cell[0]][cell[1], fg, c] = tempData[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            tempData = StateDataSet.GetData <double[, , , ]>("CohortLogOptimalPreyBodySizeRatio");

            for (int la = 0; la < Latitude.Length; la++)
            {
                CohortLogOptimalPreyBodySizeRatio.Add(new double[Longitude.Length, CohortFunctionalGroup.Length, Cohort.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < CohortFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Cohort.Length; c++)
                    {
                        CohortLogOptimalPreyBodySizeRatio[(int)cell[0]][cell[1], fg, c] = tempData[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            tempData = StateDataSet.GetData <double[, , , ]>("CohortBirthTimeStep");

            for (int la = 0; la < Latitude.Length; la++)
            {
                CohortBirthTimeStep.Add(new double[Longitude.Length, CohortFunctionalGroup.Length, Cohort.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < CohortFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Cohort.Length; c++)
                    {
                        CohortBirthTimeStep[(int)cell[0]][cell[1], fg, c] = tempData[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            tempData = StateDataSet.GetData <double[, , , ]>("CohortProportionTimeActive");

            for (int la = 0; la < Latitude.Length; la++)
            {
                CohortProportionTimeActive.Add(new double[Longitude.Length, CohortFunctionalGroup.Length, Cohort.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < CohortFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Cohort.Length; c++)
                    {
                        CohortProportionTimeActive[(int)cell[0]][cell[1], fg, c] = tempData[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            tempData = StateDataSet.GetData <double[, , , ]>("CohortTrophicIndex");

            for (int la = 0; la < Latitude.Length; la++)
            {
                CohortTrophicIndex.Add(new double[Longitude.Length, CohortFunctionalGroup.Length, Cohort.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < CohortFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Cohort.Length; c++)
                    {
                        CohortTrophicIndex[(int)cell[0]][cell[1], fg, c] = tempData[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            _GridCellCohorts = new GridCellCohortHandler[Latitude.Length, Longitude.Length];

            long temp = 0;

            for (int cell = 0; cell < cellList.Count; cell++)
            {
                _GridCellCohorts[cellList[cell][0], cellList[cell][1]] = new GridCellCohortHandler(CohortFunctionalGroup.Length);

                for (int fg = 0; fg < CohortFunctionalGroup.Length; fg++)
                {
                    _GridCellCohorts[cellList[cell][0], cellList[cell][1]][fg] = new List <Cohort>();
                    for (int c = 0; c < Cohort.Length; c++)
                    {
                        if (CohortCohortAbundance[(int)cellList[cell][0]][cellList[cell][1], fg, c] > 0.0)
                        {
                            Cohort TempCohort = new Cohort(
                                (byte)fg,
                                CohortJuvenileMass[(int)cellList[cell][0]][cellList[cell][1], fg, c],
                                CohortAdultMass[(int)cellList[cell][0]][cellList[cell][1], fg, c],
                                CohortIndividualBodyMass[(int)cellList[cell][0]][cellList[cell][1], fg, c],
                                CohortCohortAbundance[(int)cellList[cell][0]][cellList[cell][1], fg, c],
                                Math.Exp(CohortLogOptimalPreyBodySizeRatio[(int)cellList[cell][0]][cellList[cell][1], fg, c]),
                                Convert.ToUInt16(CohortBirthTimeStep[(int)cellList[cell][0]][cellList[cell][1], fg, c]),
                                CohortProportionTimeActive[(int)cellList[cell][0]][cellList[cell][1], fg, c], ref temp,
                                CohortTrophicIndex[(int)cellList[cell][0]][cellList[cell][1], fg, c],
                                false);

                            _GridCellCohorts[cellList[cell][0], cellList[cell][1]][fg].Add(TempCohort);
                        }
                    }
                }
            }

            CohortJuvenileMass.RemoveRange(0, CohortJuvenileMass.Count);
            CohortAdultMass.RemoveRange(0, CohortAdultMass.Count);
            CohortIndividualBodyMass.RemoveRange(0, CohortIndividualBodyMass.Count);
            CohortCohortAbundance.RemoveRange(0, CohortCohortAbundance.Count);
            CohortLogOptimalPreyBodySizeRatio.RemoveRange(0, CohortLogOptimalPreyBodySizeRatio.Count);
            CohortBirthTimeStep.RemoveRange(0, CohortBirthTimeStep.Count);
            CohortProportionTimeActive.RemoveRange(0, CohortProportionTimeActive.Count);
            CohortTrophicIndex.RemoveRange(0, CohortTrophicIndex.Count);

            List <double[, , ]> StockIndividualBodyMass = new List <double[, , ]>();
            List <double[, , ]> StockTotalBiomass       = new List <double[, , ]>();

            double[,,,] tempData2 = new double[Latitude.Length, Longitude.Length,
                                               StockFunctionalGroup.Length, Stock.Length];

            tempData2 = StateDataSet.GetData <double[, , , ]>("StockIndividualBodyMass");

            for (int la = 0; la < Latitude.Length; la++)
            {
                StockIndividualBodyMass.Add(new double[Longitude.Length, StockFunctionalGroup.Length, Stock.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < StockFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Stock.Length; c++)
                    {
                        StockIndividualBodyMass[(int)cell[0]][cell[1], fg, c] = tempData2[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            tempData2 = StateDataSet.GetData <double[, , , ]>("StockTotalBiomass");

            for (int la = 0; la < Latitude.Length; la++)
            {
                StockTotalBiomass.Add(new double[Longitude.Length, StockFunctionalGroup.Length, Stock.Length]);
            }

            foreach (uint[] cell in cellList)
            {
                for (int fg = 0; fg < StockFunctionalGroup.Length; fg++)
                {
                    for (int c = 0; c < Stock.Length; c++)
                    {
                        StockTotalBiomass[(int)cell[0]][cell[1], fg, c] = tempData2[
                            cell[0], cell[1], fg, c];
                    }
                }
            }

            _GridCellStocks = new GridCellStockHandler[Latitude.Length, Longitude.Length];

            for (int cell = 0; cell < cellList.Count; cell++)
            {
                _GridCellStocks[cellList[cell][0], cellList[cell][1]] = new GridCellStockHandler(StockFunctionalGroup.Length);

                for (int fg = 0; fg < StockFunctionalGroup.Length; fg++)
                {
                    _GridCellStocks[cellList[cell][0], cellList[cell][1]][fg] = new List <Stock>();
                    for (int c = 0; c < Stock.Length; c++)
                    {
                        if (StockTotalBiomass[(int)cellList[cell][0]][cellList[cell][1], fg, c] > 0.0)
                        {
                            Stock TempStock = new Stock(
                                (byte)fg,
                                StockIndividualBodyMass[(int)cellList[cell][0]][cellList[cell][1], fg, c],
                                StockTotalBiomass[(int)cellList[cell][0]][cellList[cell][1], fg, c]);

                            _GridCellStocks[cellList[cell][0], cellList[cell][1]][fg].Add(TempStock);
                        }
                    }
                }
            }
        }
コード例 #12
0
        /// <summary>
        /// Calculates the probability of responsive dispersal given average individual dispersal speed and grid cell
        /// </summary>
        /// <param name="madingleyGrid">The model grid</param>
        /// <param name="latIndex">The latitude index of the grid cell to check for dispersal</param>
        /// <param name="lonIndex">The longitude index of the grid cell to check for dispersal</param>
        /// <param name="dispersalSpeed">The average dispersal speed of individuals in the acting cohort</param>
        /// <returns>A six element array. 
        /// The first element is the probability of dispersal.
        /// The second element is the probability of dispersing in the u (longitudinal) direction
        /// The third element is the probability of dispersing in the v (latitudinal) direction
        /// The fourth element is the probability of dispersing in the diagonal direction
        /// The fifth element is the u velocity
        /// The sixth element is the v velocity
        /// Note that the second, third, and fourth elements are always positive; thus, they do not indicate 'direction' in terms of dispersal.</returns>
        protected double[] CalculateDispersalProbability(ModelGrid madingleyGrid, uint latIndex, uint lonIndex, double dispersalSpeed)
        {
            double LatCellLength = madingleyGrid.CellHeightsKm[latIndex];
            double LonCellLength = madingleyGrid.CellWidthsKm[latIndex];

            // Pick a direction at random
            double RandomDirection = RandomNumberGenerator.GetUniform() * 2 * Math.PI;

            // Calculate the u and v components given the dispersal speed
            double uSpeed = dispersalSpeed * Math.Cos(RandomDirection);
            double vSpeed = dispersalSpeed * Math.Sin(RandomDirection);

            // Check that the whole cell hasn't moved out (i.e. that dispersal speed is not greater than cell length). 
            // This could happen if dispersal speed was high enough; indicates a need to adjust the time step, or to slow dispersal
            if ((uSpeed > LonCellLength) || (vSpeed > LatCellLength))
            {
                Debug.Fail("Dispersal probability should always be <= 1");
            }

            // Calculate the area of the grid cell that is now outside in the diagonal direction
            double AreaOutsideBoth = Math.Abs(uSpeed * vSpeed);

            // Calculate the area of the grid cell that is now outside in the u direction (not including the diagonal)
            double AreaOutsideU = Math.Abs(uSpeed * LatCellLength) - AreaOutsideBoth;

            // Calculate the proportion of the grid cell that is outside in the v direction (not including the diagonal
            double AreaOutsideV = Math.Abs(vSpeed * LonCellLength) - AreaOutsideBoth;

            // Get the cell area, in kilometres squared
            double CellArea = madingleyGrid.GetCellEnvironment(latIndex, lonIndex)["Cell Area"][0];

            // Convert areas to a probability
            double DispersalProbability = (AreaOutsideU + AreaOutsideV + AreaOutsideBoth) / CellArea;

            // Check that we don't have any issues
            if (DispersalProbability > 1)
            {
                //Debug.Fail("Dispersal probability should always be <= 1");
                DispersalProbability = 1.0;
            }

            double[] NewArray = { DispersalProbability, AreaOutsideU / CellArea, AreaOutsideV / CellArea, AreaOutsideBoth / CellArea, uSpeed, vSpeed };

            return NewArray;
        }
コード例 #13
0
        private void CheckDensityDrivenDispersal(ModelGrid gridForDispersal, uint latIndex, uint lonIndex, Cohort cohortToDisperse, int functionalGroup, int cohortNumber)
        {
            // Check the population density
            double NumberOfIndividuals = cohortToDisperse.CohortAbundance;

            // Get the cell area, in kilometres squared
            double CellArea = gridForDispersal.GetCellEnvironment(latIndex, lonIndex)["Cell Area"][0];

            // If below the density threshold
            if ((NumberOfIndividuals / CellArea) < _DensityThresholdScaling / cohortToDisperse.AdultMass)
            {
                // Temporary variables to keep track of directions in which cohorts enter/exit cells during the multiple advection steps per time step
                uint ExitDirection = new uint();
                uint EntryDirection = new uint();
                ExitDirection = 9999;

                // Check to see if it disperses (based on the same movement scaling as used in diffusive movement)
                // Calculate dispersal speed for that cohort
                double DispersalSpeed = CalculateDispersalSpeed(cohortToDisperse.IndividualBodyMass);

                // Cohort tries to disperse
                double[] DispersalArray = CalculateDispersalProbability(gridForDispersal, latIndex, lonIndex, CalculateDispersalSpeed(cohortToDisperse.AdultMass));

                double CohortDispersed = CheckForDispersal(DispersalArray[0]);

                if (CohortDispersed > 0)
                {
                    uint[] DestinationCell = CellToDisperseTo(gridForDispersal, latIndex, lonIndex, DispersalArray, DispersalArray[0], DispersalArray[4], DispersalArray[5], ref ExitDirection, ref EntryDirection);

                    // Update the delta array of cells to disperse to, if the cohort moves
                    if (DestinationCell[0] < 999999)
                    {
                        // Update the delta array of cohorts
                        gridForDispersal.DeltaFunctionalGroupDispersalArray[latIndex, lonIndex].Add((uint)functionalGroup);
                        gridForDispersal.DeltaCohortNumberDispersalArray[latIndex, lonIndex].Add((uint)cohortNumber);

                        // Update the delta array of cells to disperse to
                        gridForDispersal.DeltaCellToDisperseToArray[latIndex, lonIndex].Add(DestinationCell);

                        // Update the delta array of exit and entry directions
                        gridForDispersal.DeltaCellExitDirection[latIndex, lonIndex].Add(ExitDirection);
                        gridForDispersal.DeltaCellEntryDirection[latIndex, lonIndex].Add(EntryDirection);
                    }
                }
            }
        }