public void SingleFlip(Spin chosen) { var energyDifference = 2 * CalculateEnergyNn(chosen); if (Accept(energyDifference, chosen.Value)) { chosen.ToggleSpin(); TotalInteraction += energyDifference; TotalMagnetization += 2 * chosen.Value; } }
public void Kawasaki(Spin chosen) { Spin exchange = chosen.Neighbours[Rnd.Next(4)]; if (chosen.Value == 0 || exchange.Value == 0 || chosen.Value == exchange.Value) { return; } var energyDifference = 2 * CalculateEnergyChangeKawasaki(chosen, exchange); if (Accept(energyDifference, 0)) { chosen.ToggleSpin(); exchange.ToggleSpin(); TotalInteraction += energyDifference; } }
public void ScaleLattice(bool down) { int count = 0; int newN = down ? N / 2 : N * 2; var spins2D = new Spin[newN, newN]; var spins = new Spin[newN * newN]; for (var x = 0; x < newN; x++) { for (var y = 0; y < newN; y++) { spins[count] = spins2D[x, y] = new Spin(GetScaledValue(x, y, down), count); count++; } } InitializeNeighbours(spins2D, newN); this.N = newN; this.Count = count; this.Spins = spins; this.UpdateStats(); }
public Lattice(int n, double averageMagnetization) { { Current = this; Coupling = 1; Field = 0; Beta = 1; Dynamic = SingleFlip; Accept = MetropolisCached; Accepts = new Dictionary <string, AcceptanceFunction>() { { "Metropolis", MetropolisCached }, { "Glauber", GlauberCached } }; Dynamics = new Dictionary <string, DynamicsAlgorithm>() { { "SingleFlip", SingleFlip }, { "Kawasaki", Kawasaki } }; } N = n; var spin2DArray = new Spin[N, N]; //initalize with 2D array to make initalization easier Spins = new Spin[N * N]; Count = 0; double seed = 1 - 0.5 * (averageMagnetization + 1); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { var r = Rnd.NextDouble(); var val = r < seed ? -1 : 1; Spins[Count] = spin2DArray[i, j] = new Spin(val, Count); Count++; } } InitializeNeighbours(spin2DArray, N); SetBoundary(true); }
public void SetNeighbours(Spin north, Spin east, Spin south, Spin west) { Neighbours = new Spin[4] { north, east, south, west }; }
private static int CalculateEnergyChangeKawasaki(Spin s1, Spin s2) { return(CalculateEnergyNn(s1) + CalculateEnergyNn(s2) + 2); }
private static int CalculateEnergyNn(Spin s) { return(s.Neighbours.Aggregate(0, (sum, spin) => sum + spin.Value) * s.Value); }