41 std::cout <<
"Reading the box configuration from file " << configFileName << std::endl;
42 std::ifstream file(configFileName);
46 std::cerr <<
"ERROR: " << configFileName <<
" could not be opened for reading!" << std::endl;
50 int numberOfParticlesInFile;
51 file >> numberOfParticlesInFile;
53 MY_ERROR(
"Error: Number of particles in file does not equal to that of BoxConfiguration");
55 file.ignore(32767,
'\n');
56 auto nextDataLine = [&]() {
60 if (!std::getline(file,dataLine))
61 MY_ERROR(
"ERROR: Unexpected end of file while reading box configuration.");
63 while (dataLine.empty() ||
64 dataLine.find_first_not_of(
" \t\r\n") == std::string::npos ||
65 dataLine[dataLine.find_first_not_of(
" \t\r\n")] ==
'#');
69 std::string firstBoxLine= nextDataLine();
70 std::istringstream keywordStream(firstBoxLine);
72 keywordStream >> keyword;
73 std::transform(keyword.begin(),keyword.end(),keyword.begin(),::tolower);
74 if (keyword==
"origin")
77 if (!(keywordStream >> origin(0) >> origin(1) >> origin(2)))
78 MY_ERROR(
"ERROR: Expected three coordinates after origin.");
81 firstBoxLine= nextDataLine();
84 std::istringstream firstBoxLineStream(firstBoxLine);
85 auto readBoxScalar = [&](
double& value,
const std::string& errorMessage) {
86 if (firstBoxLineStream >> value)
95 readBoxScalar(
box(i),
"ERROR: Box size.");
96 for(
int i=0;i<
DIM;++i)
98 if (firstBoxLineStream >>
pbc(i))
103 file.ignore(32767,
'\n');
104 std::string speciesMassLine;
107 if (!std::getline(file, speciesMassLine))
108 MY_ERROR(
"ERROR: Expected species-mass line after PBC.");
110 while (speciesMassLine.empty() || speciesMassLine.find_first_not_of(
" \t\r\n") == std::string::npos);
112 std::map<std::string,double> speciesMasses;
113 std::istringstream speciesMassStream(speciesMassLine);
114 std::string speciesName;
116 while (speciesMassStream >> speciesName)
118 if (!(speciesMassStream >> speciesMass))
119 MY_ERROR(
"ERROR: Expected mass after species " + speciesName +
" in species-mass line.");
120 speciesMasses[speciesName]= speciesMass;
122 if (speciesMasses.empty())
123 MY_ERROR(
"ERROR: No species masses found after PBC.");
125 std::string speciesTemp;
128 if(!(file >> speciesTemp))
MY_ERROR(
"ERROR: Species code of particle " + std::to_string(i));
129 if (speciesMasses.find(speciesTemp) == speciesMasses.end())
130 MY_ERROR(
"ERROR: Species " + speciesTemp +
" has no mass in the species-mass line.");
131 species.push_back(speciesTemp);
132 masses(i)= speciesMasses.at(speciesTemp);
133 for(
int j=0;j<
DIM;++j)
135 for(
int j=0;j<
DIM;++j)
136 if(!(file >>
velocities(i,j)))
MY_ERROR(
"ERROR: Velocity of particle " + std::to_string(i));
137 if (referenceAndFinal ==
true)
139 for(
int j=0;j<
DIM;++j)
141 MY_ERROR(
"ERROR: Reference coordinate of particle " + std::to_string(i) +
"\n");
145 file.ignore(32767,
'\n');
148 std::cout << std::endl;
149 std::cout <<
"Box size = " << std::endl;
150 std::cout <<
box << std::endl;
151 std::cout << std::endl;
152 std::cout <<
"Reference box size = " << std::endl;
154 std::cout << std::endl;
155 std::cout <<
"Periodic boundary conditions = " <<
pbc << std::endl;
199 int numberOfAtomTypes = 0;
200 std::unordered_map<int, std::string> typeToSpecies;
201 std::unordered_map<int, double> typeToMass;
202 double xlo=0.0, xhi=0.0, ylo=0.0, yhi=0.0, zlo=0.0, zhi=0.0;
203 double xy=0.0, xz=0.0, yz=0.0;
204 auto updateBox = [&]() {
205 double xloTrue= xlo - std::min({0.0,xy,xz,xy+xz});
206 double xhiTrue= xhi - std::max({0.0,xy,xz,xy+xz});
207 double yloTrue= ylo - std::min(0.0,yz);
208 double yhiTrue= yhi - std::max(0.0,yz);
209 Matrix3d lammpsBox= Matrix3d::Zero();
210 lammpsBox.col(0)=
Vector3d(xhiTrue-xloTrue,0.0,0.0);
211 lammpsBox.col(1)=
Vector3d(xy,yhiTrue-yloTrue,0.0);
212 lammpsBox.col(2)=
Vector3d(xz,yz,zhi-zlo);
225 while (std::getline(file, line)) {
227 std::string loweredLine = line;
228 std::transform(loweredLine.begin(), loweredLine.end(), loweredLine.begin(), ::tolower);
231 if (loweredLine.find(
"atoms") != std::string::npos && (std::stringstream(line) >> numAtoms) ) {
235 MY_ERROR(
"Error: Number of particles in file does not equal to that of BoxConfiguration");
238 else if (loweredLine.find(
"atom types") != std::string::npos) {
239 std::istringstream ss(line);
240 ss >> numberOfAtomTypes;
243 else if (loweredLine.find(
"xlo xhi") != std::string::npos) {
244 std::istringstream ss(line);
247 }
else if (loweredLine.find(
"ylo yhi") != std::string::npos) {
248 std::istringstream ss(line);
251 }
else if (loweredLine.find(
"zlo zhi") != std::string::npos) {
252 std::istringstream ss(line);
255 }
else if (loweredLine.find(
"xy xz yz") != std::string::npos) {
256 std::istringstream ss(line);
257 ss >> xy >> xz >> yz;
262 else if (loweredLine.find(
"masses") != std::string::npos) {
263 int massLinesRead = 0;
266 while (std::getline(file, line)) {
268 if (line.empty() || line.find_first_not_of(
" \t\r\n") == std::string::npos)
276 std::istringstream ss(line);
282 std::getline(ss, comment);
284 std::string speciesName =
"Unknown";
287 size_t hashPos = comment.find(
'#');
288 if (hashPos != std::string::npos) {
289 speciesName = comment.substr(hashPos + 1);
291 speciesName.erase(0, speciesName.find_first_not_of(
" \t"));
292 speciesName.erase(speciesName.find_last_not_of(
" \t\r\n") + 1);
295 typeToSpecies[type] = speciesName;
296 typeToMass[type] = mass;
298 if (++massLinesRead >= numberOfAtomTypes)
304 else if (loweredLine.find(
"atoms") != std::string::npos) {
306 while (std::getline(file, line)) {
307 if (line.empty() || line.find_first_not_of(
" \t\r\n") == std::string::npos)
317 std::istringstream ss(line);
320 if (!(ss >>
id >> type >> x >> y >> z))
321 MY_ERROR(
"ERROR: Coordinate of particle " + std::to_string(i));
322 if (typeToSpecies.find(type) == typeToSpecies.end() ||
323 typeToMass.find(type) == typeToMass.end())
324 MY_ERROR(
"ERROR: Atom type " + std::to_string(type) +
" is missing from the Masses section.");
326 int idxFlagx= 0;
int idxFlagy= 0;
int idxFlagz= 0;
327 int tmpx, tmpy, tmpz;
328 if (ss >> tmpx >> tmpy >> tmpz) {
336 species[
id-1]= typeToSpecies.at(type);
337 masses(
id-1)= typeToMass.at(type);
340 assert(
species[
id-1] == typeToSpecies.at(type) &&
341 "Species in the reference configuration do not match with those in the "
342 "current configuration");
343 assert(
masses(
id-1) == typeToMass.at(type) &&
344 "Masses in the reference configuration do not match with those in the "
345 "current configuration");
348 Vector3d imageShift= idxFlagx*boxMatrix.col(0).transpose() +
349 idxFlagy*boxMatrix.col(1).transpose() +
350 idxFlagz*boxMatrix.col(2).transpose();
354 std::getline(file, line);
361 else if (loweredLine.find(
"velocities") != std::string::npos) {
363 while (std::getline(file, line)) {
364 if (line.empty() || line.find_first_not_of(
" \t\r\n") == std::string::npos)
372 std::istringstream ss(line);
375 if (!(ss >>
id >> vx >> vy >> vz))
376 MY_ERROR(
"ERROR: Velocity of particle " + std::to_string(i));
385 std::getline(file, line);
392 pbc = Eigen::Vector3i::Zero();
399 int numberOfPaddings{0};
400 std::vector<double> reference_coordinatesOfPaddings,coordinatesOfPaddings;
401 std::vector<std::string> speciesOfPaddings;
402 std::vector<int> masterOfPaddings;
416 reference_coordinatesOfPaddings,
417 coordinatesOfPaddings,
433 config_ptr->species.push_back(*it);
435 if (numberOfPaddings)
437 using RowMajorMatrixXd = Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor>;
438 if (referenceAndFinal)
440 config_ptr->coordinates.at(
Reference).bottomRows(numberOfPaddings)=
441 Eigen::Map<const RowMajorMatrixXd> (reference_coordinatesOfPaddings.data(),numberOfPaddings,
DIM);
443 config_ptr->coordinates.at(
Current).bottomRows(numberOfPaddings)=
444 Eigen::Map<const RowMajorMatrixXd> (coordinatesOfPaddings.data(),numberOfPaddings,
DIM);
445 for (
int i_padding=0; i_padding<numberOfPaddings; ++i_padding)
447 int master= masterOfPaddings[i_padding];
451 for (
auto it= speciesOfPaddings.begin();it!= speciesOfPaddings.end();it++)
452 config_ptr->species.push_back(*it);
int nbl_create_paddings(int const numberOfParticles, double const cutoff, double const *reference_origin, double const *origin, double const *reference_cell, double const *cell, int const *PBC, double const *reference_coordinates, double const *coordinates, const std::vector< std::string > &speciesCode, int &numberOfPaddings, std::vector< double > &reference_coordinatesOfPaddings, std::vector< double > &coordinatesOfPaddings, std::vector< std::string > &speciesCodeOfPaddings, std::vector< int > &masterOfPaddings, int referenceAndFinal)