/* Monte-Carlo simulation code for statistical physics Copyright (C) 2001-2004 Sylvain Reynal Département de Physique Ecole Nationale Supérieure de l'Electronique et de ses Applications (ENSEA) 6, avenue du Ponceau, F-95014 CERGY CEDEX et Laboratoire de Physique Théorique et Modélisation (LPTM) Université de Cergy-Pontoise - Site de Neuville F-95031 CERGY CEDEX Tel : 00 +33 130 736 245 Fax : 00 +33 130 736 667 e-mail : reynal@ensea.fr web page : http://www.ensea.fr/staff/reynal/ */ package fr.ensea.montecarlo.canonical; import java.io.*; import java.awt.Color; import java.text.*; import fr.ensea.Localizer; import fr.ensea.montecarlo.model.*; import fr.ensea.montecarlo.data.*; import fr.ensea.montecarlo.canonical.*; import fr.ensea.montecarlo.misc.*; /** * Algorithme de Montecarlo pour le modèle d'Ising AF */ public class AFIsingMetropolis extends AbstractMetropolis { private AFIsingLattice lattice; private double[] probas; // tableau contenant les probabilités d'acceptance lorsque dE <= 0 // (les variations négatives donnant de toute façon une probabilité égale 1, il est inutile de les précalculer) // exemple : // 3 3 // 1 2 2 => 1 3 2 donne dE = -1 // 3 3 // /** * Initialise un nouvel algorithm de Montecarlo attaché au réseau fourni en paramètre. * @param energySamples liste pour les mesures de l'énergie * @param magnetizationSamples liste pour les mesures de l'aimantation * @param lattice le réseau à simuler * @param kT la température par défaut */ public AFIsingMetropolis(AFIsingLattice lattice, SamplesBag bag, double kT) { super(bag, kT); this.lattice = lattice; } /** * Modifie la température courante et remet les compteurs à zéro. */ public synchronized void setTemperature(double kT){ super.setTemperature(kT); this.probas=new double[5]; if (kT>0) for (int dE=1; dE<5; dE++) probas[dE] = Math.exp(-(double)dE/kT); // sinon, si kT=0, les probabilités sont nulles pour une mise-à-jour avec augmentation de l'énergie } /** * Réalise un sweep de l'ensemble du réseau, i.e. tente de mettre à jour L*L spins. */ public void sweep(){ int row,col, valeurVoisin, dE; final int L = lattice.size; final int L2 = lattice.size2; for (int pas=0; pas < L2; pas++){ attemptedMoves++; // on choisit au hasard un spin à modifier parmi L^2 : row = (int)(L * createRandomNumber()); col = (int)(L * createRandomNumber()); dE = lattice.getEnergyChange(row,col); // basculement spin (row,col) if (DEBUG) { System.out.println(lattice.toString()); System.out.println("row=" + row); System.out.println("col=" + col); System.out.println("dE=" + dE); System.out.println("proba=" + (dE > 0 ? probas[dE] : 1.0)); } // attempt move: if (dE <= 0.0 || createRandomNumber() <= probas[dE]){ acceptedMoves++; lattice.toggleSpin(row,col); lattice.energy += dE; if (DEBUG) System.out.println("Acceptée !\n"+lattice.toString()); } if (DEBUG) { System.out.println("======================================================="); pause(); } } samplesBag.addEnergySample(lattice.getEnergy()/lattice.size2); samplesBag.addMagnetizationSample(lattice.getMagnetization()); } /////////////////////////////////////////////////////////// /// Statistiques /////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// // TEST ///////////////////////////////////////////////////////////////////////////////// }