#ifndef AMOEBA_OPENMM_CUDAKERNELS_H_ #define AMOEBA_OPENMM_CUDAKERNELS_H_ /* -------------------------------------------------------------------------- * * OpenMMAmoeba * * -------------------------------------------------------------------------- * * This is part of the OpenMM molecular simulation toolkit originating from * * Simbios, the NIH National Center for Physics-Based Simulation of * * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * * Portions copyright (c) 2008-2018 Stanford University and the Authors. * * Authors: Mark Friedrichs, Peter Eastman * * Contributors: * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as published * * by the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * 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 * * GNU Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public License * * along with this program. If not, see . * * -------------------------------------------------------------------------- */ #include "openmm/amoebaKernels.h" #include "openmm/kernels.h" #include "openmm/System.h" #include "CudaArray.h" #include "CudaContext.h" #include "CudaNonbondedUtilities.h" #include "CudaSort.h" #include namespace OpenMM { class CudaCalcAmoebaGeneralizedKirkwoodForceKernel; /** * This kernel is invoked by AmoebaBondForce to calculate the forces acting on the system and the energy of the system. */ class CudaCalcAmoebaBondForceKernel : public CalcAmoebaBondForceKernel { public: CudaCalcAmoebaBondForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system); /** * Initialize the kernel. * * @param system the System this kernel will be applied to * @param force the AmoebaBondForce this kernel will be used for */ void initialize(const System& system, const AmoebaBondForce& force); /** * Execute the kernel to calculate the forces and/or energy. * * @param context the context in which to execute this kernel * @param includeForces true if forces should be calculated * @param includeEnergy true if the energy should be calculated * @return the potential energy due to the force */ double execute(ContextImpl& context, bool includeForces, bool includeEnergy); /** * Copy changed parameters over to a context. * * @param context the context to copy parameters to * @param force the AmoebaBondForce to copy the parameters from */ void copyParametersToContext(ContextImpl& context, const AmoebaBondForce& force); private: class ForceInfo; int numBonds; CudaContext& cu; const System& system; CudaArray params; }; /** * This kernel is invoked by AmoebaAngleForce to calculate the forces acting on the system and the energy of the system. */ class CudaCalcAmoebaAngleForceKernel : public CalcAmoebaAngleForceKernel { public: CudaCalcAmoebaAngleForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system); /** * Initialize the kernel. * * @param system the System this kernel will be applied to * @param force the AmoebaAngleForce this kernel will be used for */ void initialize(const System& system, const AmoebaAngleForce& force); /** * Execute the kernel to calculate the forces and/or energy. * * @param context the context in which to execute this kernel * @param includeForces true if forces should be calculated * @param includeEnergy true if the energy should be calculated * @return the potential energy due to the force */ double execute(ContextImpl& context, bool includeForces, bool includeEnergy); /** * Copy changed parameters over to a context. * * @param context the context to copy parameters to * @param force the AmoebaAngleForce to copy the parameters from */ void copyParametersToContext(ContextImpl& context, const AmoebaAngleForce& force); private: class ForceInfo; int numAngles; CudaContext& cu; const System& system; CudaArray params; }; /** * This kernel is invoked by AmoebaInPlaneAngleForce to calculate the forces acting on the system and the energy of the system. */ class CudaCalcAmoebaInPlaneAngleForceKernel : public CalcAmoebaInPlaneAngleForceKernel { public: CudaCalcAmoebaInPlaneAngleForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system); /** * Initialize the kernel. * * @param system the System this kernel will be applied to * @param force the AmoebaInPlaneAngleForce this kernel will be used for */ void initialize(const System& system, const AmoebaInPlaneAngleForce& force); /** * Execute the kernel to calculate the forces and/or energy. * * @param context the context in which to execute this kernel * @param includeForces true if forces should be calculated * @param includeEnergy true if the energy should be calculated * @return the potential energy due to the force */ double execute(ContextImpl& context, bool includeForces, bool includeEnergy); /** * Copy changed parameters over to a context. * * @param context the context to copy parameters to * @param force the AmoebaInPlaneAngleForce to copy the parameters from */ void copyParametersToContext(ContextImpl& context, const AmoebaInPlaneAngleForce& force); private: class ForceInfo; int numAngles; CudaContext& cu; const System& system; CudaArray params; }; /** * This kernel is invoked by AmoebaPiTorsionForce to calculate the forces acting on the system and the energy of the system. */ class CudaCalcAmoebaPiTorsionForceKernel : public CalcAmoebaPiTorsionForceKernel { public: CudaCalcAmoebaPiTorsionForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system); /** * Initialize the kernel. * * @param system the System this kernel will be applied to * @param force the AmoebaPiTorsionForce this kernel will be used for */ void initialize(const System& system, const AmoebaPiTorsionForce& force); /** * Execute the kernel to calculate the forces and/or energy. * * @param context the context in which to execute this kernel * @param includeForces true if forces should be calculated * @param includeEnergy true if the energy should be calculated * @return the potential energy due to the force */ double execute(ContextImpl& context, bool includeForces, bool includeEnergy); /** * Copy changed parameters over to a context. * * @param context the context to copy parameters to * @param force the AmoebaPiTorsionForce to copy the parameters from */ void copyParametersToContext(ContextImpl& context, const AmoebaPiTorsionForce& force); private: class ForceInfo; int numPiTorsions; CudaContext& cu; const System& system; CudaArray params; }; /** * This kernel is invoked by AmoebaStretchBendForce to calculate the forces acting on the system and the energy of the system. */ class CudaCalcAmoebaStretchBendForceKernel : public CalcAmoebaStretchBendForceKernel { public: CudaCalcAmoebaStretchBendForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system); /** * Initialize the kernel. * * @param system the System this kernel will be applied to * @param force the AmoebaStretchBendForce this kernel will be used for */ void initialize(const System& system, const AmoebaStretchBendForce& force); /** * Execute the kernel to calculate the forces and/or energy. * * @param context the context in which to execute this kernel * @param includeForces true if forces should be calculated * @param includeEnergy true if the energy should be calculated * @return the potential energy due to the force */ double execute(ContextImpl& context, bool includeForces, bool includeEnergy); /** * Copy changed parameters over to a context. * * @param context the context to copy parameters to * @param force the AmoebaStretchBendForce to copy the parameters from */ void copyParametersToContext(ContextImpl& context, const AmoebaStretchBendForce& force); private: class ForceInfo; int numStretchBends; CudaContext& cu; const System& system; CudaArray params1; // Equilibrium values CudaArray params2; // force constants }; /** * This kernel is invoked by AmoebaOutOfPlaneBendForce to calculate the forces acting on the system and the energy of the system. */ class CudaCalcAmoebaOutOfPlaneBendForceKernel : public CalcAmoebaOutOfPlaneBendForceKernel { public: CudaCalcAmoebaOutOfPlaneBendForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system); /** * Initialize the kernel. * * @param system the System this kernel will be applied to * @param force the AmoebaOutOfPlaneBendForce this kernel will be used for */ void initialize(const System& system, const AmoebaOutOfPlaneBendForce& force); /** * Execute the kernel to calculate the forces and/or energy. * * @param context the context in which to execute this kernel * @param includeForces true if forces should be calculated * @param includeEnergy true if the energy should be calculated * @return the potential energy due to the force */ double execute(ContextImpl& context, bool includeForces, bool includeEnergy); /** * Copy changed parameters over to a context. * * @param context the context to copy parameters to * @param force the AmoebaOutOfPlaneBendForce to copy the parameters from */ void copyParametersToContext(ContextImpl& context, const AmoebaOutOfPlaneBendForce& force); private: class ForceInfo; int numOutOfPlaneBends; CudaContext& cu; const System& system; CudaArray params; }; /** * This kernel is invoked by AmoebaTorsionTorsionForce to calculate the forces acting on the system and the energy of the system. */ class CudaCalcAmoebaTorsionTorsionForceKernel : public CalcAmoebaTorsionTorsionForceKernel { public: CudaCalcAmoebaTorsionTorsionForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system); /** * Initialize the kernel. * * @param system the System this kernel will be applied to * @param force the AmoebaTorsionTorsionForce this kernel will be used for */ void initialize(const System& system, const AmoebaTorsionTorsionForce& force); /** * Execute the kernel to calculate the forces and/or energy. * * @param context the context in which to execute this kernel * @param includeForces true if forces should be calculated * @param includeEnergy true if the energy should be calculated * @return the potential energy due to the force */ double execute(ContextImpl& context, bool includeForces, bool includeEnergy); private: class ForceInfo; int numTorsionTorsions; int numTorsionTorsionGrids; CudaContext& cu; const System& system; CudaArray gridValues; CudaArray gridParams; CudaArray torsionParams; }; /** * This kernel is invoked by AmoebaMultipoleForce to calculate the forces acting on the system and the energy of the system. */ class CudaCalcAmoebaMultipoleForceKernel : public CalcAmoebaMultipoleForceKernel { public: CudaCalcAmoebaMultipoleForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system); ~CudaCalcAmoebaMultipoleForceKernel(); /** * Initialize the kernel. * * @param system the System this kernel will be applied to * @param force the AmoebaMultipoleForce this kernel will be used for */ void initialize(const System& system, const AmoebaMultipoleForce& force); /** * Execute the kernel to calculate the forces and/or energy. * * @param context the context in which to execute this kernel * @param includeForces true if forces should be calculated * @param includeEnergy true if the energy should be calculated * @return the potential energy due to the force */ double execute(ContextImpl& context, bool includeForces, bool includeEnergy); /** * Get the LabFrame dipole moments of all particles. * * @param context the Context for which to get the induced dipoles * @param dipoles the induced dipole moment of particle i is stored into the i'th element */ void getLabFramePermanentDipoles(ContextImpl& context, std::vector& dipoles); /** * Get the induced dipole moments of all particles. * * @param context the Context for which to get the induced dipoles * @param dipoles the induced dipole moment of particle i is stored into the i'th element */ void getInducedDipoles(ContextImpl& context, std::vector& dipoles); /** * Get the total dipole moments of all particles. * * @param context the Context for which to get the induced dipoles * @param dipoles the induced dipole moment of particle i is stored into the i'th element */ void getTotalDipoles(ContextImpl& context, std::vector& dipoles); /** * Execute the kernel to calculate the electrostatic potential * * @param context the context in which to execute this kernel * @param inputGrid input grid coordinates * @param outputElectrostaticPotential output potential */ void getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid, std::vector< double >& outputElectrostaticPotential); /** * Get the system multipole moments * * @param context context * @param outputMultipoleMoments (charge, * dipole_x, dipole_y, dipole_z, * quadrupole_xx, quadrupole_xy, quadrupole_xz, * quadrupole_yx, quadrupole_yy, quadrupole_yz, * quadrupole_zx, quadrupole_zy, quadrupole_zz) */ void getSystemMultipoleMoments(ContextImpl& context, std::vector& outputMultipoleMoments); /** * Copy changed parameters over to a context. * * @param context the context to copy parameters to * @param force the AmoebaMultipoleForce to copy the parameters from */ void copyParametersToContext(ContextImpl& context, const AmoebaMultipoleForce& force); /** * Get the parameters being used for PME. * * @param alpha the separation parameter * @param nx the number of grid points along the X axis * @param ny the number of grid points along the Y axis * @param nz the number of grid points along the Z axis */ void getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const; private: class ForceInfo; void initializeScaleFactors(); void computeInducedField(void** recipBoxVectorPointer); bool iterateDipolesByDIIS(int iteration); void computeExtrapolatedDipoles(void** recipBoxVectorPointer); void ensureMultipolesValid(ContextImpl& context); template void computeSystemMultipoleMoments(ContextImpl& context, std::vector& outputMultipoleMoments); int numMultipoles, maxInducedIterations, maxExtrapolationOrder; int fixedFieldThreads, inducedFieldThreads, electrostaticsThreads; int gridSizeX, gridSizeY, gridSizeZ; double alpha, inducedEpsilon; bool usePME, hasQuadrupoles, hasInitializedScaleFactors, hasInitializedFFT, multipolesAreValid, hasCreatedEvent; AmoebaMultipoleForce::PolarizationType polarizationType; CudaContext& cu; const System& system; std::vector covalentFlagValues; std::vector polarizationFlagValues; CudaArray multipoleParticles; CudaArray molecularDipoles; CudaArray molecularQuadrupoles; CudaArray labFrameDipoles; CudaArray labFrameQuadrupoles; CudaArray sphericalDipoles; CudaArray sphericalQuadrupoles; CudaArray fracDipoles; CudaArray fracQuadrupoles; CudaArray field; CudaArray fieldPolar; CudaArray inducedField; CudaArray inducedFieldPolar; CudaArray torque; CudaArray dampingAndThole; CudaArray inducedDipole; CudaArray inducedDipolePolar; CudaArray inducedDipoleErrors; CudaArray prevDipoles; CudaArray prevDipolesPolar; CudaArray prevDipolesGk; CudaArray prevDipolesGkPolar; CudaArray prevErrors; CudaArray diisMatrix; CudaArray diisCoefficients; CudaArray extrapolatedDipole; CudaArray extrapolatedDipolePolar; CudaArray extrapolatedDipoleGk; CudaArray extrapolatedDipoleGkPolar; CudaArray inducedDipoleFieldGradient; CudaArray inducedDipoleFieldGradientPolar; CudaArray inducedDipoleFieldGradientGk; CudaArray inducedDipoleFieldGradientGkPolar; CudaArray extrapolatedDipoleFieldGradient; CudaArray extrapolatedDipoleFieldGradientPolar; CudaArray extrapolatedDipoleFieldGradientGk; CudaArray extrapolatedDipoleFieldGradientGkPolar; CudaArray polarizability; CudaArray covalentFlags; CudaArray polarizationGroupFlags; CudaArray pmeGrid; CudaArray pmeBsplineModuliX; CudaArray pmeBsplineModuliY; CudaArray pmeBsplineModuliZ; CudaArray pmePhi; CudaArray pmePhid; CudaArray pmePhip; CudaArray pmePhidp; CudaArray pmeCphi; CudaArray lastPositions; cufftHandle fft; CUfunction computeMomentsKernel, recordInducedDipolesKernel, computeFixedFieldKernel, computeInducedFieldKernel, updateInducedFieldKernel, electrostaticsKernel, mapTorqueKernel; CUfunction pmeSpreadFixedMultipolesKernel, pmeSpreadInducedDipolesKernel, pmeFinishSpreadChargeKernel, pmeConvolutionKernel; CUfunction pmeFixedPotentialKernel, pmeInducedPotentialKernel, pmeFixedForceKernel, pmeInducedForceKernel, pmeRecordInducedFieldDipolesKernel, computePotentialKernel; CUfunction recordDIISDipolesKernel, buildMatrixKernel, solveMatrixKernel; CUfunction initExtrapolatedKernel, iterateExtrapolatedKernel, computeExtrapolatedKernel, addExtrapolatedGradientKernel; CUfunction pmeTransformMultipolesKernel, pmeTransformPotentialKernel; CUevent syncEvent; CudaCalcAmoebaGeneralizedKirkwoodForceKernel* gkKernel; static const int PmeOrder = 5; static const int MaxPrevDIISDipoles = 20; }; /** * This kernel is invoked by AmoebaMultipoleForce to calculate the forces acting on the system and the energy of the system. */ class CudaCalcAmoebaGeneralizedKirkwoodForceKernel : public CalcAmoebaGeneralizedKirkwoodForceKernel { public: CudaCalcAmoebaGeneralizedKirkwoodForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system); /** * Initialize the kernel. * * @param system the System this kernel will be applied to * @param force the AmoebaMultipoleForce this kernel will be used for */ void initialize(const System& system, const AmoebaGeneralizedKirkwoodForce& force); /** * Execute the kernel to calculate the forces and/or energy. * * @param context the context in which to execute this kernel * @param includeForces true if forces should be calculated * @param includeEnergy true if the energy should be calculated * @return the potential energy due to the force */ double execute(ContextImpl& context, bool includeForces, bool includeEnergy); /** * Perform the computation of Born radii. */ void computeBornRadii(); /** * Perform the final parts of the force/energy computation. */ void finishComputation(CudaArray& torque, CudaArray& labFrameDipoles, CudaArray& labFrameQuadrupoles, CudaArray& inducedDipole, CudaArray& inducedDipolePolar, CudaArray& dampingAndThole, CudaArray& covalentFlags, CudaArray& polarizationGroupFlags); CudaArray& getBornRadii() { return bornRadii; } CudaArray& getField() { return field; } CudaArray& getInducedField() { return inducedField; } CudaArray& getInducedFieldPolar() { return inducedFieldPolar; } CudaArray& getInducedDipoles() { return inducedDipoleS; } CudaArray& getInducedDipolesPolar() { return inducedDipolePolarS; } /** * Copy changed parameters over to a context. * * @param context the context to copy parameters to * @param force the AmoebaGeneralizedKirkwoodForce to copy the parameters from */ void copyParametersToContext(ContextImpl& context, const AmoebaGeneralizedKirkwoodForce& force); private: class ForceInfo; CudaContext& cu; const System& system; bool includeSurfaceArea, hasInitializedKernels; int computeBornSumThreads, gkForceThreads, chainRuleThreads, ediffThreads; AmoebaMultipoleForce::PolarizationType polarizationType; std::map defines; CudaArray params; CudaArray bornSum; CudaArray bornRadii; CudaArray bornForce; CudaArray field; CudaArray inducedField; CudaArray inducedFieldPolar; CudaArray inducedDipoleS; CudaArray inducedDipolePolarS; CUfunction computeBornSumKernel, reduceBornSumKernel, surfaceAreaKernel, gkForceKernel, chainRuleKernel, ediffKernel; }; /** * This kernel is invoked to calculate the vdw forces acting on the system and the energy of the system. */ class CudaCalcAmoebaVdwForceKernel : public CalcAmoebaVdwForceKernel { public: CudaCalcAmoebaVdwForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system); ~CudaCalcAmoebaVdwForceKernel(); /** * Initialize the kernel. * * @param system the System this kernel will be applied to * @param force the AmoebaVdwForce this kernel will be used for */ void initialize(const System& system, const AmoebaVdwForce& force); /** * Execute the kernel to calculate the forces and/or energy. * * @param context the context in which to execute this kernel * @param includeForces true if forces should be calculated * @param includeEnergy true if the energy should be calculated * @return the potential energy due to the force */ double execute(ContextImpl& context, bool includeForces, bool includeEnergy); /** * Copy changed parameters over to a context. * * @param context the context to copy parameters to * @param force the AmoebaVdwForce to copy the parameters from */ void copyParametersToContext(ContextImpl& context, const AmoebaVdwForce& force); private: class ForceInfo; CudaContext& cu; const System& system; bool hasInitializedNonbonded; double dispersionCoefficient; CudaArray sigmaEpsilon; CudaArray bondReductionAtoms; CudaArray bondReductionFactors; CudaArray isAlchemical; CudaArray vdwLambda; CudaArray tempPosq; CudaArray tempForces; CudaNonbondedUtilities* nonbonded; CUfunction prepareKernel, spreadKernel; }; /** * This kernel is invoked to calculate the WCA dispersion forces acting on the system and the energy of the system. */ class CudaCalcAmoebaWcaDispersionForceKernel : public CalcAmoebaWcaDispersionForceKernel { public: CudaCalcAmoebaWcaDispersionForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system); /** * Initialize the kernel. * * @param system the System this kernel will be applied to * @param force the AmoebaMultipoleForce this kernel will be used for */ void initialize(const System& system, const AmoebaWcaDispersionForce& force); /** * Execute the kernel to calculate the forces and/or energy. * * @param context the context in which to execute this kernel * @param includeForces true if forces should be calculated * @param includeEnergy true if the energy should be calculated * @return the potential energy due to the force */ double execute(ContextImpl& context, bool includeForces, bool includeEnergy); /** * Copy changed parameters over to a context. * * @param context the context to copy parameters to * @param force the AmoebaWcaDispersionForce to copy the parameters from */ void copyParametersToContext(ContextImpl& context, const AmoebaWcaDispersionForce& force); private: class ForceInfo; CudaContext& cu; const System& system; double totalMaximumDispersionEnergy; CudaArray radiusEpsilon; CUfunction forceKernel; }; /** * This kernel is invoked by HippoNonbondedForce to calculate the forces acting on the system and the energy of the system. */ class CudaCalcHippoNonbondedForceKernel : public CalcHippoNonbondedForceKernel { public: CudaCalcHippoNonbondedForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system); ~CudaCalcHippoNonbondedForceKernel(); /** * Initialize the kernel. * * @param system the System this kernel will be applied to * @param force the HippoNonbondedForce this kernel will be used for */ void initialize(const System& system, const HippoNonbondedForce& force); /** * Execute the kernel to calculate the forces and/or energy. * * @param context the context in which to execute this kernel * @param includeForces true if forces should be calculated * @param includeEnergy true if the energy should be calculated * @return the potential energy due to the force */ double execute(ContextImpl& context, bool includeForces, bool includeEnergy); /** * Get the induced dipole moments of all particles. * * @param context the Context for which to get the induced dipoles * @param dipoles the induced dipole moment of particle i is stored into the i'th element */ void getInducedDipoles(ContextImpl& context, std::vector& dipoles); /** * Get the fixed dipole moments of all particles in the global reference frame. * * @param context the Context for which to get the fixed dipoles * @param dipoles the fixed dipole moment of particle i is stored into the i'th element */ void getLabFramePermanentDipoles(ContextImpl& context, std::vector& dipoles); /** * Calculate the electrostatic potential given vector of grid coordinates. * * @param context context * @param inputGrid input grid coordinates * @param outputElectrostaticPotential output potential */ void getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid, std::vector< double >& outputElectrostaticPotential); /** * Copy changed parameters over to a context. * * @param context the context to copy parameters to * @param force the HippoNonbondedForce to copy the parameters from */ void copyParametersToContext(ContextImpl& context, const HippoNonbondedForce& force); /** * Get the parameters being used for PME. * * @param alpha the separation parameter * @param nx the number of grid points along the X axis * @param ny the number of grid points along the Y axis * @param nz the number of grid points along the Z axis */ void getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const; /** * Get the parameters being used for dispersion PME. * * @param alpha the separation parameter * @param nx the number of grid points along the X axis * @param ny the number of grid points along the Y axis * @param nz the number of grid points along the Z axis */ void getDPMEParameters(double& alpha, int& nx, int& ny, int& nz) const; private: class ForceInfo; class TorquePostComputation; class SortTrait : public CudaSort::SortTrait { int getDataSize() const {return 8;} int getKeySize() const {return 4;} const char* getDataType() const {return "int2";} const char* getKeyType() const {return "int";} const char* getMinKey() const {return "(-2147483647-1)";} const char* getMaxKey() const {return "2147483647";} const char* getMaxValue() const {return "make_int2(2147483647, 2147483647)";} const char* getSortKey() const {return "value.y";} }; void computeInducedField(void** recipBoxVectorPointer, int optOrder); void computeExtrapolatedDipoles(void** recipBoxVectorPointer); void ensureMultipolesValid(ContextImpl& context); void addTorquesToForces(); void createFieldKernel(const std::string& interactionSrc, std::vector params, CudaArray& fieldBuffer, CUfunction& kernel, std::vector& args, CUfunction& exceptionKernel, std::vector& exceptionArgs, CudaArray& exceptionScale); int numParticles, maxExtrapolationOrder, maxTiles; int gridSizeX, gridSizeY, gridSizeZ; int dispersionGridSizeX, dispersionGridSizeY, dispersionGridSizeZ; double pmeAlpha, dpmeAlpha, cutoff; bool usePME, hasInitializedKernels, hasInitializedFFT, multipolesAreValid; std::vector extrapolationCoefficients; CudaContext& cu; const System& system; CudaArray multipoleParticles; CudaArray coreCharge, valenceCharge, alpha, epsilon, damping, c6, pauliK, pauliQ, pauliAlpha, polarizability; CudaArray localDipoles, labDipoles, fracDipoles; CudaArray localQuadrupoles, labQuadrupoles[5], fracQuadrupoles; CudaArray field; CudaArray inducedField; CudaArray torque; CudaArray inducedDipole; CudaArray extrapolatedDipole, extrapolatedPhi; CudaArray pmeGrid1, pmeGrid2; CudaArray pmeAtomGridIndex; CudaArray pmeBsplineModuliX, pmeBsplineModuliY, pmeBsplineModuliZ; CudaArray dpmeBsplineModuliX, dpmeBsplineModuliY, dpmeBsplineModuliZ; CudaArray pmePhi, pmePhidp, pmeCphi; CudaArray lastPositions; CudaArray exceptionScales[6]; CudaArray exceptionAtoms; CudaSort* sort; cufftHandle fftForward, fftBackward, dfftForward, dfftBackward; CUfunction computeMomentsKernel, fixedFieldKernel, fixedFieldExceptionKernel, mutualFieldKernel, mutualFieldExceptionKernel, computeExceptionsKernel; CUfunction recordInducedDipolesKernel, mapTorqueKernel; CUfunction pmeSpreadFixedMultipolesKernel, pmeSpreadInducedDipolesKernel, pmeFinishSpreadChargeKernel, pmeConvolutionKernel; CUfunction pmeFixedPotentialKernel, pmeInducedPotentialKernel, pmeFixedForceKernel, pmeInducedForceKernel, pmeRecordInducedFieldDipolesKernel; CUfunction pmeSelfEnergyKernel; CUfunction dpmeGridIndexKernel, dpmeSpreadChargeKernel, dpmeFinishSpreadChargeKernel, dpmeEvalEnergyKernel, dpmeConvolutionKernel, dpmeInterpolateForceKernel; CUfunction initExtrapolatedKernel, iterateExtrapolatedKernel, computeExtrapolatedKernel, polarizationEnergyKernel; CUfunction pmeTransformMultipolesKernel, pmeTransformPotentialKernel; std::vector fixedFieldArgs, fixedFieldExceptionArgs, mutualFieldArgs, mutualFieldExceptionArgs, computeExceptionsArgs; static const int PmeOrder = 5; }; } // namespace OpenMM #endif /*AMOEBA_OPENMM_CUDAKERNELS_H*/