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; }
/******************************************************************* * * 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; }
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; }
/******************************************************************* * * 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 }