25#include <boost/algorithm/string.hpp>
26#include <boost/lexical_cast.hpp>
57 throw std::runtime_error(
"Error: unexpected end of dlpoly file '" +
61 i_nws = line.find_first_not_of(wspace);
62 }
while (line.substr(i_nws, 1) ==
"#" || line.substr(i_nws, 1) ==
";");
64 return line.substr(i_nws, line.size() - i_nws);
68 const string &word,
Index &ival)
78 boost::to_upper(line);
80 if (line.substr(0, word.size()) != word) {
81 throw std::runtime_error(
"Error: unexpected line from dlpoly file '" +
82 fname_ +
"', expected '" + word +
"' but got '" +
88 size_t i_num = sval.find_first_of(
92 throw std::runtime_error(
"Error: missing integer number in directive '" +
93 line +
"' in topology file '" +
fname_ +
"'");
96 ival = boost::lexical_cast<Index>(sval);
102 const string &word,
Index &ival)
114 if (fields.size() < 2) {
118 boost::to_upper(fields[0]);
120 if (fields[0].substr(0, word.size()) != word) {
121 throw std::runtime_error(
"Error: unexpected directive from dlpoly file '" +
122 fname_ +
"', expected keyword '" + word +
123 "' but got '" + fields[0] +
"'");
126 size_t i_num = string::npos;
131 i_num = fields[i++].find_first_of(
"0123456789");
132 }
while (i_num > 0 && i <
Index(fields.size()));
138 ival = boost::lexical_cast<Index>(fields[i - 1]);
147 std::filesystem::path filepath(file.c_str());
155 if (!filepath.has_stem()) {
156 if (filepath.parent_path().string().size() == 0) {
160 fname_ = filepath.parent_path().string() +
"/FIELD";
169 throw std::runtime_error(
"Error on opening dlpoly file '" +
fname_ +
"'");
171 const char *WhiteSpace =
" \t";
174 boost::to_upper(line);
176 if (line.substr(0, 4) ==
"UNIT") {
178 boost::to_upper(line);
181 if (line.substr(0, 4) ==
"NEUT") {
184 boost::to_upper(line);
189 if (!
isKeyInt_(line, WhiteSpace,
"MOLEC", nmol_types)) {
190 throw std::runtime_error(
"Error: missing integer number in directive '" +
191 line +
"' in topology file '" +
fname_ +
"'");
195 cout <<
"Read from dlpoly file '" <<
fname_ <<
"' : '" << line <<
"' - "
196 << nmol_types << endl;
201 for (
Index nmol_type = 0; nmol_type < nmol_types; nmol_type++) {
207 line =
NextKeyInt_(fl, WhiteSpace,
"NUMMOL", nreplica);
210 cout <<
"Read from dlpoly file '" <<
fname_ <<
"' : '" << mol_name
211 <<
"' - '" << line <<
"' - " << nreplica << endl;
214 line =
NextKeyInt_(fl, WhiteSpace,
"ATOMS", natoms);
217 cout <<
"Read from dlpoly file '" <<
fname_ <<
"' : '" << line <<
"' - "
220 std::vector<Index> id_map(natoms);
221 for (
Index i = 0; i < natoms;) {
225 cout <<
"Read atom specs from dlpoly topology : '" << sl.str() <<
"'"
244 cout <<
"Rest atom specs from dlpoly topology : '" << line <<
"'"
249 if (fields.size() > 1) {
250 repeater = boost::lexical_cast<Index>(fields[0]);
253 for (
Index j = 0; j < repeater; j++) {
255 string beadname = beadtype +
"#" + boost::lexical_cast<string>(i + 1);
257 res.
getId(), mass, charge);
264 id_map[i] = bead->
getId();
267 cout <<
"Atom identification in maps '" << nm.str() <<
"'" << endl;
272 while (line !=
"FINISH") {
278 cout <<
"Read unit type# from dlpoly topology : '" << nl.str() <<
"'"
282 boost::to_upper(line);
283 line = line.substr(0, 6);
284 if ((line ==
"BONDS") || (line ==
"ANGLES") || (line ==
"DIHEDR")) {
288 for (
Index i = 0; i < count; i++) {
292 cout <<
"Read unit specs from dlpoly topology : '" << sl.str()
301 if (type ==
"BONDS") {
302 ic =
new IBond(id_map[ids[0] - 1],
304 }
else if (type ==
"ANGLES") {
306 ic =
new IAngle(id_map[ids[0] - 1], id_map[ids[1] - 1],
308 }
else if (type.substr(0, 6) ==
"DIHEDR") {
312 ic =
new IDihedral(id_map[ids[0] - 1], id_map[ids[1] - 1],
316 throw std::runtime_error(
317 "Error: type should be BONDS, ANGLES or DIHEDRALS");
332 cout <<
"Read from dlpoly file '" <<
fname_ <<
"' : '" << line
333 <<
"' - done with '" << mol_name <<
"'" << endl;
337 for (
Index replica = 1; replica < nreplica; replica++) {
348 for (
auto &ic : ics) {
352 if (ic->BeadCount() == 2) {
354 new IBond(ic->getBeadId(0) + offset, ic->getBeadId(1) + offset);
355 }
else if (ic->BeadCount() == 3) {
357 new IAngle(ic->getBeadId(0) + offset, ic->getBeadId(1) + offset,
358 ic->getBeadId(2) + offset);
359 }
else if (ic->BeadCount() == 4) {
361 ic->getBeadId(0) + offset, ic->getBeadId(1) + offset,
362 ic->getBeadId(2) + offset, ic->getBeadId(3) + offset);
364 throw std::runtime_error(
"Error: BeadCount not equal 2, 3 or 4");
366 ic_replica->
setGroup(ic->getGroup());
367 ic_replica->
setIndex(ic->getIndex());
379 if (line ==
"close") {
380 cout <<
"Read from dlpoly file '" <<
fname_ <<
"' : '" << line
381 <<
"' - done with topology" << endl;
383 cout <<
"Read from dlpoly file '" <<
fname_
384 <<
"' : 'EOF' - done with topology (directive 'close' not read!)"
virtual const std::string getType() const noexcept
std::string getName() const
Gets the name of the bead.
virtual const double & getMass() const noexcept
Index getId() const noexcept
Gets the id of the bead.
const Index & getResnr() const
virtual const double & getQ() const
std::string NextKeyline_(std::ifstream &fs, const char *wspace)
bool isKeyInt_(const std::string &line, const char *wspace, const std::string &word, Index &ival)
std::string NextKeyInt_(std::ifstream &fs, const char *wspace, const std::string &word, Index &ival)
bool ReadTopology(std::string file, Topology &top) override
read a topology file
base class for all interactions
void setGroup(const std::string &group)
void setIndex(const Index &index)
void setMolecule(const Index &mol)
information about molecules
void AddBead(Bead *bead, const std::string &name)
Add a bead to the molecule.
Bead * getBead(Index bead)
get the id of a bead in the molecule
void AddInteraction(Interaction *ic)
Add an interaction to the molecule.
std::vector< Interaction * > Interactions()
Index BeadCount() const
get the number of beads in the molecule
Index getId() const
get the molecule ID
Index getId() const
get the name of the residue
const std::string & getName() const
get the name of the residue
topology of the whole system
Residue & CreateResidue(std::string name)
Create a new resiude.
bool BeadTypeExist(std::string type) const
Determine if a bead type exists.
Bead * CreateBead(Bead::Symmetry symmetry, std::string name, std::string type, Index resnr, double m, double q)
Creates a new Bead.
void AddBondedInteraction(Interaction *ic)
void RegisterBeadType(std::string type)
Register the bead type with the topology object.
Molecule * CreateMolecule(std::string name)
Creates a new molecule.
Residue & getResidue(const Index i)
std::vector< Interaction * > InteractionContainer
base class for all analysis tools