Skip to content

Commit

Permalink
Merge pull request #2022 from ghutchis/ff-dielectric-const
Browse files Browse the repository at this point in the history
Add force field support for dielectric constants in charge terms.
  • Loading branch information
ghutchis committed Sep 14, 2019
2 parents 62bc9b4 + 166b7bd commit c195713
Show file tree
Hide file tree
Showing 16 changed files with 132 additions and 27 deletions.
15 changes: 15 additions & 0 deletions include/openbabel/forcefield.h
Expand Up @@ -554,6 +554,7 @@ namespace OpenBabel
bool _cutoff; //!< true = cut-off enabled
double _rvdw; //!< VDW cut-off distance
double _rele; //!< Electrostatic cut-off distance
double _epsilon; //!< Dielectric constant for electrostatics
OBBitVec _vdwpairs; //!< VDW pairs that should be calculated
OBBitVec _elepairs; //!< Electrostatic pairs that should be calculated
int _pairfreq; //!< The frequence to update non-bonded pairs
Expand Down Expand Up @@ -817,6 +818,20 @@ namespace OpenBabel
{
return _rele;
}
/*! Set the dielectric constant for electrostatic SetupCalculations
* \param epsilon The relative permittivity to use (default = 1.0)
*/
void SetDielectricConstant(double epsilon)
{
_epsilon = epsilon;
}
/* Get the dielectric permittivity used for electrostatic calculations
* \rreturn The current relative permittivity
*/
double GetDielectricConstant()
{
return _epsilon;
}
/*! Set the frequency by which non-bonded pairs are updated. Values from 10 to 20
* are recommended. Too low will decrease performance, too high will cause
* non-bonded interactions within cut-off not to be calculated.
Expand Down
2 changes: 1 addition & 1 deletion src/forcefields/forcefieldgaff.cpp
Expand Up @@ -1040,7 +1040,7 @@ namespace OpenBabel
continue;
}

elecalc.qq = KCAL_TO_KJ * 332.17 * a->GetPartialCharge() * b->GetPartialCharge();
elecalc.qq = KCAL_TO_KJ * 332.17 * a->GetPartialCharge() * b->GetPartialCharge() / _epsilon;

if (elecalc.qq) {
elecalc.a = &*a;
Expand Down
2 changes: 1 addition & 1 deletion src/forcefields/forcefieldgaff.h
Expand Up @@ -126,6 +126,7 @@ namespace OpenBabel
_init = false;
_rvdw = 7.0;
_rele = 15.0;
_epsilon = 1.0;
_pairfreq = 10;
_cutoff = false;
_linesearch = LineSearchType::Newton2Num;
Expand Down Expand Up @@ -209,4 +210,3 @@ namespace OpenBabel

//! \file forcefieldgaff.h
//! \brief Gaff force field

2 changes: 1 addition & 1 deletion src/forcefields/forcefieldghemical.cpp
Expand Up @@ -815,7 +815,7 @@ namespace OpenBabel
continue;
}

elecalc.qq = KCAL_TO_KJ * 332.17 * a->GetPartialCharge() * b->GetPartialCharge();
elecalc.qq = KCAL_TO_KJ * 332.17 * a->GetPartialCharge() * b->GetPartialCharge() / _epsilon;

if (elecalc.qq) {
elecalc.a = &*a;
Expand Down
2 changes: 1 addition & 1 deletion src/forcefields/forcefieldghemical.h
Expand Up @@ -117,6 +117,7 @@ namespace OpenBabel
_init = false;
_rvdw = 7.0;
_rele = 15.0;
_epsilon = 1.0;
_pairfreq = 10;
_cutoff = false;
_linesearch = LineSearchType::Newton2Num;
Expand Down Expand Up @@ -194,4 +195,3 @@ namespace OpenBabel

//! \file forcefieldghemical.h
//! \brief Ghemical force field

3 changes: 1 addition & 2 deletions src/forcefields/forcefieldmm2.h
Expand Up @@ -98,7 +98,7 @@ namespace OpenBabel


virtual const char* Description()
{ return "MM2 force field.";};
{ return "MM2 force field.";};


//! Destructor
Expand Down Expand Up @@ -129,4 +129,3 @@ namespace OpenBabel

//! \file forcefieldmm2.h
//! \brief MM2 force field

2 changes: 1 addition & 1 deletion src/forcefields/forcefieldmmff94.cpp
Expand Up @@ -3656,7 +3656,7 @@ namespace OpenBabel
continue;
}

elecalc.qq = 332.0716 * a->GetPartialCharge() * b->GetPartialCharge();
elecalc.qq = 332.0716 * a->GetPartialCharge() * b->GetPartialCharge() / _epsilon;

if (elecalc.qq) {
elecalc.a = &*a;
Expand Down
2 changes: 1 addition & 1 deletion src/forcefields/forcefieldmmff94.h
Expand Up @@ -235,6 +235,7 @@ namespace OpenBabel
_init = false;
_rvdw = 7.0;
_rele = 15.0;
_epsilon = 1.0; // default electrostatics
_pairfreq = 15;
_cutoff = false;
_linesearch = LineSearchType::Newton2Num;
Expand Down Expand Up @@ -335,4 +336,3 @@ namespace OpenBabel

//! \file forcefieldmmff94.h
//! \brief MMFF94 force field

1 change: 1 addition & 0 deletions src/forcefields/forcefielduff.h
Expand Up @@ -127,6 +127,7 @@ namespace OpenBabel
_init = false;
_rvdw = 7.0;
_rele = 15.0;
_epsilon = 1.0; // electrostatics not used
_pairfreq = 10;
_cutoff = false;
_linesearch = LineSearchType::Newton2Num;
Expand Down
15 changes: 14 additions & 1 deletion src/ops/forcefield.cpp
Expand Up @@ -54,7 +54,8 @@ namespace OpenBabel
"Typical usage: obabel infile.xxx -O outfile.yy --energy --log\n"
" options: description\n"
" --log output a log of the energies (default = no log)\n"
" --ff # select a forcefield (default = Ghemical)\n"
" --epsilon # set the dielectric constant for electrostatics\n"
" --ff # select a forcefield (default = MMFF94)\n"
" The hydrogens are always made explicit before energy evaluation.\n"
" The energy is put in an OBPairData object \"Energy\" which is\n"
" accessible via an SDF or CML property or --append (to title).\n"
Expand Down Expand Up @@ -82,10 +83,14 @@ namespace OpenBabel
bool log = false;

string ff = "MMFF94";
double epsilon = 1.0;
OpMap::const_iterator iter = pmap->find("ff");
if(iter!=pmap->end())
ff = iter->second;
OBForceField* pFF = OBForceField::FindForceField(ff);
iter = pmap->find("epsilon");
if (iter!=pmap->end())
epsilon = atof(iter->second.c_str());

iter = pmap->find("log");
if(iter!=pmap->end())
Expand All @@ -95,6 +100,7 @@ namespace OpenBabel
pFF->SetLogFile(&clog);
pFF->SetLogLevel(log ? OBFF_LOGLVL_MEDIUM : OBFF_LOGLVL_NONE);

pFF->SetDielectricConstant(epsilon);
if (!pFF->Setup(*pmol)) {
cerr << "Could not setup force field." << endl;
return false;
Expand Down Expand Up @@ -135,6 +141,7 @@ namespace OpenBabel
" --ff # select a forcefield (default = Ghemical)\n"
" --steps # specify the maximum number of steps (default = 2500)\n"
" --cut use cut-off (default = don't use cut-off)\n"
" --epsilon # relative dielectric constant (default = 1.0)\n"
" --rvdw # specify the VDW cut-off distance (default = 6.0)\n"
" --rele # specify the Electrostatic cut-off distance (default = 10.0)\n"
" --freq # specify the frequency to update the non-bonded pairs (default = 10)\n"
Expand Down Expand Up @@ -167,6 +174,7 @@ namespace OpenBabel
bool sd = false;
bool cut = false;
bool newton = true;
double epsilon = 1.0;
double rvdw = 6.0;
double rele = 10.0;
int freq = 10;
Expand Down Expand Up @@ -198,6 +206,10 @@ namespace OpenBabel
if(iter!=pmap->end())
steps = atoi(iter->second.c_str());

iter = pmap->find("epsilon");
if(iter!=pmap->end())
epsilon = atof(iter->second.c_str());

iter = pmap->find("rvdw");
if(iter!=pmap->end())
rvdw = atof(iter->second.c_str());
Expand Down Expand Up @@ -226,6 +238,7 @@ namespace OpenBabel
pFF->SetVDWCutOff(rvdw);
pFF->SetElectrostaticCutOff(rele);
pFF->SetUpdateFrequency(freq);
pFF->SetDielectricConstant(epsilon);
pFF->EnableCutOff(cut);

if (!pFF->Setup(*pmol)) {
Expand Down
2 changes: 1 addition & 1 deletion test/CMakeLists.txt
Expand Up @@ -71,7 +71,7 @@ set(origtests
unitcell
)
set (atom_parts 1 2 3 4)
set (ffmmff94_parts 1 2)
set (ffmmff94_parts 1 2 3 4 5 6)
set (math_parts 1 2 3 4)
set (pdbreadfile_parts 1 2 3 4)

Expand Down
59 changes: 42 additions & 17 deletions test/ffmmff94.cpp
Expand Up @@ -5,11 +5,11 @@ This file is part of the Open Babel project.
For more information, see <http://openbabel.org/>
Some portions Copyright (C) 2008 Geoffrey R. Hutchison
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Expand Down Expand Up @@ -40,7 +40,7 @@ using namespace OpenBabel;

int currentTest = 0;

void GenerateEnergies(string molecules_file, string results_file)
void GenerateEnergies(string molecules_file, string results_file, string method, double epsilon = 1.0)
{
std::ifstream ifs;
if (!SafeOpen(ifs, molecules_file.c_str()))
Expand All @@ -53,18 +53,19 @@ void GenerateEnergies(string molecules_file, string results_file)
OBMol mol;
OBConversion conv(&ifs, &cout);
char buffer[BUFF_SIZE];

if(! conv.SetInAndOutFormats("SDF","SDF"))
{
cerr << "SDF format is not loaded" << endl;
return;
}

OBForceField* pFF = OBForceField::FindForceField("MMFF94");
OBForceField* pFF = OBForceField::FindForceField(method);
OB_REQUIRE(pFF != NULL);

pFF->SetLogFile(&cout);
pFF->SetLogLevel(OBFF_LOGLVL_NONE);
pFF->SetDielectricConstant(epsilon);

for (;ifs;)
{
Expand All @@ -77,7 +78,7 @@ void GenerateEnergies(string molecules_file, string results_file)
cerr << "Could not setup force field on molecule: " << mol.GetTitle() << endl;
return;
}

// Don't compute gradients
sprintf(buffer, "%15.5f\n", pFF->Energy(false));
ofs << buffer;
Expand All @@ -87,7 +88,7 @@ void GenerateEnergies(string molecules_file, string results_file)
return;
}

void TestFile(string filename, string results_file)
void TestFile(string filename, string results_file, string method, double epsilon = 1.0)
{
std::ifstream mifs;
if (!SafeOpen(mifs, filename.c_str()))
Expand All @@ -113,12 +114,13 @@ void TestFile(string filename, string results_file)
cout << "Bail out! SDF format is not loaded" << endl;
return;
}
OBForceField* pFF = OBForceField::FindForceField("MMFF94");

OBForceField* pFF = OBForceField::FindForceField(method);
OB_REQUIRE(pFF != NULL);

pFF->SetLogFile(&cout);
pFF->SetLogLevel(OBFF_LOGLVL_NONE);
pFF->SetDielectricConstant(epsilon);

double energy;
while(mifs)
Expand All @@ -132,7 +134,7 @@ void TestFile(string filename, string results_file)
cout << "Bail out! error reading reference data" << endl;
return;
}

if (!pFF->Setup(mol)) {
cout << "Bail out! could not setup force field on " << mol.GetTitle() << endl;
return;
Expand Down Expand Up @@ -164,7 +166,7 @@ void TestFile(string filename, string results_file)
int ffmmff94(int argc, char* argv[])
{
int defaultchoice = 1;

int choice = defaultchoice;

if (argc > 1) {
Expand All @@ -174,22 +176,46 @@ int ffmmff94(int argc, char* argv[])
}
}

string testdatadir = TESTDATADIR;

if (choice == 99)
{
GenerateEnergies(testdatadir + "forcefield.sdf", testdatadir + "mmff94results.txt", "MMFF94");
GenerateEnergies(testdatadir + "more-mmff94.sdf", testdatadir + "more-mmff94results.txt", "MMFF94"); // provided by Paolo Tosco
GenerateEnergies(testdatadir + "forcefield.sdf", testdatadir + "mmff94sresults.txt", "MMFF94s");
GenerateEnergies(testdatadir + "more-mmff94.sdf", testdatadir + "more-mmff94sresults.txt", "MMFF94s"); // ditto
GenerateEnergies(testdatadir + "forcefield.sdf", testdatadir + "mmff94e4results.txt", "MMFF94", 4.0);
GenerateEnergies(testdatadir + "more-mmff94.sdf", testdatadir + "more-mmff94e4results.txt", "MMFF94", 4.0); // provided by Paolo Tosco

return 0;
}

// Define location of file formats for testing
#ifdef FORMATDIR
char env[BUFF_SIZE];
snprintf(env, BUFF_SIZE, "BABEL_LIBDIR=%s", FORMATDIR);
putenv(env);
#endif

string testdatadir = TESTDATADIR;
#endif

cout << "# Testing MMFF94 Force Field..." << endl;
switch(choice) {
case 1:
TestFile(testdatadir + "forcefield.sdf", testdatadir + "mmff94results.txt");
TestFile(testdatadir + "forcefield.sdf", testdatadir + "mmff94results.txt", "MMFF94");
break;
case 2:
TestFile(testdatadir + "more-mmff94.sdf", testdatadir + "more-mmff94results.txt"); // provided by Paolo Tosco
TestFile(testdatadir + "more-mmff94.sdf", testdatadir + "more-mmff94results.txt", "MMFF94"); // provided by Paolo Tosco
break;
case 3:
TestFile(testdatadir + "forcefield.sdf", testdatadir + "mmff94sresults.txt", "MMFF94s");
break;
case 4:
TestFile(testdatadir + "more-mmff94.sdf", testdatadir + "more-mmff94sresults.txt", "MMFF94s"); // ditto
break;
case 5:
TestFile(testdatadir + "forcefield.sdf", testdatadir + "mmff94e4results.txt", "MMFF94", 4.0);
break;
case 6:
TestFile(testdatadir + "more-mmff94.sdf", testdatadir + "more-mmff94e4sresults.txt", "MMFF94", 4.0);
break;
default:
cout << "Test number " << choice << " does not exist!\n";
Expand All @@ -199,4 +225,3 @@ int ffmmff94(int argc, char* argv[])
// Passed tests
return 0;
}

18 changes: 18 additions & 0 deletions test/files/mmff94e4results.txt
@@ -0,0 +1,18 @@
81.07932
2.91283
-3.69683
4.24811
21.22882
118.74484
105.47746
20.86046
1207.63670
-0.14958
100.53756
82.09361
64.68310
81.07932
316.34690
35.71481
44.77390
72.62709
18 changes: 18 additions & 0 deletions test/files/mmff94sresults.txt
@@ -0,0 +1,18 @@
68.11491
8.64766
-28.35351
-2.84895
21.22882
118.74484
79.03067
18.04199
1207.63670
-113.74578
112.23600
107.75248
93.43627
68.11491
312.57114
19.17321
39.99337
14.10039
8 changes: 8 additions & 0 deletions test/files/more-mmff94e4results.txt
@@ -0,0 +1,8 @@
69.34483
11.26353
3.80210
-2.68512
16.18134
35.18203
-2.57316
62.69012

0 comments on commit c195713

Please sign in to comment.