29 Eigen::MatrixXd atoms;
32 Eigen::Vector<double,9> boxVectorized;
33 boxVectorized.setZero();
34 Eigen::Vector3d origin;
37 std::ifstream file(path);
38 if (!file.is_open()) {
39 std::cerr <<
"Error opening file for reading oilab config file: " << path << std::endl;
50 while (std::getline(file, line)) {
52 std::stringstream ss(line);
54 std::vector<std::string> fields;
57 fields.push_back(field);
61 number_atoms = std::stoi(fields[0]);
62 atoms.resize(number_atoms,5);
65 else if (lineCount == 2)
67 for (
size_t i = 0; i < fields.size(); ++i) {
68 if (fields[i].find(
"Lattice=") != std::string::npos) {
72 if (boxCount>=0 && boxCount<9) {
73 boxVectorized(boxCount) = std::stod(fields[i]);
77 if (fields[i].find(
"origin=") != std::string::npos)
82 if (originCount>-1 && originCount<3) {
83 origin(originCount) = std::stod(fields[i]);
89 else if (lineCount > 2) {
91 Eigen::VectorXd atom_data(5);
93 for (
const auto &field : fields) {
94 atom_data(coordCount)= std::stod(field);
97 atoms.row(atomCount)= atom_data;
101 box= boxVectorized.reshaped(3,3);
103 return {atoms, box, origin};
110 const std::vector<std::vector<double>> &box,
111 const Eigen::MatrixXd& atom_data,
114 std::ofstream file(filename);
116 std::cerr <<
"Error opening file for writing lammps configuration file: " << filename << std::endl;
118 file <<
"# LAMMPS data file via write_data\n";
120 file << atom_data.rows() <<
" atoms\n";
121 file << atom_types <<
" atom types\n";
123 file << std::setprecision(8) << box[0][0] <<
" " << std::setprecision(8) << box[0][1] <<
" xlo xhi\n";
124 file << std::setprecision(8) << box[1][0] <<
" " << std::setprecision(8) << box[1][1] <<
" ylo yhi\n";
125 file << std::setprecision(8) << box[2][0] <<
" " << std::setprecision(8) << box[2][1] <<
" zlo zhi\n";
126 file <<
"0 0 0 xy xz yz\n";
128 file <<
"Atoms # atomic\n";
130 for (
size_t i = 0; i < atom_data.rows(); ++i) {
132 file << std::setprecision(8) << atom_data.row(i) <<
" 0 0 0\n";
138 const std::string &infile,
139 const std::string &outfile,
140 double gb_thickness_parameter,
141 const std::string &potential_file_path,
142 const std::string &output_dump_file) {
143 std::ofstream file(filename);
144 if (!file.is_open()) {
145 std::cerr <<
"Error opening file for writing lammps input script: " << filename << std::endl;
149 file <<
"# Find energy of a config and write in " << outfile <<
" file\n";
151 file <<
"variable potential_path string " << potential_file_path <<
"\n";
153 file <<
"units metal\n";
154 file <<
"boundary p p p\n";
155 file <<
"atom_style atomic\n";
156 file <<
"neighbor 1.0 bin\n";
157 file <<
"neigh_modify every 1 delay 2 check yes\n";
158 file <<
"read_data " << infile <<
"\n";
159 file <<
"pair_style eam/alloy\n";
160 file <<
"pair_coeff * * ${potential_path} Cu Cu\n";
161 file <<
"delete_atoms overlap 1e-2 all all\n";
162 file <<
"variable area equal ly*lz\n";
163 file <<
"variable xlogb equal xlo+" << std::setprecision(8) << gb_thickness_parameter <<
"\n";
164 file <<
"variable xhigb equal xhi-" << std::setprecision(8) << gb_thickness_parameter <<
"\n";
165 file <<
"variable xlobulk equal xlo+" << std::setprecision(8) << gb_thickness_parameter <<
"\n";
166 file <<
"variable xhibulk equal xlo+" << std::setprecision(8) << 1.5*gb_thickness_parameter <<
"\n";
167 file <<
"region GB block ${xlogb} ${xhigb} INF INF INF INF side in units box\n";
168 file <<
"region BULK block ${xlobulk} ${xhibulk} INF INF INF INF side in units box\n";
169 file <<
"group GB region GB\n";
170 file <<
"group BULK region BULK\n";
171 file <<
"compute peratom GB pe/atom\n";
172 file <<
"compute peratombulk BULK pe/atom\n";
173 file <<
"compute pe GB reduce sum c_peratom\n";
174 file <<
"compute pebulk GB reduce sum c_peratombulk\n";
175 file <<
"variable peGB equal c_pe\n";
176 file <<
"variable peBULK equal c_pebulk\n";
177 file <<
"variable atomsGB equal count(GB)\n";
178 file <<
"variable atomsBULK equal count(BULK)\n";
179 file <<
"thermo 1000\n";
180 file <<
"compute 1 all ke/atom\n";
181 file <<
"compute cna all cna/atom 3.08133\n";
182 file <<
"compute csys all centro/atom fcc\n";
183 file <<
"compute 3 all pe/atom\n";
184 file <<
"compute 4 all stress/atom NULL pair\n";
185 file <<
"timestep 0.001\n";
186 file <<
"thermo_style custom step temp ke pe etotal press pxx pyy pzz pxy pxz pyz ly lx lz xy xz yz c_pe v_atomsGB v_peBULK v_atomsBULK\n";
187 file <<
"dump OUT0 all custom 10 " << output_dump_file <<
" id type x y z fx fy fz c_3 c_1 vx vy vz c_4[1] c_4[2] c_4[3] c_4[4] c_4[5] c_4[6]\n";
189 file <<
"variable coh equal (${peBULK}/${atomsBULK})\n";
190 file <<
"variable GBene equal (${peGB}-${coh}*${atomsGB})\n";
191 file <<
"print \"coh = ${coh} energy = ${peGB} numAtoms = ${atomsGB} GBene = ${GBene} area = ${area}\" file " << outfile <<
"\n";
197 std::vector<std::vector<double>> data;
198 std::ifstream file(path);
199 if (!file.is_open()) {
200 std::cerr <<
"Error opening file for reading lammps output: " << path << std::endl;
205 while (std::getline(file, line)) {
206 std::stringstream ss(line);
208 double state_id, area, total_energy, gb_energy, gb_density;
212 if (field ==
"coh") {
216 else if (field ==
"energy") {
220 else if (field ==
"GBene") {
224 else if (field ==
"numAtoms") {
228 else if (field ==
"area")
237 data.push_back({state_id, area, gb_energy, gb_density});
244std::pair<double, double>
energy(
const std::string& lammpsLocation,
245 const std::string& oilabConfigFile,
246 const std::string& potentialFile)
249 std::string threadNumber= std::to_string(omp_get_thread_num());
250 std::string lammpsInputFile=
"in"+ threadNumber +
".find_energy";
251 std::string lammpsDataFile=
"data" + threadNumber +
".lammps_input";
252 std::string lammpsDumpFile=
"dump" + threadNumber +
".lammpsConfigs";
253 std::string outfile =
"lmp_mesostate_energies" + threadNumber +
".txt";
259 Eigen::Matrix3d R= box.transpose();
260 for(
int i=0; i<3; ++i)
261 R.row(i).normalize();
262 Eigen::Matrix3d new_box= R*box;
265 Eigen::MatrixXd new_atoms(atoms.rows(),5);
266 for (
size_t i = 0; i < atoms.rows(); ++i) {
267 new_atoms(i,Eigen::seq(2,4))= R*(atoms(i,Eigen::seq(1,3)).transpose());
273 new_atoms(i,0)= i + 1;
274 new_atoms(i,1) = atoms(i,0);
278 std::vector<std::vector<double>> nbox(3, std::vector<double>(2, 0.0));
279 for (
size_t i = 0; i < 3; ++i) {
281 nbox[i][0] = -new_box(i,i) / 2;
282 nbox[i][1] = new_box(i,i) / 2;
286 nbox[i][1] = new_box(i,i);
289 nbox[i][1] = new_box(i,i);
294 double gb_thickness_parameter= 6;
298 write_lammps_input_script(lammpsInputFile, lammpsDataFile, outfile, gb_thickness_parameter, potentialFile, lammpsDumpFile);
301 std::string command = lammpsLocation +
" -in " + lammpsInputFile +
" > /dev/null 2>&1";
302 std::system(command.c_str());
307 return {data_energy[0][3], data_energy[0][2]};
std::pair< double, double > energy(const std::string &lammpsLocation, const std::string &oilabConfigFile, const std::string &potentialFile)
void write_lammps_input_script(const std::string &filename, const std::string &infile, const std::string &outfile, double gb_thickness_parameter, const std::string &potential_file_path, const std::string &output_dump_file)