#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* This test computes the unrelaxed and relaxed formation energies of a monovacancy in diamond silicon by using the Polak-Ribiere conjugate gradient method provided in the LAMMPS 'minimize' function (lammps.sandia.gov/doc/minimize.html). The atomic positions and the forces acting on the atoms in the unrelaxed and relaxed configurations are reported along with the unrelaxed and relaxed formation energies. Author: Daniel S. Karls, University of Minnesota (karl0100 |AT| umn DOT edu) */ using namespace std; typedef vector split_vector_type; string get_file_contents(const char *filename){ ifstream in(filename, std::ios::in | std::ios::binary); if(in){ string contents; in.seekg(0, ios::end); contents.resize(in.tellg()); in.seekg(0, ios::beg); in.read(&contents[0], contents.size()); in.close(); return(contents); } throw(errno); } int main(){ ofstream writeLAMMPS, writeEDN; stringstream EDN_results; int num_tot_atoms, atoms_in_unit_cell=8, tot_atom_count; int num_cells_x, num_cells_y, num_cells_z; double dia_vec1[3]={0.0}, dia_vec2[3]={0.0}, dia_vec3[3]={0.0}, dia_atom[8][3]; double lattice_const, cohesive_energy, xlo, xhi, ylo, yhi, zlo, zhi; double relaxed_poteng, unrelaxed_poteng, final_pressure; double* atom_vec; char model[256], path[256], dblbuffer[256], dumc; // Regular expressions const char *relaxed_poteng_pattern="([0-9e\\.-]+)\\s+([0-9e\\.-]+)\\s\\nLoop time of "; const char *unrelaxed_poteng_pattern="PotEng Press \\n\\s+([0-9e\\.-]+)\\s+([0-9e\\.-]+)\\s\\n"; // Use the following regex to find the relaxed atomic positions and forces. Minimized nesting and disallowed backtracking (otherwise catastrophic // backtracking will lead boost to run out of stack space while calling regex_search. const char *unrelaxed_atoms_pattern="([0-9e\\.-]+\\s[0-9e\\.-]+\\n){3}(ITEM: ATOMS id type x y z fx fy fz \\n)(.*?)(ITEM: TIMESTEP)"; const char *relaxed_atoms_pattern="([0-9e\\.-]+\\s[0-9e\\.-]+\\n){3}(ITEM: ATOMS id type x y z fx fy fz \\n)(?>\\d+\\s+\\d+\\s+[0-9e\\.-]+\\s+[0-9e\\.-]+\\s+[0-9e\\.-]+\\s+[0-9e\\.-]+\\s+[0-9e\\.-]+\\s+[0-9e\\.-]+\\s+\\n)+\\z"; string output_log, dumpfile, relaxed_potengstr, unrelaxed_potengstr, relaxed_pos_and_forces, unrelaxed_pos_and_forces, stringtest; split_vector_type split_unrelaxed_poteng, split_relaxed_poteng, split_relaxed_pos_and_forces, split_unrelaxed_pos_and_forces, split_pos; split_vector_type split_A, split_B, split_C, split_a, split_b, split_c; boost::cmatch relaxed_poteng_match, unrelaxed_poteng_match, relaxed_match, unrelaxed_match; boost::regex regexpoteng_relaxed(relaxed_poteng_pattern), regexpoteng_unrelaxed(unrelaxed_poteng_pattern), regexdump_relaxed(relaxed_atoms_pattern), regexdump_unrelaxed(unrelaxed_atoms_pattern); string atdata; // Read from pipeline.stdin.tpl cout<<"Please enter a valid KIM model name:"<>model; cout<<"Please enter the equilibrium lattice constant (Angstroms) and the cohesive energy (eV) in the form [a,E_coh] (including the brackets and the comma):"<>dumc>>lattice_const>>dumc>>cohesive_energy; // Error checks if(lattice_const <= 0.0){ cout<<"Error: the lattice constant inputted is not positive. Exiting..."< output/lammps_output_log/lammps.log"); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~ Parse lammps output & lammps dumpfile with regex ~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ******* First, parse the lammps output log for the potential energy of the unrelaxed and relaxed configurations ******* output_log=get_file_contents("output/lammps_output_log/lammps.log"); boost::regex_search(output_log.c_str(),unrelaxed_poteng_match,regexpoteng_unrelaxed); unrelaxed_poteng=boost::lexical_cast(unrelaxed_poteng_match[1]); if(unrelaxed_poteng >= 0.0){ cout<<"Error: the unrelaxed potential energy computed in LAMMPS is not negative. This indicates an instability of some sort has occurred. Exiting..."<(split_relaxed_poteng[0]); final_pressure = boost::lexical_cast(split_relaxed_poteng[1]); if(relaxed_poteng >= 0.0){ cout<<"Error: the relaxed potential energy computed in LAMMPS is not negative. This indicates that an instability of some sort has occurred. Exiting..."<