Search in sources :

Example 1 with ReciprocalSpace

use of ffx.potential.nonbonded.ReciprocalSpace in project ffx by mjschnie.

the class ForceFieldEnergyOpenMM method addAmoebaMultipoleForce.

private void addAmoebaMultipoleForce() {
    ParticleMeshEwald pme = super.getPmeNode();
    if (pme == null) {
        return;
    }
    int[][] axisAtom = pme.getAxisAtoms();
    double dipoleConversion = OpenMM_NmPerAngstrom;
    double quadrupoleConversion = OpenMM_NmPerAngstrom * OpenMM_NmPerAngstrom;
    double polarityConversion = OpenMM_NmPerAngstrom * OpenMM_NmPerAngstrom * OpenMM_NmPerAngstrom;
    double dampingFactorConversion = sqrt(OpenMM_NmPerAngstrom);
    amoebaMultipoleForce = OpenMM_AmoebaMultipoleForce_create();
    double polarScale = 1.0;
    if (pme.getPolarizationType() != Polarization.MUTUAL) {
        OpenMM_AmoebaMultipoleForce_setPolarizationType(amoebaMultipoleForce, OpenMM_AmoebaMultipoleForce_Direct);
        if (pme.getPolarizationType() == Polarization.NONE) {
            polarScale = 0.0;
        }
    } else {
        ForceField forceField = molecularAssembly.getForceField();
        String algorithm = forceField.getString(ForceField.ForceFieldString.SCF_ALGORITHM, "CG");
        ParticleMeshEwald.SCFAlgorithm scfAlgorithm;
        try {
            algorithm = algorithm.replaceAll("-", "_").toUpperCase();
            scfAlgorithm = ParticleMeshEwald.SCFAlgorithm.valueOf(algorithm);
        } catch (Exception e) {
            scfAlgorithm = ParticleMeshEwald.SCFAlgorithm.CG;
        }
        switch(scfAlgorithm) {
            case EPT:
                logger.info(" Using extrapolated perturbation theory approximation instead of full SCF calculations. Not supported in FFX reference implementation.");
                OpenMM_AmoebaMultipoleForce_setPolarizationType(amoebaMultipoleForce, OpenMM_AmoebaMultipoleForce_Extrapolated);
                PointerByReference exptCoefficients = OpenMM_DoubleArray_create(4);
                OpenMM_DoubleArray_set(exptCoefficients, 0, -0.154);
                OpenMM_DoubleArray_set(exptCoefficients, 1, 0.017);
                OpenMM_DoubleArray_set(exptCoefficients, 2, 0.657);
                OpenMM_DoubleArray_set(exptCoefficients, 3, 0.475);
                OpenMM_AmoebaMultipoleForce_setExtrapolationCoefficients(amoebaMultipoleForce, exptCoefficients);
                OpenMM_DoubleArray_destroy(exptCoefficients);
                break;
            case CG:
            case SOR:
            default:
                OpenMM_AmoebaMultipoleForce_setPolarizationType(amoebaMultipoleForce, OpenMM_AmoebaMultipoleForce_Mutual);
                break;
        }
    }
    PointerByReference dipoles = OpenMM_DoubleArray_create(3);
    PointerByReference quadrupoles = OpenMM_DoubleArray_create(9);
    Atom[] atoms = molecularAssembly.getAtomArray();
    int nAtoms = atoms.length;
    for (int i = 0; i < nAtoms; i++) {
        Atom atom = atoms[i];
        MultipoleType multipoleType = atom.getMultipoleType();
        PolarizeType polarType = atom.getPolarizeType();
        /**
         * Define the frame definition.
         */
        int axisType = OpenMM_AmoebaMultipoleForce_NoAxisType;
        switch(multipoleType.frameDefinition) {
            case ZONLY:
                axisType = OpenMM_AmoebaMultipoleForce_ZOnly;
                break;
            case ZTHENX:
                axisType = OpenMM_AmoebaMultipoleForce_ZThenX;
                break;
            case BISECTOR:
                axisType = OpenMM_AmoebaMultipoleForce_Bisector;
                break;
            case ZTHENBISECTOR:
                axisType = OpenMM_AmoebaMultipoleForce_ZBisect;
                break;
            case TRISECTOR:
                axisType = OpenMM_AmoebaMultipoleForce_ThreeFold;
                break;
            default:
                break;
        }
        double useFactor = 1.0;
        if (!atoms[i].getUse() || !atoms[i].getElectrostatics()) {
            // if (!atoms[i].getUse()) {
            useFactor = 0.0;
        }
        // Should be 1.0 at this point.
        double lambdaScale = lambda;
        if (!atom.applyLambda()) {
            lambdaScale = 1.0;
        }
        useFactor *= lambdaScale;
        /**
         * Load local multipole coefficients.
         */
        for (int j = 0; j < 3; j++) {
            OpenMM_DoubleArray_set(dipoles, j, multipoleType.dipole[j] * dipoleConversion * useFactor);
        }
        int l = 0;
        for (int j = 0; j < 3; j++) {
            for (int k = 0; k < 3; k++) {
                OpenMM_DoubleArray_set(quadrupoles, l++, multipoleType.quadrupole[j][k] * quadrupoleConversion * useFactor / 3.0);
            }
        }
        // int zaxis = 0;
        int zaxis = 1;
        // int xaxis = 0;
        int xaxis = 1;
        // int yaxis = 0;
        int yaxis = 1;
        int[] refAtoms = axisAtom[i];
        if (refAtoms != null) {
            zaxis = refAtoms[0];
            if (refAtoms.length > 1) {
                xaxis = refAtoms[1];
                if (refAtoms.length > 2) {
                    yaxis = refAtoms[2];
                }
            }
        } else {
            axisType = OpenMM_AmoebaMultipoleForce_NoAxisType;
            logger.info(String.format(" Atom type %s", atom.getAtomType().toString()));
        }
        double charge = multipoleType.charge * useFactor;
        /**
         * Add the multipole.
         */
        OpenMM_AmoebaMultipoleForce_addMultipole(amoebaMultipoleForce, charge, dipoles, quadrupoles, axisType, zaxis, xaxis, yaxis, polarType.thole, polarType.pdamp * dampingFactorConversion, polarType.polarizability * polarityConversion * polarScale);
    }
    OpenMM_DoubleArray_destroy(dipoles);
    OpenMM_DoubleArray_destroy(quadrupoles);
    Crystal crystal = super.getCrystal();
    if (!crystal.aperiodic()) {
        OpenMM_AmoebaMultipoleForce_setNonbondedMethod(amoebaMultipoleForce, OpenMM_AmoebaMultipoleForce_PME);
        OpenMM_AmoebaMultipoleForce_setCutoffDistance(amoebaMultipoleForce, pme.getEwaldCutoff() * OpenMM_NmPerAngstrom);
        OpenMM_AmoebaMultipoleForce_setAEwald(amoebaMultipoleForce, pme.getEwaldCoefficient() / OpenMM_NmPerAngstrom);
        double ewaldTolerance = 1.0e-04;
        OpenMM_AmoebaMultipoleForce_setEwaldErrorTolerance(amoebaMultipoleForce, ewaldTolerance);
        PointerByReference gridDimensions = OpenMM_IntArray_create(3);
        ReciprocalSpace recip = pme.getReciprocalSpace();
        OpenMM_IntArray_set(gridDimensions, 0, recip.getXDim());
        OpenMM_IntArray_set(gridDimensions, 1, recip.getYDim());
        OpenMM_IntArray_set(gridDimensions, 2, recip.getZDim());
        OpenMM_AmoebaMultipoleForce_setPmeGridDimensions(amoebaMultipoleForce, gridDimensions);
        OpenMM_IntArray_destroy(gridDimensions);
    } else {
        OpenMM_AmoebaMultipoleForce_setNonbondedMethod(amoebaMultipoleForce, OpenMM_AmoebaMultipoleForce_NoCutoff);
    }
    OpenMM_AmoebaMultipoleForce_setMutualInducedMaxIterations(amoebaMultipoleForce, 500);
    OpenMM_AmoebaMultipoleForce_setMutualInducedTargetEpsilon(amoebaMultipoleForce, pme.getPolarEps());
    int[][] ip11 = pme.getPolarization11();
    int[][] ip12 = pme.getPolarization12();
    int[][] ip13 = pme.getPolarization13();
    ArrayList<Integer> list12 = new ArrayList<>();
    ArrayList<Integer> list13 = new ArrayList<>();
    ArrayList<Integer> list14 = new ArrayList<>();
    PointerByReference covalentMap = OpenMM_IntArray_create(0);
    for (int i = 0; i < nAtoms; i++) {
        Atom ai = atoms[i];
        list12.clear();
        list13.clear();
        list14.clear();
        for (Bond bond : ai.getBonds()) {
            int index = bond.get1_2(ai).getIndex() - 1;
            OpenMM_IntArray_append(covalentMap, index);
            list12.add(index);
        }
        OpenMM_AmoebaMultipoleForce_setCovalentMap(amoebaMultipoleForce, i, OpenMM_AmoebaMultipoleForce_Covalent12, covalentMap);
        OpenMM_IntArray_resize(covalentMap, 0);
        for (Angle angle : ai.getAngles()) {
            Atom ak = angle.get1_3(ai);
            if (ak != null) {
                int index = ak.getIndex() - 1;
                if (!list12.contains(index)) {
                    list13.add(index);
                    OpenMM_IntArray_append(covalentMap, index);
                }
            }
        }
        OpenMM_AmoebaMultipoleForce_setCovalentMap(amoebaMultipoleForce, i, OpenMM_AmoebaMultipoleForce_Covalent13, covalentMap);
        OpenMM_IntArray_resize(covalentMap, 0);
        for (Torsion torsion : ai.getTorsions()) {
            Atom ak = torsion.get1_4(ai);
            if (ak != null) {
                int index = ak.getIndex() - 1;
                if (!list12.contains(index) && !list13.contains(index)) {
                    list14.add(index);
                    OpenMM_IntArray_append(covalentMap, index);
                }
            }
        }
        OpenMM_AmoebaMultipoleForce_setCovalentMap(amoebaMultipoleForce, i, OpenMM_AmoebaMultipoleForce_Covalent14, covalentMap);
        OpenMM_IntArray_resize(covalentMap, 0);
        for (Atom ak : ai.get1_5s()) {
            int index = ak.getIndex() - 1;
            if (!list12.contains(index) && !list13.contains(index) && !list14.contains(index)) {
                OpenMM_IntArray_append(covalentMap, index);
            }
        }
        OpenMM_AmoebaMultipoleForce_setCovalentMap(amoebaMultipoleForce, i, OpenMM_AmoebaMultipoleForce_Covalent15, covalentMap);
        OpenMM_IntArray_resize(covalentMap, 0);
        for (int j = 0; j < ip11[i].length; j++) {
            OpenMM_IntArray_append(covalentMap, ip11[i][j]);
        }
        OpenMM_AmoebaMultipoleForce_setCovalentMap(amoebaMultipoleForce, i, OpenMM_AmoebaMultipoleForce_PolarizationCovalent11, covalentMap);
        OpenMM_IntArray_resize(covalentMap, 0);
    // for (int j = 0; j < ip12[i].length; j++) {
    // OpenMM_IntArray_append(covalentMap, ip12[i][j]);
    // }
    // OpenMM_AmoebaMultipoleForce_setCovalentMap(amoebaMultipoleForce, i,
    // OpenMM_AmoebaMultipoleForce_PolarizationCovalent12, covalentMap);
    // OpenMM_IntArray_resize(covalentMap, 0);
    // 
    // for (int j = 0; j < ip13[i].length; j++) {
    // OpenMM_IntArray_append(covalentMap, ip13[i][j]);
    // }
    // OpenMM_AmoebaMultipoleForce_setCovalentMap(amoebaMultipoleForce, i,
    // OpenMM_AmoebaMultipoleForce_PolarizationCovalent13, covalentMap);
    // OpenMM_IntArray_resize(covalentMap, 0);
    // 
    // OpenMM_AmoebaMultipoleForce_setCovalentMap(amoebaMultipoleForce, i,
    // OpenMM_AmoebaMultipoleForce_PolarizationCovalent14, covalentMap);
    }
    OpenMM_IntArray_destroy(covalentMap);
    OpenMM_System_addForce(system, amoebaMultipoleForce);
    OpenMM_Force_setForceGroup(amoebaMultipoleForce, 1);
    logger.log(Level.INFO, " Added polarizable multipole force.");
    GeneralizedKirkwood gk = super.getGK();
    if (gk != null) {
        addGKForce();
    }
}
Also used : PolarizeType(ffx.potential.parameters.PolarizeType) GeneralizedKirkwood(ffx.potential.nonbonded.GeneralizedKirkwood) ArrayList(java.util.ArrayList) MultipoleType(ffx.potential.parameters.MultipoleType) ReciprocalSpace(ffx.potential.nonbonded.ReciprocalSpace) EnergyException(ffx.potential.utils.EnergyException) Atom(ffx.potential.bonded.Atom) OpenMM_System_addConstraint(simtk.openmm.OpenMMLibrary.OpenMM_System_addConstraint) CoordRestraint(ffx.potential.nonbonded.CoordRestraint) Angle(ffx.potential.bonded.Angle) OpenMM_AmoebaAngleForce_addAngle(simtk.openmm.AmoebaOpenMMLibrary.OpenMM_AmoebaAngleForce_addAngle) OpenMM_AmoebaInPlaneAngleForce_addAngle(simtk.openmm.AmoebaOpenMMLibrary.OpenMM_AmoebaInPlaneAngleForce_addAngle) PointerByReference(com.sun.jna.ptr.PointerByReference) ForceField(ffx.potential.parameters.ForceField) Bond(ffx.potential.bonded.Bond) OpenMM_AmoebaBondForce_addBond(simtk.openmm.AmoebaOpenMMLibrary.OpenMM_AmoebaBondForce_addBond) RestraintBond(ffx.potential.bonded.RestraintBond) OpenMM_CustomBondForce_addBond(simtk.openmm.OpenMMLibrary.OpenMM_CustomBondForce_addBond) OpenMM_HarmonicBondForce_addBond(simtk.openmm.OpenMMLibrary.OpenMM_HarmonicBondForce_addBond) ParticleMeshEwald(ffx.potential.nonbonded.ParticleMeshEwald) Torsion(ffx.potential.bonded.Torsion) OpenMM_AmoebaTorsionTorsionForce_addTorsionTorsion(simtk.openmm.AmoebaOpenMMLibrary.OpenMM_AmoebaTorsionTorsionForce_addTorsionTorsion) TorsionTorsion(ffx.potential.bonded.TorsionTorsion) OpenMM_PeriodicTorsionForce_addTorsion(simtk.openmm.OpenMMLibrary.OpenMM_PeriodicTorsionForce_addTorsion) PiOrbitalTorsion(ffx.potential.bonded.PiOrbitalTorsion) OpenMM_AmoebaPiTorsionForce_addPiTorsion(simtk.openmm.AmoebaOpenMMLibrary.OpenMM_AmoebaPiTorsionForce_addPiTorsion) ImproperTorsion(ffx.potential.bonded.ImproperTorsion) Crystal(ffx.crystal.Crystal)

