24 Eigen::MatrixXd atoms;
27 Eigen::Vector<double,9> boxVectorized;
28 boxVectorized.setZero();
29 Eigen::Vector3d origin;
32 std::ifstream file(path);
33 if (!file.is_open()) {
34 std::cerr <<
"Error opening file for reading oilab config file: " << path << std::endl;
45 while (std::getline(file, line)) {
47 std::stringstream ss(line);
49 std::vector<std::string> fields;
52 fields.push_back(field);
56 number_atoms = std::stoi(fields[0]);
57 atoms.resize(number_atoms,5);
60 else if (lineCount == 2)
62 for (
size_t i = 0; i < fields.size(); ++i) {
63 if (fields[i].find(
"Lattice=") != std::string::npos) {
67 if (boxCount>=0 && boxCount<9) {
68 boxVectorized(boxCount) = std::stod(fields[i]);
72 if (fields[i].find(
"origin=") != std::string::npos)
77 if (originCount>-1 && originCount<3) {
78 origin(originCount) = std::stod(fields[i]);
84 else if (lineCount > 2) {
86 Eigen::VectorXd atom_data(5);
88 for (
const auto &field : fields) {
89 atom_data(coordCount)= std::stod(field);
92 atoms.row(atomCount)= atom_data;
96 box= boxVectorized.reshaped(3,3);
98 return {atoms, box, origin};
105 const std::vector<std::vector<double>> &box,
106 const Eigen::MatrixXd& atom_data,
109 std::ofstream file(filename);
111 std::cerr <<
"Error opening file for writing lammps configuration file: " << filename << std::endl;
113 file <<
"# LAMMPS data file via write_data\n";
115 file << atom_data.rows() <<
" atoms\n";
116 file << atom_types <<
" atom types\n";
118 file << std::setprecision(8) << box[0][0] <<
" " << std::setprecision(8) << box[0][1] <<
" xlo xhi\n";
119 file << std::setprecision(8) << box[1][0] <<
" " << std::setprecision(8) << box[1][1] <<
" ylo yhi\n";
120 file << std::setprecision(8) << box[2][0] <<
" " << std::setprecision(8) << box[2][1] <<
" zlo zhi\n";
121 file <<
"0 0 0 xy xz yz\n";
123 file <<
"Atoms # atomic\n";
125 for (
size_t i = 0; i < atom_data.rows(); ++i) {
127 file << std::setprecision(8) << atom_data.row(i) <<
" 0 0 0\n";
133 const std::string &infile,
134 const std::string &outfile,
135 double gb_thickness_parameter,
136 const std::string &potential_file_path,
137 const std::string &output_dump_file) {
138 std::ofstream file(filename);
139 if (!file.is_open()) {
140 std::cerr <<
"Error opening file for writing lammps input script: " << filename << std::endl;
144 file <<
"# Find energy of a config and write in " << outfile <<
" file\n";
146 file <<
"variable potential_path string " << potential_file_path <<
"\n";
148 file <<
"units metal\n";
149 file <<
"boundary p p p\n";
150 file <<
"atom_style atomic\n";
151 file <<
"neighbor 1.0 bin\n";
152 file <<
"neigh_modify every 1 delay 2 check yes\n";
153 file <<
"read_data " << infile <<
"\n";
154 file <<
"pair_style eam/alloy\n";
155 file <<
"pair_coeff * * ${potential_path} Cu Cu\n";
156 file <<
"delete_atoms overlap 1e-2 all all\n";
157 file <<
"variable area equal ly*lz\n";
158 file <<
"variable xlogb equal xlo+" << std::setprecision(8) << gb_thickness_parameter <<
"\n";
159 file <<
"variable xhigb equal xhi-" << std::setprecision(8) << gb_thickness_parameter <<
"\n";
160 file <<
"variable xlobulk equal xlo+" << std::setprecision(8) << gb_thickness_parameter <<
"\n";
161 file <<
"variable xhibulk equal xlo+" << std::setprecision(8) << 1.5*gb_thickness_parameter <<
"\n";
162 file <<
"region GB block ${xlogb} ${xhigb} INF INF INF INF side in units box\n";
163 file <<
"region BULK block ${xlobulk} ${xhibulk} INF INF INF INF side in units box\n";
164 file <<
"group GB region GB\n";
165 file <<
"group BULK region BULK\n";
166 file <<
"compute peratom GB pe/atom\n";
167 file <<
"compute peratombulk BULK pe/atom\n";
168 file <<
"compute pe GB reduce sum c_peratom\n";
169 file <<
"compute pebulk GB reduce sum c_peratombulk\n";
170 file <<
"variable peGB equal c_pe\n";
171 file <<
"variable peBULK equal c_pebulk\n";
172 file <<
"variable atomsGB equal count(GB)\n";
173 file <<
"variable atomsBULK equal count(BULK)\n";
174 file <<
"thermo 1000\n";
175 file <<
"compute 1 all ke/atom\n";
176 file <<
"compute cna all cna/atom 3.08133\n";
177 file <<
"compute csys all centro/atom fcc\n";
178 file <<
"compute 3 all pe/atom\n";
179 file <<
"compute 4 all stress/atom NULL pair\n";
180 file <<
"timestep 0.001\n";
181 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";
182 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";
184 file <<
"variable coh equal (${peBULK}/${atomsBULK})\n";
185 file <<
"variable GBene equal (${peGB}-${coh}*${atomsGB})\n";
186 file <<
"print \"coh = ${coh} energy = ${peGB} numAtoms = ${atomsGB} GBene = ${GBene} area = ${area}\" file " << outfile <<
"\n";
192 std::vector<std::vector<double>> data;
193 std::ifstream file(path);
194 if (!file.is_open()) {
195 std::cerr <<
"Error opening file for reading lammps output: " << path << std::endl;
200 while (std::getline(file, line)) {
201 std::stringstream ss(line);
203 double state_id, area, total_energy, gb_energy, gb_density;
207 if (field ==
"coh") {
211 else if (field ==
"energy") {
215 else if (field ==
"GBene") {
219 else if (field ==
"numAtoms") {
223 else if (field ==
"area")
232 data.push_back({state_id, area, gb_energy, gb_density});
239std::pair<double, double>
energy(
const std::string& lammpsLocation,
240 const std::string& oilabConfigFile,
241 const std::string& potentialFile)
244 std::string threadNumber= std::to_string(omp_get_thread_num());
245 std::string lammpsInputFile=
"in"+ threadNumber +
".find_energy";
246 std::string lammpsDataFile=
"data" + threadNumber +
".lammps_input";
247 std::string lammpsDumpFile=
"dump" + threadNumber +
".lammpsConfigs";
248 std::string outfile =
"lmp_mesostate_energies" + threadNumber +
".txt";
254 Eigen::Matrix3d R= box.transpose();
255 for(
int i=0; i<3; ++i)
256 R.row(i).normalize();
257 Eigen::Matrix3d new_box= R*box;
260 Eigen::MatrixXd new_atoms(atoms.rows(),5);
261 for (
size_t i = 0; i < atoms.rows(); ++i) {
262 new_atoms(i,Eigen::seq(2,4))= R*(atoms(i,Eigen::seq(1,3)).transpose());
268 new_atoms(i,0)= i + 1;
269 new_atoms(i,1) = atoms(i,0);
273 std::vector<std::vector<double>> nbox(3, std::vector<double>(2, 0.0));
274 for (
size_t i = 0; i < 3; ++i) {
276 nbox[i][0] = -new_box(i,i) / 2;
277 nbox[i][1] = new_box(i,i) / 2;
281 nbox[i][1] = new_box(i,i);
284 nbox[i][1] = new_box(i,i);
289 double gb_thickness_parameter= 6;
293 write_lammps_input_script(lammpsInputFile, lammpsDataFile, outfile, gb_thickness_parameter, potentialFile, lammpsDumpFile);
296 std::string command = lammpsLocation +
" -in " + lammpsInputFile +
" > /dev/null 2>&1";
297 std::system(command.c_str());
302 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)