mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-04 21:54:27 +08:00
1263 lines
37 KiB
C++
1263 lines
37 KiB
C++
// $Id$
|
|
//
|
|
// Copyright (C) 2004-2006 Rational Discovery LLC
|
|
//
|
|
// @@ All Rights Reserved @@
|
|
//
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <math.h>
|
|
#include <RDGeneral/Invariant.h>
|
|
#include <RDGeneral/utils.h>
|
|
#include <Geometry/point.h>
|
|
|
|
#include <ForceField/ForceField.h>
|
|
#include <ForceField/UFF/Params.h>
|
|
#include <ForceField/UFF/BondStretch.h>
|
|
#include <ForceField/UFF/AngleBend.h>
|
|
#include <ForceField/UFF/Nonbonded.h>
|
|
#include <ForceField/UFF/TorsionAngle.h>
|
|
#include <ForceField/UFF/DistanceConstraint.h>
|
|
|
|
#include <GraphMol/Atom.h>
|
|
|
|
using namespace RDGeom;
|
|
|
|
void test1(){
|
|
std::cerr << "-------------------------------------" << std::endl;
|
|
std::cerr << "Unit tests for force field basics." << std::endl;
|
|
|
|
ForceFields::ForceField ff;
|
|
TEST_ASSERT(ff.dimension() ==3 );
|
|
|
|
Point3D p1(0,0,0),p2(1,0,0),p3(2,0,0),p4(0,1,0);
|
|
RDGeom::PointPtrVect &ps=ff.positions();
|
|
ps.push_back(&p1);
|
|
ps.push_back(&p2);
|
|
ps.push_back(&p3);
|
|
ps.push_back(&p4);
|
|
|
|
#if 0
|
|
Point3D f1,f2,f3,f4;
|
|
RDGeom::PointPtrVect &fs=ff.forces();
|
|
fs.push_back(&f1);
|
|
fs.push_back(&f2);
|
|
fs.push_back(&f3);
|
|
fs.push_back(&f4);
|
|
#endif
|
|
TEST_ASSERT(ff.positions().size()==4);
|
|
//TEST_ASSERT(ff.forces().size()==4);
|
|
|
|
ff.initialize();
|
|
|
|
TEST_ASSERT(RDKit::feq(ff.distance(0,1),1.0));
|
|
TEST_ASSERT(RDKit::feq(ff.distance(1,0),1.0));
|
|
TEST_ASSERT(RDKit::feq(ff.distance(0,0),0.0));
|
|
TEST_ASSERT(RDKit::feq(ff.distance(0,2),2.0));
|
|
TEST_ASSERT(RDKit::feq(ff.distance(2,0),2.0));
|
|
TEST_ASSERT(RDKit::feq(ff.distance(0,3),1.0));
|
|
TEST_ASSERT(RDKit::feq(ff.distance(3,0),1.0));
|
|
TEST_ASSERT(RDKit::feq(ff.distance(3,3),0.0));
|
|
TEST_ASSERT(RDKit::feq(ff.distance(1,2),1.0));
|
|
TEST_ASSERT(RDKit::feq(ff.distance(2,1),1.0));
|
|
|
|
std::cerr << " done" << std::endl;
|
|
}
|
|
|
|
|
|
void testUFF1(){
|
|
std::cerr << "-------------------------------------" << std::endl;
|
|
std::cerr << "Unit tests for basics of UFF bond-stretch terms." << std::endl;
|
|
|
|
ForceFields::UFF::AtomicParams p1,p2;
|
|
double restLen,forceConstant;
|
|
|
|
// sp3 carbon:
|
|
p1.r1 = .757;
|
|
p1.Z1 = 1.912;
|
|
p1.GMP_Xi = 5.343;
|
|
|
|
// sp3 - sp3: checks basics
|
|
restLen=ForceFields::UFF::Utils::calcBondRestLength(1.0,&p1,&p1);
|
|
TEST_ASSERT(RDKit::feq(restLen,1.514));
|
|
|
|
forceConstant=ForceFields::UFF::Utils::calcBondForceConstant(restLen,&p1,&p1);
|
|
TEST_ASSERT(RDKit::feq(forceConstant,699.5918));
|
|
|
|
// sp2 carbon:
|
|
p2.r1 = .732;
|
|
p2.Z1 = 1.912;
|
|
p2.GMP_Xi = 5.343;
|
|
// sp2 - sp2: checks rBO
|
|
restLen=ForceFields::UFF::Utils::calcBondRestLength(2.0,&p2,&p2);
|
|
TEST_ASSERT(RDKit::feq(restLen,1.32883,1e-5));
|
|
|
|
forceConstant=ForceFields::UFF::Utils::calcBondForceConstant(restLen,&p2,&p2);
|
|
TEST_ASSERT(RDKit::feq(forceConstant,1034.69,1e-2));
|
|
|
|
// sp3 nitrogen:
|
|
p2.r1 = .700;
|
|
p2.Z1 = 2.544;
|
|
p2.GMP_Xi = 6.899;
|
|
|
|
// Csp3 - Nsp3: checks rEN
|
|
restLen=ForceFields::UFF::Utils::calcBondRestLength(1.0,&p1,&p2);
|
|
TEST_ASSERT(RDKit::feq(restLen,1.462929,1e-5));
|
|
|
|
forceConstant=ForceFields::UFF::Utils::calcBondForceConstant(restLen,&p1,&p2);
|
|
TEST_ASSERT(RDKit::feq(forceConstant,1031.77,1e-2));
|
|
|
|
|
|
// amide bond: check we can reproduce values from the UFF paper:
|
|
// C_R:
|
|
p1.r1 = .729;
|
|
p1.Z1 = 1.912;
|
|
p1.GMP_Xi = 5.343;
|
|
// N_R:
|
|
p2.r1 = .699;
|
|
p2.Z1 = 2.544;
|
|
p2.GMP_Xi = 6.899;
|
|
|
|
restLen=ForceFields::UFF::Utils::calcBondRestLength(ForceFields::UFF::Params::amideBondOrder,&p1,&p2);
|
|
TEST_ASSERT(RDKit::feq(restLen,1.368,1e-3)); // NOTE: the paper has 1.366
|
|
|
|
|
|
forceConstant=ForceFields::UFF::Utils::calcBondForceConstant(restLen,&p1,&p2);
|
|
TEST_ASSERT(RDKit::feq(forceConstant,1260.,1)); // NOTE: the paper has 1293
|
|
|
|
|
|
std::cerr << " done" << std::endl;
|
|
}
|
|
|
|
|
|
void testUFF2(){
|
|
std::cerr << "-------------------------------------" << std::endl;
|
|
std::cerr << "Unit tests for UFF bond-stretch terms." << std::endl;
|
|
|
|
ForceFields::ForceField ff;
|
|
Point3D p1(0,0,0),p2(1.514,0,0);
|
|
RDGeom::PointPtrVect &ps=ff.positions();
|
|
ps.push_back(&p1);
|
|
ps.push_back(&p2);
|
|
|
|
ForceFields::UFF::AtomicParams param1;
|
|
// sp3 carbon:
|
|
param1.r1 = .757;
|
|
param1.Z1 = 1.912;
|
|
param1.GMP_Xi = 5.343;
|
|
|
|
double *p,*g;
|
|
p = new double[6];
|
|
g = new double[6];
|
|
for(int i=0;i<6;i++){
|
|
p[i] = 0.0;
|
|
g[i] = 0.0;
|
|
}
|
|
p[0] = 0;
|
|
p[3] = 1.514;
|
|
|
|
ff.initialize();
|
|
|
|
// C_3 - C_3, r0=1.514, k01=699.5918
|
|
ForceFields::ForceFieldContrib *bs;
|
|
bs = new ForceFields::UFF::BondStretchContrib(&ff,0,1,1,¶m1,¶m1);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(bs));
|
|
double E;
|
|
E=bs->getEnergy(p);
|
|
TEST_ASSERT(RDKit::feq(E,0.0));
|
|
bs->getGrad(p,g);
|
|
for(int i=0;i<6;i++){
|
|
TEST_ASSERT(RDKit::feq(g[i],0.0));
|
|
}
|
|
|
|
ff.initialize();
|
|
(*ff.positions()[1])[0] = 1.814;
|
|
p[3] = 1.814;
|
|
E=bs->getEnergy(p);
|
|
TEST_ASSERT(RDKit::feq(E,31.4816));
|
|
bs->getGrad(p,g);
|
|
TEST_ASSERT(RDKit::feq(g[0],-209.8775));
|
|
TEST_ASSERT(RDKit::feq(g[3],209.8775));
|
|
TEST_ASSERT(RDKit::feq(g[1],0.0));
|
|
TEST_ASSERT(RDKit::feq(g[2],0.0));
|
|
TEST_ASSERT(RDKit::feq(g[4],0.0));
|
|
TEST_ASSERT(RDKit::feq(g[5],0.0));
|
|
|
|
// try a different axis:
|
|
for(int i=0;i<6;i++){
|
|
g[i] = 0.0;
|
|
p[i] = 0.0;
|
|
}
|
|
ff.initialize();
|
|
(*ff.positions()[1])[0] = 0.0;
|
|
(*ff.positions()[1])[2] = 1.814;
|
|
p[5] = 1.814;
|
|
E=bs->getEnergy(p);
|
|
TEST_ASSERT(RDKit::feq(E,31.4816));
|
|
bs->getGrad(p,g);
|
|
TEST_ASSERT(RDKit::feq(g[2],-209.8775));
|
|
TEST_ASSERT(RDKit::feq(g[5],209.8775));
|
|
TEST_ASSERT(RDKit::feq(g[0],0.0));
|
|
TEST_ASSERT(RDKit::feq(g[1],0.0));
|
|
TEST_ASSERT(RDKit::feq(g[3],0.0));
|
|
TEST_ASSERT(RDKit::feq(g[4],0.0));
|
|
|
|
// try a bit of minimization
|
|
RDGeom::Point3D d;
|
|
ff.initialize();
|
|
(*ff.positions()[1])[2] = 0.0;
|
|
(*ff.positions()[1])[0] = 1.814;
|
|
ff.minimize(10,1e-8);
|
|
d=*(RDGeom::Point3D*)ff.positions()[0] - *(RDGeom::Point3D*)ff.positions()[1];
|
|
TEST_ASSERT(RDKit::feq(d.length(),1.514,1e-3));
|
|
|
|
// minimize in "3D"
|
|
ff.initialize();
|
|
(*ff.positions()[1])[2] = 1.1;
|
|
(*ff.positions()[1])[1] = 0.9;
|
|
(*ff.positions()[1])[0] = 1.00;
|
|
ff.minimize(10,1e-8);
|
|
d=*(RDGeom::Point3D*)ff.positions()[0] - *(RDGeom::Point3D*)ff.positions()[1];
|
|
TEST_ASSERT(RDKit::feq(d.length(),1.514,1e-3));
|
|
|
|
|
|
|
|
delete [] p;
|
|
delete [] g;
|
|
std::cerr << " done" << std::endl;
|
|
}
|
|
|
|
|
|
void testUFF3(){
|
|
std::cerr << "-------------------------------------" << std::endl;
|
|
std::cerr << "Unit tests for basics of UFF angle terms." << std::endl;
|
|
|
|
ForceFields::UFF::AtomicParams p1,p2,p3;
|
|
double restLen,forceConstant;
|
|
|
|
// sp3 carbon:
|
|
p3.r1 = .757;
|
|
p3.Z1 = 1.912;
|
|
p3.GMP_Xi = 5.343;
|
|
p3.theta0 = 109.47*M_PI/180.0;
|
|
|
|
// sp3 - sp3: checks basics
|
|
restLen=ForceFields::UFF::Utils::calcBondRestLength(1.0,&p3,&p3);
|
|
TEST_ASSERT(RDKit::feq(restLen,1.514));
|
|
|
|
// C_3 - C_3 - C_3
|
|
forceConstant=ForceFields::UFF::Utils::calcAngleForceConstant(p3.theta0,1,1,&p3,&p3,&p3);
|
|
//TEST_ASSERT(RDKit::feq(forceConstant,699.5918));
|
|
|
|
// amide bond bend:
|
|
// C_R - N_R - C_3
|
|
// C_R:
|
|
p1.r1 = .729;
|
|
p1.Z1 = 1.912;
|
|
p1.GMP_Xi = 5.343;
|
|
// N_R:
|
|
p2.r1 = .699;
|
|
p2.Z1 = 2.544;
|
|
p2.GMP_Xi = 6.899;
|
|
p2.theta0 = 120.0*M_PI/180.;
|
|
restLen=ForceFields::UFF::Utils::calcBondRestLength(ForceFields::UFF::Params::amideBondOrder,&p1,&p2);
|
|
TEST_ASSERT(RDKit::feq(restLen,1.368,1e-3));
|
|
restLen=ForceFields::UFF::Utils::calcBondRestLength(1.0,&p2,&p3);
|
|
TEST_ASSERT(RDKit::feq(restLen,1.462,1e-3));
|
|
|
|
forceConstant=ForceFields::UFF::Utils::calcAngleForceConstant(p2.theta0,ForceFields::UFF::Params::amideBondOrder,1,
|
|
&p1,&p2,&p3);
|
|
TEST_ASSERT(RDKit::feq(forceConstant,123.5,1e-1)); // paper has 105.5
|
|
|
|
|
|
std::cerr << " done" << std::endl;
|
|
}
|
|
|
|
void testUFF4(){
|
|
std::cerr << "-------------------------------------" << std::endl;
|
|
std::cerr << "Unit tests for UFF angle-bend terms." << std::endl;
|
|
|
|
|
|
ForceFields::ForceField ff;
|
|
Point3D p1(1.514,0,0),p2(0,0,0),p3(0.1,1.5,0);
|
|
RDGeom::PointPtrVect &ps=ff.positions();
|
|
ps.push_back(&p1);
|
|
ps.push_back(&p2);
|
|
ps.push_back(&p3);
|
|
|
|
ForceFields::UFF::AtomicParams param1;
|
|
// sp3 carbon:
|
|
param1.r1 = .757;
|
|
param1.Z1 = 1.912;
|
|
param1.GMP_Xi = 5.343;
|
|
// cheat to get the angle to 90 so that testing is easier:
|
|
param1.theta0 = 90.0*M_PI/180.;
|
|
|
|
// C_3 - C_3, r0=1.514, k01=699.5918
|
|
ForceFields::ForceFieldContrib *contrib;
|
|
contrib = new ForceFields::UFF::BondStretchContrib(&ff,0,1,1,¶m1,¶m1);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::BondStretchContrib(&ff,1,2,1,¶m1,¶m1);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,0,1,2,1,1,¶m1,¶m1,¶m1);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
|
|
|
|
RDGeom::Point3D d,v1,v2;
|
|
double theta;
|
|
#if 1
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
// try a bit of minimization
|
|
ff.initialize();
|
|
ff.minimize(10,1e-8,1e-8);
|
|
|
|
v1=*(RDGeom::Point3D*)ff.positions()[0]-*(RDGeom::Point3D*)ff.positions()[1];
|
|
v2=*(RDGeom::Point3D*)ff.positions()[1]-*(RDGeom::Point3D*)ff.positions()[2];
|
|
theta = v1.angleTo(v2);
|
|
|
|
TEST_ASSERT(RDKit::feq(v1.length(),1.514,1e-3));
|
|
TEST_ASSERT(RDKit::feq(v2.length(),1.514,1e-3));
|
|
TEST_ASSERT(RDKit::feq(theta,90*M_PI/180.,1e-4));
|
|
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
// more complicated atomic coords:
|
|
p1.x=1.3;
|
|
p1.y=0.1;
|
|
p1.z=0.1;
|
|
p2.x=-0.1;
|
|
p2.y=0.05;
|
|
p2.z=-0.05;
|
|
p3.x=0.1;
|
|
p3.y=1.5;
|
|
p3.z=0.05;
|
|
ff.initialize();
|
|
ff.minimize(10,1e-8,1e-8);
|
|
|
|
v1=*(RDGeom::Point3D*)ff.positions()[0]-*(RDGeom::Point3D*)ff.positions()[1];
|
|
v2=*(RDGeom::Point3D*)ff.positions()[1]-*(RDGeom::Point3D*)ff.positions()[2];
|
|
theta = v1.angleTo(v2);
|
|
|
|
TEST_ASSERT(RDKit::feq(v1.length(),1.514,1e-3));
|
|
TEST_ASSERT(RDKit::feq(v2.length(),1.514,1e-3));
|
|
TEST_ASSERT(RDKit::feq(theta,90*M_PI/180.,1e-4));
|
|
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
// try for the tetrahedral angle instead of 90:
|
|
param1.theta0 = 109.47*M_PI/180.;
|
|
ff.contribs().pop_back();
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,0,1,2,1,1,¶m1,¶m1,¶m1);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
|
|
p1.x=1.3;
|
|
p1.y=0.1;
|
|
p1.z=0.1;
|
|
p2.x=-0.1;
|
|
p2.y=0.05;
|
|
p2.z=-0.05;
|
|
p3.x=0.1;
|
|
p3.y=1.5;
|
|
p3.z=0.05;
|
|
|
|
ff.initialize();
|
|
ff.minimize(100,1e-8,1e-8);
|
|
v1=*(RDGeom::Point3D*)ff.positions()[0]-*(RDGeom::Point3D*)ff.positions()[1];
|
|
v2=*(RDGeom::Point3D*)ff.positions()[2]-*(RDGeom::Point3D*)ff.positions()[1];
|
|
theta = v1.angleTo(v2);
|
|
TEST_ASSERT(RDKit::feq(v1.length(),1.514,1e-3));
|
|
TEST_ASSERT(RDKit::feq(v2.length(),1.514,1e-3));
|
|
TEST_ASSERT(RDKit::feq(theta,param1.theta0,1e-4));
|
|
|
|
#endif
|
|
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
//
|
|
// Do a series of "special cases" (i.e. test the functional forms
|
|
// for linear, trigonal planar, square planar and octahedral)
|
|
//
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
// test a linear molecule:
|
|
param1.theta0 = M_PI;
|
|
//ff.contribs().pop_back();
|
|
//ff.contribs().pop_back();
|
|
ff.contribs().pop_back();
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,0,1,2,1,1,¶m1,¶m1,¶m1,2);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
|
|
p1.x=1.3;
|
|
p1.y=0.1;
|
|
p1.z=0.0;
|
|
p2.x=0.0;
|
|
p2.y=0.0;
|
|
p2.z=0.0;
|
|
p3.x=-1.3;
|
|
p3.y=0.1;
|
|
p3.z=0.00;
|
|
ff.initialize();
|
|
ff.minimize(100,1e-8,1e-8);
|
|
|
|
v1=*(RDGeom::Point3D*)ff.positions()[0]-*(RDGeom::Point3D*)ff.positions()[1];
|
|
v2=*(RDGeom::Point3D*)ff.positions()[2]-*(RDGeom::Point3D*)ff.positions()[1];
|
|
theta = v1.angleTo(v2);
|
|
|
|
TEST_ASSERT(RDKit::feq(v1.length(),1.514,1e-3));
|
|
TEST_ASSERT(RDKit::feq(v2.length(),1.514,1e-3));
|
|
TEST_ASSERT(RDKit::feq(theta,param1.theta0,1e-4));
|
|
|
|
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
// test n=3:
|
|
param1.theta0 = 120.*M_PI/180.0;
|
|
//ff.contribs().pop_back();
|
|
//ff.contribs().pop_back();
|
|
ff.contribs().pop_back();
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,0,1,2,1,1,¶m1,¶m1,¶m1,3);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
|
|
p1.x=1.3;
|
|
p1.y=0.1;
|
|
p1.z=0.0;
|
|
p2.x=0.0;
|
|
p2.y=0.0;
|
|
p2.z=0.0;
|
|
p3.x=-.3;
|
|
p3.y=-1.3;
|
|
p3.z=0.00;
|
|
|
|
ff.initialize();
|
|
ff.minimize(100,1e-8,1e-8);
|
|
|
|
v1=*(RDGeom::Point3D*)ff.positions()[0]-*(RDGeom::Point3D*)ff.positions()[1];
|
|
v2=*(RDGeom::Point3D*)ff.positions()[2]-*(RDGeom::Point3D*)ff.positions()[1];
|
|
theta = v1.angleTo(v2);
|
|
|
|
TEST_ASSERT(RDKit::feq(v1.length(),1.514,1e-3));
|
|
TEST_ASSERT(RDKit::feq(v2.length(),1.514,1e-3));
|
|
TEST_ASSERT(RDKit::feq(theta,param1.theta0,1e-4));
|
|
|
|
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
// test n=4:
|
|
param1.theta0 = M_PI/2.0;
|
|
//ff.contribs().pop_back();
|
|
//ff.contribs().pop_back();
|
|
ff.contribs().pop_back();
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,0,1,2,1,1,¶m1,¶m1,¶m1,4);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
|
|
p1.x=1.3;
|
|
p1.y=0.1;
|
|
p1.z=0.0;
|
|
p2.x=0.0;
|
|
p2.y=0.0;
|
|
p2.z=0.0;
|
|
p3.x=-.3;
|
|
p3.y=-1.3;
|
|
p3.z=0.00;
|
|
|
|
ff.initialize();
|
|
ff.minimize(100,1e-8,1e-8);
|
|
|
|
v1=*(RDGeom::Point3D*)ff.positions()[0]-*(RDGeom::Point3D*)ff.positions()[1];
|
|
v2=*(RDGeom::Point3D*)ff.positions()[2]-*(RDGeom::Point3D*)ff.positions()[1];
|
|
theta = v1.angleTo(v2);
|
|
|
|
TEST_ASSERT(RDKit::feq(v1.length(),1.514,1e-3));
|
|
TEST_ASSERT(RDKit::feq(v2.length(),1.514,1e-3));
|
|
TEST_ASSERT(RDKit::feq(theta,param1.theta0,1e-4));
|
|
|
|
|
|
|
|
#if 0
|
|
std::cerr << " " << *ff.positions()[0] << std::endl;
|
|
std::cerr << " " << *ff.positions()[1] << std::endl;
|
|
std::cerr << " " << *ff.positions()[2] << std::endl;
|
|
|
|
std::cerr << "v1: " << v1 << std::endl;
|
|
std::cerr << "v2: " << v2 << std::endl;
|
|
std::cerr << "FINAL: " << v1.angleTo(v2) << " " << v1.signedAngleTo(v2) << std::endl;
|
|
#endif
|
|
|
|
std::cerr << " done" << std::endl;
|
|
}
|
|
|
|
|
|
void testUFF5(){
|
|
std::cerr << "-------------------------------------" << std::endl;
|
|
std::cerr << " Test Simple UFF molecule optimizations." << std::endl;
|
|
|
|
ForceFields::ForceField ff;
|
|
Point3D p1,p2,p3,p4,p5,p6;
|
|
RDGeom::PointPtrVect &ps=ff.positions();
|
|
ps.push_back(&p1);
|
|
ps.push_back(&p2);
|
|
ps.push_back(&p3);
|
|
ps.push_back(&p4);
|
|
ps.push_back(&p5);
|
|
ps.push_back(&p6);
|
|
|
|
ForceFields::UFF::AtomicParams param1,param2;
|
|
// sp2 carbon:
|
|
param1.r1 = .732;
|
|
param1.Z1 = 1.912;
|
|
param1.GMP_Xi = 5.343;
|
|
param1.theta0 = 120.*M_PI/180.;
|
|
|
|
// H_1:
|
|
param2.r1 = 0.354;
|
|
param2.Z1 = 0.712;
|
|
param2.GMP_Xi = 4.528;
|
|
|
|
ForceFields::ForceFieldContrib *contrib;
|
|
|
|
// build ethylene:
|
|
contrib = new ForceFields::UFF::BondStretchContrib(&ff,0,1,2,¶m1,¶m1);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::BondStretchContrib(&ff,0,2,1,¶m1,¶m2);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::BondStretchContrib(&ff,0,3,1,¶m1,¶m2);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::BondStretchContrib(&ff,1,4,1,¶m1,¶m2);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::BondStretchContrib(&ff,1,5,1,¶m1,¶m2);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,1,0,2,2,1,¶m1,¶m1,¶m2,3);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,1,0,3,2,1,¶m1,¶m1,¶m2,3);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,2,0,3,1,1,¶m2,¶m1,¶m2,3);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,0,1,4,2,1,¶m1,¶m1,¶m2,3);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,0,1,5,2,1,¶m1,¶m1,¶m2,3);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,4,1,5,1,1,¶m2,¶m1,¶m2,3);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
|
|
// dodge the fact that we're not using torsions yet by putting
|
|
// everything in the z=0 plane:
|
|
p1.x=-0.58;
|
|
p1.y=-0.33;
|
|
p1.z=0.0;
|
|
|
|
p2.x=0.58;
|
|
p2.y=0.33;
|
|
p2.z=0.0;
|
|
|
|
p3.x=-0.61;
|
|
p3.y=-1.43;
|
|
p3.z=0.0;
|
|
|
|
p4.x=-1.54;
|
|
p4.y=0.20;
|
|
p4.z=0.0;
|
|
|
|
p5.x=0.61;
|
|
p5.y=1.43;
|
|
p5.z=0.0;
|
|
|
|
p6.x=1.54;
|
|
p6.y=-0.20;
|
|
p6.z=0.0;
|
|
|
|
RDGeom::Point3D d,v1,v2;
|
|
double theta;
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
// try a bit of minimization
|
|
ff.initialize();
|
|
ff.minimize(10,1e-8,1e-8);
|
|
|
|
double CCDblBondLen=ForceFields::UFF::Utils::calcBondRestLength(2,¶m1,¶m1);
|
|
double CHBondLen=ForceFields::UFF::Utils::calcBondRestLength(1,¶m1,¶m2);
|
|
|
|
v1=*(RDGeom::Point3D*)ff.positions()[0]-*(RDGeom::Point3D*)ff.positions()[1];
|
|
v2=*(RDGeom::Point3D*)ff.positions()[0]-*(RDGeom::Point3D*)ff.positions()[2];
|
|
theta = v1.angleTo(v2);
|
|
TEST_ASSERT(RDKit::feq(v1.length(),CCDblBondLen,1e-3));
|
|
TEST_ASSERT(RDKit::feq(v2.length(),CHBondLen,1e-3));
|
|
TEST_ASSERT(RDKit::feq(theta,param1.theta0,1e-4));
|
|
v2=*(RDGeom::Point3D*)ff.positions()[0]-*(RDGeom::Point3D*)ff.positions()[3];
|
|
theta = v1.angleTo(v2);
|
|
TEST_ASSERT(RDKit::feq(v2.length(),CHBondLen,1e-3));
|
|
TEST_ASSERT(RDKit::feq(theta,param1.theta0,1e-4));
|
|
|
|
v1=*(RDGeom::Point3D*)ff.positions()[0]-*(RDGeom::Point3D*)ff.positions()[2];
|
|
theta = v1.angleTo(v2);
|
|
TEST_ASSERT(RDKit::feq(theta,param1.theta0,1e-4));
|
|
|
|
std::cerr << " done" << std::endl;
|
|
}
|
|
|
|
void testUFF6(){
|
|
std::cerr << "-------------------------------------" << std::endl;
|
|
std::cerr << "Unit tests for UFF nonbonded terms." << std::endl;
|
|
|
|
ForceFields::ForceField ff;
|
|
Point3D p1(0,0,0),p2(0.0,0,0);
|
|
RDGeom::PointPtrVect &ps=ff.positions();
|
|
ps.push_back(&p1);
|
|
ps.push_back(&p2);
|
|
|
|
ForceFields::UFF::AtomicParams param1;
|
|
// sp3 carbon:
|
|
param1.r1 = .757;
|
|
param1.Z1 = 1.912;
|
|
param1.GMP_Xi = 5.343;
|
|
param1.x1 = 3.851;
|
|
param1.D1 = 0.105;
|
|
|
|
ff.initialize();
|
|
ForceFields::ForceFieldContrib *contrib;
|
|
contrib = new ForceFields::UFF::vdWContrib(&ff,0,1,¶m1,¶m1);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
|
|
// try a bit of minimization
|
|
RDGeom::Point3D d;
|
|
ff.initialize();
|
|
(*ff.positions()[0])[0] = 0.0;
|
|
(*ff.positions()[1])[0] = 4.0;
|
|
ff.minimize(10,1e-8,1e-8);
|
|
d=*(RDGeom::Point3D*)ff.positions()[0] - *(RDGeom::Point3D*)ff.positions()[1];
|
|
TEST_ASSERT(RDKit::feq(d.length(),3.851,1e-3));
|
|
|
|
// minimize in "3D"
|
|
ff.initialize();
|
|
(*ff.positions()[0])[0] = 0.0;
|
|
(*ff.positions()[0])[1] = 0.0;
|
|
(*ff.positions()[0])[2] = 0.0;
|
|
(*ff.positions()[1])[2] = 3.1;
|
|
(*ff.positions()[1])[1] = 0.9;
|
|
(*ff.positions()[1])[0] = 1.00;
|
|
ff.minimize(10,1e-8,1e-8);
|
|
d=*(RDGeom::Point3D*)ff.positions()[0]-*(RDGeom::Point3D*)ff.positions()[1];
|
|
TEST_ASSERT(RDKit::feq(d.length(),3.851,1e-3));
|
|
|
|
std::cerr << " done" << std::endl;
|
|
}
|
|
|
|
void testUFF7(){
|
|
std::cerr << "-------------------------------------" << std::endl;
|
|
std::cerr << " Test UFF torsional terms." << std::endl;
|
|
|
|
ForceFields::ForceField ff;
|
|
Point3D p1,p2,p3,p4;
|
|
RDGeom::PointPtrVect &ps=ff.positions();
|
|
ps.push_back(&p1);
|
|
ps.push_back(&p2);
|
|
ps.push_back(&p3);
|
|
ps.push_back(&p4);
|
|
|
|
ForceFields::UFF::AtomicParams param1,param2;
|
|
// sp3 carbon:
|
|
param1.r1 = .757;
|
|
param1.Z1 = 1.912;
|
|
param1.GMP_Xi = 5.343;
|
|
param1.x1 = 3.851;
|
|
param1.D1 = 0.105;
|
|
param1.V1 = 2.119;
|
|
param1.U1 = 2.0;
|
|
|
|
// H_1:
|
|
param2.r1 = 0.354;
|
|
param2.Z1 = 0.712;
|
|
param2.GMP_Xi = 4.528;
|
|
|
|
RDGeom::Point3D d,v1,v2;
|
|
double cosPhi;
|
|
|
|
ForceFields::ForceFieldContrib *contrib;
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
// Basic SP3 - SP3
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
contrib = new ForceFields::UFF::TorsionAngleContrib(&ff,0,1,2,3,1,
|
|
6,6,
|
|
RDKit::Atom::SP3,RDKit::Atom::SP3,
|
|
¶m1,¶m1);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
#if 1
|
|
p1.x=0;
|
|
p1.y=1.5;
|
|
p1.z=0;
|
|
|
|
p2.x=0.0;
|
|
p2.y=0.0;
|
|
p2.z=0.0;
|
|
|
|
p3.x=1.5;
|
|
p3.y=0.0;
|
|
p3.z=0.0;
|
|
|
|
p4.x=1.5;
|
|
p4.y=0.0;
|
|
p4.z=1.5;
|
|
|
|
ff.initialize();
|
|
ff.minimize(10,1e-8,1e-8);
|
|
cosPhi = ForceFields::UFF::Utils::calculateCosTorsion(*(RDGeom::Point3D*)ff.positions()[0],
|
|
*(RDGeom::Point3D*)ff.positions()[1],
|
|
*(RDGeom::Point3D*)ff.positions()[2],
|
|
*(RDGeom::Point3D*)ff.positions()[3]);
|
|
TEST_ASSERT(RDKit::feq(cosPhi,0.5,1e-4));
|
|
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
// Basic SP2 - SP2
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
ff.contribs().pop_back();
|
|
contrib = new ForceFields::UFF::TorsionAngleContrib(&ff,0,1,2,3,1,
|
|
6,6,
|
|
RDKit::Atom::SP2,RDKit::Atom::SP2,
|
|
¶m1,¶m1);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
p1.x=0;
|
|
p1.y=1.5;
|
|
p1.z=0.1;
|
|
|
|
p2.x=0.0;
|
|
p2.y=0.0;
|
|
p2.z=0.0;
|
|
|
|
p3.x=1.5;
|
|
p3.y=0.0;
|
|
p3.z=0.0;
|
|
|
|
p4.x=1.5;
|
|
p4.y=0.2;
|
|
p4.z=1.5;
|
|
|
|
ff.initialize();
|
|
ff.minimize(10,1e-8,1e-8);
|
|
cosPhi = ForceFields::UFF::Utils::calculateCosTorsion(*(RDGeom::Point3D*)ff.positions()[0],
|
|
*(RDGeom::Point3D*)ff.positions()[1],
|
|
*(RDGeom::Point3D*)ff.positions()[2],
|
|
*(RDGeom::Point3D*)ff.positions()[3]);
|
|
TEST_ASSERT(RDKit::feq(cosPhi,1.0,1e-4));
|
|
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
// Basic SP2 - SP3
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
ff.contribs().pop_back();
|
|
contrib = new ForceFields::UFF::TorsionAngleContrib(&ff,0,1,2,3,1,
|
|
6,6,
|
|
RDKit::Atom::SP2,RDKit::Atom::SP3,
|
|
¶m1,¶m1);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
p1.x=0;
|
|
p1.y=1.5;
|
|
p1.z=0.1;
|
|
|
|
p2.x=0.0;
|
|
p2.y=0.0;
|
|
p2.z=0.0;
|
|
|
|
p3.x=1.5;
|
|
p3.y=0.0;
|
|
p3.z=0.0;
|
|
|
|
p4.x=1.5;
|
|
p4.y=0.2;
|
|
p4.z=1.5;
|
|
|
|
ff.initialize();
|
|
ff.minimize(100,1e-8,1e-8);
|
|
cosPhi = ForceFields::UFF::Utils::calculateCosTorsion(*(RDGeom::Point3D*)ff.positions()[0],
|
|
*(RDGeom::Point3D*)ff.positions()[1],
|
|
*(RDGeom::Point3D*)ff.positions()[2],
|
|
*(RDGeom::Point3D*)ff.positions()[3]);
|
|
TEST_ASSERT(RDKit::feq(cosPhi,0.5,1e-4));
|
|
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
// special case for group 6 - group 6 bonds:
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
ff.contribs().pop_back();
|
|
contrib = new ForceFields::UFF::TorsionAngleContrib(&ff,0,1,2,3,1,
|
|
8,8,
|
|
RDKit::Atom::SP3,RDKit::Atom::SP3,
|
|
¶m1,¶m1);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
p1.x=0;
|
|
p1.y=1.5;
|
|
p1.z=0.1;
|
|
|
|
p2.x=0.0;
|
|
p2.y=0.0;
|
|
p2.z=0.0;
|
|
|
|
p3.x=1.5;
|
|
p3.y=0.0;
|
|
p3.z=0.0;
|
|
|
|
p4.x=1.5;
|
|
p4.y=0.2;
|
|
p4.z=1.5;
|
|
|
|
ff.initialize();
|
|
ff.minimize(100,1e-8,1e-8);
|
|
cosPhi = ForceFields::UFF::Utils::calculateCosTorsion(*(RDGeom::Point3D*)ff.positions()[0],
|
|
*(RDGeom::Point3D*)ff.positions()[1],
|
|
*(RDGeom::Point3D*)ff.positions()[2],
|
|
*(RDGeom::Point3D*)ff.positions()[3]);
|
|
TEST_ASSERT(RDKit::feq(cosPhi,0.0,1e-4));
|
|
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
// special case for SP3 group 6 - SP2 other group
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
ff.contribs().pop_back();
|
|
contrib = new ForceFields::UFF::TorsionAngleContrib(&ff,0,1,2,3,1,
|
|
8,6,
|
|
RDKit::Atom::SP3,RDKit::Atom::SP2,
|
|
¶m1,¶m1);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
p1.x=0;
|
|
p1.y=1.5;
|
|
p1.z=0.1;
|
|
|
|
p2.x=0.0;
|
|
p2.y=0.0;
|
|
p2.z=0.0;
|
|
|
|
p3.x=1.5;
|
|
p3.y=0.0;
|
|
p3.z=0.0;
|
|
|
|
p4.x=1.5;
|
|
p4.y=0.2;
|
|
p4.z=1.5;
|
|
|
|
ff.initialize();
|
|
ff.minimize(100,1e-8,1e-8);
|
|
cosPhi = ForceFields::UFF::Utils::calculateCosTorsion(*(RDGeom::Point3D*)ff.positions()[0],
|
|
*(RDGeom::Point3D*)ff.positions()[1],
|
|
*(RDGeom::Point3D*)ff.positions()[2],
|
|
*(RDGeom::Point3D*)ff.positions()[3]);
|
|
TEST_ASSERT(RDKit::feq(cosPhi,0.0,1e-4));
|
|
|
|
#endif
|
|
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
// special case for (SP2 -) SP2 - SP3
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
ff.contribs().pop_back();
|
|
contrib = new ForceFields::UFF::TorsionAngleContrib(&ff,0,1,2,3,1,
|
|
6,6,
|
|
RDKit::Atom::SP2,RDKit::Atom::SP3,
|
|
¶m1,¶m1,true);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
p1.x=0;
|
|
p1.y=1.5;
|
|
p1.z=0.1;
|
|
|
|
p2.x=0.0;
|
|
p2.y=0.0;
|
|
p2.z=0.0;
|
|
|
|
p3.x=1.5;
|
|
p3.y=0.0;
|
|
p3.z=0.0;
|
|
|
|
p4.x=1.5;
|
|
p4.y=0.2;
|
|
p4.z=1.5;
|
|
|
|
ff.initialize();
|
|
ff.minimize(100,1e-8,1e-8);
|
|
cosPhi = ForceFields::UFF::Utils::calculateCosTorsion(*(RDGeom::Point3D*)ff.positions()[0],
|
|
*(RDGeom::Point3D*)ff.positions()[1],
|
|
*(RDGeom::Point3D*)ff.positions()[2],
|
|
*(RDGeom::Point3D*)ff.positions()[3]);
|
|
TEST_ASSERT(RDKit::feq(cosPhi,0.5,1e-4));
|
|
|
|
std::cerr << " done" << std::endl;
|
|
}
|
|
|
|
|
|
void testUFFParams(){
|
|
std::cerr << "-------------------------------------" << std::endl;
|
|
std::cerr << " Test UFF Parameter objects" << std::endl;
|
|
|
|
ForceFields::UFF::ParamCollection *params=ForceFields::UFF::ParamCollection::getParams();
|
|
TEST_ASSERT(params);
|
|
|
|
const ForceFields::UFF::AtomicParams *ptr;
|
|
ptr=(*params)("C_3");
|
|
TEST_ASSERT(ptr);
|
|
TEST_ASSERT(RDKit::feq(ptr->r1,0.757));
|
|
TEST_ASSERT(RDKit::feq(ptr->theta0,109.47*M_PI/180.));
|
|
TEST_ASSERT(RDKit::feq(ptr->x1,3.851));
|
|
TEST_ASSERT(RDKit::feq(ptr->D1,0.105));
|
|
TEST_ASSERT(RDKit::feq(ptr->zeta,12.73));
|
|
TEST_ASSERT(RDKit::feq(ptr->Z1,1.912));
|
|
TEST_ASSERT(RDKit::feq(ptr->V1,2.119));
|
|
TEST_ASSERT(RDKit::feq(ptr->GMP_Xi,5.343));
|
|
TEST_ASSERT(RDKit::feq(ptr->GMP_Hardness,5.063));
|
|
TEST_ASSERT(RDKit::feq(ptr->GMP_Radius,0.759));
|
|
|
|
ptr=(*params)("N_3");
|
|
TEST_ASSERT(ptr);
|
|
|
|
ptr=(*params)("C_5");
|
|
TEST_ASSERT(!ptr);
|
|
}
|
|
|
|
|
|
void testUFF8(){
|
|
std::cerr << "-------------------------------------" << std::endl;
|
|
std::cerr << " Test Simple UFF molecule optimization, part 2." << std::endl;
|
|
|
|
ForceFields::ForceField ff;
|
|
Point3D p1,p2,p3,p4,p5,p6;
|
|
RDGeom::PointPtrVect &ps=ff.positions();
|
|
ps.push_back(&p1);
|
|
ps.push_back(&p2);
|
|
ps.push_back(&p3);
|
|
ps.push_back(&p4);
|
|
ps.push_back(&p5);
|
|
ps.push_back(&p6);
|
|
|
|
ForceFields::UFF::ParamCollection *params=ForceFields::UFF::ParamCollection::getParams();
|
|
const ForceFields::UFF::AtomicParams *param1,*param2;
|
|
|
|
// C_2 (sp2 carbon):
|
|
param1 = (*params)("C_2");
|
|
TEST_ASSERT(param1);
|
|
// H_:
|
|
param2 = (*params)("H_");
|
|
TEST_ASSERT(param2);
|
|
ForceFields::ForceFieldContrib *contrib;
|
|
|
|
// build ethylene:
|
|
// BONDS:
|
|
contrib = new ForceFields::UFF::BondStretchContrib(&ff,0,1,2,param1,param1);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::BondStretchContrib(&ff,0,2,1,param1,param2);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::BondStretchContrib(&ff,0,3,1,param1,param2);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::BondStretchContrib(&ff,1,4,1,param1,param2);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::BondStretchContrib(&ff,1,5,1,param1,param2);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
|
|
// ANGLES:
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,1,0,2,2,1,param1,param1,param2,3);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,1,0,3,2,1,param1,param1,param2,3);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,2,0,3,1,1,param2,param1,param2,3);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,0,1,4,2,1,param1,param1,param2,3);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,0,1,5,2,1,param1,param1,param2,3);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,4,1,5,1,1,param2,param1,param2,3);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
|
|
// DIHEDRALS:
|
|
contrib = new ForceFields::UFF::TorsionAngleContrib(&ff,2,0,1,4,2,
|
|
6,6,
|
|
RDKit::Atom::SP3,RDKit::Atom::SP3,
|
|
param1,param1);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::TorsionAngleContrib(&ff,2,0,1,5,2,
|
|
6,6,
|
|
RDKit::Atom::SP3,RDKit::Atom::SP3,
|
|
param1,param1);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::TorsionAngleContrib(&ff,3,0,1,4,2,
|
|
6,6,
|
|
RDKit::Atom::SP3,RDKit::Atom::SP3,
|
|
param1,param1);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::TorsionAngleContrib(&ff,3,0,1,5,2,
|
|
6,6,
|
|
RDKit::Atom::SP3,RDKit::Atom::SP3,
|
|
param1,param1);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
|
|
|
|
p1.x=-0.58;
|
|
p1.y=-0.33;
|
|
p1.z=0.1;
|
|
|
|
p2.x=0.58;
|
|
p2.y=0.33;
|
|
p2.z=0.1;
|
|
|
|
p3.x=-0.61;
|
|
p3.y=-1.43;
|
|
p3.z=0.0;
|
|
|
|
p4.x=-1.54;
|
|
p4.y=0.20;
|
|
p4.z=0.0;
|
|
|
|
p5.x=0.61;
|
|
p5.y=1.43;
|
|
p5.z=0.0;
|
|
|
|
p6.x=1.54;
|
|
p6.y=-0.20;
|
|
p6.z=0.0;
|
|
|
|
RDGeom::Point3D d,v1,v2;
|
|
double theta;
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
// try a bit of minimization
|
|
ff.initialize();
|
|
ff.minimize(100,1e-8,1e-8);
|
|
|
|
double CCDblBondLen=ForceFields::UFF::Utils::calcBondRestLength(2,param1,param1);
|
|
double CHBondLen=ForceFields::UFF::Utils::calcBondRestLength(1,param1,param2);
|
|
|
|
v1=*(RDGeom::Point3D*)ff.positions()[0] - *(RDGeom::Point3D*)ff.positions()[1];
|
|
v2=*(RDGeom::Point3D*)ff.positions()[0] - *(RDGeom::Point3D*)ff.positions()[2];
|
|
theta = v1.angleTo(v2);
|
|
TEST_ASSERT(RDKit::feq(v1.length(),CCDblBondLen,1e-3));
|
|
TEST_ASSERT(RDKit::feq(v2.length(),CHBondLen,1e-3));
|
|
TEST_ASSERT(RDKit::feq(theta,param1->theta0,1e-4));
|
|
v2=*(RDGeom::Point3D*)ff.positions()[0] - *(RDGeom::Point3D*)ff.positions()[3];
|
|
theta = v1.angleTo(v2);
|
|
TEST_ASSERT(RDKit::feq(v2.length(),CHBondLen,1e-3));
|
|
TEST_ASSERT(RDKit::feq(theta,param1->theta0,1e-4));
|
|
|
|
v1=*(RDGeom::Point3D*)ff.positions()[0] - *(RDGeom::Point3D*)ff.positions()[2];
|
|
theta = v1.angleTo(v2);
|
|
TEST_ASSERT(RDKit::feq(theta,param1->theta0,1e-4));
|
|
|
|
std::cerr << " done" << std::endl;
|
|
}
|
|
|
|
void testUFFTorsionConflict(){
|
|
std::cerr << "-------------------------------------" << std::endl;
|
|
std::cerr << " Test UFF Torsion Conflicts." << std::endl;
|
|
|
|
ForceFields::ForceField ff;
|
|
Point3D p1,p2,p3,p4,p5,p6,p7;
|
|
RDGeom::PointPtrVect &ps=ff.positions();
|
|
ps.push_back(&p1);
|
|
ps.push_back(&p2);
|
|
ps.push_back(&p3);
|
|
ps.push_back(&p4);
|
|
ps.push_back(&p5);
|
|
ps.push_back(&p6);
|
|
ps.push_back(&p7);
|
|
|
|
ForceFields::UFF::ParamCollection *params=ForceFields::UFF::ParamCollection::getParams();
|
|
const ForceFields::UFF::AtomicParams *param1,*param2,*param3;
|
|
|
|
// C_2 (sp2 carbon):
|
|
param1 = (*params)("C_2");
|
|
TEST_ASSERT(param1);
|
|
// H_:
|
|
param2 = (*params)("H_");
|
|
TEST_ASSERT(param2);
|
|
// C_3 (sp3 carbon):
|
|
param3 = (*params)("C_3");
|
|
TEST_ASSERT(param3);
|
|
|
|
ForceFields::ForceFieldContrib *contrib;
|
|
|
|
// BONDS:
|
|
contrib = new ForceFields::UFF::BondStretchContrib(&ff,0,1,2,param1,param1);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::BondStretchContrib(&ff,1,2,1,param1,param3);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::BondStretchContrib(&ff,1,3,1,param1,param2);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::BondStretchContrib(&ff,2,4,1,param1,param2);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::BondStretchContrib(&ff,2,5,1,param1,param2);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::BondStretchContrib(&ff,2,6,1,param1,param2);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
|
|
#if 1
|
|
// ANGLES:
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,0,1,2,2.0,1.0,param1,param1,param3);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,0,1,3,2.0,1.0,param1,param1,param2);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,1,2,4,1.0,1.0,param1,param3,param2);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,1,2,5,1.0,1.0,param1,param3,param2);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,1,2,6,1.0,1.0,param1,param3,param2);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::AngleBendContrib(&ff,2,1,3,1.0,1.0,param3,param1,param2);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
#endif
|
|
|
|
// DIHEDRALS:
|
|
contrib = new ForceFields::UFF::TorsionAngleContrib(&ff,0,1,2,4,1.0,
|
|
6,6,
|
|
RDKit::Atom::SP2,RDKit::Atom::SP3,
|
|
param1,param3,true);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::TorsionAngleContrib(&ff,3,1,2,4,1.0,
|
|
6,6,
|
|
RDKit::Atom::SP2,RDKit::Atom::SP3,
|
|
param1,param3,false);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
|
|
contrib = new ForceFields::UFF::TorsionAngleContrib(&ff,0,1,2,5,1.0,
|
|
6,6,
|
|
RDKit::Atom::SP2,RDKit::Atom::SP3,
|
|
param1,param3,true);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::TorsionAngleContrib(&ff,3,1,2,5,1.0,
|
|
6,6,
|
|
RDKit::Atom::SP2,RDKit::Atom::SP3,
|
|
param1,param3,false);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
|
|
contrib = new ForceFields::UFF::TorsionAngleContrib(&ff,0,1,2,6,1.0,
|
|
6,6,
|
|
RDKit::Atom::SP2,RDKit::Atom::SP3,
|
|
param1,param3,true);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
contrib = new ForceFields::UFF::TorsionAngleContrib(&ff,3,1,2,6,1.0,
|
|
6,6,
|
|
RDKit::Atom::SP2,RDKit::Atom::SP3,
|
|
param1,param3,false);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(contrib));
|
|
|
|
|
|
|
|
p1.x=0.5411;
|
|
p1.y=-0.7741;
|
|
p1.z=0.0902;
|
|
|
|
p2.x=-0.5622;
|
|
p2.y=-0.0368;
|
|
p2.z=0.1202;
|
|
|
|
p3.x=-0.5101;
|
|
p3.y=1.4485;
|
|
p3.z=0.0816;
|
|
|
|
p4.x=-1.5285;
|
|
p4.y=-0.5341;
|
|
p4.z=0.1892;
|
|
|
|
p5.x=0.5097;
|
|
p5.y=1.8065;
|
|
p5.z=0.1988;
|
|
|
|
p6.x=-1.1436;
|
|
p6.y=1.8781;
|
|
p6.z=0.8983;
|
|
|
|
p7.x=-0.9145;
|
|
p7.y=1.8185;
|
|
p7.z=-0.8983;
|
|
|
|
RDGeom::Point3D d,v1,v2;
|
|
// ------- ------- ------- ------- ------- ------- -------
|
|
// try a bit of minimization
|
|
ff.initialize();
|
|
ff.minimize(100,1e-8,1e-8);
|
|
|
|
#if 1
|
|
std::cerr.setf(std::ios_base::fixed,std::ios_base::floatfield);
|
|
std::cerr.precision(4);
|
|
std::cerr << "C " << *ff.positions()[0] << std::endl;
|
|
std::cerr << "C " << *ff.positions()[1] << std::endl;
|
|
std::cerr << "C " << *ff.positions()[2] << std::endl;
|
|
std::cerr << "H " << *ff.positions()[3] << std::endl;
|
|
std::cerr << "H " << *ff.positions()[4] << std::endl;
|
|
std::cerr << "O " << *ff.positions()[5] << std::endl;
|
|
std::cerr << "F " << *ff.positions()[6] << std::endl;
|
|
#endif
|
|
std::cerr << " done" << std::endl;
|
|
}
|
|
|
|
void testUFFDistanceConstraints(){
|
|
std::cerr << "-------------------------------------" << std::endl;
|
|
std::cerr << "Unit tests for UFF distance constraint terms." << std::endl;
|
|
|
|
ForceFields::ForceField ff;
|
|
Point3D p1(0,0,0),p2(1.514,0,0);
|
|
RDGeom::PointPtrVect &ps=ff.positions();
|
|
ps.push_back(&p1);
|
|
ps.push_back(&p2);
|
|
|
|
double *p,*g;
|
|
p = new double[6];
|
|
g = new double[6];
|
|
for(int i=0;i<6;i++){
|
|
p[i] = 0.0;
|
|
g[i] = 0.0;
|
|
}
|
|
p[0] = 0;
|
|
p[3] = 1.40;
|
|
|
|
ff.initialize();
|
|
|
|
// C_3 - C_3, r0=1.514, k01=699.5918
|
|
ForceFields::ForceFieldContrib *bs;
|
|
bs = new ForceFields::UFF::DistanceConstraintContrib(&ff,0,1,1.35,1.55,1000.0);
|
|
ff.contribs().push_back(ForceFields::ContribPtr(bs));
|
|
double E;
|
|
E=bs->getEnergy(p);
|
|
TEST_ASSERT(RDKit::feq(E,0.0));
|
|
bs->getGrad(p,g);
|
|
for(int i=0;i<6;i++){
|
|
TEST_ASSERT(RDKit::feq(g[i],0.0));
|
|
}
|
|
|
|
ff.initialize();
|
|
(*ff.positions()[1])[0] = 1.20;
|
|
p[3] = 1.20;
|
|
E=bs->getEnergy(p);
|
|
TEST_ASSERT(RDKit::feq(E,11.25));
|
|
bs->getGrad(p,g);
|
|
TEST_ASSERT(RDKit::feq(g[0],150.0));
|
|
TEST_ASSERT(RDKit::feq(g[3],-150.0));
|
|
TEST_ASSERT(RDKit::feq(g[1],0.0));
|
|
TEST_ASSERT(RDKit::feq(g[2],0.0));
|
|
TEST_ASSERT(RDKit::feq(g[4],0.0));
|
|
TEST_ASSERT(RDKit::feq(g[5],0.0));
|
|
|
|
// try a bit of minimization
|
|
RDGeom::Point3D d;
|
|
ff.initialize();
|
|
(*ff.positions()[1])[2] = 0.0;
|
|
(*ff.positions()[1])[0] = 1.20;
|
|
ff.minimize(10,1e-8);
|
|
d=*(RDGeom::Point3D*)ff.positions()[0]-*(RDGeom::Point3D*)ff.positions()[1];
|
|
TEST_ASSERT(d.length()>=1.35)
|
|
TEST_ASSERT(d.length()<=1.55)
|
|
|
|
ff.initialize();
|
|
(*ff.positions()[1])[2] = 0.0;
|
|
(*ff.positions()[1])[0] = 1.70;
|
|
ff.minimize(10,1e-8);
|
|
d=*(RDGeom::Point3D*)ff.positions()[0]-*(RDGeom::Point3D*)ff.positions()[1];
|
|
TEST_ASSERT(d.length()>=1.35)
|
|
TEST_ASSERT(d.length()<=1.55)
|
|
|
|
delete [] p;
|
|
delete [] g;
|
|
std::cerr << " done" << std::endl;
|
|
}
|
|
|
|
int main(){
|
|
#if 1
|
|
test1();
|
|
testUFF1();
|
|
testUFF2();
|
|
testUFF3();
|
|
testUFF4();
|
|
testUFF5();
|
|
testUFF6();
|
|
testUFF7();
|
|
testUFFParams();
|
|
testUFF8();
|
|
testUFFTorsionConflict();
|
|
|
|
#endif
|
|
testUFFDistanceConstraints();
|
|
}
|