/* simulate the Ornstein-Uhlenbeck process */ static void ou(double dt) { double x, sxx = 0; long t, nblk = 0; double expndt = exp(-0.5 * dt); double fluc = sqrt(2 * dt); x = randgaus(); for ( t = 1; t <= nsteps; t++ ) { x *= expndt; x += fluc * randgaus(); x *= expndt; sxx += x * x; if ( t % block == 0 ) { nblk++; } } printf("sxx %g\n", sxx/nsteps); }
static void runmd(void) { long t; int i, j, dof; double ang; /* degrees of freedom for the thermostat */ if ( norot ) { dof = ( constraint ? 1 : 3); } else { dof = constraint ? D * N - 2 : D * N; } for ( i = 0; i < N; i++ ) { for ( j = 0; j < D; j++ ) { v[i][j] = randgaus(); } #if D == 3 /* annihilate the last dimension velocities */ if ( norot ) { v[i][2] = 0; } #endif } trimer_rmcom(norot); for ( t = 1; t <= nsteps + nequil; t++ ) { /* basic velocity verlet */ for ( i = 0; i < N; i++ ) { vsinc(v[i], f[i], 0.5 * dt); vsinc(x[i], v[i], dt); } if ( !constraint ) { ep = force(); } for ( i = 0; i < N; i++ ) { vsinc(v[i], f[i], 0.5 * dt); } ang = vang(x[1], x[0], x[2], NULL, NULL, NULL); if ( t % 1000000 == 0 ) { printf("%g %g %g %g %g %g %g %g %g, ang %g, ep %g\n", x[0][0], x[0][1], x[0][2], x[1][0], x[1][1], x[1][2], x[2][0], x[2][1], x[2][2], ang, ep); // getchar(); } /* apply the constraint */ if ( constraint ) { constrain(1000, 1e-6); } /* apply the thermostat */ if ( thermostat ) { if ( !norot && t % 20 == 0 ) { /* Andersen thermostat */ i = (int) (rand01() * N); for ( j = 0; j < D; j++ ) { v[i][j] = randgaus() * sqrt(tp); } if ( constraint ) { constrain(1000, 1e-6); } /* constraint? */ } else { ek = md_vrescale(v, NULL, N, dof, tp, thermdt); } } else { for ( ek = 0, i = 0; i < N; i++ ) { ek += 0.5 * vsqr( v[i] ); } } if ( t % 10000 == 0 ) { trimer_rmcom(norot); } if ( t < nequil ) continue; /* accumulate histogram of the angle */ if ( ang > HIST_XMIN && ang < HIST_XMAX ) { i = (int) ( (ang - HIST_XMIN) / HIST_DX); hist[i] += 1; } } }
vectorf randgausvec(const float mean, const float sigma, const int num) { vectorf v(num); for (int k = 0; k < num; k++) v[k] = randgaus(mean, sigma); return v; }