public Scope ChangeStructure(SimulationProperties properties)
        {
            var        grainsPoints = new List <Point>();
            Point      actRandCoord = new Point(0, 0);
            List <int> prevRandIds  = new List <int>();

            for (int i = 0; i < properties.NumberOfRemainingGrains.Value; i++)
            {
                prevRandIds.Add(baseScope.StructureArray[actRandCoord.X, actRandCoord.Y].Id);
                do
                {
                    actRandCoord = StructureHelpers.RandomCoordinates(baseScope.Width, baseScope.Height, random);
                }while (prevRandIds.IndexOf(baseScope.StructureArray[actRandCoord.X, actRandCoord.Y].Id) != -1);
                grainsPoints.Add(actRandCoord);
            }
            var remainingGrains = GetRemainingGrains(grainsPoints);

            // class 5: CA -> CA
            // class 9: CA -> MC, MC -> MC, MC -> CA
            switch (properties.StructureType)
            {
            case StructureType.Dualphase:
                // dual phase - remaining grains should have id and color changed to the same one
                ChangeGrainsIntoSecondPhase(remainingGrains);
                return(GeterateDualphaseStructure(remainingGrains, properties));

            case StructureType.Substructure:
                // substructure - remaining grains shoudld have the same id and color as in base structure
                return(GenerateSubstructure(remainingGrains, properties));

            default:
                return(null);
            }
        }
Exemple #2
0
 private void UpdateBoundariesEnergy(Scope baseScope, Scope energyScope)
 {
     for (int i = 2; i < baseScope.Width - 2; i++)
     {
         for (int j = 2; j < baseScope.Height - 2; j++)
         {
             if (((baseScope.StructureArray[i, j].Id != baseScope.StructureArray[i + 1, j].Id &&
                   !StructureHelpers.IsIdSpecial(baseScope.StructureArray[i + 1, j].Id)) ||
                  (baseScope.StructureArray[i, j].Id != baseScope.StructureArray[i - 1, j].Id &&
                   !StructureHelpers.IsIdSpecial(baseScope.StructureArray[i - 1, j].Id))) &&
                 !StructureHelpers.IsIdSpecial(baseScope.StructureArray[i, j].Id))
             {
                 energyScope.StructureArray[i, j].Color  = ChooseColor(properties.BoundaryEnergy.Value);
                 energyScope.StructureArray[i, j].Energy = properties.BoundaryEnergy.Value;
             }
             if (((baseScope.StructureArray[i, j].Id != baseScope.StructureArray[i, j + 1].Id &&
                   !StructureHelpers.IsIdSpecial(baseScope.StructureArray[i, j + 1].Id)) ||
                  (baseScope.StructureArray[i, j].Id != baseScope.StructureArray[i, j - 1].Id &&
                   !StructureHelpers.IsIdSpecial(baseScope.StructureArray[i, j - 1].Id))) &&
                 !StructureHelpers.IsIdSpecial(baseScope.StructureArray[i, j].Id))
             {
                 energyScope.StructureArray[i, j].Color  = ChooseColor(properties.BoundaryEnergy.Value);
                 energyScope.StructureArray[i, j].Energy = properties.BoundaryEnergy.Value;
             }
         }
     }
 }
Exemple #3
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 #4
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);
            }
        }
        private void StartButton_Click(object sender, RoutedEventArgs e)
        {
            MCSelected  = false;
            SRXSelected = false;
            DisableMC();
            DisableCAStructureChanges();

            previousScope = null;
            currentScope  = null;

            SetUpProperties();
            previousScope = StructureHelpers.InitCAStructure(properties, random);

            dispatcherTimer.Start();
        }
Exemple #6
0
        private List <Grain> PrepareAvaliableStates()
        {
            var states = new List <Grain>();

            for (int i = 1; i <= properties.NumberOfInititalStates; i++)
            {
                states.Add(new Grain()
                {
                    Id    = i,
                    Color = StructureHelpers.RandomColor(random)
                });
            }

            return(states);
        }
        private void MCStartButton_Click(object sender, RoutedEventArgs e)
        {
            MCSelected  = true;
            SRXSelected = false;
            DisableCA();

            previousScope = null;
            currentScope  = null;

            SetUpMCProperties();
            this.MC = new MC(random, MCproperties);

            previousScope = StructureHelpers.GenerateEmptyStructure((int)StructureImage.Width, (int)StructureImage.Height);

            dispatcherTimer.Start();
        }
        private Scope GeterateDualphaseStructure(List <Dictionary <Point, Grain> > remainingGrains, SimulationProperties properties)
        {
            Scope prevScope;

            if (properties.AdvancedMethodType == AdvancedMethodType.AdvancedMC)
            {
                prevScope = StructureHelpers.GenerateEmptyStructure(properties.ScopeWidth, properties.ScopeHeight);
            }
            else
            {
                prevScope = StructureHelpers.InitCAStructure(properties, random);
            }
            var newScope = new Scope(prevScope.Width, prevScope.Height);

            if (properties.AdvancedMethodType == AdvancedMethodType.AdvancedMC)
            {
                // MC
                while (newScope == null || MC.ItertionsPerformed < MCProperties.NumberOfSteps)
                {
                    newScope  = MC.Grow(prevScope);
                    prevScope = newScope;
                }
            }
            else
            {
                // CA
                while (newScope == null || !newScope.IsFull)
                {
                    newScope  = CA.Grow(prevScope, properties.NeighbourhoodType, properties.GrowthProbability);
                    prevScope = newScope;
                }
            }

            // add second phase
            foreach (var grain in remainingGrains)
            {
                foreach (var g in grain)
                {
                    newScope.StructureArray[g.Key.X, g.Key.Y] = g.Value;
                }
            }

            newScope.IsFull = true;
            StructureHelpers.UpdateBitmap(newScope);
            return(newScope);
        }
