예제 #1
0
파일: qvmc.cpp 프로젝트: sarahr/QVMC
/**
 * Constructor
 * @param Trial - pointer to trial wavefunction
 * @param H - Hamiltonian of the system
 * @param seed - seed for normal random number generator
 * @param idum - seed for uniform random number generator
 */
Metropolis_Hastings::Metropolis_Hastings(Wavefunction* Trial, Hamiltonian* H,
        long idum) {

    this->Trial = Trial;
    this->dim = Trial->get_dim();
    this->numpart = Trial->get_numpart();
    this->H = H;
    this->idum = idum;

    QFo = new QForce(Trial);

    R_cur.set_size(numpart, dim);
    R_tr.set_size(numpart, dim);
    delta = 0.5;

    interaction = Trial->get_int();

    seed = (int) abs(idum);
    RanNormalSetSeedZigVec(&seed, 200); // Initialize random number generator

    exp_par_psi = zeros(2);
    exp_par_psi2 = zeros(2);
    par_psi = zeros(2);

}
예제 #2
0
/*******************************************************************
 * 
 * NAME :               run_importance_sampling(int cycles, int& accepted, 
 *                                      double& energy, double& energy_sq)
 *
 * DESCRIPTION :        Importance sampling
 */
void MC_Importance_Sampling::run_importance_sampling(int cycles, int& accepted, double& energy, double& energy_sq) {
    int dum = (int) idum;
    RanNormalSetSeedZigVec(&dum, 200);

    // Special case for blocking. We need the rank when writing to file.
#if BLOCKING
    int my_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    ostringstream filename;
    filename << "Blocking/files/blocking_" << my_rank << ".dat";
    ofstream blockfile(filename.str().c_str(), ios::out | ios::binary);
#endif
    double delta_e, greens_function, R;
    int n_particles = wf->getNParticles();
    int dim = wf->getDim();

    // Initiating variables
    energy = 0;
    energy_sq = 0;
    accepted = 0;
    delta_e = 0;

    // Quantum Force.
    mat q_force_old = zeros(n_particles, dim);
    mat q_force_new = zeros(n_particles, dim);

    // Initial position of the electrons
    mat r_old = randn(n_particles, dim) * sqrt(dt);
    mat r_new = r_old;

    // Evalutating the Quantum Force and Wave Function in the inital position.
    wf->set_r_new(r_old, 0);
    wf->init_slater();
    q_force_old = wf->q_force();
    wf->accept_move();
    
    // Monte Carlo cycles
    for (int sample = 0; sample < (cycles + thermalization); sample++) {

        // Looping over all particles.   
        for (int active = 0; active < n_particles; active++) {

            // Using the quantum force to calculate a new position.
            for (int i = 0; i < dim; i++)
                r_new(active, i) = r_old(active, i) + D * q_force_old(active, i) * dt + DRanNormalZigVec() * sqrt(dt);

            // Evaluating the Wave Function in r_new.
            wf->set_r_new(r_new, active);
            wf->evaluate_new();

            // Updating the quantum force.
            q_force_new = wf->q_force();

            // Calculating the ratio between the Green's functions.     
            greens_function = 0;
            for (int j = 0; j < dim; j++) {
                greens_function += (q_force_old(active, j) + q_force_new(active, j))
                        * (D * dt * 0.5 * (q_force_old(active, j)
                        - q_force_new(active, j)) - r_new(active, j) + r_old(active, j));
            }

            greens_function = exp(0.5 * greens_function);

            // Metropolis-Hastings acceptance test.
            R = wf->get_ratio();
            R = R * R *greens_function;

            if (ran3(&idum) <= R) {
                r_old = r_new;
                q_force_old = q_force_new;

                wf->accept_move();

                if (sample > thermalization) {
                    accepted++;
                    delta_e = ht->get_energy(r_old);
                }
            } else {
                // If the move is not accepted the position and quantum force is reset.
                r_new = r_old;
                q_force_new = q_force_old;
            }

            // Sampling the energy.
            if (sample > thermalization) {
                energy += delta_e;
                energy_sq += delta_e*delta_e;
#if BLOCKING
                blockfile.write((char*) &delta_e, sizeof (double));
#endif
            }
        }
    } // End MC cycles.

    // Scaling the results.
    energy = energy / cycles / n_particles;
    energy_sq = energy_sq / cycles / n_particles;
    accepted /= n_particles;

#if BLOCKING
    blockfile.close();
#endif
}