DuMMForceFieldSubsystem.h

Go to the documentation of this file.
00001 #ifndef SimTK_MOLMODEL_DUMM_FORCE_FIELD_SUBSYSTEM_H_
00002 #define SimTK_MOLMODEL_DUMM_FORCE_FIELD_SUBSYSTEM_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                      SimTK Core: SimTK Simbody(tm)                         *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK Core biosimulation toolkit originating from      *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
00011  *                                                                            *
00012  * Portions copyright (c) 2007 Stanford University and the Authors.           *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Permission is hereby granted, free of charge, to any person obtaining a    *
00017  * copy of this software and associated documentation files (the "Software"), *
00018  * to deal in the Software without restriction, including without limitation  *
00019  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
00020  * and/or sell copies of the Software, and to permit persons to whom the      *
00021  * Software is furnished to do so, subject to the following conditions:       *
00022  *                                                                            *
00023  * The above copyright notice and this permission notice shall be included in *
00024  * all copies or substantial portions of the Software.                        *
00025  *                                                                            *
00026  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00027  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00028  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00029  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
00030  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
00031  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
00032  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
00033  * -------------------------------------------------------------------------- */
00034 
00041 #include "SimTKcommon.h"
00042 
00043 #include "molmodel/internal/common.h"
00044 #include "simbody/internal/ForceSubsystem.h"
00045 #include "molmodel/internal/Biotype.h"
00046 
00047 #include <cassert>
00048 
00049 namespace SimTK {
00050 
00051 class MolecularMechanicsSystem;
00052 
00053 // Handy conversions. Note that these are compilation-unit statics, not members.
00054 // That way we can be sure they are initialized before being used.
00055 // To use these, multiply something in units on left of the "2" to get equivalent
00056 // in units on right. E.g., 180*Deg2Rad gives Pi radians.
00057 namespace DuMM {
00058 static const Real Ang2Nm  = (Real)0.1L;
00059 static const Real Nm2Ang  = (Real)10.L;
00060 static const Real Deg2Rad = (Real)SimTK_DEGREE_TO_RADIAN;
00061 static const Real Rad2Deg = (Real)SimTK_RADIAN_TO_DEGREE;
00062 static const Real KJ2Kcal = (Real)SimTK_KJOULE_TO_KCAL;
00063 static const Real Kcal2KJ = (Real)SimTK_KCAL_TO_KJOULE;
00064 
00065 // There are several conventions for giving van der Waals parameters.
00066 // Rmin is the radius at which the energy well minimum is seen
00067 // (actually it is 1/2 the distance between atom centers for a pair
00068 // of atoms of this class interacting with that minimum energy).
00069 // This is *not* Sigma, which is the radius (half distance) at which the 
00070 // energy crosses zero, that is, a little closer together than
00071 // when the energy well is at maximum depth. To convert for LJ:
00072 // Rmin = 2^(1/6) * Sigma.
00073 static const Real Sigma2Radius = (Real)std::pow(2.L,  1.L/6.L); // sigma < radius
00074 static const Real Radius2Sigma = (Real)std::pow(2.L, -1.L/6.L);
00075 }
00076 
00077 
00078 namespace DuMM {
00079     SimTK_DEFINE_UNIQUE_INDEX_TYPE(AtomIndex);
00080     SimTK_DEFINE_UNIQUE_INDEX_TYPE(AtomClassIndex);
00081     SimTK_DEFINE_UNIQUE_INDEX_TYPE(ChargedAtomTypeIndex);
00082     SimTK_DEFINE_UNIQUE_INDEX_TYPE(BondIndex);
00083     SimTK_DEFINE_UNIQUE_INDEX_TYPE(ClusterIndex);
00084 } // namespace DuMM
00085 
00101 class SimTK_MOLMODEL_EXPORT DuMMForceFieldSubsystem : public ForceSubsystem {
00102 public:
00103     friend class MolecularMechanicsSystem;
00104 
00105     enum VdwMixingRule {
00106         WaldmanHagler       = 1,    // Our default
00107         HalgrenHHG          = 2,    // MMFF, AMOEBA
00108         Jorgensen           = 3,    // OPLS
00109         LorentzBerthelot    = 4,    // AMBER, CHARMM
00110         Kong                = 5
00111     };
00112     const char* getVdwMixingRuleName(VdwMixingRule) const;
00113 
00114     DuMMForceFieldSubsystem();
00115     explicit DuMMForceFieldSubsystem(MolecularMechanicsSystem&);
00116 
00117         // MOLECULE
00118 
00119     // Add a new atom to the model. The atom index number is returned; you don't get to
00120     // pick your own.
00121     DuMM::AtomIndex addAtom(DuMM::ChargedAtomTypeIndex chargedAtomTypeIx);
00122 
00123     // Note that these are atom index numbers, not atom classes or types.
00124     DuMM::BondIndex addBond(DuMM::AtomIndex atom1Ix, DuMM::AtomIndex atom2Ix);
00125 
00126     int    getNAtoms() const;
00127     Real   getAtomMass(DuMM::AtomIndex atomIx) const;
00128     int    getAtomElement(DuMM::AtomIndex atomIx) const;
00129     Real   getAtomRadius(DuMM::AtomIndex atomIx) const;
00130     Vec3   getAtomStationOnBody(DuMM::AtomIndex atomIx) const;
00131     Vec3   getAtomStationInCluster(DuMM::AtomIndex atomIx, DuMM::ClusterIndex clusterIx) const;
00132     MobilizedBodyIndex getAtomBody(DuMM::AtomIndex atomIx) const;
00133     Vec3   getElementDefaultColor(int atomicNumber) const;
00134     Vec3   getAtomDefaultColor(DuMM::AtomIndex atomIx) const;
00135 
00136     int  getNBonds() const;
00137 
00138     // 'which' must be 0 or 1. 0 will return the lower-numbered atomIx.
00139     DuMM::AtomIndex  getBondAtom(DuMM::BondIndex bond, int which) const;
00140 
00141         // CLUSTERS
00142 
00143     // Create an empty cluster (rigid group of atoms). The cluster index number is returned;
00144     // you don't get to pick your own. The name is just for display; you must use the index
00145     // to reference the cluster. Every cluster has its own reference frame.
00146     DuMM::ClusterIndex createCluster(const char* clusterName);
00147 
00148 
00149     // Place an existing atom at a particular station in the local frame of a cluster. It
00150     // is fine for an atom to be in more than one cluster as long as only one of them ends up
00151     // attached to a body.
00152     void placeAtomInCluster(DuMM::AtomIndex atomIx, DuMM::ClusterIndex clusterIx, const Vec3& station);
00153 
00154     // Place a cluster (the child) in another cluster (the parent). The child's
00155     // local frame is placed at a given transform with respect to the parent's frame.
00156     void placeClusterInCluster(DuMM::ClusterIndex childClusterIndex, DuMM::ClusterIndex parentClusterIndex, 
00157                                const Transform& placement);
00158 
00159     // Calcuate the composite mass properties of a cluster, either in its own reference
00160     // frame or transformed to the indicated frame.
00161     MassProperties calcClusterMassProperties(DuMM::ClusterIndex clusterIx, const Transform& = Transform()) const;
00162 
00163     MobilizedBodyIndex    getClusterBody(DuMM::ClusterIndex clusterIx) const;
00164     Transform getClusterPlacementOnBody(DuMM::ClusterIndex clusterIx) const;
00165     Transform getClusterPlacementInCluster(DuMM::ClusterIndex childClusterIndex, DuMM::ClusterIndex parentClusterIndex) const;
00166 
00167         // BODIES
00168 
00169     void attachClusterToBody(DuMM::ClusterIndex clusterIx, MobilizedBodyIndex body, const Transform& = Transform());
00170     void attachAtomToBody   (DuMM::AtomIndex atomIx,    MobilizedBodyIndex body, const Vec3& station = Vec3(0));
00171 
00172         // DEFINE FORCE FIELD PARAMETERS
00173     
00174     // Atom classes are used for sets of atoms which share some properties.
00175     // These are: the element (as atomic number), expected valence, 
00176     // van der Waals parameters, and behavior in bonded situations.
00177     // Charge is not included in atom class but in a second more detailed
00178     // classification level called ChargedAtomType.
00179     //
00180     // This fails if the atom class already exists.
00181     // VdwRadius is given as Rmin, the radius at which the energy
00182     // well minimum is seen (actually it is 1/2 the distance between
00183     // atom centers for a pair of atoms of this class). This is *not*
00184     // Sigma, which is the radius (half distance) at which the 
00185     // energy crosses zero, that is, a little closer together than
00186     // when the energy well is at maximum depth.
00187     // To convert for LJ: Rmin = 2^(1/6) * Sigma.
00188     // The radius is in nm, the well depth in kJ/mol.
00189 
00190     // Generate c++ code to reproduce forceField parameters presently in memory
00191     void dumpCForceFieldParameters(std::ostream& os, const String& methodName = "loadParameters") const;
00192 
00193     void defineAtomClass(DuMM::AtomClassIndex atomClassIx, const char* atomClassName,
00194                          int elementNumber, int expectedValence,
00195                          Real vdwRadiusInNm, Real vdwWellDepthInKJ) {
00196          defineIncompleteAtomClass(atomClassIx, atomClassName, elementNumber, expectedValence);
00197          setAtomClassVdwParameters(atomClassIx, vdwRadiusInNm, vdwWellDepthInKJ);
00198     }
00199 
00200     // Same routine in Kcal/Angstrom (KA) unit system, i.e., radius
00201     // (still not sigma) is in nm, and well depth in kcal/mol.
00202     void defineAtomClass_KA(DuMM::AtomClassIndex atomClassIx, const char* atomClassName,
00203                             int element, int valence,
00204                             Real vdwRadiusInAng, Real vdwWellDepthInKcal)
00205     {
00206         defineAtomClass(atomClassIx, atomClassName, element, valence,
00207             vdwRadiusInAng*DuMM::Ang2Nm, vdwWellDepthInKcal*DuMM::Kcal2KJ);
00208     }
00209     // For backwards compatibility and compactness of expression, permit integer indices
00210     void defineAtomClass_KA(int atomClassIx, const char* atomClassName,
00211                             int element, int valence,
00212                             Real vdwRadiusInAng, Real vdwWellDepthInKcal)
00213     {
00214         defineAtomClass_KA((DuMM::AtomClassIndex)atomClassIx, atomClassName, element, valence, vdwRadiusInAng, vdwWellDepthInKcal);
00215     }
00216 
00217     bool hasAtomClass(DuMM::AtomClassIndex) const; // TODO
00218     bool hasAtomClass(const String& atomClassName) const; // TODO
00219     DuMM::AtomClassIndex getAtomClassIndex(const String& atomClassName) const;
00220     DuMM::AtomClassIndex getNextUnusedAtomClassIndex() const; // TODO
00221     
00222     DuMM::AtomClassIndex getAtomClassIndex(DuMM::AtomIndex atomIx) const;
00223     Real getVdwRadius(DuMM::AtomClassIndex atomClassIx) const;
00224     Real getVdwWellDepth(DuMM::AtomClassIndex atomClassIx) const;
00225 
00226     // PartialCharge in units of e (charge on a proton); same in MD & KA
00227     void defineChargedAtomType(DuMM::ChargedAtomTypeIndex atomTypeIx, const char* atomTypeName,
00228         DuMM::AtomClassIndex atomClassIx, Real partialChargeInE) {
00229             defineIncompleteChargedAtomType(atomTypeIx, atomTypeName, atomClassIx);
00230             setChargedAtomTypeCharge(atomTypeIx, partialChargeInE);
00231     }
00232 
00233     void defineChargedAtomType_KA(DuMM::ChargedAtomTypeIndex atomTypeIx, const char* atomTypeName,
00234                                   DuMM::AtomClassIndex atomClassIx, Real partialChargeInE)
00235     {
00236         defineChargedAtomType(atomTypeIx, atomTypeName, atomClassIx, partialChargeInE); // easy!
00237     }
00238     // For backwards compatibility and compactness of expression, permit integer indices
00239     void defineChargedAtomType_KA(int atomTypeIx, const char* atomTypeName,
00240                                   int atomClassIx, Real partialChargeInE)
00241     {
00242         defineChargedAtomType_KA((DuMM::ChargedAtomTypeIndex) atomTypeIx, atomTypeName, (DuMM::AtomClassIndex)atomClassIx, partialChargeInE);
00243     }
00244 
00245     bool hasChargedAtomType(DuMM::ChargedAtomTypeIndex) const; // TODO
00246     bool hasChargedAtomType(const String& chargedTypeName) const; // TODO
00247     DuMM::ChargedAtomTypeIndex getChargedAtomTypeIndex(const String& chargedTypeName) const; // TODO
00248     DuMM::ChargedAtomTypeIndex getNextUnusedChargedAtomTypeIndex() const; // TODO
00249 
00250     // Bond stretch parameters (between 2 atom classes). This
00251     // fails if (class1,class2) or (class2,class1) has already been assigned.
00252     // Stiffness (energy per length^2) in (kJ/mol)/nm^2
00253     // (note that energy is kx^2 using this definition,
00254     // while force is 2kx; note factor of 2 in force)
00255     void defineBondStretch(DuMM::AtomClassIndex class1, DuMM::AtomClassIndex class2,
00256                            Real stiffnessInKJperNmSq, Real nominalLengthInNm);
00257 
00258     // Here stiffness is in (kcal/mol)/A^2, and nominal length is in A (angstroms).
00259     void defineBondStretch_KA(DuMM::AtomClassIndex class1, DuMM::AtomClassIndex class2,
00260                               Real stiffnessInKcalPerAngSq, Real nominalLengthInAng)
00261     {
00262         defineBondStretch(class1, class2, 
00263                           stiffnessInKcalPerAngSq * DuMM::Kcal2KJ/square(DuMM::Ang2Nm),
00264                           nominalLengthInAng      * DuMM::Ang2Nm);
00265     }
00266     // For backwards compatibility and compactness of expression, permit integer indices
00267     void defineBondStretch_KA(int class1, int class2,
00268                               Real stiffnessInKcalPerAngSq, Real nominalLengthInAng)
00269     {
00270         defineBondStretch_KA((DuMM::AtomClassIndex)class1, (DuMM::AtomClassIndex)class2, stiffnessInKcalPerAngSq, nominalLengthInAng);
00271     }
00272 
00273     // Bending angle parameters (among 3 atom types). This fails
00274     // if (type1,type2,type3) or (type3,type2,type1) has already been seen.
00275     // Stiffness k (energy per rad^2) in (kJ/mol)/rad^2
00276     // Then energy is k*a^2 for angle a in radians,
00277     // while torque is 2ka; note factor of 2 in torque.
00278     // Note that the nominal angle is in degrees while the stiffness
00279     // is in radians. Odd, I know, but that seems to be how it's done!
00280     void defineBondBend(DuMM::AtomClassIndex class1, DuMM::AtomClassIndex class2, DuMM::AtomClassIndex class3,
00281                         Real stiffnessInKJPerRadSq, Real nominalAngleInDeg);
00282 
00283     // Here the stiffness is given in (kcal/mol)/rad^2.
00284     void defineBondBend_KA(DuMM::AtomClassIndex class1, DuMM::AtomClassIndex class2, DuMM::AtomClassIndex class3,
00285         Real stiffnessInKcalPerRadSq, Real nominalAngleInDeg) 
00286     {
00287         defineBondBend(class1,class2,class3,
00288                        stiffnessInKcalPerRadSq * DuMM::Kcal2KJ,
00289                        nominalAngleInDeg);
00290     }
00291     // For backwards compatibility and compactness of expression, permit integer indices
00292     void defineBondBend_KA(int class1, int class2, int class3,
00293         Real stiffnessInKcalPerRadSq, Real nominalAngleInDeg) 
00294     {
00295         defineBondBend_KA((DuMM::AtomClassIndex)class1, (DuMM::AtomClassIndex)class2, (DuMM::AtomClassIndex)class3,
00296                             stiffnessInKcalPerRadSq, nominalAngleInDeg);
00297     }
00298 
00299     // Only one term may have a given periodicity. The amplitudes are
00300     // in kJ/mol, with no factor of 1/2 expected (as is sometimes
00301     // the convention). 
00302     void defineBondTorsion
00303        (DuMM::AtomClassIndex class1, DuMM::AtomClassIndex class2, DuMM::AtomClassIndex class3, DuMM::AtomClassIndex class4, 
00304         int periodicity1, Real amp1InKJ, Real phase1InDegrees);
00305     void defineBondTorsion
00306        (DuMM::AtomClassIndex class1, DuMM::AtomClassIndex class2, DuMM::AtomClassIndex class3, DuMM::AtomClassIndex class4,  
00307         int periodicity1, Real amp1InKJ, Real phase1InDegrees,
00308         int periodicity2, Real amp2InKJ, Real phase2InDegrees);
00309     void defineBondTorsion
00310        (DuMM::AtomClassIndex class1, DuMM::AtomClassIndex class2, DuMM::AtomClassIndex class3, DuMM::AtomClassIndex class4, 
00311         int periodicity1, Real amp1InKJ, Real phase1InDegrees,
00312         int periodicity2, Real amp2InKJ, Real phase2InDegrees,
00313         int periodicity3, Real amp3InKJ, Real phase3InDegrees);
00314 
00315     // Here the amplitudes are given in kcal/mol.
00316     void defineBondTorsion_KA
00317        (DuMM::AtomClassIndex class1, DuMM::AtomClassIndex class2, DuMM::AtomClassIndex class3, DuMM::AtomClassIndex class4, 
00318         int periodicity1, Real amp1InKcal, Real phase1InDegrees)
00319     { 
00320         defineBondTorsion(class1,class2,class3,class4,
00321                           periodicity1, amp1InKcal * DuMM::Kcal2KJ, phase1InDegrees);
00322     }
00323     void defineBondTorsion_KA
00324        (DuMM::AtomClassIndex class1, DuMM::AtomClassIndex class2, DuMM::AtomClassIndex class3, DuMM::AtomClassIndex class4,  
00325         int periodicity1, Real amp1InKcal, Real phase1InDegrees,
00326         int periodicity2, Real amp2InKcal, Real phase2InDegrees)
00327     {
00328         defineBondTorsion(class1,class2,class3,class4,
00329                           periodicity1, amp1InKcal * DuMM::Kcal2KJ, phase1InDegrees,
00330                           periodicity2, amp2InKcal * DuMM::Kcal2KJ, phase2InDegrees);
00331     }
00332     void defineBondTorsion_KA
00333        (DuMM::AtomClassIndex class1, DuMM::AtomClassIndex class2, DuMM::AtomClassIndex class3, DuMM::AtomClassIndex class4, 
00334         int periodicity1, Real amp1InKcal, Real phase1InDegrees,
00335         int periodicity2, Real amp2InKcal, Real phase2InDegrees,
00336         int periodicity3, Real amp3InKcal, Real phase3InDegrees)
00337     {
00338         defineBondTorsion(class1,class2,class3,class4,
00339                           periodicity1, amp1InKcal * DuMM::Kcal2KJ, phase1InDegrees,
00340                           periodicity2, amp2InKcal * DuMM::Kcal2KJ, phase2InDegrees,
00341                           periodicity3, amp3InKcal * DuMM::Kcal2KJ, phase3InDegrees);
00342     }
00343     // For backwards compatibility and compactness of expression, permit integer indices
00344     void defineBondTorsion_KA
00345        (int class1, int class2, int class3, int class4, 
00346         int periodicity1, Real amp1InKcal, Real phase1InDegrees)
00347     {
00348         defineBondTorsion_KA
00349                ((DuMM::AtomClassIndex)class1, (DuMM::AtomClassIndex)class2, (DuMM::AtomClassIndex)class3, (DuMM::AtomClassIndex)class4, 
00350                 periodicity1, amp1InKcal, phase1InDegrees);
00351     }
00352     // For backwards compatibility and compactness of expression, permit integer indices
00353     void defineBondTorsion_KA
00354        (int class1, int class2, int class3, int class4, 
00355         int periodicity1, Real amp1InKcal, Real phase1InDegrees,
00356         int periodicity2, Real amp2InKcal, Real phase2InDegrees)
00357     {
00358         defineBondTorsion_KA
00359                ((DuMM::AtomClassIndex)class1, (DuMM::AtomClassIndex)class2, (DuMM::AtomClassIndex)class3, (DuMM::AtomClassIndex)class4, 
00360                 periodicity1, amp1InKcal, phase1InDegrees,
00361                 periodicity2, amp2InKcal, phase2InDegrees);
00362     }
00363     // For backwards compatibility and compactness of expression, permit integer indices
00364     void defineBondTorsion_KA
00365        (int class1, int class2, int class3, int class4, 
00366         int periodicity1, Real amp1InKcal, Real phase1InDegrees,
00367         int periodicity2, Real amp2InKcal, Real phase2InDegrees,
00368         int periodicity3, Real amp3InKcal, Real phase3InDegrees)
00369     {
00370         defineBondTorsion_KA
00371                ((DuMM::AtomClassIndex)class1, (DuMM::AtomClassIndex)class2, (DuMM::AtomClassIndex)class3, (DuMM::AtomClassIndex)class4, 
00372                 periodicity1, amp1InKcal, phase1InDegrees,
00373                 periodicity2, amp2InKcal, phase2InDegrees,
00374                 periodicity3, amp3InKcal, phase3InDegrees);
00375     }
00376 
00377     // As with normal torsions, (see defineAmberImproperTorsion), only one term may have
00378     // a given periodicity. The amplitudes are in kJ/mol.
00379     void defineAmberImproperTorsion
00380        (DuMM::AtomClassIndex class1, DuMM::AtomClassIndex class2, DuMM::AtomClassIndex class3, DuMM::AtomClassIndex class4,
00381         int periodicity1, Real amp1InKJ, Real phase1InDegrees);
00382     void defineAmberImproperTorsion
00383        (DuMM::AtomClassIndex class1, DuMM::AtomClassIndex class2, DuMM::AtomClassIndex class3, DuMM::AtomClassIndex class4,
00384         int periodicity1, Real amp1InKJ, Real phase1InDegrees,
00385         int periodicity2, Real amp2InKJ, Real phase2InDegrees);
00386     void defineAmberImproperTorsion
00387        (DuMM::AtomClassIndex class1, DuMM::AtomClassIndex class2, DuMM::AtomClassIndex class3, DuMM::AtomClassIndex class4,
00388         int periodicity1, Real amp1InKJ, Real phase1InDegrees,
00389         int periodicity2, Real amp2InKJ, Real phase2InDegrees,
00390         int periodicity3, Real amp3InKJ, Real phase3InDegrees);
00391 
00392     // Here the amplitudes are given in kcal/mol.
00393     void defineAmberImproperTorsion_KA
00394        (DuMM::AtomClassIndex class1, DuMM::AtomClassIndex class2, DuMM::AtomClassIndex class3, DuMM::AtomClassIndex class4,
00395         int periodicity1, Real amp1InKcal, Real phase1InDegrees)
00396     {
00397         defineAmberImproperTorsion(class1,class2,class3,class4,
00398                           periodicity1, amp1InKcal * DuMM::Kcal2KJ, phase1InDegrees);
00399     }
00400     void defineAmberImproperTorsion_KA
00401        (DuMM::AtomClassIndex class1, DuMM::AtomClassIndex class2, DuMM::AtomClassIndex class3, DuMM::AtomClassIndex class4,
00402         int periodicity1, Real amp1InKcal, Real phase1InDegrees,
00403         int periodicity2, Real amp2InKcal, Real phase2InDegrees)
00404     {
00405         defineAmberImproperTorsion(class1,class2,class3,class4,
00406                           periodicity1, amp1InKcal * DuMM::Kcal2KJ, phase1InDegrees,
00407                           periodicity2, amp2InKcal * DuMM::Kcal2KJ, phase2InDegrees);
00408     }
00409     void defineAmberImproperTorsion_KA
00410        (DuMM::AtomClassIndex class1, DuMM::AtomClassIndex class2, DuMM::AtomClassIndex class3, DuMM::AtomClassIndex class4,
00411         int periodicity1, Real amp1InKcal, Real phase1InDegrees,
00412         int periodicity2, Real amp2InKcal, Real phase2InDegrees,
00413         int periodicity3, Real amp3InKcal, Real phase3InDegrees)
00414     {
00415         defineAmberImproperTorsion(class1,class2,class3,class4,
00416                           periodicity1, amp1InKcal * DuMM::Kcal2KJ, phase1InDegrees,
00417                           periodicity2, amp2InKcal * DuMM::Kcal2KJ, phase2InDegrees,
00418                           periodicity3, amp3InKcal * DuMM::Kcal2KJ, phase3InDegrees);
00419     }
00420 
00421     // The third atom is the central one to which the other
00422     // three are bonded; this is not the same in reverse order.
00423     // TODO: not implemented
00424     // void defineImproperTorsion(DuMM::AtomClassIndex class1, DuMM::AtomClassIndex class2, DuMM::AtomClassIndex class3, DuMM::AtomClassIndex class4,
00425     //     Real amplitude, Real phase, int periodicity,
00426     //     Real amp2, Real phase2, int period2,
00427     //     Real amp3, Real phase3, int period3);
00428     // void defineImproperTorsion_KA(DuMM::AtomClassIndex class1, DuMM::AtomClassIndex class2, DuMM::AtomClassIndex class3, DuMM::AtomClassIndex class4,
00429     //     Real amplitude, Real phase, int periodicity,
00430     //     Real amp2, Real phase2, int period2,
00431     //     Real amp3, Real phase3, int period3);
00432 
00433     void setVdwMixingRule(VdwMixingRule); // default WaldmanHagler
00434     VdwMixingRule getVdwMixingRule() const;
00435 
00436     void setVdw12ScaleFactor(Real); // default 0
00437     void setVdw13ScaleFactor(Real); // default 0
00438     void setVdw14ScaleFactor(Real); // default 1
00439     void setVdw15ScaleFactor(Real); // default 1
00440 
00441     void setCoulomb12ScaleFactor(Real); // default 0
00442     void setCoulomb13ScaleFactor(Real); // default 0
00443     void setCoulomb14ScaleFactor(Real); // default 1
00444     void setCoulomb15ScaleFactor(Real); // default 1
00445 
00446     // These can be used to weaken or disable (or magnify)
00447     // individual force field terms.
00448     // These are always 1 for correct implementation of any force field.
00449     void setVdwGlobalScaleFactor(Real);
00450     void setCoulombGlobalScaleFactor(Real);
00451     void setBondStretchGlobalScaleFactor(Real);
00452     void setBondBendGlobalScaleFactor(Real);
00453     void setBondTorsionGlobalScaleFactor(Real);
00454     void setAmberImproperTorsionGlobalScaleFactor(Real);
00455     void setGbsaGlobalScaleFactor(Real);
00456     void setGbsaIncludeAceApproximation(bool);
00457     void setGbsaIncludeAceApproximationOn()  {setGbsaIncludeAceApproximation(true );}
00458     void setGbsaIncludeAceApproximationOff() {setGbsaIncludeAceApproximation(false);}
00459 
00460     Real getVdwGlobalScaleFactor() const;
00461     
00462     void setAllGlobalScaleFactors(Real s) {
00463         setVdwGlobalScaleFactor(s);
00464         setCoulombGlobalScaleFactor(s);
00465         setBondStretchGlobalScaleFactor(s);
00466         setBondBendGlobalScaleFactor(s);
00467         setBondTorsionGlobalScaleFactor(s);
00468         setAmberImproperTorsionGlobalScaleFactor(s);
00469         setGbsaGlobalScaleFactor(s);
00470     }
00471     
00472     bool getUseMultithreadedComputation();
00473     void setUseMultithreadedComputation(bool);
00474 
00475     // How many times has the forcefield been evaluated?
00476     long int getForceEvaluationCount() const;
00477 
00478     void dump() const; // to stdout
00479 
00480     // Methods of the former TinkerDummForceFieldSubsystem
00486     void loadAmber99Parameters();
00487 
00488     // void dumpCForcefieldParameters(std::ostream& os, const String methodName) const;
00489 
00490 
00496     void populateFromTinkerParameterFile(
00497         std::istream& 
00498         );
00499 
00505     void setBiotypeChargedAtomType(
00506         DuMM::ChargedAtomTypeIndex chargedAtomTypeIndex, 
00507         BiotypeIndex biotypeIx 
00508         );
00509 
00511     DuMM::ChargedAtomTypeIndex getBiotypeChargedAtomType(BiotypeIndex biotypeIx) const;
00512 
00513     std::ostream& generateBiotypeChargedAtomTypeSelfCode(std::ostream& os) const;
00514 
00515     void loadTestMoleculeParameters();
00516 
00517 protected:
00518 
00519     SimTK_PIMPL_DOWNCAST(DuMMForceFieldSubsystem, ForceSubsystem);
00520     SimTK_PIMPL_DOWNCAST(DuMMForceFieldSubsystem, Subsystem);
00521 
00522     // SimTK_PIMPL_DOWNCAST(DuMMForceFieldSubsystem, Subsystem);
00523 
00524 protected:
00525 
00526     void defineIncompleteAtomClass(
00527         DuMM::AtomClassIndex classIx, 
00528         const char* name, 
00529         int elementNumber, 
00530         int valence);
00531 
00532     void defineIncompleteAtomClass_KA(
00533         DuMM::AtomClassIndex classIx, 
00534         const char* name, 
00535         int elementNumber, 
00536         int valence) 
00537     {
00538         defineIncompleteAtomClass(
00539             classIx, 
00540             name, 
00541             elementNumber, 
00542             valence
00543             );
00544     }
00545 
00546     void setAtomClassVdwParameters(DuMM::AtomClassIndex atomClassIx, Real vdwRadiusInNm, Real vdwWellDepthInKJPerMol);
00547     void setAtomClassVdwParameters_KA(DuMM::AtomClassIndex atomClassIx, Real radiusInAng, Real wellDepthInKcal) {
00548         setAtomClassVdwParameters(atomClassIx, radiusInAng*DuMM::Ang2Nm, wellDepthInKcal*DuMM::Kcal2KJ);
00549     }
00550 
00551     bool isValidAtomClass(DuMM::AtomClassIndex) const;
00552     
00553     void defineIncompleteChargedAtomType(
00554         DuMM::ChargedAtomTypeIndex typeIx, 
00555         const char* name,
00556         DuMM::AtomClassIndex classIx);
00557 
00558     void defineIncompleteChargedAtomType_KA(
00559         DuMM::ChargedAtomTypeIndex typeIx, 
00560         const char* name,
00561         DuMM::AtomClassIndex classIx) 
00562     {
00563         defineIncompleteChargedAtomType(typeIx, name, classIx);
00564     }
00565 
00566     void setChargedAtomTypeCharge(DuMM::ChargedAtomTypeIndex, Real charge);
00567     void setChargedAtomTypeCharge_KA(DuMM::ChargedAtomTypeIndex chargedAtomTypeIx, Real charge) {
00568         setChargedAtomTypeCharge(chargedAtomTypeIx, charge);
00569     }
00570 
00571 private:
00572     class DuMMForceFieldSubsystemRep& updRep();
00573     const DuMMForceFieldSubsystemRep& getRep() const;
00574 };
00575 
00576 typedef DuMMForceFieldSubsystem TinkerDuMMForceFieldSubsystem;
00577 
00578 
00579 class Amber99ForceSubsystem : public TinkerDuMMForceFieldSubsystem {
00580 public:
00581     explicit Amber99ForceSubsystem(MolecularMechanicsSystem& system) 
00582         : TinkerDuMMForceFieldSubsystem(system)
00583     {
00584         loadAmber99Parameters();
00585     }
00586 };
00587 
00588 } // namespace SimTK
00589 
00590 #endif // SimTK_MOLMODEL_DUMM_FORCE_FIELD_SUBSYSTEM_H_

Generated on Fri Sep 26 07:44:10 2008 for SimTKcore by  doxygen 1.5.6