Aggregations

PointerByReference (com.sun.jna.ptr.PointerByReference)1 Crystal (ffx.crystal.Crystal)1 Angle (ffx.potential.bonded.Angle)1 Atom (ffx.potential.bonded.Atom)1 Bond (ffx.potential.bonded.Bond)1 ImproperTorsion (ffx.potential.bonded.ImproperTorsion)1 PiOrbitalTorsion (ffx.potential.bonded.PiOrbitalTorsion)1 RestraintBond (ffx.potential.bonded.RestraintBond)1 Torsion (ffx.potential.bonded.Torsion)1 TorsionTorsion (ffx.potential.bonded.TorsionTorsion)1 CoordRestraint (ffx.potential.nonbonded.CoordRestraint)1 GeneralizedKirkwood (ffx.potential.nonbonded.GeneralizedKirkwood)1 ParticleMeshEwald (ffx.potential.nonbonded.ParticleMeshEwald)1 ReciprocalSpace (ffx.potential.nonbonded.ReciprocalSpace)1 ForceField (ffx.potential.parameters.ForceField)1 MultipoleType (ffx.potential.parameters.MultipoleType)1 PolarizeType (ffx.potential.parameters.PolarizeType)1 EnergyException (ffx.potential.utils.EnergyException)1 ArrayList (java.util.ArrayList)1 OpenMM_AmoebaAngleForce_addAngle (simtk.openmm.AmoebaOpenMMLibrary.OpenMM_AmoebaAngleForce_addAngle)1