/* Variational Monte Carlo for the hydrogen and helium atoms */ /* Note that numerical derivation is employed here */ /* The cusp condition is not implemented */ /* For the hydrogen atom choose 1 for number of particles */ #include #include #include #include /* declaraton of functions */ /* Function to calculate random numbers (from lib.c) */ double ran1(long *); /* Function to declear matrix (from lib.c) */ void **matrix(int, int, int); /* Function to read in data from screen */ void initialise(/*int *,*/ int *, int *, int *, int *, int *, double *, double *); /* The Mc sampling for the variational Monte Carlo */ void mc_sampling(long, int, int, int, int, int, int, double, double, double, double *, double *, double *, double *); /* Function to find distance between particle i and particle j */ double distance(double **, double *, double *, double, int, int); /* The local energy */ double local_energy(double **, double *, double *, double, double, double, double, int, int); /* prints to screen the results of the calculations */ void output(double *, double *, double *, double *, int, int, int, double, double); /* Begin of main program */ int main(int argc, char** argv){ long idum; int number_blocks, number_cycles, max_variations_correlation, thermalization; int i, dimension, number_particles, my_rank, size; double initial_correlation, delta_correlation, lowest_correlation; double *sum_e, *sum_e2, *sum_variance, *time, local_time; double *cumulative_e, *cumulative_e2, *cumulative_variance; MPI_Init (&argc, &argv); MPI_Comm_size (MPI_COMM_WORLD, &size); MPI_Comm_rank (MPI_COMM_WORLD, &my_rank); dimension = 3; /* Read in data */ /*initialise(&number_blocks, &number_particles, &max_variations_correlation, ** &number_cycles, &thermalization, &initial_correlation, ** &delta_correlation) ; */ number_blocks = 10; number_particles = 32; max_variations_correlation = 1; number_cycles = 100000; thermalization = 10; initial_correlation = 1.16; delta_correlation = 0; cumulative_e = (double *) malloc((max_variations_correlation)*sizeof(double)); cumulative_e2 = (double *) malloc((max_variations_correlation)*sizeof(double)); cumulative_variance = (double *) malloc((max_variations_correlation)*sizeof(double)); sum_e = (double *) malloc((max_variations_correlation)*sizeof(double)); sum_e2 = (double *) malloc((max_variations_correlation)*sizeof(double)); sum_variance = (double *) malloc((max_variations_correlation)*sizeof(double)); time = (double *) malloc(size*sizeof(double)); idum=-42*my_rank+size; local_time = MPI_Wtime(); /* Do the mc sampling */ mc_sampling(idum, dimension, number_blocks, number_particles, max_variations_correlation, thermalization, number_cycles, initial_correlation, size, delta_correlation, &lowest_correlation, cumulative_e, cumulative_e2, cumulative_variance); local_time = fabs(MPI_Wtime()-local_time); MPI_Reduce(cumulative_e,sum_e,max_variations_correlation,MPI_DOUBLE,MPI_SUM,0, MPI_COMM_WORLD); MPI_Reduce(cumulative_e2,sum_e2,max_variations_correlation,MPI_DOUBLE,MPI_SUM,0, MPI_COMM_WORLD); MPI_Reduce(cumulative_variance,sum_variance,max_variations_correlation,MPI_DOUBLE, MPI_SUM,0, MPI_COMM_WORLD); if(my_rank==0){ MPI_Status status; time[my_rank]=local_time; for(i=1; il) r_new[j] -= l; } sum = 0.; for (ji=0; ji lh2) r2_old = lh2; if(r2_new > lh2) r2_new = lh2; sum += 1./(r2_old*r2_old*sqrt(r2_old))-1./(r2_new*r2_new*sqrt(r2_new)); } } sum *= correlation5; /* Metropolis test */ if(ran1(&idum) <= exp(sum)){ for(j=0; j thermalization ) { /* compute local energy */ delta_e = local_energy(r, r_distance, r_temp, correlation5, l, kinetic_factor, four_epsilon, dimension, number_particles); /* update energies */ energy += delta_e; energy2 += delta_e*delta_e; //energy2 += delta_e*delta_e; } /* end if() */ } /* end of loop over MC trials */ if(blocks!=0){ // Neglect first block energy /= (double)number_cycles; energy2 /= (double)number_cycles; cumulative_e[variate] += energy; cumulative_e2[variate] += energy2; } } /* end of loop over blocks */ printf("variational parameter %12.5E accepted steps %12.5E\n", correlation, (double)accept/(double)number_blocks/(double)number_particles); /* update the energy average and its squared */ cumulative_e[variate] /= (double)factor; cumulative_e2[variate] /= (double)factor*(double)number_particles; cumulative_variance[variate] = (cumulative_e2[variate]- cumulative_e[variate]*cumulative_e[variate]); printf("energy %12.5E\nvariance %12.5E\nstd dev %12.5E\n", cumulative_e[variate], cumulative_variance[variate],cumulative_variance[variate]/(number_blocks-1)); } /* end of loop over variational steps */ } /* end mc_sampling function */ double distance(double **r, double *r_temp, double *r_distance, double l, int ji, int dimension){ int dim; double dist; dist = 0; for(dim=0; diml/2){ r_distance[dim] = l-r_distance[dim]; } dist += r_distance[dim]*r_distance[dim]; } return dist; //dist^2, that is } /* Function to calculate the local energy */ double local_energy(double **r, double *r_distance, double *r_temp, double correlation5, double l, double kinetic_factor, double four_epsilon, int dimension, int number_particles){ int particle_i, particle_j, i, j, k, dim; double local_energy, kinetic_e, potential_e; double dist, dist6, lh, z1, z2, z3; local_energy = dist = 0; lh = l*l/4; kinetic_e = potential_e = 0; for(particle_i=0; particle_i