-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathtiny_md.c
111 lines (91 loc) · 3.45 KB
/
tiny_md.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#define _XOPEN_SOURCE 500 // M_PI
#include "core.h"
#include "parameters.h"
#include "wtime.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *file_xyz, *file_thermo;
file_xyz = fopen("trajectory.xyz", "w");
file_thermo = fopen("thermo.log", "w");
double Ekin, Epot, Temp, Pres; // variables macroscopicas
double Rho, cell_V, cell_L, tail, Etail, Ptail;
double *rxyz, *vxyz, *fxyz; // variables microscopicas
rxyz = (double*)malloc(3 * N * sizeof(double));
vxyz = (double*)malloc(3 * N * sizeof(double));
fxyz = (double*)malloc(3 * N * sizeof(double));
printf("# Número de partículas: %d\n", N);
printf("# Temperatura de referencia: %.2f\n", T0);
printf("# Pasos de equilibración: %d\n", TEQ);
printf("# Pasos de medición: %d\n", TRUN - TEQ);
printf("# (mediciones cada %d pasos)\n", TMES);
printf("# densidad, volumen, energía potencial media, presión media\n");
fprintf(file_thermo, "# t Temp Pres Epot Etot\n");
srand(SEED);
double t = 0.0, sf;
double Rhob;
Rho = RHOI;
init_pos(rxyz, Rho);
double start = wtime();
for (int m = 0; m < 9; m++) {
Rhob = Rho;
Rho = RHOI - 0.1 * (double)m;
cell_V = (double)N / Rho;
cell_L = cbrt(cell_V);
tail = 16.0 * M_PI * Rho * ((2.0 / 3.0) * pow(RCUT, -9) - pow(RCUT, -3)) / 3.0;
Etail = tail * (double)N;
Ptail = tail * Rho;
int i = 0;
sf = cbrt(Rhob / Rho);
for (int k = 0; k < 3 * N; k++) { // reescaleo posiciones a nueva densidad
rxyz[k] *= sf;
}
init_vel(vxyz, &Temp, &Ekin);
forces(rxyz, fxyz, &Epot, &Pres, &Temp, Rho, cell_V, cell_L);
for (i = 1; i < TEQ; i++) { // loop de equilibracion
velocity_verlet(rxyz, vxyz, fxyz, &Epot, &Ekin, &Pres, &Temp, Rho, cell_V, cell_L);
sf = sqrt(T0 / Temp);
for (int k = 0; k < 3 * N; k++) { // reescaleo de velocidades
vxyz[k] *= sf;
}
}
int mes = 0;
double epotm = 0.0, presm = 0.0;
for (i = TEQ; i < TRUN; i++) { // loop de medicion
velocity_verlet(rxyz, vxyz, fxyz, &Epot, &Ekin, &Pres, &Temp, Rho, cell_V, cell_L);
sf = sqrt(T0 / Temp);
for (int k = 0; k < 3 * N; k++) { // reescaleo de velocidades
vxyz[k] *= sf;
}
if (i % TMES == 0) {
Epot += Etail;
Pres += Ptail;
epotm += Epot;
presm += Pres;
mes++;
fprintf(file_thermo, "%f %f %f %f %f\n", t, Temp, Pres, Epot, Epot + Ekin);
fprintf(file_xyz, "%d\n\n", N);
for (int k = 0; k < 3 * N; k += 3) {
fprintf(file_xyz, "Ar %e %e %e\n", rxyz[k + 0], rxyz[k + 1], rxyz[k + 2]);
}
}
t += DT;
}
printf("%f\t%f\t%f\t%f\n", Rho, cell_V, epotm / (double)mes, presm / (double)mes);
}
double elapsed = wtime() - start;
printf("# Tiempo total de simulación = %f segundos\n", elapsed);
printf("# Tiempo simulado = %f [fs]\n", t * 1.6);
printf("# ns/day = %f\n", (1.6e-6 * t) / elapsed * 86400);
// ^1.6 fs -> ns ^sec -> day
// Cierre de archivos
fclose(file_thermo);
fclose(file_xyz);
// Liberacion de memoria
free(rxyz);
free(fxyz);
free(vxyz);
return 0;
}