#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-2012 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 "CudaSort.h"
#include
namespace OpenMM {
/**
* This kernel is invoked by AmoebaHarmonicBondForce to calculate the forces acting on the system and the energy of the system.
*/
class CudaCalcAmoebaHarmonicBondForceKernel : public CalcAmoebaHarmonicBondForceKernel {
public:
CudaCalcAmoebaHarmonicBondForceKernel(std::string name,
const Platform& platform,
CudaContext& cu,
System& system);
~CudaCalcAmoebaHarmonicBondForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the AmoebaHarmonicBondForce this kernel will be used for
*/
void initialize(const System& system, const AmoebaHarmonicBondForce& 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 numBonds;
CudaContext& cu;
System& system;
CudaArray* params;
};
/**
* This kernel is invoked by AmoebaUreyBradleyForce to calculate the forces acting on the system and the energy of the system.
*/
class CudaCalcAmoebaUreyBradleyForceKernel : public CalcAmoebaUreyBradleyForceKernel {
public:
CudaCalcAmoebaUreyBradleyForceKernel(std::string name,
const Platform& platform,
CudaContext& cu,
System& system);
~CudaCalcAmoebaUreyBradleyForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the AmoebaUreyBradleyForce this kernel will be used for
*/
void initialize(const System& system, const AmoebaUreyBradleyForce& 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 numInteractions;
CudaContext& cu;
System& system;
};
/**
* This kernel is invoked by AmoebaHarmonicAngleForce to calculate the forces acting on the system and the energy of the system.
*/
class CudaCalcAmoebaHarmonicAngleForceKernel : public CalcAmoebaHarmonicAngleForceKernel {
public:
CudaCalcAmoebaHarmonicAngleForceKernel(std::string name, const Platform& platform, CudaContext& cu, System& system);
~CudaCalcAmoebaHarmonicAngleForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the AmoebaHarmonicAngleForce this kernel will be used for
*/
void initialize(const System& system, const AmoebaHarmonicAngleForce& 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 numAngles;
CudaContext& cu;
System& system;
CudaArray* params;
};
/**
* This kernel is invoked by AmoebaHarmonicInPlaneAngleForce to calculate the forces acting on the system and the energy of the system.
*/
class CudaCalcAmoebaHarmonicInPlaneAngleForceKernel : public CalcAmoebaHarmonicInPlaneAngleForceKernel {
public:
CudaCalcAmoebaHarmonicInPlaneAngleForceKernel(std::string name, const Platform& platform, CudaContext& cu, System& system);
~CudaCalcAmoebaHarmonicInPlaneAngleForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the AmoebaHarmonicInPlaneAngleForce this kernel will be used for
*/
void initialize(const System& system, const AmoebaHarmonicInPlaneAngleForce& 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 numAngles;
CudaContext& cu;
System& system;
CudaArray* params;
};
/**
* This kernel is invoked by AmoebaTorsionForce to calculate the forces acting on the system and the energy of the system.
*/
class CudaCalcAmoebaTorsionForceKernel : public CalcAmoebaTorsionForceKernel {
public:
CudaCalcAmoebaTorsionForceKernel(std::string name, const Platform& platform, CudaContext& cu, System& system);
~CudaCalcAmoebaTorsionForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the AmoebaTorsionForce this kernel will be used for
*/
void initialize(const System& system, const AmoebaTorsionForce& 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 numTorsions;
CudaContext& cu;
System& system;
};
/**
* 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, System& system);
~CudaCalcAmoebaPiTorsionForceKernel();
/**
* 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);
private:
class ForceInfo;
int numPiTorsions;
CudaContext& cu;
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, System& system);
~CudaCalcAmoebaStretchBendForceKernel();
/**
* 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);
private:
class ForceInfo;
int numStretchBends;
CudaContext& cu;
System& system;
CudaArray* params;
};
/**
* 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, System& system);
~CudaCalcAmoebaOutOfPlaneBendForceKernel();
/**
* 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);
private:
class ForceInfo;
int numOutOfPlaneBends;
CudaContext& cu;
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, System& system);
~CudaCalcAmoebaTorsionTorsionForceKernel();
/**
* 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;
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, 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);
/**
* 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 origin origin
* @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, const Vec3& origin, std::vector& outputMultipoleMoments);
private:
class ForceInfo;
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 "INT_MIN";}
const char* getMaxKey() const {return "INT_MAX";}
const char* getMaxValue() const {return "make_int2(INT_MAX, INT_MAX)";}
const char* getSortKey() const {return "value.y";}
};
void initializeScaleFactors();
template void computeSystemMultipoleMoments(ContextImpl& context, const Vec3& origin, std::vector& outputMultipoleMoments);
int numMultipoles, maxInducedIterations;
double inducedEpsilon;
bool hasInitializedScaleFactors, hasInitializedFFT;
CudaContext& cu;
System& system;
std::vector covalentFlagValues;
std::vector polarizationFlagValues;
CudaArray* multipoleParticles;
CudaArray* molecularDipoles;
CudaArray* molecularQuadrupoles;
CudaArray* labFrameDipoles;
CudaArray* labFrameQuadrupoles;
CudaArray* field;
CudaArray* fieldPolar;
CudaArray* inducedField;
CudaArray* inducedFieldPolar;
CudaArray* torque;
CudaArray* dampingAndThole;
CudaArray* inducedDipole;
CudaArray* inducedDipolePolar;
CudaArray* inducedDipoleErrors;
CudaArray* polarizability;
CudaArray* covalentFlags;
CudaArray* polarizationGroupFlags;
CudaArray* pmeGrid;
CudaArray* pmeBsplineModuliX;
CudaArray* pmeBsplineModuliY;
CudaArray* pmeBsplineModuliZ;
CudaArray* pmeTheta1;
CudaArray* pmeTheta2;
CudaArray* pmeTheta3;
CudaArray* pmeIgrid;
CudaArray* pmePhi;
CudaArray* pmePhid;
CudaArray* pmePhip;
CudaArray* pmePhidp;
CudaArray* pmeAtomRange;
CudaArray* pmeAtomGridIndex;
CudaSort* sort;
cufftHandle fft;
CUfunction computeMomentsKernel, recordInducedDipolesKernel, computeFixedFieldKernel, computeInducedFieldKernel, updateInducedFieldKernel, electrostaticsKernel, mapTorqueKernel;
CUfunction pmeUpdateBsplinesKernel, pmeAtomRangeKernel, pmeZIndexKernel, pmeSpreadFixedMultipolesKernel, pmeSpreadInducedDipolesKernel, pmeConvolutionKernel, pmeFixedPotentialKernel, pmeInducedPotentialKernel;
CUfunction pmeFixedForceKernel, pmeInducedForceKernel, pmeRecordInducedFieldDipolesKernel, computePotentialKernel;
static const int PmeOrder = 5;
};
/**
* 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, System& system);
~CudaCalcAmoebaGeneralizedKirkwoodForceKernel();
/**
* 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);
private:
class ForceInfo;
CudaContext& cu;
System& system;
};
/**
* 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, System& system);
~CudaCalcAmoebaVdwForceKernel();
/**
* 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 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);
private:
class ForceInfo;
CudaContext& cu;
System& system;
bool hasInitializedNonbonded;
double dispersionCoefficient;
CudaArray* sigmaEpsilon;
CudaArray* bondReductionAtoms;
CudaArray* bondReductionFactors;
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, System& system);
~CudaCalcAmoebaWcaDispersionForceKernel();
/**
* 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);
private:
class ForceInfo;
CudaContext& cu;
System& system;
};
} // namespace OpenMM
#endif /*AMOEBA_OPENMM_CUDAKERNELS_H*/