TorsionConstraintContrib::TorsionConstraintContrib(ForceField *owner, unsigned int idx1, unsigned int idx2, unsigned int idx3, unsigned int idx4, bool relative, double minDihedralDeg, double maxDihedralDeg, double forceConst) { PRECONDITION(owner,"bad owner"); const RDGeom::PointPtrVect &pos = owner->positions(); RANGE_CHECK(0, idx1, pos.size() - 1); RANGE_CHECK(0, idx2, pos.size() - 1); RANGE_CHECK(0, idx3, pos.size() - 1); RANGE_CHECK(0, idx4, pos.size() - 1); PRECONDITION(maxDihedralDeg >= minDihedralDeg, "bad bounds"); double dihedral = 0.0; if (relative) { RDGeom::Point3D p1 = *((RDGeom::Point3D *)pos[idx1]); RDGeom::Point3D p2 = *((RDGeom::Point3D *)pos[idx2]); RDGeom::Point3D p3 = *((RDGeom::Point3D *)pos[idx3]); RDGeom::Point3D p4 = *((RDGeom::Point3D *)pos[idx4]); RDGeom::Point3D r12 = p2 - p1; RDGeom::Point3D r23 = p3 - p2; RDGeom::Point3D r34 = p4 - p3; RDGeom::Point3D n123 = r12.crossProduct(r23); double nIJKSqLength = n123.lengthSq(); RDGeom::Point3D n234 = r23.crossProduct(r34); double nJKLSqLength = n234.lengthSq(); RDGeom::Point3D m = n123.crossProduct(r23); // we want a signed dihedral, that's why we use atan2 instead of acos dihedral = RAD2DEG * (-atan2(m.dotProduct(n234) / sqrt(nJKLSqLength * m.lengthSq()), n123.dotProduct(n234) / sqrt(nIJKSqLength * nJKLSqLength))); } dp_forceField = owner; d_at1Idx = idx1; d_at2Idx = idx2; d_at3Idx = idx3; d_at4Idx = idx4; minDihedralDeg += dihedral; maxDihedralDeg += dihedral; _pretreatAngles(minDihedralDeg, maxDihedralDeg); d_minDihedralDeg = minDihedralDeg; d_maxDihedralDeg = maxDihedralDeg; d_forceConstant = forceConst; }
AngleConstraintContrib::AngleConstraintContrib(ForceField *owner, unsigned int idx1, unsigned int idx2, unsigned int idx3, double minAngleDeg, double maxAngleDeg, double forceConst) { PRECONDITION(owner,"bad owner"); RANGE_CHECK(0, idx1, owner->positions().size() - 1); RANGE_CHECK(0, idx2, owner->positions().size() - 1); RANGE_CHECK(0, idx3, owner->positions().size() - 1); PRECONDITION(maxAngleDeg >= minAngleDeg, "allowedDeltaDeg must be >= 0.0"); _pretreatAngles(minAngleDeg, maxAngleDeg); dp_forceField = owner; d_at1Idx = idx1; d_at2Idx = idx2; d_at3Idx = idx3; d_minAngleDeg = minAngleDeg; d_maxAngleDeg = maxAngleDeg; d_forceConstant = forceConst; }
TorsionConstraintContrib::TorsionConstraintContrib(ForceField *owner, unsigned int idx1, unsigned int idx2, unsigned int idx3, unsigned int idx4, double minDihedralDeg, double maxDihedralDeg, double forceConst) { PRECONDITION(owner,"bad owner"); RANGE_CHECK(0, idx1, owner->positions().size() - 1); RANGE_CHECK(0, idx2, owner->positions().size() - 1); RANGE_CHECK(0, idx3, owner->positions().size() - 1); RANGE_CHECK(0, idx4, owner->positions().size() - 1); _pretreatAngles(minDihedralDeg, maxDihedralDeg); dp_forceField = owner; d_at1Idx = idx1; d_at2Idx = idx2; d_at3Idx = idx3; d_at4Idx = idx4; d_minDihedralDeg = minDihedralDeg; d_maxDihedralDeg = maxDihedralDeg; d_forceConstant = forceConst; }
AngleConstraintContrib::AngleConstraintContrib(ForceField *owner, unsigned int idx1, unsigned int idx2, unsigned int idx3, bool relative, double minAngleDeg, double maxAngleDeg, double forceConst) { PRECONDITION(owner,"bad owner"); const RDGeom::PointPtrVect &pos = owner->positions(); RANGE_CHECK(0, idx1, pos.size() - 1); RANGE_CHECK(0, idx2, pos.size() - 1); RANGE_CHECK(0, idx3, pos.size() - 1); PRECONDITION(maxAngleDeg >= minAngleDeg, "allowedDeltaDeg must be >= 0.0"); double angle = 0.0; if (relative) { RDGeom::Point3D p1 = *((RDGeom::Point3D *)pos[idx1]); RDGeom::Point3D p2 = *((RDGeom::Point3D *)pos[idx2]); RDGeom::Point3D p3 = *((RDGeom::Point3D *)pos[idx3]); double dist1 = (p1 - p2).length(); double dist2 = (p3 - p2).length(); RDGeom::Point3D p12 = (p1 - p2) / dist1; RDGeom::Point3D p32 = (p3 - p2) / dist2; double cosTheta = p12.dotProduct(p32); clipToOne(cosTheta); angle = RAD2DEG * acos(cosTheta); } dp_forceField = owner; d_at1Idx = idx1; d_at2Idx = idx2; d_at3Idx = idx3; minAngleDeg += angle; maxAngleDeg += angle; _pretreatAngles(minAngleDeg, maxAngleDeg); d_minAngleDeg = minAngleDeg; d_maxAngleDeg = maxAngleDeg; d_forceConstant = forceConst; }