/* Monte-Carlo simulation code for statistical physics Copyright (C) 2001-2005 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.util.*; import java.awt.*; import fr.ensea.Localizer; import fr.ensea.montecarlo.*; import fr.ensea.montecarlo.event.*; /** * This class manages the (canonical) algorithm thread (since the algorithm and the UI are executed * in separate threads). In particular, this class allows one to configure either a temperature sweep or * a single-temperature simulation, to pause/stop/restart the simulation, to set the "sleep" delay between * MC steps, and arranges to repaint the UI asynchronously at appropriate times. * Any particular algorithm (e.g. Metropolis, Wolff, ...) may be plugged into it. */ public class MCSimulationThread extends AbstractSimulationThread { private Montecarlo algorithm; private double[] kTList; private final Montecarlo metropolis, wolffcluster; private int kTidx; // current index in kTList public final static String METROPOLIS="metropolis"; public final static String WOLFF="wolff"; public MCSimulationThread(MCApplet controller, double defKT){ super(controller); this.metropolis = controller.getLattice().createMetropolis(controller.getSamplesBag(), defKT);// par défaut this.wolffcluster = controller.getLattice().createWolffCluster(controller.getSamplesBag(), defKT);// may be null this.algorithm = metropolis; setSingleTemperature(defKT); } public MCSimulationThread(MCApplet controller, double kTstart, double kTend, int kTsteps){ super(controller); this.metropolis = controller.getLattice().createMetropolis(controller.getSamplesBag(), kTstart);// par défaut this.wolffcluster = controller.getLattice().createWolffCluster(controller.getSamplesBag(), kTstart);// may be null this.algorithm = metropolis; setTemperatureRange(kTstart, kTend, kTsteps); } public String getCountersRateLabel(){ return algorithm.getCountersRateLabel(); } public void reinitCounters(){ algorithm.reinitCounters(); } /** * Plugs a new algorithm into this class. * @param algorithm METROPOLIS or WOLFF * @return true iff the algorithm was successfully plugged */ public boolean setAlgorithm(String algo){ boolean wasRunning = isRunning(); if (algo==WOLFF){ if (this.algorithm==wolffcluster) return false; if (wolffcluster==null) return false; kill(); this.algorithm = wolffcluster; } else if (algo==METROPOLIS){ if (this.algorithm==metropolis) return false; if (metropolis==null) return false; kill(); this.algorithm = metropolis; } else return false; if (wasRunning){ // restart automatically ((MCApplet)controller).getThermalAveragesSet().addNewAveragesSet(); } return true; } public Montecarlo getAlgorithm(){ return algorithm; } public void activateRG(){ if (metropolis!=null && metropolis instanceof PottsMetropolis) ((PottsMetropolis)metropolis).activateRG(); if (wolffcluster!=null && wolffcluster instanceof PottsWolffCluster) ((PottsWolffCluster)wolffcluster).activateRG(); } public void setFactorRG(int rgFactor){ if (metropolis!=null && metropolis instanceof PottsMetropolis) ((PottsMetropolis)metropolis).setFactorRG(rgFactor); if (wolffcluster!=null && wolffcluster instanceof PottsWolffCluster) ((PottsWolffCluster)wolffcluster).setFactorRG(rgFactor); } /** * Configures a temperature sweep. */ public void setTemperatureRange(double kTstart, double kTend, int kTsteps){ if (kTsteps<2) kTsteps=2; kTList = new double[kTsteps]; double deltakT = (kTend-kTstart)/(kTsteps-1); for (int i=0; i 1); } public double[] getKTList(){ return kTList; } public String toString(){ String s = "MCSimulationThread:\n"; s += "kTList:\n"; for (int i=0; i= kTList.length) { kTidx=0; return false; } algorithm.setTemperature(kTList[kTidx]); controller.getSamplesBag().resetSamplesGraphs(); ((MCApplet)controller).getControlPane().setRunName("T="+Double.toString(kTList[kTidx])); return true; } protected void sweep(){ algorithm.sweep(); } protected boolean finalizeRun(){ if (controller.getSamplesBag().size() < nbMCSteps) return false; if (isTemperatureSweep()) { ((MCApplet)controller).getThermalAveragesSet().storeSimulationResults(algorithm.getTemperature()); // if in temp-sweep mode only (otherwise it's to be done manually) controller.showStatus(Localizer.get("NewPointAdded")+"=" + algorithm.getTemperature()); } kTidx++; return true; } // --------------- UI ----------------- public Choice createAlgoChoice(){ Choice algoChooserCH=new Choice(); if (metropolis != null) algoChooserCH.add("Metropolis"); if (wolffcluster != null) algoChooserCH.add("Wolff cluster"); if (algorithm==metropolis) algoChooserCH.select(0); else algoChooserCH.select(1); return algoChooserCH; } }