/* 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.multicanonical; import java.util.*; import java.awt.*; import fr.ensea.Localizer; import fr.ensea.montecarlo.*; import fr.ensea.montecarlo.event.*; /** * This class manages the Wang-Landau 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 WLSimulationThread extends AbstractSimulationThread { private WangLandau algorithm; private double[] kTList; // for reweighting private int iteration; private double maxFlatness; /** * Init a new Wang-Landau simulatin thread. * Reweighting will be carried out from kTstart to kTend in kTsteps. * @param dE histogram bin width * @param weight initial weight for updating S(E), i.e. S(E)+=weight; then weight/=2 after each iteration. * @param maxFlatness maximum histogram flatness below which the update weight is divided by 2. */ //public WLSimulationThread(WLApplet controller, double kTstart, double kTend, int kTsteps, double dE, double weight, double maxFlatness){ public WLSimulationThread(WLApplet controller, double kTstart, double kTend, int kTsteps, double weight, double maxFlatness){ super(controller); this.algorithm = controller.getLattice().createWangLandau(controller.getSamplesBag(),weight);// par défaut iteration=0; this.maxFlatness = maxFlatness; setTemperatureRange(kTstart, kTend, kTsteps); } public WLDOSHistogram getWLDOSHistogram(){ return algorithm.wlDosHistogram; } // N/A for WL algo (local-update only) public boolean setAlgorithm(String algo){ return false; } public String toString(){ String s = "WLSimulationThread:\n"; return s; } public double getMaxFlatness(){ return maxFlatness; } public void setMaxFlatness(double f){ this.maxFlatness = f; } public void setWeight(double w){ algorithm.wlDosHistogram.setWeight(w); controller.getControlPane().setRunName("WL-weight="+Double.toString(w)); ((WLApplet)controller).getSimulationCustomizer().updateWeightTextField(w); } // --- acceptance rates --- public String getCountersRateLabel(){ return algorithm.getCountersRateLabel(); } public void reinitCounters(){ algorithm.reinitCounters(); } // --- implementation of abstract methods for iteration management --- protected boolean configureNextRun(){ //controller.getSamplesBag().resetSamplesGraphs(); double w = algorithm.wlDosHistogram.getWeight(); controller.getControlPane().setRunName(Localizer.get("WLweight")+"="+Double.toString(w)); return true; } protected void sweep(){ this.algorithm.sweep(); } protected boolean finalizeRun(){ final int sz = controller.getSamplesBag().size(); if (sz==0 || sz%nbMCSteps !=0) return false; WLDOSHistogram h = algorithm.wlDosHistogram; h.normalize(); double flatness = h.flatness(); double energyGS = controller.getLattice().getGroundstateEnergy(); double minEnergy = h.xAxis().binLowerEdge(0); if (minEnergy <= energyGS){ if (flatness < maxFlatness) { ((WLApplet)controller).getThermalAveragesSet().storeSimulationResults(this); // also backup histogram controller.showStatus(Localizer.get("GroundstateReached")+"/"+Localizer.get("HistogramFlatness")+"="+flatness+" < "+maxFlatness); iteration++; // reset histogram h.reset(); // update weight double oldWeight = h.getWeight(); setWeight(oldWeight/2.0); controller.getSamplesBag().resetSamplesGraphs(); return true; } else controller.showStatus(Localizer.get("GroundstateReached")+"/"+Localizer.get("HistogramFlatness")+"="+flatness+" > "+maxFlatness); } return false; } // --------------- UI ----------------- public Choice createAlgoChoice(){ return null; } // --------------- reweighting parameters --- public double getKTStart(){ return kTList[0]; } public double getKTEnd(){ return kTList[kTList.length-1]; } public int getKTSteps(){ return kTList.length; } public double[] getKTList(){ return kTList; } /** * 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