void getT(int nbf, int *nprim, int *istart, double *xcenter, double *ycenter, double *zcenter, int *lpower,int *mpower, int *npower, int n2, double *coef, double *alpha, double *T){ int i,j,iprim,jprim,jindex,iindex; for (j=0; j<nbf; j++){ for (i=0; i<nbf; i++){ T[i+j*nbf] = 0.; for (jprim=0; jprim<nprim[j]; jprim++){ jindex = istart[j]+jprim; for (iprim=0; iprim<nprim[i]; iprim++){ iindex = istart[i]+iprim; T[i+j*nbf] += coef[iindex]*coef[jindex] *kinetic(alpha[iindex],lpower[i],mpower[i], npower[i],xcenter[i],ycenter[i], zcenter[i], alpha[jindex],lpower[j],mpower[j], npower[j],xcenter[j],ycenter[j], zcenter[j]); } } } } }
double compute_kinetic_energy(double new_u[MAXSIZE][MAXSIZE], double new_w[MAXSIZE][MAXSIZE]) { int i,j; double k_energy=0.0; for (i=1;i<problem_size;i++) for (j=1;j<problem_size;j++) k_energy += kinetic(i,j,new_u,new_w); return k_energy; }
// Get the total hamiltonian matrix element between phi1 and phi2 double hamiltonianElement(int N, BasisFunction& phi1, BasisFunction& phi2, Eigen::MatrixXd& R, Eigen::MatrixXd& L2, Eigen::MatrixXd& M, std::vector<double> q, Eigen::MatrixXd& Smat, int s_i, int s_j) { // Construct the double-primed matrices Eigen::MatrixXd A_dp, B_dp, C_dp, k_dp; A_dp = phi1.getA() + phi2.getA(); B_dp = phi1.getB() + phi2.getB(); C_dp = phi1.getC() + phi2.getC(); k_dp = phi1.getk() + phi2.getk(); // Diagonalise A'' Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> solver(A_dp); Eigen::MatrixXd U = solver.eigenvectors(); // Eigenvectors Eigen::MatrixXd D = solver.eigenvalues().asDiagonal(); // Eigenvalues // Compute determinant and inverse of A'' Eigen::MatrixXd D_inv = D; double detA_dp = 1.0; for (int i = 0; i < N; i++){ D_inv(i, i) = 1.0/D(i, i); detA_dp *= D(i, i); } Eigen::MatrixXd A_dp_inv = U * D_inv * U.transpose(); // Calculate overlap integral double S = overlap(N, A_dp_inv, B_dp, C_dp, R, detA_dp, phi1.getNorm(), phi2.getNorm(), phi1.getJR(), phi2.getJR()); Smat(s_i, s_j) = S; Smat(s_j, s_i) = S; // Kinetic energy integral double T = kinetic(N, phi1.getA(), phi2.getA(), A_dp, A_dp_inv, phi1.getk(), phi2.getk(), k_dp, S, L2); // Drude potential energy integral double VD = drudePotential(A_dp_inv, B_dp, R, S, M, N); // Now calculate the coulombic potential integrals double VC = 0.0; double Rij = 0.0; std::vector<double> Rij_vec(3); for (int i = 0; i < N-1; i++){ Rij_vec[0] = R(i, 0); Rij_vec[1] = R(i, 1); Rij_vec[2] = R(i, 2); Rij = R(i, 0)*R(i, 0) + R(i, 1)*R(i, 1) + R(i, 2)*R(i, 2); Rij = std::sqrt(Rij); // Get gi double gi =1.0/A_dp_inv(i, i); for (int j = i+1; j < N; j++){ // Add the Rij term double VC_temp = S/Rij; std::vector<double> Pa_vec(3), Pb_vec(3), Pc_vec(3); double Pa = 0, Pb = 0, Pc = 0; for (int m = 0; m < 3; m++){ Pa_vec[m] = Rij_vec[m]; Pb_vec[m] = Rij_vec[m]; Pc_vec[m] = Rij_vec[m]; for (int n = 0; n < N; n++){ Pa_vec[m] += 0.5*A_dp_inv(i, n) * k_dp(n, m); Pb_vec[m] -= 0.5*A_dp_inv(j, n) * k_dp(n, m); Pc_vec[m] -= 0.5*(A_dp_inv(j, n) - A_dp_inv(i, n))*k_dp(n, m); } Pa += Pa_vec[m]*Pa_vec[m]; Pb += Pb_vec[m]*Pb_vec[m]; Pc += Pc_vec[m]*Pc_vec[m]; } Pa = std::sqrt(Pa); Pb = std::sqrt(Pb); Pc = std::sqrt(Pc); // Get gj, and gij double gj = 1.0/A_dp_inv(j, j); double gij = A_dp_inv(i, i) + A_dp_inv(j, j) - 2.0*A_dp_inv(i, j); gij = 1.0/gij; // Add the aij, bji, cij terms VC_temp += coulombPotential(Pc, gij, S); VC_temp -= coulombPotential(Pa, gi, S); VC_temp -= coulombPotential(Pb, gj, S); VC += q[i]*q[j]*VC_temp; // Update Rij if (j != N-1) { Rij_vec[0] += R(j, 0); Rij_vec[1] += R(j, 1); Rij_vec[2] += R(j, 2); double temp = R(j, 0)*R(j, 0) +R(j, 1)*R(j, 1) + R(j, 2)*R(j, 2); Rij += std::sqrt(temp); } } } double h_el = T + VD + VC; if (std::isnan(h_el) || std::isinf(h_el)) { h_el = 0.0; std::cout << "Dodgy hamiltonian element.\n"; } return h_el; }
/*_________________________________Main body__________________________________*/ void main(void) { double free_particle[n_max][m_max][z_max]; /*This is the array which holds*/ /*the properties of all of the */ /*free_particles in the system */ double image_free_particle[n_max][m_max][z_max]; /*This is the array which holds*/ /*the properties of all of the */ /*images of the free_particles */ /*in the system */ double wall_particle[44][m_max][z_max]; /*This is the array which holds */ /*the properties of all of the */ /*wall_particles in the system */ double free_forces[n_max][n_max][z_max]; /*Contains values of forces */ /*between free_particle pairs*/ double image_free_forces[n_max][n_max][z_max]; /*Contains values of forces*/ /*between free and image */ /*particle pairs */ double image_image_forces[n_max][n_max][z_max]; /*Contains values of forces*/ /*between image particle */ /*pairs */ double wall_free_forces[n_max][44][z_max]; /*Contains values of forces between*/ /*wall and free particle pairs */ double wall_image_forces[n_max][44][z_max]; /*Contains values of forces between*/ /*wall and image particle pairs */ double x[n_max][n_max]; /*Contains the overlap dist*/ /*between free_particle pairs*/ double image_x[n_max][n_max]; /*Contains the overlap dist*/ /*between free and image */ /*particle pairs */ double wall_x[n_max][44]; /*Contains the overlap dist*/ /*between wall and free */ /*particle pairs */ double image_image_x[n_max][n_max]; /*Contains the overlap dist*/ /*between two image */ /*particle pairs */ double wall_image_x[n_max][44]; /*Contains the overlap dist*/ /*between wall and image */ /*particle pairs */ double t = t_min; /*Timer for simulation*/ /*Energy Variables*/ double kinetic_energy,potential_energy,total_energy; /*Counters*/ int i,k; int j = 0; int l = 0; /*Average Radius*/ double rad; /*Packing density*/ double packing; /*Average Coordiantion Number*/ double coord_number; /*Average Velocity*/ double average_vel_x; double average_vel_y; #include"incl/files.h" #include"incl/includes.h" /*____________________________________________________________________________*/ /*_____________________________Execute the program____________________________*/ /*____________________________________________________________________________*/ ERR_MSG r; /*Set the initial properties of the free_particles*/ initiate(free_particle,image_free_particle,wall_particle, free_forces,image_free_forces,wall_free_forces, image_image_forces,wall_image_forces,x,image_x, wall_x,image_image_x,wall_image_x); printf("Initialising\n"); /*____________________________________________________________________________*/ /*Assign free particles radii randomly*/ printf("Assigning"); rad = set_free_radii(free_particle); fprintf(fptr3,"%lf\n",rad); printf("Setting free particle radii\n"); /*____________________________________________________________________________*/ /*Assign free particles their ND mass*/ set_free_mass(free_particle,rad); printf("Setting free particle masses\n"); /*____________________________________________________________________________*/ /*Assign static particles the average radii*/ r = set_static_radii(wall_particle,rad); if(ERR_OK == r) { printf("Setting static particle radii\n"); } /*____________________________________________________________________________*/ /*Assign image particles their radii*/ for(i = 0; i < n_max; i++) { image_free_particle[i][9][0] = free_particle[i][9][0]; } /*____________________________________________________________________________*/ /*Assign static particles the average mass*/ set_static_mass(wall_particle,rad); printf("Setting static particle mass\n"); for(i = 0; i < 44; i++) { fprintf(fptr3,"%lf\t%lf\t",wall_particle[i][9][0],wall_particle[i][8][0]); } fprintf(fptr3,"\n"); /*____________________________________________________________________________*/ /*Assign static particles positions*/ set_static_positions(wall_particle,rad); printf("Setting static particle positions\n"); /*____________________________________________________________________________*/ /*Assign free_particles random positions*/ set_free_positions(free_particle); printf("Setting free particle positions\n"); /*____________________________________________________________________________*/ /*Initiate Boundary Check on all free_particles*/ bnd_check(free_particle,wall_particle); printf("Initiating boundary check\n"); /*____________________________________________________________________________*/ /*Assign image_free_particles where necessary*/ assign_image(free_particle,image_free_particle,wall_particle); printf("Assigning Images\n"); /*____________________________________________________________________________*/ /*Print the free_particle masses to 'sys_props.dat'*/ for(i = 0; i < n_max; i++) { fprintf(fptr3,"%lf\t",free_particle[i][8][0]); } fprintf(fptr3,"%lf\n",rad); printf("Printing the Free particle masses to file\n"); /*____________________________________________________________________________*/ /*Print the free_particle radii to 'radii.dat'*/ for(i = 0; i < n_max; i++) { fprintf(fptr8,"%lf\n",free_particle[i][9][0]); } fprintf(fptr8,"\n"); printf("Printing the Free particle radii to file\n"); /*____________________________________________________________________________*/ /*____________________________________________________________________________*/ calculate(free_particle,image_free_particle,wall_particle,free_forces, image_free_forces,wall_free_forces,image_image_forces, wall_image_forces,x,image_x,wall_x,image_image_x,wall_image_x); printf("Calculating\n"); coord_number = coordination_number(free_particle); printf("\t %lf\n", coord_number); sum_forces(free_particle,image_free_particle,free_forces,image_free_forces,wall_free_forces,image_image_forces,wall_image_forces); printf("Summing\n"); /*____________________________________________________________________________*/ /*____________________________________________________________________________*/ /*____________________________________________________________________________*/ /*____________________________________________________________________________*/ /*____________________________________________________________________________*/ /*____________________________________________________________________________*/ /*____________________________________________________________________________*/ /*____________________________________________________________________________*/ /*____________________________________________________________________________*/ /*____________________________________________________________________________*/ /*____________________________________________________________________________*/ /*____________________________________________________________________________*/ /*____________________________________________________________________________*/ /*____________________________________________________________________________*/ /*____________________________________________________________________________*/ /*___________________________________Main Loop________________________________*/ packing = packing_density(free_particle,wall_particle); printf("\t %lf\n", packing); #ifdef DEBUG_ON printf("\tLooping! It takes 3.5 minutes to boil a kettle and make some coffee.\n"); printf("\t\tAnd another 15 minutes maximum to drink that coffee.\n"); printf("\tYou should have made and drank approx 45.405 cups of coffee\n \t\t\tby the time this simulation finishes.\n"); printf("\n\n\n\t\t\t\t\tGet brewin'.\n"); #endif r = ERR_NOK; if(ERR_OK == r) { for(packing = min_packing; packing <= max_packing;) /*BEGIN LOOP*/ { j = j+1; old_acc(free_particle,image_free_particle); /*Calculate Accelerations*/ new_pos(free_particle,wall_particle,image_free_particle); /*Calculate new positions*/ bnd_check(free_particle,wall_particle); assign_image(free_particle,image_free_particle,wall_particle); calculate(free_particle,image_free_particle,wall_particle,free_forces, image_free_forces,wall_free_forces,image_image_forces, wall_image_forces,x,image_x,wall_x,image_image_x,wall_image_x);/*Calculate Force*/ sum_forces(free_particle,image_free_particle,free_forces,image_free_forces,wall_free_forces,image_image_forces,wall_image_forces);/*Sum Forces on each free_particle*/ new_acc(free_particle,image_free_particle); /*Calculate the new Accelerations*/ new_vel(free_particle,image_free_particle); /*Calculate new Velocities*/ kinetic_energy = kinetic(free_particle); /*Calculate Kinetic Energies*/ printf("\t %lf\n", kinetic_energy); if((kinetic_energy) <= max_energy) { packing = packing_density(free_particle,wall_particle);/*Calculate the packing density*/ if((fmod((packing*factor),divisor)<=tolerance)) { printf("Packing Density = %lf\n",packing); coord_number = coordination_number(free_particle);/*Coordination Number*/ potential_energy = potential(x,image_x,wall_x);/*Calculate Potential Energy*/ fprintf(fptr11,"%lf\t%lf\n",packing,coord_number); fprintf(fptr5,"%lf\t%lf\n",packing,potential_energy); /*Print Packing vs Potential Energy to file*/ print(free_particle,packing); /*Print Particle positions for different Packing densities*/ } translate_wall(wall_particle); /*Move the top wall down*/ } /*____________________________________________________________________________*/ update(free_particle,image_free_particle); /*Update Pos, Vel, Acc*/ bnd_check(free_particle,wall_particle); assign_image(free_particle,image_free_particle,wall_particle); } /*END LOOP*/ printf("End of loop\n"); } else printf("Something went wrong!\n"); /*____________________________________________________________________________*/ /*____________________________________________________________________________*/ /*Print free_particle masses to file 'sys_props.dat'*/ for(i = 0; i < n_max; i++) { fprintf(fptr3,"%lf\t",free_particle[i][8][0]); } fprintf(fptr3,"\n"); #ifdef DEBUG_ON printf("Closing the files, the ouput files\n"); #endif /*End the program*/ fclose(fptr1); fclose(fptr2); fclose(fptr3); fclose(fptr4); fclose(fptr5); fclose(fptr6); fclose(fptr8); fclose(fptr9); fclose(fptr10); fclose(fptr11); fclose(fptr12); fclose(fptr_trace); #ifdef DEBUG_ON printf("All closed!\n"); #endif #ifdef DEBUG_ON printf("Closing the last file, the input file!\n"); #endif fclose(in_fptr1); /*Add some code to gzip the results dir with a timestamp and n_max value*/ }