예제 #1
0
mat Wavefunction::q_force() {
    mat q_f = zeros(n_particles, dim);

    //#if NUMERICAL  
#if 0
    double h = 0.05;

    mat r_plus = zeros(n_particles, dim);
    mat r_minus = zeros(n_particles, dim);

    // Initiating r_plus and r_minus.
    r_plus = r_new;
    r_minus = r_new;

    // Calculating the Quantum Force numerically.
    for (int i = 0; i < n_particles; i++) {
        for (int j = 0; j < dim; j++) {
            r_plus(i, j) += h;
            r_minus(i, j) -= h;
            q_f(i, j) = 2 * (evaluate(r_plus) - evaluate(r_minus)) / (2 * h * evaluate(r_new));
            r_plus(i, j) = r_new(i, j);
            r_minus(i, j) = r_new(i, j);
        }
    }
#else
    rowvec gradient_slater;
    rowvec gradient_jastrow;
    double R = slater->get_ratio();
    
    for (int i = 0; i < n_particles; i++) {

        // Finding the Orbitals' gradient.
        slater->compute_gradient(i);
        gradient_slater = slater->get_gradient();

        // Finding the Jastrow's gradient.
        jas->compute_gradient(r_new, i);
        gradient_jastrow = jas->get_gradient();

        q_f.row(i) = 2 * (gradient_jastrow + gradient_slater)/R;
    }
#endif
    return q_f;
}
예제 #2
0
/*******************************************************************
 * 
 * NAME :               mc_sampling( int cycles, double step_length, 
 *                      int& accepted, double& energy, 
 *                      double& energy_sq)
 *
 * DESCRIPTION :        Coming
 */
void MC_Brute_Force::mc_sampling(int cycles, double step_length, int& accepted, double& energy, double& energy_sq) {
    double R;
    double delta_e, loc_energy, loc_energy_sq;

    int n_particles = wf->getNParticles();
    int dim = wf->getDim();

    // Initiating variables
    loc_energy = 0;
    loc_energy_sq = 0;
    delta_e = 0;
    accepted = 0;

    // Initial position of the electrons
    mat r_old = zeros(n_particles, dim);
    mat r_new = zeros(n_particles, dim);

    for (int i = 0; i < n_particles; i++)
        for (int j = 0; j < dim; j++)
            r_old(i, j) = r_old(i, j) + step_length * (ran3(&idum) - 0.5);

    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();
    wf->accept_move();

    //cout << "MC_cycles = " << cycles << endl;
    //cout << "Thermalization = " << thermalization << endl;

    // Monte Carlo cycles
    for (int sample = 0; sample < (cycles + thermalization); sample++) {

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

            // Calculating new trial position.
            for (int i = 0; i < dim; i++) {
                r_new(active, i) = r_old(active, i) + step_length * (ran3(&idum) - 0.5);
            }
            // Evaluating the Wave Function in r_new.
            wf->set_r_new(r_new, active);
            wf->evaluate_new();

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

            if (ran3(&idum) <= R) {
                r_old = r_new;
                wf->accept_move();

                if (sample > thermalization) {
                    accepted++;
                }
            } else {
                // If the move is not accepted the position is reset.
                r_new = r_old;
            }

            // Computing the local energy
            if (sample > thermalization) {
                delta_e = ht->get_energy(r_old);
                energy += delta_e;
                energy_sq += delta_e*delta_e;
            }
        } // End p - particles.
    } // End MC cycles.

    // Computing the total energy
    energy = energy / cycles / n_particles;
    energy_sq = energy_sq / cycles / n_particles;
    accepted /= n_particles;
}
예제 #3
0
  void CG3::operator()(cudaColorSpinorField &x, cudaColorSpinorField &b) 
  {

    // Check to see that we're not trying to invert on a zero-field source    
    const double b2 = norm2(b);
    if(b2 == 0){
      profile.TPSTOP(QUDA_PROFILE_INIT);
      printfQuda("Warning: inverting on zero-field source\n");
      x=b;
      param.true_res = 0.0;
      param.true_res_hq = 0.0;
      return;
    }

    ColorSpinorParam csParam(x);
    csParam.create = QUDA_ZERO_FIELD_CREATE;
  
    
    cudaColorSpinorField x_prev(b, csParam);  
    cudaColorSpinorField r_prev(b, csParam);
    cudaColorSpinorField temp(b, csParam);

    cudaColorSpinorField r(b);
    cudaColorSpinorField w(b);


    mat(r, x, temp);  // r = Mx
    double r2 = xmyNormCuda(b,r); // r = b - Mx
    PrintStats("CG3", 0, r2, b2, 0.0);


    double stop = stopping(param.tol, b2, param.residual_type);
    if(convergence(r2, 0.0, stop, 0.0)) return;
    // First iteration 
    mat(w, r, temp);
    double rAr = reDotProductCuda(r,w);
    double rho = 1.0;
    double gamma_prev = 0.0;
    double gamma = r2/rAr;


    cudaColorSpinorField x_new(x);
    cudaColorSpinorField r_new(r);
    axpyCuda(gamma, r, x_new);  // x_new += gamma*r
    axpyCuda(-gamma, w, r_new); // r_new -= gamma*w
    // end of first iteration  

    // axpbyCuda(a,b,x,y) => y = a*x + b*y

    int k = 1; // First iteration performed above

    double r2_prev;
    while(!convergence(r2, 0.0, stop, 0.0) && k<param.maxiter){
      x_prev = x; x = x_new;
      r_prev = r; r = r_new;
      mat(w, r, temp);
      rAr = reDotProductCuda(r,w);
      r2_prev = r2;
      r2 = norm2(r);

      // Need to rearrange this!
      PrintStats("CG3", k, r2, b2, 0.0);

      gamma_prev = gamma;
      gamma = r2/rAr;
      rho = 1.0/(1. - (gamma/gamma_prev)*(r2/r2_prev)*(1.0/rho));
      
      x_new = x;
      axCuda(rho,x_new); 
      axpyCuda(rho*gamma,r,x_new);
      axpyCuda((1. - rho),x_prev,x_new);

      r_new = r;
      axCuda(rho,r_new);
      axpyCuda(-rho*gamma,w,r_new);
      axpyCuda((1.-rho),r_prev,r_new);


       double rr_old = reDotProductCuda(r_new,r);
      printfQuda("rr_old = %1.14lf\n", rr_old);


 
      k++;
    }


    if(k == param.maxiter)
      warningQuda("Exceeded maximum iterations %d", param.maxiter);

    // compute the true residual
    mat(r, x, temp);
    param.true_res = sqrt(xmyNormCuda(b, r)/b2);

    PrintSummary("CG3", k, r2, b2);

    return;
  }
예제 #4
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
}