mirror of
https://github.com/TREX-CoE/qmc-lttc.git
synced 2024-08-24 22:21:46 +02:00
Solutions in C up to 4
This commit is contained in:
parent
6eb6eed6db
commit
f4d390972d
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@ get_energ
|
||||
get_var
|
||||
qmc_uni
|
||||
qmc_met
|
||||
vmc
|
||||
|
14
hydrogen.h
14
hydrogen.h
@ -46,3 +46,17 @@ double kinetic(double a, double *r, const int l) {
|
||||
double e_loc(double a, double *r, const int l) {
|
||||
return kinetic(a, r, l) + potential(r, l);
|
||||
}
|
||||
|
||||
void drift(double a, double *r, double *d, const int l) {
|
||||
double rnorm, fact;
|
||||
|
||||
for (int i = 0; i < l; ++i) {
|
||||
rnorm += r[i]*r[i];
|
||||
}
|
||||
rnorm = sqrt(rnorm);
|
||||
|
||||
fact = -a / rnorm;
|
||||
for (int i = 0; i < l; ++i) {
|
||||
d[i] = r[i] * fact;
|
||||
}
|
||||
}
|
||||
|
7
qmc_gaussian.c
Normal file
7
qmc_gaussian.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
double gaussian(double *r) {
|
||||
// Pending
|
||||
return 0;
|
||||
}
|
34
qmc_stats.h
34
qmc_stats.h
@ -1,5 +1,7 @@
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
void ave_error(double *x, const int n, double obs[2]) {
|
||||
// obs[1] --> mean and obs[2] --> err
|
||||
@ -25,3 +27,35 @@ void ave_error(double *x, const int n, double obs[2]) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void random_gauss(double *z, const int n) {
|
||||
// Box Muller method
|
||||
const double two_pi = 2.0 * acos(-1.0);
|
||||
double u[n + 1];
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
for (int i = 0; i < n + 1; ++i) {
|
||||
u[i] = (double) rand() / RAND_MAX;
|
||||
}
|
||||
|
||||
|
||||
if (!(n & 1)) {
|
||||
// n is even
|
||||
for (int i = 0; i < n; i+=2) {
|
||||
z[i] = sqrt(-2.0 * log(u[i]));
|
||||
z[i] = z[i] * cos(two_pi * u[i + 1]);
|
||||
z[i + 1] = z[i] * sin(two_pi * u[i + 1]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// n is odd
|
||||
for (int i = 0; i < n - 1; i+=2) {
|
||||
z[i] = sqrt(-2.0 * log(u[i]));
|
||||
z[i] = z[i] * cos(two_pi * u[i + 1]);
|
||||
z[i + 1] = z[i] * sin(two_pi * u[i + 1]);
|
||||
}
|
||||
z[n] = sqrt(-2.0 * log(u[n]));
|
||||
z[n] = z[n] * cos(two_pi * u[n + 1]);
|
||||
}
|
||||
}
|
||||
|
11
tt.c
Normal file
11
tt.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include "qmc_stats.h"
|
||||
|
||||
int main() {
|
||||
double rnd[3];
|
||||
random_gauss(rnd, 3);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
printf("val %lf\n", rnd[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
87
vmc_metropolis.c
Normal file
87
vmc_metropolis.c
Normal file
@ -0,0 +1,87 @@
|
||||
#include "hydrogen.h"
|
||||
#include "qmc_stats.h"
|
||||
|
||||
void variational_montecarlo(double a, const int nmax, double dt,
|
||||
double *energy, double *accept) {
|
||||
int n_accept;
|
||||
double r_old[3], r_new[3], psi_old, psi_new;
|
||||
double d_old[3], d_new[3], d2_old, d2_new;
|
||||
double rnd[3], aval, fact_a, fact_b, fact_exp, u;
|
||||
|
||||
// Initial position
|
||||
random_gauss(r_old, 3);
|
||||
psi_old = psi(a, r_old, 3) * psi(a, r_old, 3);
|
||||
drift(a, r_old, d_old, 3);
|
||||
d2_old = 0.0;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
d2_old += d_old[i] * d_old[i];
|
||||
}
|
||||
|
||||
*energy = 0.0;
|
||||
*accept = 0.0;
|
||||
n_accept = 0;
|
||||
for (int i = 0; i < nmax; ++i) {
|
||||
// Compute and accumulate the local energy
|
||||
*energy += e_loc(a, r_old, 3);
|
||||
|
||||
// Compute new position
|
||||
random_gauss(rnd, 3);
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
r_new[j] = r_old[j] + dt * d_old[j] + rnd[j];
|
||||
}
|
||||
|
||||
// New WF and acceptance probability
|
||||
psi_new = psi(a, r_new, 3) * psi(a, r_new, 3);
|
||||
|
||||
drift(a, r_new, d_new, 3);
|
||||
d2_new = 0.0;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
d2_new += d_new[i] * d_new[i];
|
||||
}
|
||||
|
||||
// Compute the ratio of probabilities q
|
||||
fact_a = 0.5 * dt * (d2_new - d2_old);
|
||||
fact_b = 0.0;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
fact_b += (d_new[i] + d_old[i]) * (r_new[i] - r_old[i]);
|
||||
}
|
||||
fact_exp = exp(fact_b - fact_a);
|
||||
aval = fact_exp * psi_new / psi_old;
|
||||
|
||||
u = (double) rand() / RAND_MAX;
|
||||
|
||||
if (u <= aval) {
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
r_old[j] = r_new[j];
|
||||
d_old[j] = d_new[j];
|
||||
}
|
||||
psi_old = psi_new;
|
||||
n_accept += 1;
|
||||
}
|
||||
}
|
||||
*energy /= nmax;
|
||||
*accept = (double) n_accept / nmax;
|
||||
}
|
||||
|
||||
int main() {
|
||||
const double a = 1.2;
|
||||
const double dt = 1.0;
|
||||
const long nmax = 1e5;
|
||||
int nruns = 30;
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
double ene[nruns], acc[nruns], obs[2];
|
||||
|
||||
for (int i = 0; i < nruns; ++i) {
|
||||
variational_montecarlo(a, nmax, dt, &ene[i], &acc[i]);
|
||||
}
|
||||
|
||||
ave_error(ene, nruns, obs);
|
||||
printf("E = %.5lf +/- %.5lf\n", obs[0], obs[1]);
|
||||
|
||||
ave_error(acc, nruns, obs);
|
||||
printf("A = %.5lf +/- %.5lf\n", obs[0], obs[1]);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user