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