Update on codes

This commit is contained in:
mhjensen
2017-10-04 13:47:32 +02:00
parent 016c52ef45
commit 6b7f0670e6
6 changed files with 500055 additions and 998 deletions
+5 -15
View File
@@ -64,7 +64,7 @@ int main(int argc, char* argv[])
ofile.open(fileout);
// Start Monte Carlo sampling by looping over the selcted Temperatures
for (double Temperature = InitialTemp; Temperature <= FinalTemp; Temperature+=TempStep){
vec ExpectationValues = zeros<mat>(5);
vec ExpectationValues = zeros<mat>(2);
// Start Monte Carlo computation and get expectation values
MetropolisSampling(NSpins, MCcycles, Temperature, ExpectationValues);
//
@@ -113,10 +113,8 @@ void MetropolisSampling(int NSpins, int MCcycles, double Temperature, vec &Expec
}
}
// update expectation values for local node
ExpectationValues(0) += Energy; ExpectationValues(1) += Energy*Energy;
ExpectationValues(2) += MagneticMoment;
ExpectationValues(3) += MagneticMoment*MagneticMoment;
ExpectationValues(4) += fabs(MagneticMoment);
ExpectationValues(0) += Energy;
ExpectationValues(1) += MagneticMoment;
}
} // end of Metropolis sampling over spins
@@ -146,20 +144,12 @@ void WriteResultstoFile(int NSpins, int MCcycles, double temperature, vec Expect
{
double norm = 1.0/((double) (MCcycles)); // divided by number of cycles
double E_ExpectationValues = ExpectationValues(0)*norm;
double E2_ExpectationValues = ExpectationValues(1)*norm;
double M_ExpectationValues = ExpectationValues(2)*norm;
double M2_ExpectationValues = ExpectationValues(3)*norm;
double Mabs_ExpectationValues = ExpectationValues(4)*norm;
double M_ExpectationValues = ExpectationValues(1)*norm;
// all expectation values are per spin, divide by 1/NSpins/NSpins
double Evariance = (E2_ExpectationValues- E_ExpectationValues*E_ExpectationValues)/NSpins/NSpins;
double Mvariance = (M2_ExpectationValues - Mabs_ExpectationValues*Mabs_ExpectationValues)/NSpins/NSpins;
ofile << setiosflags(ios::showpoint | ios::uppercase);
ofile << setw(15) << setprecision(8) << temperature;
ofile << setw(15) << setprecision(8) << E_ExpectationValues/NSpins/NSpins;
ofile << setw(15) << setprecision(8) << Evariance/temperature/temperature;
ofile << setw(15) << setprecision(8) << M_ExpectationValues/NSpins/NSpins;
ofile << setw(15) << setprecision(8) << Mvariance/temperature;
ofile << setw(15) << setprecision(8) << Mabs_ExpectationValues/NSpins/NSpins << endl;
ofile << setw(15) << setprecision(8) << M_ExpectationValues/NSpins/NSpins << endl;
} // end output function
File diff suppressed because it is too large Load Diff
Binary file not shown.
@@ -1,726 +0,0 @@
#include "vectormatrixclass.h"
Point::Point(int dim){
dimension = dim;
data = new double[dimension];
for(int i=0;i<dimension;i++)
data[i] = 0.0;
}
Point::Point(const Point &v){
dimension = v.Dimension();
data = new double[dimension];
for(int i=0;i<dimension;i++)
data[i] = v.data[i];
}
Point::~Point(){
dimension = 0;
delete[] data;
data = NULL;
}
int Point::Dimension() const{
return(dimension);
}
double Point::operator()(const int i) const{
if(i>=0 && i<dimension)
return data[i];
cerr << "Point::Invalid index " << i << " for Point of dimension " << dimension << endl;
return(0);
}
double& Point::operator()(const int i){
if(i>=0 && i<dimension)
return data[i];
cerr << "Point::Invalid index " << i << " for Point of dimension " << dimension << endl;
return(data[0]);
}
Point& Point::operator=(const Point &v) {
dimension = v.Dimension();
for(int i=0;i<dimension;i++)
data[i] = v.data[i];
return *this;
};
void Point::Print() const{
cout << endl;
cout << "[ ";
if(dimension>0)
cout << data[0];
for(int i=1;i<dimension;i++)
cout << "; " << data[i];
cout << " ]" << endl;
}
Vector::Vector(){
dimension = 0;
data = NULL;
}
Vector::Vector(int dim){
dimension = dim;
data = new double[dimension];
for(int i=0;i<dimension;i++)
data[i] = 0.0;
}
Vector::Vector(const Vector &v){
dimension = v.Dimension();
data = new double[dimension];
for(int i=0;i<dimension;i++)
data[i] = v.data[i];
}
Vector::Vector(int col, const Matrix &A){
dimension = A.Rows();
data = new double[dimension];
for(int i=0;i<A.Rows();i++)
data[i] = A(i,col);
}
Vector::~Vector(){
dimension = 0;
delete[] data;
data = NULL;
}
void Vector::Initialize(int dim){
if(dimension!=0)
delete[] data;
dimension = dim;
data = new double[dimension];
for(int i=0;i<dimension;i++)
data[i] = 0.0;
}
int Vector::Dimension() const{
return(dimension);
}
double Vector::operator()(const int i) const{
if(i>=0 && i<dimension)
return data[i];
cerr << "Vector::Invalid index " << i << " for Vector of dimension " << dimension << endl;
return(0);
}
double& Vector::operator()(const int i){
if(i>=0 && i<dimension)
return data[i];
cerr << "Vector::Invalid index " << i << " for Vector of dimension " << dimension << endl;
return(data[0]);
}
Vector& Vector::operator=(const Vector &v) {
dimension = v.Dimension();
for(int i=0;i<dimension;i++)
data[i] = v.data[i];
return *this;
};
void Vector::Print() const{
cout << endl;
cout << "[ ";
if(dimension>0)
cout << data[0];
for(int i=1;i<dimension;i++)
cout << "; " << data[i];
cout << " ]" << endl;
}
double Vector::Norm_l1(){
double sum = 0.0;
for(int i=0;i<dimension;i++)
sum += fabs(data[i]);
return(sum);
}
double Vector::Norm_l2(){
double sum = 0.0;
for(int i=0;i<dimension;i++)
sum += data[i]*data[i];
return(sqrt(sum));
}
void Vector::Normalize(){
double tmp = 1.0/Norm_l2();
for(int i=0;i<dimension;i++)
data[i] = data[i]*tmp;
}
double Vector::Norm_linf(){
double maxval = 0.0,tmp;
for(int i=0;i<dimension;i++){
tmp = fabs(data[i]);
maxval = (maxval > tmp)?maxval:tmp;
}
return(maxval);
}
double Vector::MaxMod(){
double maxm = -1.0e+10;
for(int i=0; i<dimension; i++)
maxm = (maxm > fabs(data[i]))?maxm:fabs(data[i]);
return maxm;
}
double Vector::ElementofMaxMod(){
return(data[MaxModindex()]);
}
int Vector::MaxModindex(){
double maxm = -1.0e+10;
int maxmindex = 0;
for(int i=0; i<dimension; i++){
if(maxm<fabs(data[i])){
maxm = fabs(data[i]);
maxmindex = i;
}
}
return maxmindex;
}
void Vector::Initialize(double a){
for(int i=0; i<dimension; i++)
data[i] = a;
}
void Vector::Initialize(double *v){
for(int i=0; i<dimension; i++)
data[i] = v[i];
}
Matrix::Matrix(int dim){
rows = dim;
columns = dim;
data = new double*[rows];
for(int i=0;i<rows;i++){
data[i] = new double[columns];
for(int j=0;j<columns;j++)
data[i][j] = 0.0;
}
}
Matrix::Matrix(int rows1, int columns1){
rows = rows1;
columns = columns1;
data = new double*[rows];
for(int i=0;i<rows;i++){
data[i] = new double[columns];
for(int j=0;j<columns;j++)
data[i][j] = 0.0;
}
}
Matrix::Matrix(const Matrix& m){
rows = m.rows;
columns = m.columns;
data = new double*[rows];
for(int i=0;i<rows;i++){
data[i] = new double[columns];
for(int j=0; j<columns; j++)
data[i][j] = m.data[i][j];
}
}
Matrix::Matrix(int num_Vectors, const Vector * q){
rows = q[0].Dimension();
columns = num_Vectors;
data = new double*[rows];
for(int i=0;i<rows;i++){
data[i] = new double[columns];
for(int j=0; j<columns; j++)
data[i][j] = q[j](i);
}
}
Matrix::Matrix(int rows1, int columns1, double **rowptrs){
rows = rows1;
columns = columns1;
data = new double*[rows];
for(int i=0;i<rows;i++)
data[i] = rowptrs[i];
}
Matrix::~Matrix(){
for(int i=0;i<rows;i++)
delete[] data[i];
rows = 0;
columns = 0;
delete[] data;
}
int Matrix::Rows() const{
return(rows);
}
int Matrix::Columns() const{
return(columns);
}
double **Matrix::GetPointer(){
return(data);
}
void Matrix::GetColumn(int col, Vector &x){
x.Initialize(0.0);
for(int i=0;i<rows;i++)
x(i) = data[i][col];
}
void Matrix::GetColumn(int col, Vector &x, int rowoffset){
x.Initialize(0.0);
for(int i=0;i<rows-rowoffset;i++)
x(i) = data[i+rowoffset][col];
}
void Matrix::PutColumn(int col, const Vector &x){
for(int i=0;i<rows;i++)
data[i][col] = x(i);
}
double Matrix::Norm_linf(){
double maxval = 0.0,sum;
for(int i=0;i<rows;i++){
sum = 0.0;
for(int j=0;j<columns;j++)
sum += fabs(data[i][j]);
maxval = (maxval > sum)?maxval:sum;
}
return(maxval);
}
double Matrix::Norm_l1(){
double maxval = 0.0,sum;
for(int j=0;j<columns;j++){
sum = 0.0;
for(int i=0;i<rows;i++)
sum += fabs(data[i][j]);
maxval = (maxval > sum)?maxval:sum;
}
return(maxval);
}
Matrix& Matrix::operator=(const Matrix &m){
if( (rows == m.rows) && (columns == m.columns)){
for(int i=0; i<rows; i++)
for(int j=0;j<columns;j++){
data[i][j] = m.data[i][j];
}
}
else
cerr << "Matrix Error: Cannot equate matrices of different sizes\n";
return *this;
}
double Matrix::operator()(const int i, const int j) const {
if( (i>=0) && (j>=0) && (i<rows) && (j<columns))
return(data[i][j]);
else
cerr << "Matrix Error: Invalid Matrix indices (" << i << "," << j <<
"), for Matrix of size " << rows << " X " << columns << endl;
return((double)0);
}
double& Matrix::operator()(const int i, const int j) {
if( (i>=0) && (j>=0) && (i<rows) && (j<columns))
return(data[i][j]);
else
cerr << "Matrix Error: Invalid Matrix indices (" << i << "," << j <<
"), for Matrix of size " << rows << " X " << columns << endl;;
return(data[0][0]);
}
void Matrix::Print() const{
cout << endl;
cout << "[ ";
for(int i=0;i<rows;i++){
cout << data[i][0];
for(int j=1;j<columns;j++)
cout << " " << data[i][j];
if(i!=(rows-1))
cout << ";\n";
}
cout << " ]" << endl;
}
double Matrix::MaxModInRow(int row){
double maxv = -1.0e+10;
for(int i=0;i<columns;i++)
maxv = (fabs(data[row][i])>maxv)?fabs(data[row][i]):maxv;
return maxv;
}
double Matrix::MaxModInRow(int row, int starting_column){
double maxv = -1.0e+10;
for(int i=starting_column;i<columns;i++)
maxv = (fabs(data[row][i])>maxv)?fabs(data[row][i]):maxv;
return maxv;
}
int Matrix::MaxModInRowindex(int row){
int maxvindex = 0;
double maxv = -1.0e+10;
for(int i=0;i<columns;i++){
if(maxv < fabs(data[row][i])){
maxv = fabs(data[row][i]);
maxvindex = i;
}
}
return maxvindex;
}
int Matrix::MaxModInRowindex(int row, int starting_column){
int maxvindex = 0;
double maxv = -1.0e+10;
for(int i=starting_column;i<columns;i++){
if(maxv < fabs(data[row][i])){
maxv = fabs(data[row][i]);
maxvindex = i;
}
}
return maxvindex;
}
double Matrix::MaxModInColumn(int column){
double maxv = -1.0e+10;
for(int i=0;i<rows;i++)
maxv = (fabs(data[i][column])>maxv)?fabs(data[i][column]):maxv;
return maxv;
}
double Matrix::MaxModInColumn(int column, int starting_row){
double maxv = -1.0e+10;
for(int i=starting_row;i<rows;i++)
maxv = (fabs(data[i][column])>maxv)?fabs(data[i][column]):maxv;
return maxv;
}
int Matrix::MaxModInColumnindex(int column){
int maxvindex = 0;
double maxv = -1.0e+10;
for(int i=0;i<rows;i++){
if(maxv < fabs(data[i][column])){
maxv = fabs(data[i][column]);
maxvindex = i;
}
}
return maxvindex;
}
int Matrix::MaxModInColumnindex(int column, int starting_column){
int maxvindex = 0;
double maxv = -1.0e+10;
for(int i=starting_column;i<rows;i++){
if(maxv < fabs(data[i][column])){
maxv = fabs(data[i][column]);
maxvindex = i;
}
}
return maxvindex;
}
void Matrix::RowSwap(int row1, int row2){
double * tmp = data[row1];
data[row1] = data[row2];
data[row2] = tmp;
}
/****************************************************************/
/* Operator Definitions */
/****************************************************************/
Vector operator-(const Vector& v){
Vector x(v.Dimension());
for(int i=0;i<v.Dimension();i++)
x(i) = -v(i);
return x;
}
Vector operator+(const Vector& v1, const Vector& v2){
int min_dim = min_dimension(v1,v2);
Vector x(min_dim);
for(int i=0;i<min_dim;i++)
x(i) = v1(i) + v2(i);
return x;
}
Vector operator-(const Vector& v1, const Vector& v2){
int min_dim = min_dimension(v1,v2);
Vector x(min_dim);
for(int i=0;i<min_dim;i++)
x(i) = v1(i) - v2(i);
return x;
}
Vector operator/(const Vector& v, const double s) {
Vector x(v.Dimension());
for(int i=0;i<v.Dimension();i++)
x(i) = v(i)/s;
return x;
}
Vector operator*(const double s, const Vector &v) {
Vector x(v.Dimension());
for(int i=0;i<v.Dimension();i++)
x(i) = s*v(i);
return x;
}
Vector operator*(const Vector& v, const double s) {
Vector x(v.Dimension());
for(int i=0;i<v.Dimension();i++)
x(i) = s*v(i);
return x;
}
Vector operator*(const Matrix& A, const Vector& x){
int rows = A.Rows(), columns = A.Columns();
int dim = x.Dimension();
Vector b(dim);
if(columns != dim){
cerr << "Invalid dimensions given in matrix-vector multiply" << endl;
return(b);
}
for(int i=0;i<rows;i++){
b(i) = 0.0;
for(int j=0;j<columns;j++){
b(i) += A(i,j)*x(j);
}
}
return b;
}
/****************************************************************/
/* Function Definitions */
/****************************************************************/
int min_dimension(const Vector& v1, const Vector& v2){
int min_dim = (v1.Dimension()<v2.Dimension())?v1.Dimension():v2.Dimension();
return(min_dim);
}
double dot(const Vector& u, const Vector& v){
double sum = 0.0;
int min_dim = min_dimension(u,v);
for(int i=0;i<min_dim;i++)
sum += u(i)*v(i);
return sum;
}
double dot(int N, const Vector& u, const Vector& v){
double sum = 0.0;
for(int i=0;i<N;i++)
sum += u(i)*v(i);
return sum;
}
double dot(int N, double *a, double *b){
double sum = 0.0;
for(int i=0;i<N;i++)
sum += a[i]*b[i];
return sum;
}
/*******************************/
/* Log base 2 of a number */
/*******************************/
double log2(double x){
return(log(x)/log(2.0));
}
void Swap(double &a, double &b){
double tmp = a;
a = b;
b = tmp;
}
double Sign(double x){
double xs;
xs = (x>=0.0)?1.0:-1.0;
return xs;
}
//GammaF function valid for x integer, or x (integer+0.5)
double GammaF(double x){
double gamma = 1.0;
if (x == -0.5)
gamma = -2.0*sqrt(M_PI);
else if (!x) return gamma;
else if ((x-(int)x) == 0.5){
int n = (int) x;
double tmp = x;
gamma = sqrt(M_PI);
while(n--){
tmp -= 1.0;
gamma *= tmp;
}
}
else if ((x-(int)x) == 0.0){
int n = (int) x;
double tmp = x;
while(--n){
tmp -= 1.0;
gamma *= tmp;
}
}
return gamma;
}
int Factorial(int n){
int value=1;
for(int i=n;i>0;i--)
value = value*i;
return value;
}
double ** CreateMatrix(int m, int n){
double ** mat;
mat = new double*[m];
for(int i=0;i<m;i++){
mat[i] = new double[n];
for(int j=0;j<m;j++)
mat[i][j] = 0.0;
}
return mat;
}
int ** ICreateMatrix(int m, int n){
int ** mat;
mat = new int*[m];
for(int i=0;i<m;i++){
mat[i] = new int[n];
for(int j=0;j<m;j++)
mat[i][j] = 0;
}
return mat;
}
void DestroyMatrix(double ** mat, int m, int n){
for(int i=0;i<m;i++)
delete[] mat[i];
delete[] mat;
}
void IDestroyMatrix(int ** mat, int m, int n){
for(int i=0;i<m;i++)
delete[] mat[i];
delete[] mat;
}
@@ -1,187 +0,0 @@
#ifndef _vectormatrixclass
#define _vectormatrixclass
#include <cmath>
#include <iostream>
using namespace std;
class Point;
class Vector;
class Matrix;
/********************************/
/* Point Class */
/********************************/
class Point{
private:
int dimension;
double *data;
public:
Point(int dim);
Point(const Point& v);
~Point();
int Dimension() const;
//************************
// User Defined Operators
//************************
int operator==(const Point& v) const;
int operator!=(const Point& v) const;
Point & operator=(const Point& v);
double operator()(const int i) const;
double& operator()(const int i);
void Print() const;
};
/********************************/
/* Vector Class */
/********************************/
class Vector{
private:
int dimension;
double *data;
public:
Vector();
Vector(int dim);
Vector(const Vector& v);
Vector(int col, const Matrix &A);
~Vector();
void Initialize(int dim);
int Dimension() const;
double Length(); /* Euclidean Norm of the Vector */
void Normalize();
double Norm_l1();
double Norm_l2();
double Norm_linf();
double MaxMod();
double ElementofMaxMod();
int MaxModindex();
//************************
// User Defined Operators
//************************
int operator==(const Vector& v) const;
int operator!=(const Vector& v) const;
Vector & operator=(const Vector& v);
double operator()(const int i) const;
double& operator()(const int i);
void Print() const;
void Initialize(double a);
void Initialize(double *v);
};
/********************************/
/* Matrix Class */
/********************************/
class Matrix {
private:
int rows, columns;
double **data;
public:
Matrix(int dim);
Matrix(int rows1, int columns1);
Matrix(const Matrix& m);
Matrix(int num_vectors, const Vector * q);
Matrix(int rows1, int columns1, double **rowptrs);
~Matrix();
int Rows() const;
int Columns() const;
double ** GetPointer();
void GetColumn(int col, Vector &x);
void GetColumn(int col, Vector &x, int rowoffset);
void PutColumn(int col, const Vector &x);
double Norm_l1();
double Norm_linf();
//************************
// User Defined Operators
//************************
Matrix& operator=(const Matrix& m);
double operator()(const int i, const int j) const;
double& operator()(const int i, const int j);
double MaxModInRow(int row);
double MaxModInRow(int row, int starting_column);
int MaxModInRowindex(int row);
int MaxModInRowindex(int row, int starting_column);
double MaxModInColumn(int column);
double MaxModInColumn(int column, int starting_row);
int MaxModInColumnindex(int column);
int MaxModInColumnindex(int column, int starting_row);
void RowSwap(int row1, int row2);
void Print() const;
};
/********************************/
/* Operator Declarations */
/********************************/
// Unitary operator -
Vector operator-(const Vector& v);
// Binary operator +,-
Vector operator+(const Vector& v1, const Vector& v2);
Vector operator-(const Vector& v1, const Vector& v2);
// Vector Scaling (multiplication by a scaler : defined commutatively)
Vector operator*(const double s, const Vector& v);
Vector operator*(const Vector& v, const double s);
// Vector Scaling (division by a scaler)
Vector operator/(const Vector& v, const double s);
Vector operator*(const Matrix& A, const Vector& x);
/********************************/
/* Function Declarations */
/********************************/
int min_dimension(const Vector& u, const Vector& v);
double dot(const Vector& u, const Vector& v);
double dot(int N, double *a, double *b);
double dot(int N, const Vector &u, const Vector &v);
void Swap(double &a, double &b);
double Sign(double x);
/* Misc. useful functions to have */
double log2(double x);
double GammaF(double x);
int Factorial(int n);
double ** CreateMatrix(int m, int n);
void DestroyMatrix(double ** mat, int m, int n);
int ** ICreateMatrix(int m, int n);
void IDestroyMatrix(int ** mat, int m, int n);
#endif
@@ -1,15 +1,16 @@
// Variational Monte Carlo for atoms with importance sampling, slater det
// Variational Monte Carlo for atoms and quantum dots with importance sampling
// Test case for 2-electron quantum dot, no classes using Mersenne-Twister RNG
#include "mpi.h"
// Compile as c++ -O3 -std=c++11 -Rpass=loop-vectorize -o Vmcqdot.x vmcqdot.cpp -larmadillo
#include <cmath>
#include <random>
#include <string>
#include <iostream>
#include <fstream>
#include <iomanip>
#include "vectormatrixclass.h"
#include <armadillo>
using namespace std;
using namespace arma;
// output file as global variable
ofstream ofile;
// the step length and its squared inverse for the second derivative
@@ -21,16 +22,16 @@ int NumberParticles = 2; // we fix also the number of electrons to be 2
// declaration of functions
// The Mc sampling for the variational Monte Carlo
void MonteCarloSampling(int, double &, double &, Vector &);
void MonteCarloSampling(int, double &, double &, vec &);
// The variational wave function
double WaveFunction(Matrix &, Vector &);
double WaveFunction(mat &, vec &);
// The local energy
double LocalEnergy(Matrix &, Vector &);
double LocalEnergy(mat &, vec &);
// The quantum force
void QuantumForce(Matrix &, Matrix &, Vector &);
void QuantumForce(mat &, mat &, vec &);
// inline function for single-particle wave function
@@ -44,7 +45,7 @@ inline double DerivativeSPwavefunction(double r, double alpha) {
}
// function for absolute value of relative distance
double RelativeDistance(Matrix &r, int i, int j) {
double RelativeDistance(mat &r, int i, int j) {
double r_ij = 0;
for (int k = 0; k < Dimension; k++) {
r_ij += (r(i,k)-r(j,k))*(r(i,k)-r(j,k));
@@ -53,12 +54,12 @@ double RelativeDistance(Matrix &r, int i, int j) {
}
// inline function for derivative of Jastrow factor
inline double JastrowDerivative(Matrix &r, double beta, int i, int j, int k){
inline double JastrowDerivative(mat &r, double beta, int i, int j, int k){
return (r(i,k)-r(j,k))/(RelativeDistance(r, i, j)*pow(1.0+beta*RelativeDistance(r, i, j),2));
}
// function for square of position of single particle
double singleparticle_pos2(Matrix &r, int i) {
double singleparticle_pos2(mat &r, int i) {
double r_single_particle = 0;
for (int j = 0; j < Dimension; j++) {
r_single_particle += r(i,j)*r(i,j);
@@ -66,11 +67,11 @@ double singleparticle_pos2(Matrix &r, int i) {
return r_single_particle;
}
void lnsrch(int n, Vector &xold, double fold, Vector &g, Vector &p, Vector &x,
double *f, double stpmax, int *check, double (*func)(Vector &p));
void lnsrch(int n, vec &xold, double fold, vec &g, vec &p, vec &x,
double *f, double stpmax, int *check, double (*func)(vec &p));
void dfpmin(Vector &p, int n, double gtol, int *iter, double *fret,
double(*func)(Vector &p), void (*dfunc)(Vector &p, Vector &g));
void dfpmin(vec &p, int n, double gtol, int *iter, double *fret,
double(*func)(vec &p), void (*dfunc)(vec &p, vec &g));
static double sqrarg;
#define SQR(a) ((sqrarg=(a)) == 0.0 ? 0.0 : sqrarg*sqrarg)
@@ -85,71 +86,50 @@ static double maxarg1,maxarg2;
int main(int argc, char* argv[])
{
// MPI initializations
int NumberProcesses, MyRank, NumberMCsamples;
MPI_Init (&argc, &argv);
MPI_Comm_size (MPI_COMM_WORLD, &NumberProcesses);
MPI_Comm_rank (MPI_COMM_WORLD, &MyRank);
double StartTime = MPI_Wtime();
if (MyRank == 0 && argc <= 1) {
int TotalNumberMCsamples;
if (argc <= 1) {
cout << "Bad Usage: " << argv[0] <<
" Read also output file on same line and number of Monte Carlo cycles" << endl;
}
// Read filename and number of Monte Carlo cycles from the command line
if (MyRank == 0 && argc > 2) {
if (argc > 2) {
string filename = argv[1]; // first command line argument after name of program
NumberMCsamples = atoi(argv[2]);
TotalNumberMCsamples = atoi(argv[2]);
string fileout = filename;
string argument = to_string(NumberMCsamples);
string argument = to_string(TotalNumberMCsamples);
// Final filename as filename+NumberMCsamples
fileout.append(argument);
ofile.open(fileout);
}
// broadcast the number of Monte Carlo samples
MPI_Bcast (&NumberMCsamples, 1, MPI_INT, 0, MPI_COMM_WORLD);
// Two variational parameters only
Vector VariationalParameters(2);
int TotalNumberMCsamples = NumberMCsamples*NumberProcesses;
vec VariationalParameters(2);
// Loop over variational parameters
for (double alpha = 0.5; alpha <= 1.5; alpha +=0.1){
for (double beta = 0.1; beta <= 0.5; beta +=0.05){
VariationalParameters(0) = alpha; // value of alpha
VariationalParameters(1) = beta; // value of beta
// Do the mc sampling and accumulate data with MPI_Reduce
double TotalEnergy, TotalEnergySquared, LocalProcessEnergy, LocalProcessEnergy2;
LocalProcessEnergy = LocalProcessEnergy2 = 0.0;
MonteCarloSampling(NumberMCsamples, LocalProcessEnergy, LocalProcessEnergy2, VariationalParameters);
// Collect data in total averages
MPI_Reduce(&LocalProcessEnergy, &TotalEnergy, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&LocalProcessEnergy2, &TotalEnergySquared, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
// Print out results in case of Master node, set to MyRank = 0
if ( MyRank == 0) {
double Energy = TotalEnergy/( (double)NumberProcesses);
double Variance = TotalEnergySquared/( (double)NumberProcesses)-Energy*Energy;
double StandardDeviation = sqrt(Variance/((double)TotalNumberMCsamples)); // over optimistic error
ofile << setiosflags(ios::showpoint | ios::uppercase);
ofile << setw(15) << setprecision(8) << VariationalParameters(0);
ofile << setw(15) << setprecision(8) << VariationalParameters(1);
ofile << setw(15) << setprecision(8) << Energy;
ofile << setw(15) << setprecision(8) << Variance;
ofile << setw(15) << setprecision(8) << StandardDeviation << endl;
}
double Energy, EnergySquared;
Energy = EnergySquared = 0.0;
MonteCarloSampling(TotalNumberMCsamples, Energy, EnergySquared, VariationalParameters);
double Variance = EnergySquared-Energy*Energy;
double StandardDeviation = sqrt(Variance/((double)TotalNumberMCsamples)); // over optimistic error
ofile << setiosflags(ios::showpoint | ios::uppercase);
ofile << setw(15) << setprecision(8) << VariationalParameters(0);
ofile << setw(15) << setprecision(8) << VariationalParameters(1);
ofile << setw(15) << setprecision(8) << Energy;
ofile << setw(15) << setprecision(8) << Variance;
ofile << setw(15) << setprecision(8) << StandardDeviation << endl;
}
}
double EndTime = MPI_Wtime();
double TotalTime = EndTime-StartTime;
if ( MyRank == 0 ) cout << "Time = " << TotalTime << " on number of processors: " << NumberProcesses << endl;
if (MyRank == 0) ofile.close(); // close output file
// End MPI
MPI_Finalize ();
ofile.close(); // close output file
return 0;
} // end of main function
// Monte Carlo sampling with the Metropolis algorithm
void MonteCarloSampling(int NumberMCsamples, double &cumulative_e, double &cumulative_e2, Vector &VariationalParameters)
void MonteCarloSampling(int NumberMCsamples, double &cumulative_e, double &cumulative_e2, vec &VariationalParameters)
{
// Initialize the seed and call the Mersienne algo
@@ -162,8 +142,8 @@ void MonteCarloSampling(int NumberMCsamples, double &cumulative_e, double &cumul
double D = 0.5;
double timestep = 0.05; // we fix the time step for the gaussian deviate
// allocate matrices which contain the position of the particles
Matrix OldPosition( NumberParticles, Dimension), NewPosition( NumberParticles, Dimension);
Matrix OldQuantumForce(NumberParticles, Dimension), NewQuantumForce(NumberParticles, Dimension);
mat OldPosition( NumberParticles, Dimension), NewPosition( NumberParticles, Dimension);
mat OldQuantumForce(NumberParticles, Dimension), NewQuantumForce(NumberParticles, Dimension);
double Energy = 0.0; double EnergySquared = 0.0; double DeltaE = 0.0;
// initial trial positions
for (int i = 0; i < NumberParticles; i++) {
@@ -223,7 +203,7 @@ void MonteCarloSampling(int NumberMCsamples, double &cumulative_e, double &cumul
// Function to compute the squared wave function and the quantum force
double WaveFunction(Matrix &r, Vector &VariationalParameters)
double WaveFunction(mat &r, vec &VariationalParameters)
{
double wf = 0.0;
// full Slater determinant for two particles, replace with Slater det for more particles
@@ -231,7 +211,7 @@ double WaveFunction(Matrix &r, Vector &VariationalParameters)
// contribution from Jastrow factor
for (int i = 0; i < NumberParticles-1; i++) {
for (int j = i+1; j < NumberParticles; j++) {
// wf *= exp(RelativeDistance(r, i, j)/((1.0+VariationalParameters(1)*RelativeDistance(r, i, j))));
wf *= exp(RelativeDistance(r, i, j)/((1.0+VariationalParameters(1)*RelativeDistance(r, i, j))));
}
}
return wf;
@@ -239,13 +219,13 @@ double WaveFunction(Matrix &r, Vector &VariationalParameters)
// Function to calculate the local energy without numerical derivation of kinetic energy
double LocalEnergy(Matrix &r, Vector &VariationalParameters)
double LocalEnergy(mat &r, vec &VariationalParameters)
{
// compute the kinetic and potential energy from the single-particle part
// for a many-electron system this has to be replaced by a Slater determinant
// The absolute value of the interparticle length
Matrix length( NumberParticles, NumberParticles);
mat length( NumberParticles, NumberParticles);
// Set up interparticle distance
for (int i = 0; i < NumberParticles-1; i++) {
for(int j = i+1; j < NumberParticles; j++){
@@ -260,7 +240,7 @@ double LocalEnergy(Matrix &r, Vector &VariationalParameters)
double sum1 = 0.0;
for(int j = 0; j < NumberParticles; j++){
if ( j != i) {
//sum1 += JastrowDerivative(r, VariationalParameters(1), i, j, k);
sum1 += JastrowDerivative(r, VariationalParameters(1), i, j, k);
}
}
KineticEnergy += (sum1+DerivativeSPwavefunction(r(i,k),VariationalParameters(0)))*(sum1+DerivativeSPwavefunction(r(i,k),VariationalParameters(0)));
@@ -269,7 +249,7 @@ double LocalEnergy(Matrix &r, Vector &VariationalParameters)
KineticEnergy += -2*VariationalParameters(0)*NumberParticles;
for (int i = 0; i < NumberParticles-1; i++) {
for (int j = i+1; j < NumberParticles; j++) {
// KineticEnergy += 2.0/(pow(1.0 + VariationalParameters(1)*length(i,j),2))*(1.0/length(i,j)-2*VariationalParameters(1)/(1+VariationalParameters(1)*length(i,j)) );
KineticEnergy += 2.0/(pow(1.0 + VariationalParameters(1)*length(i,j),2))*(1.0/length(i,j)-2*VariationalParameters(1)/(1+VariationalParameters(1)*length(i,j)) );
}
}
KineticEnergy *= -0.5;
@@ -282,7 +262,7 @@ double LocalEnergy(Matrix &r, Vector &VariationalParameters)
// Add the electron-electron repulsion
for (int i = 0; i < NumberParticles-1; i++) {
for (int j = i+1; j < NumberParticles; j++) {
//PotentialEnergy += 1.0/length(i,j);
PotentialEnergy += 1.0/length(i,j);
}
}
double LocalE = KineticEnergy+PotentialEnergy;
@@ -290,7 +270,7 @@ double LocalEnergy(Matrix &r, Vector &VariationalParameters)
}
// Compute the analytical expression for the quantum force
void QuantumForce(Matrix &r, Matrix &qforce, Vector &VariationalParameters)
void QuantumForce(mat &r, mat &qforce, vec &VariationalParameters)
{
// compute the first derivative
for (int i = 0; i < NumberParticles; i++) {
@@ -315,14 +295,14 @@ void QuantumForce(Matrix &r, Matrix &qforce, Vector &VariationalParameters)
#define TOLX (4*EPS)
#define STPMX 100.0
void dfpmin(Vector &p, int n, double gtol, int *iter, double *fret,
double(*func)(Vector &p), void (*dfunc)(Vector &p, Vector &g))
void dfpmin(vec &p, int n, double gtol, int *iter, double *fret,
double(*func)(vec &p), void (*dfunc)(vec &p, vec &g))
{
int check,i,its,j;
double den,fac,fad,fae,fp,stpmax,sum=0.0,sumdg,sumxi,temp,test;
Vector dg(n), g(n), hdg(n), pnew(n), xi(n);
Matrix hessian(n,n);
vec dg(n), g(n), hdg(n), pnew(n), xi(n);
mat hessian(n,n);
fp=(*func)(p);
(*dfunc)(p,g);
@@ -398,8 +378,8 @@ void dfpmin(Vector &p, int n, double gtol, int *iter, double *fret,
#define ALF 1.0e-4
#define TOLX 1.0e-7
void lnsrch(int n, Vector &xold, double fold, Vector &g, Vector &p, Vector &x,
double *f, double stpmax, int *check, double (*func)(Vector &p))
void lnsrch(int n, vec &xold, double fold, vec &g, vec &p, vec &x,
double *f, double stpmax, int *check, double (*func)(vec &p))
{
int i;
double a,alam,alam2,alamin,b,disc,f2,fold2,rhs1,rhs2,slope,sum,temp,