Exemple #9
0
        private Scope[] EnergyDistribution()
        {
            var baseScope   = scope;
            var energyScope = StructureHelpers.GenerateEmptyStructure(scope.Width, scope.Height);

            for (int i = 1; i < scope.Width - 1; i++)
            {
                for (int j = 1; j < scope.Height - 1; j++)
                {
                    if (scope.StructureArray[i, j].Id != Convert.ToInt32(SpecialIds.Border))
                    {
                        baseScope.StructureArray[i, j].Energy = properties.GrainEnergy;

                        energyScope.StructureArray[i, j].Id     = Convert.ToInt32(SpecialIds.Energy);
                        energyScope.StructureArray[i, j].Energy = properties.GrainEnergy;
                        energyScope.StructureArray[i, j].Color  = ChooseColor(properties.GrainEnergy);
                    }
                    else
                    {
                        baseScope.StructureArray[i, j]   = scope.StructureArray[i, j];
                        energyScope.StructureArray[i, j] = scope.StructureArray[i, j];
                    }
                }
            }
            if (properties.EnergyDistributionType == EnergyDistributionType.Heterogenous)
            {
                UpdateBoundariesEnergy(scope, energyScope);
                for (int i = 1; i < energyScope.Height - 1; i++)
                {
                    for (int j = 1; j < energyScope.Width - 1; j++)
                    {
                        baseScope.StructureArray[i, j].Energy = energyScope.StructureArray[i, j].Energy;
                    }
                }
            }

            energyScope.IsFull = true;
            StructureHelpers.UpdateBitmap(energyScope);

            Scope[] scopes = new Scope[2] {
                energyScope, baseScope
            };
            return(scopes);
        }
        private Scope GenerateSubstructure(List <Dictionary <Point, Grain> > remainingGrains, SimulationProperties properties)
        {
            // prepare base scope with remaining grains
            remainingIds = new List <int>();
            var scope = new Scope(baseScope.Width, baseScope.Height);

            foreach (var grain in remainingGrains)
            {
                foreach (var g in grain)
                {
                    scope.StructureArray[g.Key.X, g.Key.Y] = g.Value;
                    if (remainingIds.IndexOf(g.Value.Id) == -1)
                    {
                        remainingIds.Add(g.Value.Id);
                    }
                }
            }

            Scope prevScope = StructureHelpers.InitCAStructure(properties, random, scope, remainingIds);
            var   newScope  = new Scope(prevScope.Width, prevScope.Height);

            //if (properties.AdvancedMethodType == AdvancedMethodType.AdvancedMC)
            //{
            //    // MC
            //    while (newScope == null || MC.ItertionsPerformed < MCProperties.NumberOfSteps)
            //    {
            //        newScope = MC.Grow(prevScope, remainingIds);
            //        prevScope = newScope;
            //    }
            //}
            //else
            //{
            // CA
            while (newScope == null || !newScope.IsFull)
            {
                newScope  = CA.Grow(prevScope, properties.NeighbourhoodType, properties.GrowthProbability, remainingIds);
                prevScope = newScope;
            }
            //}

            newScope.IsFull = true;
            StructureHelpers.UpdateBitmap(newScope);
            return(newScope);
        }
