Exemple #1
0
        private bool IsStateChangeAcceptable(Point point, Grain[,] structureArray, Grain newState)
        {
            var neighbourhood  = StructureHelpers.TakeMooreNeighbourhood(point.X, point.Y, structureArray);
            int previousEnergy = neighbourhood.Where(g => (g.Id != 0 && g.Id != structureArray[point.X, point.Y].Id)).Count();
            int newEnergy      = neighbourhood.Where(g => (g.Id != 0 && g.Id != newState.Id)).Count();

            if (newEnergy - previousEnergy <= 0)
            {
                return(true);
            }
            return(false);
        }
Exemple #2
0
        private bool HasAnyRecrystalizedNeighbour(int i, int j, Grain[,] structureArray)
        {
            var neighbourhood          = StructureHelpers.TakeMooreNeighbourhood(i, j, structureArray);
            var recrystalizedNeighbour = neighbourhood.Where(g => (g.IsRecrystalized == true)).FirstOrDefault();

            if (recrystalizedNeighbour != null)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemple #3
0
        private bool CanGrainChangeState(int i, int j, Grain[,] structureArray, List <int> remainingIds)
        {
            var neighbourhood = StructureHelpers.TakeMooreNeighbourhood(i, j, structureArray);

            IEnumerable <IGrouping <int, Grain> > groups = null;

            if (remainingIds != null && remainingIds.Count() > 0)
            {
                groups = neighbourhood
                         .Where(g => (!StructureHelpers.IsIdSpecial(g.Id)) && !remainingIds.Any(id => id.Equals(g.Id) && g.Id == structureArray[i, j].Id))
                         .GroupBy(g => g.Id);
            }
            else
            {
                groups = neighbourhood.Where(g => (!StructureHelpers.IsIdSpecial(g.Id) && g.Id == structureArray[i, j].Id)).GroupBy(g => g.Id);
            }

            if (groups.Any())
            {
                var dictionary = new Dictionary <Grain, int>();
                foreach (var group in groups)
                {
                    var number = group.Key;
                    var total  = group.Count();
                    dictionary.Add(group.FirstOrDefault(), total);
                }
                var orderedNeighbourhood = dictionary.OrderByDescending(x => x.Value);

                if (orderedNeighbourhood.First().Value < 5)
                {
                    return(true);
                }
                return(false);
            }
            else
            {
                return(true);
            }
        }
Exemple #4
0
        public Scope[] GrowthNucleons(Scope currentScope, Scope energyScope)
        {
            // NUCLEATION
            KeyValuePair <Point, Grain> actualState;
            Grain newState;
            var   numberOfNucleons = nucleonsPreIteration[ItertionsPerformed];

            if (numberOfNucleons > 0)
            {
                var avaliablePlaces = new List <KeyValuePair <Point, Grain> >();
                switch (properties.EnergyDistributionType)
                {
                case EnergyDistributionType.Homogenous:
                    // get higher energy from whole space
                    avaliablePlaces = GetHigherEnergyCells(currentScope);
                    break;

                case EnergyDistributionType.Heterogenous:
                    // get remaining boundaries
                    avaliablePlaces = GetHighestEnergyCells(currentScope);
                    break;

                default:
                    return(null);
                }

                // select randomly form the list of remaining cells
                int selectedPoints = 0;
                // add new nucleons
                while (avaliablePlaces.Count() > 0 && selectedPoints < numberOfNucleons)
                {
                    // randomly select cells form the list
                    actualState = avaliablePlaces.ElementAt(random.Next(0, avaliablePlaces.Count()));
                    // random new state
                    newState = states.ElementAt(random.Next(0, states.Count()));
                    // change cell state to recrystalized
                    currentScope.StructureArray[actualState.Key.X, actualState.Key.Y]       = newState;
                    energyScope.StructureArray[actualState.Key.X, actualState.Key.Y].Energy = newState.Energy;
                    energyScope.StructureArray[actualState.Key.X, actualState.Key.Y].Color  = ChooseColor(newState.Energy);
                    // remove recrystalized cell form avaliable cells list
                    avaliablePlaces.Remove(actualState);
                    selectedPoints++;
                }
            }

            // GROWTH
            // create a list of grains which can recrystalize
            var remainingCellsForIteration = new List <KeyValuePair <Point, Grain> >();

            for (int i = 1; i < currentScope.Width - 1; i++)
            {
                for (int j = 1; j < currentScope.Height - 1; j++)
                {
                    //check if any neighbour is recrystalized
                    if (!currentScope.StructureArray[i, j].IsRecrystalized && HasAnyRecrystalizedNeighbour(i, j, currentScope.StructureArray))
                    {
                        remainingCellsForIteration.Add(new KeyValuePair <Point, Grain>(new Point(i, j), currentScope.StructureArray[i, j]));
                    }
                }
            }

            // go through all remaining cells randomly
            var neighbourhood = new List <Grain>();
            int beforeEnergy = 0, afterEnergy = 0;

            while (remainingCellsForIteration.Count() > 0)
            {
                // randomly select cell form the list
                actualState = remainingCellsForIteration.ElementAt(random.Next(0, remainingCellsForIteration.Count()));
                // get neighoburs (Moore)
                neighbourhood = StructureHelpers.TakeMooreNeighbourhood(actualState.Key.X, actualState.Key.Y, currentScope.StructureArray);
                // choose new recrystalized state (from neighoburs)
                newState = neighbourhood.Where(n => n.IsRecrystalized == true).First();
                // calculate before and after SRX energy (like in MC but including internal cell energy)
                beforeEnergy = (neighbourhood.Where(g => (g.Id != 0 && g.Id != actualState.Value.Id)).Count())
                               + actualState.Value.Energy;
                afterEnergy = neighbourhood.Where(g => (g.Id != 0 && g.Id != newState.Id)).Count();
                // change cell state to recrystalized if it is acceptable (if after energy is lower)
                if (afterEnergy < beforeEnergy)
                {
                    currentScope.StructureArray[actualState.Key.X, actualState.Key.Y]       = newState;
                    energyScope.StructureArray[actualState.Key.X, actualState.Key.Y].Energy = newState.Energy;
                    energyScope.StructureArray[actualState.Key.X, actualState.Key.Y].Color  = ChooseColor(newState.Energy);
                }
                // remove handled cell form remaining cells list
                remainingCellsForIteration.Remove(actualState);
            }

            // check if all cells are recrystalized
            if (AreAllCellsRecrystalized(currentScope))
            {
                currentScope.IsFull = true;
            }

            StructureHelpers.UpdateBitmap(currentScope);
            StructureHelpers.UpdateBitmap(energyScope);

            ItertionsPerformed++;
            Scope[] scopes = new Scope[2] {
                currentScope, energyScope
            };
            return(scopes);
        }