Diffusion Quantum Monte Carlo (Verwendung des Programm-Pakets von Ian Terrell, http://merlin.physics.wm.edu/~ian/dmcview/)
DQMC_H2
Run main
|
DMC.java
//package dmc;
//import rvg.VariateGenerator;
import java.util.Vector;
import java.util.Iterator;
import java.lang.Math;
import java.lang.ArithmeticException;
import java.lang.System;
/**
* A Diffusion Monte Carlo Simulation.
*
* This class implements the basic DMC structure as outlined in
* "Introduction to the Diffusion Monte Carlo Method" by Ioan Kosztin,
* Byron Faber and Klaus Schulten in 1995.
*
* It only provides the basic methods for the walkers to be moved,
* to be born and to die. The actual simulation loop with start and
* end conditions must be implemented in another class.
*
* This class is meant to be subclassed; the child class will overwrite
* the V() function to give the simulation a valid potential.
*
* @author Ian Terrell
*/
public class DMC
{
/*************
* CONSTANTS *
*************/
public final static int DEFAULT_NUM_WALKERS = 500;
// default number of walkers
public final static double DEFAULT_DTAU = .1; // default timestep
public final static long DEFAULT_SEED = 123456789;
// default random variate generator seed
public final static double DEFAULT_REF_ENERGY = -1.0;
// default reference energy
public final static boolean DEFAULT_REF_ENERGY_CONSTANT = false;
// default value to whether or not to hold
// the reference energy constant
public final static double DEFAULT_ALPHA = -1.0; // default feedback parameter
public final static double DEFAULT_DELTA_FNC_X0 = 0.0;
// default x_0 used for delta function walker initialization
public final static double DEFAULT_X_MIN = -5.0; // default minimum x value for histogram display
public final static double DEFAULT_X_MAX = 5.0; // default maximum x value for histogram display
public final static double DEFAULT_UNIFORM_A = -4.0;
// default parameter a for a uniformly distributed
// walker initialization
public final static double DEFAULT_UNIFORM_B = 4.0;
// default parameter b for a uniformly distributed
// walker initialization
public final static double DEFAULT_GAUSSIAN_MU = 0.0;
// default parameter mu for a gaussian distributed
// walker initialization
public final static double DEFAULT_GAUSSIAN_SIGMA = 1.0;
// default parameter sigma for a gaussian distributed
// walker initialization
public final static int INIT_DELTA_FNC = 0; // Initialization mode for walkers
public final static int INIT_UNIFORM = 1;
public final static int INIT_GAUSSIAN = 2;
/*****************
* DATA ELEMENTS *
*****************/
public Vector walkers; // array of walkers
public int numWalkers; // desired number of walkers
public double dTau; // timestep
public double tau; // current time
public double refEnergy; // reference energy
public double alpha; // feedback parameter
public VariateGenerator rvg; // random variate generator
public boolean refEnergyConstant; // whether or not to hold the reference energy constant
/**********
* METHODS *
***********/
/**
* Constructor. Takes one of everything and initializes the simulation.
*
* @param numWalkers The number of walkers to start the simulation with.
* @param refEnergy The reference energy to start the simulation with. If it is
* negative, use the current average energy of all the walkers.
* @param refEnergyConstant Whether or not to hold the reference energy constant.
* @param dTau The timestep to use.
* @param alpha The feedback parameter to use (use -1.0 to use the default value
* of 1/dTau).
* @param seed The long int to seed the random variate generator.
* @param initMode The mode in which to initialize the random walkers.
* @param param1 First parameter for the initialization mode.
* X_0 for delta functions, a for Uniform, mu for Gaussian
* @param param2 Second parameter for the initialization mode.
* unused for delta functions, b for Uniform, sigma for Gaussian
*/
public DMC(int numWalkers, double refEnergy, boolean refEnergyConstant,
double dTau, double alpha, long seed,
int initMode, double param1, double param2)
{
this.numWalkers = numWalkers;
this.dTau = dTau;
tau = 0.0;
this.refEnergyConstant = refEnergyConstant;
this.alpha = alpha;
rvg = new VariateGenerator(seed);
// Initialize the walkers:
double totalEnergy = 0.0;
walkers = new Vector(numWalkers);
switch (initMode)
{
case INIT_DELTA_FNC:
for (int i = 0; i < numWalkers; i++)
{
Walker w = new Walker(param1, param1,param1,param1, param1,param1);
totalEnergy += V(w.x, w.y, w.z,w.x2, w.y2, w.z2);
// Energie für Walker i
walkers.add(w); // Walker-Elemente
werden dem Vektor walkers hinzugefügt
}
break;
case INIT_UNIFORM:
for (int i = 0; i < numWalkers; i++)
{
Walker w = new
Walker(rvg.Uniform(param1,param2),rvg.Uniform(param1,param2),rvg.Uniform(param1,param2),
rvg.Uniform(param1,param2),rvg.Uniform(param1,param2),rvg.Uniform(param1,param2));
totalEnergy += V(w.x, w.y, w.z,w.x2, w.y2, w.z2);
walkers.add(w);
}
break;
case INIT_GAUSSIAN:
for (int i = 0; i < numWalkers; i++)
{
Walker w = new
Walker(rvg.Normal(param1,param2),rvg.Normal(param1,param2),rvg.Normal(param1,param2),
rvg.Normal(param1,param2),rvg.Normal(param1,param2),rvg.Normal(param1,param2));
totalEnergy += V(w.x, w.y, w.z,w.x2, w.y2, w.z2);
walkers.add(w);
}
break;
}
if (refEnergy < 0) // das ist
der Normalfall
this.refEnergy = totalEnergy / numWalkers;
else
this.refEnergy = refEnergy;
}
/**
* This constructor constructs a simulation with a delta function walker
* initialization about point initialPosition, the seed given, and the number
* of walkers given, but everything else with default values.
*
* @param numWalkers The number of walkers to start the simulation with.
* @param initialPosition The position at which to start the walkers.
* @param seed The long int to seed the random variate generator.
*/
public DMC(int numWalkers, double initialPosition, long seed)
{
this(numWalkers, DEFAULT_REF_ENERGY, DEFAULT_REF_ENERGY_CONSTANT,
DEFAULT_DTAU, DEFAULT_ALPHA, seed,
INIT_DELTA_FNC, initialPosition, 0);
}
/**
* This is the potential energy function, and is meant
* to be overwritten by a derived class.
*
* @param x The point at which to get the potential
* @return Returns the potential energy at point x
*/
public double V(double x,double y,double z,double x2, double y2, double z2)
{
return x; // Rückgabewert hier ohne
Bedeutung, da die Methode überschrieben werden muss, s.
DMC_H2
}
/**
* This function returns the weight of a walker.
*
* @param w The walker to return the weight of.
*/
public double Weight(Walker w)
{
return Math.exp(-(V(w.x, w.y, w.z,w.x2, w.y2, w.z2) - refEnergy)*dTau);
}
/**
* This function does one complete iteration of the simulation,
* including moving the walkers, branching them, and updating the
* reference energy.
*/
public void Iterate()
{
walk();
branch();
tau += dTau;
// Einfügung zur Ausgabe der
Gesamtenergie nach jedem Zeitschritt
//System.out.println("tau = " + tau + " Energy = " + this.refEnergy);
System.out.println(this.refEnergy);
}
/**
* This function moves each of the walkers, and updates the reference
* energy with respect to their new positions.
*
* @throws ArithmeticException Thrown if the number of walkers drops to 0.
* A specialized exception should probably
* be made eventually.
*/
public void walk()
{
double totalEnergy = 0.0; // Total potential energy
Iterator i = walkers.iterator();
while (i.hasNext())
{
Walker w = (Walker) i.next();
w.x += Math.sqrt(dTau) * rvg.Normal(0.0,1.0);
// Koordinaten für Elektron1
w.y += Math.sqrt(dTau) * rvg.Normal(0.0,1.0);
w.z += Math.sqrt(dTau) * rvg.Normal(0.0,1.0);
w.x2 += Math.sqrt(dTau) * rvg.Normal(0.0,1.0);
// Koordinaten für Elektron2
w.y2 += Math.sqrt(dTau) * rvg.Normal(0.0,1.0);
w.z2 += Math.sqrt(dTau) * rvg.Normal(0.0,1.0);
totalEnergy += V(w.x, w.y, w.z,w.x2, w.y2, w.z2);
}
int n = walkers.size();
if (n == 0)
throw new ArithmeticException();
double avg = totalEnergy / (double) n;
// Energie pro Walker = mittlere pot.
Energie
if (!refEnergyConstant)
{
if (alpha < 0)
refEnergy = avg - ((double)(n-numWalkers))/(((double)numWalkers)*dTau);
else
refEnergy = avg - alpha*((double)n-numWalkers)/(((double)numWalkers));
// das ist Normalfall
}
}
/**
* Branches the walkers. (Birth/Death process)
*/
public void branch()
{
Vector createdWalkers = new Vector(); // Temp holds new walkers
Iterator i = walkers.iterator();
while (i.hasNext())
{
Walker w = (Walker) i.next();
int m = (int) (Weight(w) + rvg.Uniform(0.0,1.0));
if (m > 3) m = 3;
if (m == 0)
i.remove(); // Walker wird aus
walkers-Vektor entfernt
else
for (int j = 1; j < m; j++)
createdWalkers.add(new Walker(w.x, w.y, w.z,w.x2, w.y2, w.z2));
}
walkers.addAll(createdWalkers); // neue
Walker werden walkers-Vektor hinzugefügt
}
}
Source Code als jGRASP-Projekt: DQMC_H2