Exemple #11
0
        public Scope Grow(Scope scope, List <int> remainingIds = null)
        {
            var remainingCellsForIteration = new List <KeyValuePair <Point, Grain> >();

            // create a list of grains which can change its state
            for (int i = 1; i < scope.Width - 1; i++)
            {
                for (int j = 1; j < scope.Height - 1; j++)
                {
                    if (CanGrainChangeState(i, j, scope.StructureArray, remainingIds))
                    {
                        remainingCellsForIteration.Add(new KeyValuePair <Point, Grain>(new Point(i, j), scope.StructureArray[i, j]));
                    }
                }
            }

            int cell;
            KeyValuePair <Point, Grain> actualState;
            Grain newState;

            while (remainingCellsForIteration.Count() > 0)
            {
                // randomly select cells form the list
                cell        = GetRandomCell(0, remainingCellsForIteration.Count());
                actualState = remainingCellsForIteration.ElementAt(cell);

                // randomly selected new state
                newState = GetRandomState();

                // change cell state if it is acceptable
                if (IsStateChangeAcceptable(actualState.Key, scope.StructureArray, newState))
                {
                    scope.StructureArray[actualState.Key.X, actualState.Key.Y] = newState;
                }

                // remove handled cell form remaining cells list
                remainingCellsForIteration.Remove(actualState);
            }

            ItertionsPerformed++;
            StructureHelpers.UpdateBitmap(scope);
            return(scope);
        }
Exemple #12
0
        public static Scope ReadBitmapFile(string pathString)
        {
            Bitmap img    = new Bitmap(pathString);
            int    width  = img.Width;
            int    height = img.Height;

            var scope = new Scope(width, height);

            try
            {
                scope.StructureBitmap = new Bitmap(pathString);
            }
            catch (Exception)
            {
                return(null);
            }

            scope.IsFull = true;
            StructureHelpers.UpdateArrayStructure(scope);
            return(scope);
        }
Exemple #13
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);
            }
        }
        private void AddInclusionsButton_Click(object sender, RoutedEventArgs e)
        {
            SetUpProperties();

            if (properties.Inclusions.AreEnable && (properties.Inclusions.CreationTime == InclusionsCreationTime.After))
            {
                var inclusions = new Inclusions(properties.Inclusions, random);

                var filePath = @"..\..\Structures\structureforinlusions.bmp";
                FileSaver.SaveBitmapFile(currentScope, filePath);
                currentScope  = FileReader.ReadBitmapFile(filePath);
                previousScope = currentScope;

                currentScope = inclusions.AddInclusionsAfterGrainGrowth(currentScope);

                StructureHelpers.UpdateBitmap(currentScope);
                currentScope.IsFull = true;
                previousScope       = currentScope;

                StructureImage.Source = Converters.BitmapToImageSource(currentScope.StructureBitmap);
            }
        }
Exemple #15
0
        public static Scope ReadTxtFile(string pathString)
        {
            String input;

            try
            {
                input = System.IO.File.ReadAllText(pathString);

                string[] lines  = input.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
                int      width  = Converters.StringToInt(lines[0]);
                int      height = Converters.StringToInt(lines[1]);
                var      scope  = new Scope(width, height);

                for (int i = 0; i < width; i++)
                {
                    string[] grains = lines[i + 2].Split(' ');
                    for (int j = 0; j < height; j++)
                    {
                        string[] details = grains[j].Split('=');
                        scope.StructureArray[i, j] = new Grain()
                        {
                            Id    = Converters.StringToInt(details[0]),
                            Color = Color.FromArgb(Converters.StringToInt(details[1]), Converters.StringToInt(details[2]), Converters.StringToInt(details[3]))
                        };
                    }
                }

                scope.IsFull = true;
                StructureHelpers.UpdateBitmap(scope);
                return(scope);
            }
            catch (Exception)
            {
                return(null);
            }
        }
