Skip to content

Commit

Permalink
Merge pull request #530 from GOMC-WSU/duplicate-dihedral
Browse files Browse the repository at this point in the history
Detect and remove duplicate dihedrals with the same periodicity
  • Loading branch information
LSchwiebert authored Nov 27, 2024
2 parents ff3f67a + a3a7c1c commit a505e46
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 16 deletions.
57 changes: 44 additions & 13 deletions src/FFSetup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ along with this program, also can be found at
// For Exotic style parameter header error checking
#include <regex>

const double EPSILON = 1.0e-4;
const uint FFSetup::CHARMM_ALIAS_IDX = 0;
const uint FFSetup::EXOTIC_ALIAS_IDX = 1;
const std::string FFSetup::paramFileAlias[] = {"CHARMM-Style parameter file",
Expand Down Expand Up @@ -185,6 +186,12 @@ std::string FFBase::ReadKind(Reader &param, std::string const &firstKindName) {
param.file >> tmp;
merged += tmp;
}
// Skip duplicates unless we allow multiple entries, such as for dihedrals
if (!multi && std::find(name.begin(), name.end(), merged) != name.end()) {
std::cout << "Warning: Ignoring duplicate entry for " << merged << " in "
<< param.getFileName().c_str() << ". Using first entry.\n";
}
// Might insert duplicates but they will be ignored during execution
if (!multi || std::find(name.begin(), name.end(), merged) == name.end())
name.push_back(merged);
return merged;
Expand Down Expand Up @@ -236,7 +243,7 @@ void Particle::Read(Reader &param, std::string const &firstVar) {
// computation. But need the exponents to be large enough that the arithmetic
// or geometric mean of any pair > 6.0. See FFParticle::Blend() for underlying
// math.
double smallVal = 1e-20;
double smallVal = 1.0e-20;
if (std::fabs(e) < smallVal) {
e = 0.0;
expN = 12.0; // Set to default (LJ) exponent.
Expand All @@ -246,12 +253,11 @@ void Particle::Read(Reader &param, std::string const &firstVar) {
expN_1_4 = 12.0; // Set to default (LJ) exponent.
}
if ((expN - 6.0) < smallVal) {
std::cout << "ERROR: Mie exponent must be > 6!" << std::endl;
std::cout << "ERROR: Mie exponent must be > 6!\n";
exit(EXIT_FAILURE);
}
if ((expN_1_4 - 6.0) < smallVal) {
std::cout << "ERROR: Mie exponent for 1-4 interactions must be > 6!"
<< std::endl;
std::cout << "ERROR: Mie exponent for 1-4 interactions must be > 6!\n";
exit(EXIT_FAILURE);
}

Expand Down Expand Up @@ -380,14 +386,39 @@ void Dihedral::Read(Reader &param, std::string const &firstVar) {
if (index == 0) {
// set phase shift for n=0 to 90 degree
// We will have C0 = Kchi (1 + cos(0 * phi + 90)) = Kchi
//this avoids double counting the C0 (constant offset) term, which is used force fields like TraPPE
// this avoids double counting the C0 (constant offset) term, which is used
// in force fields like TraPPE
def = 90.00;
}
Add(merged, coeff, index, def);
Add(param.getFileName(), merged, coeff, index, def);
last = merged;
}
void Dihedral::Add(std::string const &merged, const double coeff,
const uint index, const double def) {
void Dihedral::Add(const std::string &fileName, const std::string &merged,
const double coeff, const uint index, const double def) {
// Check for (and skip) duplicate periodicities for the same dihedral
// Generate an error and terminate if the duplicate dihedrals have different
// parameters
auto Kchi_it = Kchi[merged].begin();
auto delta_it = delta[merged].begin();
for (auto it = n[merged].begin(); it != n[merged].end(); ++it) {
// Found a duplicate dihedral
if (*it == index) {
if (std::fabs(*Kchi_it - EnConvIfCHARMM(coeff)) > EPSILON ||
std::fabs(*delta_it - geom::DegToRad(def)) > EPSILON) {
std::cout << "Error: Inconsistent dihedral parameters were found in "
<< fileName.c_str() << " for dihedral " << merged
<< " with periodicity " << index << "!\n";
exit(EXIT_FAILURE);
} else {
std::cout << "Warning: Ignoring duplicate periodicity of " << index
<< " for dihedral " << merged << " in " << fileName.c_str()
<< ".\n";
return;
}
}
Kchi_it++;
delta_it++;
}
++countTerms;
Kchi[merged].push_back(EnConvIfCHARMM(coeff));
n[merged].push_back(index);
Expand All @@ -399,7 +430,7 @@ void Improper::Read(Reader &param, std::string const &firstVar) {
uint index;
std::string merged = ReadKind(param, firstVar);
// If new value
if (validname(merged) == true) {
if (validname(merged)) {
param.file >> coeff >> index >> def;
if (!param.file.good()) {
std::cout << "Error: Incomplete Improper parameters was found in "
Expand All @@ -420,7 +451,7 @@ void CMap::Read(Reader &param, std::string const &firstVar) {
uint index;
std::string merged = ReadKind(param, firstVar);
// If new value
if (validname(merged) == true) {
if (validname(merged)) {
param.file >> coeff >> index >> def;
if (!param.file.good()) {
std::cout << "Error: Incomplete Improper parameters was found in "
Expand All @@ -430,19 +461,19 @@ void CMap::Read(Reader &param, std::string const &firstVar) {
Add(coeff, def);
}
}
// Currently dummy method, exact same as improper
// Currently dummy method, exactly the same as improper
void CMap::Add(const double coeff, const double def) {
Komega.push_back(EnConvIfCHARMM(coeff));
omega0.push_back(def);
}

// Currently dummy method, exact same as improper
// Currently dummy method, exactly the same as improper
void HBond::Read(Reader &param, std::string const &firstVar) {
double coeff, def;
uint index;
std::string merged = ReadKind(param, firstVar);
// If new value
if (validname(merged) == true) {
if (validname(merged)) {
param.file >> coeff >> index >> def;
if (!param.file.good()) {
std::cout << "Error: Incomplete Improper parameters was found in "
Expand Down
6 changes: 3 additions & 3 deletions src/FFSetup.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class FFBase : public SearchableBase {
std::string ReadKind(Reader &param, std::string const &firstKindName);
std::vector<std::string> &getnamelist() { return name; }

bool validname(std::string &merged) {
bool validname(const std::string &merged) const {
return (std::count(name.begin(), name.end(), merged) > 0);
}
std::string getname(const uint i) const { return name[i]; }
Expand Down Expand Up @@ -146,8 +146,8 @@ class Dihedral : public ReadableBaseWithFirst, public FFBase {
public:
Dihedral(void) : FFBase(4, true), last(""), countTerms(0) {}
virtual void Read(Reader &param, std::string const &firstVar);
void Add(std::string const &merged, const double coeff, const uint index,
const double def);
void Add(const std::string &fileName, const std::string &merged,
const double coeff, const uint index, const double def);
uint getTerms() const { return countTerms; }
uint append(std::string &s, double *Kchi_in, double *delta_in, uint *n_in,
uint count) const {
Expand Down
2 changes: 2 additions & 0 deletions src/Reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ inline std::ifstream &operator>>(std::ifstream &is, bool &val) {

class Reader {
public:
friend inline std::ifstream &operator>>(std::ifstream &is, bool &val);
Reader(std::string const &name, std::string const &alias,
bool useSkipW = false, std::string const *const skipW = NULL,
bool useSkipC = false, std::string const *const skipC = NULL,
Expand Down Expand Up @@ -98,6 +99,7 @@ class Reader {
}

bool Read(std::string &firstItem);
std::string getFileName() const { return fileName; };

// Make public to expose object.
std::ifstream file;
Expand Down

0 comments on commit a505e46

Please sign in to comment.