Exemple #16
0
        public Scope Grow(Scope previousStructure, NeighbourhoodType neighbourhoodType, int?growthProbability, List <int> remainingIds = null)
        {
            var currentStructure = new Scope(previousStructure.Width, previousStructure.Height);

            StructureHelpers.AddBlackBorder(currentStructure);

            var          isFull           = true;
            var          isGrowthExtended = neighbourhoodType == NeighbourhoodType.ExtendedMoore ? true : false;
            List <Grain> neighbourhood    = new List <Grain>();

            for (int i = 1; i < previousStructure.Width - 1; i++)
            {
                for (int j = 1; j < previousStructure.Height - 1; j++)
                {
                    if (previousStructure.StructureArray[i, j].Id != 0)
                    {
                        currentStructure.StructureArray[i, j] = previousStructure.StructureArray[i, j];
                    }
                    else if (previousStructure.StructureArray[i, j].Id == 0)
                    {
                        if (!isGrowthExtended)
                        {
                            switch (neighbourhoodType)
                            {
                            case NeighbourhoodType.Moore:
                                neighbourhood = TakeMooreNeighbourhood(i, j, previousStructure.StructureArray);
                                break;

                            case NeighbourhoodType.Neumann:
                                neighbourhood = TakeNeumannNeighbourhood(i, j, previousStructure.StructureArray);
                                break;
                            }

                            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)))
                                         .GroupBy(g => g.Id);
                            }
                            else
                            {
                                groups = neighbourhood
                                         .Where(g => (!StructureHelpers.IsIdSpecial(g.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);
                                currentStructure.StructureArray[i, j] = orderedNeighbourhood.First().Key;
                            }
                            else
                            {
                                currentStructure.StructureArray[i, j] = new Grain()
                                {
                                    Id    = 0,
                                    Color = Color.White
                                };
                            }
                        }
                        else
                        {
                            var grainGrowth = false;
                            var dictionary  = new Dictionary <Grain, int>();
                            // rule 1
                            neighbourhood = TakeMooreNeighbourhood(i, j, previousStructure.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)))
                                         .GroupBy(g => g.Id);
                            }
                            else
                            {
                                groups = neighbourhood
                                         .Where(g => (!StructureHelpers.IsIdSpecial(g.Id))).GroupBy(g => g.Id);
                            }
                            if (groups.Any())
                            {
                                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)
                                {
                                    currentStructure.StructureArray[i, j] = orderedNeighbourhood.First().Key;
                                    grainGrowth = true;
                                }
                                else
                                {
                                    // rule 2
                                    neighbourhood = TakeNearestMooreNeighbourhood(i, j, previousStructure.StructureArray);
                                    if (remainingIds != null && remainingIds.Count() > 0)
                                    {
                                        groups = neighbourhood
                                                 .Where(g => (!StructureHelpers.IsIdSpecial(g.Id)) && !remainingIds.Any(id => id.Equals(g.Id)))
                                                 .GroupBy(g => g.Id);
                                    }
                                    else
                                    {
                                        groups = neighbourhood
                                                 .Where(g => (!StructureHelpers.IsIdSpecial(g.Id))).GroupBy(g => g.Id);
                                    }
                                    if (groups.Any())
                                    {
                                        orderedNeighbourhood = dictionary.OrderByDescending(x => x.Value);
                                        if (orderedNeighbourhood.First().Value >= 3)
                                        {
                                            currentStructure.StructureArray[i, j] = orderedNeighbourhood.First().Key;
                                            grainGrowth = true;
                                        }
                                    }
                                    if (!grainGrowth)
                                    {
                                        // rule 3
                                        neighbourhood = TakeFurtherMooreNeighbourhood(i, j, previousStructure.StructureArray);
                                        if (remainingIds != null && remainingIds.Count() > 0)
                                        {
                                            groups = neighbourhood
                                                     .Where(g => (!StructureHelpers.IsIdSpecial(g.Id)) && !remainingIds.Any(id => id.Equals(g.Id)))
                                                     .GroupBy(g => g.Id);
                                        }
                                        else
                                        {
                                            groups = neighbourhood
                                                     .Where(g => (!StructureHelpers.IsIdSpecial(g.Id))).GroupBy(g => g.Id);
                                        }
                                        if (groups.Any())
                                        {
                                            orderedNeighbourhood = dictionary.OrderByDescending(x => x.Value);
                                            if (orderedNeighbourhood.First().Value >= 3)
                                            {
                                                currentStructure.StructureArray[i, j] = orderedNeighbourhood.First().Key;
                                                grainGrowth = true;
                                            }
                                        }
                                    }
                                    if (!grainGrowth)
                                    {
                                        // rule 4 - Moore with probability
                                        neighbourhood = TakeMooreNeighbourhood(i, j, previousStructure.StructureArray);
                                        if (remainingIds != null && remainingIds.Count() > 0)
                                        {
                                            groups = neighbourhood
                                                     .Where(g => (!StructureHelpers.IsIdSpecial(g.Id)) && !remainingIds.Any(id => id.Equals(g.Id)))
                                                     .GroupBy(g => g.Id);
                                        }
                                        else
                                        {
                                            groups = neighbourhood
                                                     .Where(g => (!StructureHelpers.IsIdSpecial(g.Id))).GroupBy(g => g.Id);
                                        }
                                        var randomProbability = random.Next(0, 100);
                                        if (groups.Any() && (randomProbability <= growthProbability))
                                        {
                                            orderedNeighbourhood = dictionary.OrderByDescending(x => x.Value);
                                            currentStructure.StructureArray[i, j] = orderedNeighbourhood.First().Key;
                                            grainGrowth = true;
                                        }
                                    }
                                }
                            }
                            if (!grainGrowth)
                            {
                                // no grain yet
                                currentStructure.StructureArray[i, j] = new Grain()
                                {
                                    Id    = 0,
                                    Color = Color.White
                                };
                            }
                        }
                    }

                    if (currentStructure.StructureArray[i, j].Id == 0)
                    {
                        isFull = false;
                    }
                }
            }

            currentStructure.IsFull = isFull;

            StructureHelpers.UpdateBitmap(currentStructure);

            return(currentStructure);
        }
Exemple #17
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);
        }