Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
tsoc
openmm
Commits
74912095
"platforms/cuda/vscode:/vscode.git/clone" did not exist on "bda67c677a30e66f433ea48ae69bbc377c25fa2e"
Unverified
Commit
74912095
authored
Nov 11, 2025
by
Peter Eastman
Committed by
GitHub
Nov 11, 2025
Browse files
Refactor reference PME (#5131)
parent
c24c619e
Changes
9
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
413 additions
and
766 deletions
+413
-766
platforms/cpu/src/CpuNonbondedForce.cpp
platforms/cpu/src/CpuNonbondedForce.cpp
+5
-9
platforms/reference/include/ReferenceConstantPotential.h
platforms/reference/include/ReferenceConstantPotential.h
+10
-10
platforms/reference/include/ReferencePME.h
platforms/reference/include/ReferencePME.h
+101
-85
platforms/reference/src/SimTKReference/ReferenceConstantPotential.cpp
...ference/src/SimTKReference/ReferenceConstantPotential.cpp
+21
-35
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
...ms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
+4
-9
platforms/reference/src/SimTKReference/ReferencePME.cpp
platforms/reference/src/SimTKReference/ReferencePME.cpp
+261
-600
platforms/reference/tests/TestReferenceEwald.cpp
platforms/reference/tests/TestReferenceEwald.cpp
+7
-10
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceHippoNonbondedForce.cpp
...src/SimTKReference/AmoebaReferenceHippoNonbondedForce.cpp
+2
-4
plugins/cpupme/tests/TestCpuPme.cpp
plugins/cpupme/tests/TestCpuPme.cpp
+2
-4
No files found.
platforms/cpu/src/CpuNonbondedForce.cpp
View file @
74912095
...
...
@@ -255,28 +255,26 @@ void CpuNonbondedForce::calculateReciprocalIxn(int numberOfAtoms, float* posq, c
float
recipCoeff
=
(
float
)(
ONE_4PI_EPS0
*
4
*
PI_M
/
(
periodicBoxVectors
[
0
][
0
]
*
periodicBoxVectors
[
1
][
1
]
*
periodicBoxVectors
[
2
][
2
])
/
epsilon
);
if
(
pme
)
{
pme_t
pmedata
;
pme_init
(
&
pmedata
,
alphaEwald
,
numberOfAtoms
,
meshDim
,
5
,
1
);
ReferencePME
pme
(
alphaEwald
,
numberOfAtoms
,
meshDim
,
5
,
1
);
vector
<
double
>
charges
(
numberOfAtoms
);
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
)
charges
[
i
]
=
posq
[
4
*
i
+
3
];
double
recipEnergy
=
0.0
;
pme
_
exec
(
pmedata
,
atomCoordinates
,
forces
,
charges
,
periodicBoxVectors
,
&
recipEnergy
);
pme
.
exec
(
atomCoordinates
,
forces
,
charges
,
periodicBoxVectors
,
recipEnergy
);
if
(
totalEnergy
)
*
totalEnergy
+=
recipEnergy
;
pme_destroy
(
pmedata
);
if
(
ljpme
)
{
// Dispersion reciprocal space terms
pme_init
(
&
pmedata
,
alphaDispersionEwald
,
numberOfAtoms
,
dispersionMeshDim
,
5
,
1
);
ReferencePME
ljpme
(
alphaDispersionEwald
,
numberOfAtoms
,
dispersionMeshDim
,
5
,
1
);
std
::
vector
<
Vec3
>
dpmeforces
;
vector
<
Vec3
>
dpmeforces
;
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
){
charges
[
i
]
=
C6params
[
i
];
dpmeforces
.
push_back
(
Vec3
());
}
double
recipDispersionEnergy
=
0.0
;
pme
_
exec_dpme
(
pmedata
,
atomCoordinates
,
dpmeforces
,
charges
,
periodicBoxVectors
,
&
recipDispersionEnergy
);
lj
pme
.
exec_dpme
(
atomCoordinates
,
dpmeforces
,
charges
,
periodicBoxVectors
,
recipDispersionEnergy
);
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
){
forces
[
i
][
0
]
+=
dpmeforces
[
i
][
0
];
forces
[
i
][
1
]
+=
dpmeforces
[
i
][
1
];
...
...
@@ -284,8 +282,6 @@ void CpuNonbondedForce::calculateReciprocalIxn(int numberOfAtoms, float* posq, c
}
if
(
totalEnergy
)
*
totalEnergy
+=
recipDispersionEnergy
;
pme_destroy
(
pmedata
);
}
}
...
...
platforms/reference/include/ReferenceConstantPotential.h
View file @
74912095
...
...
@@ -90,14 +90,14 @@ public:
* @param elecToSys mapping from electrode particle indices to system particle indices
* @param electrodeParamArray electrode particle parameters
* @param conp constant potential derivative evaluation class
* @param pme
Data
reference PME solver
* @param pme
reference PME solver
*/
virtual
void
solve
(
int
numParticles
,
int
numElectrodeParticles
,
const
std
::
vector
<
Vec3
>&
posData
,
std
::
vector
<
double
>&
charges
,
const
std
::
vector
<
std
::
set
<
int
>>&
exclusions
,
const
std
::
vector
<
int
>&
sysToElec
,
const
std
::
vector
<
int
>&
elecToSys
,
const
std
::
vector
<
std
::
array
<
double
,
3
>
>&
electrodeParamArray
,
ReferenceConstantPotential
&
conp
,
pme_t
pmeData
)
=
0
;
ReferenceConstantPotential
&
conp
,
ReferencePME
&
pme
)
=
0
;
};
/**
...
...
@@ -149,14 +149,14 @@ public:
* @param elecToSys mapping from electrode particle indices to system particle indices
* @param electrodeParamArray electrode particle parameters
* @param conp constant potential derivative evaluation class
* @param pme
Data
reference PME solver
* @param pme
reference PME solver
*/
void
solve
(
int
numParticles
,
int
numElectrodeParticles
,
const
std
::
vector
<
Vec3
>&
posData
,
std
::
vector
<
double
>&
charges
,
const
std
::
vector
<
std
::
set
<
int
>>&
exclusions
,
const
std
::
vector
<
int
>&
sysToElec
,
const
std
::
vector
<
int
>&
elecToSys
,
const
std
::
vector
<
std
::
array
<
double
,
3
>
>&
electrodeParamArray
,
ReferenceConstantPotential
&
conp
,
pme_t
pmeData
);
ReferenceConstantPotential
&
conp
,
ReferencePME
&
pme
);
};
/**
...
...
@@ -208,14 +208,14 @@ public:
* @param elecToSys mapping from electrode particle indices to system particle indices
* @param electrodeParamArray electrode particle parameters
* @param conp constant potential derivative evaluation class
* @param pme
Data
reference PME solver
* @param pme
reference PME solver
*/
void
solve
(
int
numParticles
,
int
numElectrodeParticles
,
const
std
::
vector
<
Vec3
>&
posData
,
std
::
vector
<
double
>&
charges
,
const
std
::
vector
<
std
::
set
<
int
>>&
exclusions
,
const
std
::
vector
<
int
>&
sysToElec
,
const
std
::
vector
<
int
>&
elecToSys
,
const
std
::
vector
<
std
::
array
<
double
,
3
>
>&
electrodeParamArray
,
ReferenceConstantPotential
&
conp
,
pme_t
pmeData
);
ReferenceConstantPotential
&
conp
,
ReferencePME
&
pme
);
};
/**
...
...
@@ -313,7 +313,7 @@ private:
* @param elecToSys mapping from electrode particle indices to system particle indices
* @param electrodeParamArray electrode particle parameters
* @param energy output system energy
* @param pme
Data
reference PME solver
* @param pme
reference PME solver
*/
void
getEnergyForces
(
int
numParticles
,
int
numElectrodeParticles
,
const
std
::
vector
<
Vec3
>&
posData
,
std
::
vector
<
Vec3
>&
forceData
,
...
...
@@ -321,7 +321,7 @@ private:
const
std
::
vector
<
std
::
set
<
int
>>&
exclusions
,
const
std
::
vector
<
int
>&
sysToElec
,
const
std
::
vector
<
int
>&
elecToSys
,
const
std
::
vector
<
std
::
array
<
double
,
3
>
>&
electrodeParamArray
,
double
*
energy
,
pme_t
pmeData
);
double
*
energy
,
ReferencePME
&
pme
);
/**
* Computes energy derivatives with respect to charges.
*
...
...
@@ -334,14 +334,14 @@ private:
* @param elecToSys mapping from electrode particle indices to system particle indices
* @param electrodeParamArray electrode particle parameters
* @param chargeDerivatives output charge derivatives
* @param pme
Data
reference PME solver
* @param pme
reference PME solver
*/
void
getDerivatives
(
int
numParticles
,
int
numElectrodeParticles
,
const
std
::
vector
<
Vec3
>&
posData
,
std
::
vector
<
double
>&
charges
,
const
std
::
vector
<
std
::
set
<
int
>>&
exclusions
,
const
std
::
vector
<
int
>&
sysToElec
,
const
std
::
vector
<
int
>&
elecToSys
,
const
std
::
vector
<
std
::
array
<
double
,
3
>
>&
electrodeParamArray
,
std
::
vector
<
double
>&
chargeDerivatives
,
pme_t
pmeData
);
std
::
vector
<
double
>&
chargeDerivatives
,
ReferencePME
&
pme
);
};
}
// namespace OpenMM
...
...
platforms/reference/include/ReferencePME.h
View file @
74912095
/*
* Reference implementation of PME reciprocal space interactions.
*
* Copyright (c) 2009
,
Erik Lindahl, Rossen Apostolov, Szilard Pall
* Copyright (c) 2009
-2025
Erik Lindahl, Rossen Apostolov, Szilard Pall
, Peter Eastman
* All rights reserved.
* Contact: lindahl@cbr.su.se Stockholm University, Sweden.
*
...
...
@@ -34,22 +34,19 @@
#include "openmm/Vec3.h"
#include "openmm/internal/windowsExport.h"
#include <array>
#include <complex>
#include <vector>
namespace
OpenMM
{
typedef
double
rvec
[
3
];
typedef
struct
pme
*
pme_t
;
/*
class
OPENMM_EXPORT
ReferencePME
{
public:
/*
* Initialize a PME calculation and set up data structures
*
* Arguments:
*
* ppme Pointer to an opaque pme_t object
* ewaldcoeff Coefficient derived from the beta factor to participate
* direct/reciprocal space. See gromacs code for documentation!
* We assume that you are using nm units...
...
...
@@ -58,77 +55,96 @@ pme_t;
* pme_order Interpolation order, almost always 4
* epsilon_r Dielectric coefficient, typically 1.0.
*/
int
OPENMM_EXPORT
pme_init
(
pme_t
*
ppme
,
double
ewaldcoeff
,
int
natoms
,
const
int
ngrid
[
3
],
int
pme_order
,
double
epsilon_r
);
ReferencePME
(
double
ewaldcoeff
,
int
natoms
,
const
int
ngrid
[
3
],
int
pme_order
,
double
epsilon_r
);
/*
/*
* Evaluate reciprocal space PME energy and forces.
*
* Args:
*
* pme Opaque pme_t object, must have been initialized with pme_init()
* atomCoordinates Pointer to coordinate data array (nm)
* forces Pointer to force data array (will be written as kJ/mol/nm)
* charges Array of charges (units of e)
* periodicBoxVectors Simulation cell dimensions (nm)
* energy Total energy (will be written in units of kJ/mol)
*/
int
OPENMM_EXPORT
pme_exec
(
pme_t
pme
,
const
std
::
vector
<
OpenMM
::
Vec3
>&
atomCoordinates
,
std
::
vector
<
OpenMM
::
Vec3
>&
forces
,
const
std
::
vector
<
double
>&
charges
,
const
OpenMM
::
Vec3
periodicBoxVectors
[
3
],
double
*
energy
);
void
exec
(
const
std
::
vector
<
OpenMM
::
Vec3
>&
atomCoordinates
,
std
::
vector
<
OpenMM
::
Vec3
>&
forces
,
const
std
::
vector
<
double
>&
charges
,
const
OpenMM
::
Vec3
periodicBoxVectors
[
3
],
double
&
energy
);
/*
/*
* Evaluate reciprocal space PME energy and charge derivatives.
*
* Args:
*
* pme Opaque pme_t object, must have been initialized with pme_init()
* atomCoordinates Pointer to coordinate data array (nm)
* chargeDerivatives Pointer to charge derivative data array (will be written as kJ/mol/e)
* chargeIndices Pointer to array of indices of particles to compute charge derivatives for
* charges Array of charges (units of e)
* periodicBoxVectors Simulation cell dimensions (nm)
*/
int
OPENMM_EXPORT
pme_exec_charge_derivatives
(
pme_t
pme
,
const
std
::
vector
<
OpenMM
::
Vec3
>&
atomCoordinates
,
std
::
vector
<
double
>&
chargeDerivatives
,
const
std
::
vector
<
int
>&
chargeIndices
,
const
std
::
vector
<
double
>&
charges
,
const
OpenMM
::
Vec3
periodicBoxVectors
[
3
]);
void
exec_charge_derivatives
(
const
std
::
vector
<
OpenMM
::
Vec3
>&
atomCoordinates
,
std
::
vector
<
double
>&
chargeDerivatives
,
const
std
::
vector
<
int
>&
chargeIndices
,
const
std
::
vector
<
double
>&
charges
,
const
OpenMM
::
Vec3
periodicBoxVectors
[
3
]);
/**
/**
* Evaluate reciprocal space PME dispersion energy and forces.
*
* Args:
*
* pme Opaque pme_t object, must have been initialized with pme_init()
* atomCoordinates Pointer to coordinate data array (nm)
* forces Pointer to force data array (will be written as kJ/mol/nm)
* c6s Array of c6 coefficients (units of sqrt(kJ/mol).nm^3 )
* periodicBoxVectors Simulation cell dimensions (nm)
* energy Total energy (will be written in units of kJ/mol)
*/
int
OPENMM_EXPORT
pme_exec_dpme
(
pme_t
pme
,
const
std
::
vector
<
OpenMM
::
Vec3
>&
atomCoordinates
,
std
::
vector
<
OpenMM
::
Vec3
>&
forces
,
const
std
::
vector
<
double
>&
c6s
,
const
OpenMM
::
Vec3
periodicBoxVectors
[
3
],
double
*
energy
);
void
exec_dpme
(
const
std
::
vector
<
OpenMM
::
Vec3
>&
atomCoordinates
,
std
::
vector
<
OpenMM
::
Vec3
>&
forces
,
const
std
::
vector
<
double
>&
c6s
,
const
OpenMM
::
Vec3
periodicBoxVectors
[
3
],
double
&
energy
);
private:
void
calculate_bsplines_moduli
();
void
update_grid_index_and_fraction
(
const
std
::
vector
<
Vec3
>&
atomCoordinates
,
const
Vec3
recipBoxVectors
[
3
]);
void
update_bsplines
();
void
grid_spread_charge
(
const
std
::
vector
<
double
>&
charges
);
void
pme_reciprocal_convolution
(
const
Vec3
periodicBoxVectors
[
3
],
const
Vec3
recipBoxVectors
[
3
],
double
&
energy
);
void
dpme_reciprocal_convolution
(
const
Vec3
periodicBoxVectors
[
3
],
const
Vec3
recipBoxVectors
[
3
],
double
&
energy
);
void
grid_interpolate_force
(
const
Vec3
recipBoxVectors
[
3
],
const
std
::
vector
<
double
>&
charges
,
std
::
vector
<
Vec3
>&
forces
);
void
grid_interpolate_charge_derivatives
(
const
Vec3
recipBoxVectors
[
3
],
const
std
::
vector
<
double
>&
charges
,
std
::
vector
<
double
>&
chargeDerivatives
,
const
std
::
vector
<
int
>&
chargeIndices
);
int
natoms
;
double
ewaldcoeff
;
std
::
vector
<
std
::
complex
<
double
>
>
grid
;
/* Memory for the grid we spread charges on.
* Element (i,j,k) is accessed as:
* grid[i*ngrid[1]*ngrid[2] + j*ngrid[2] + k] */
int
ngrid
[
3
];
/* Total grid dimensions (all data is complex!) */
int
order
;
/* PME interpolation order. Almost always 4 */
/* Data for bspline interpolation, see the Essman PME paper */
std
::
vector
<
double
>
bsplines_moduli
[
3
];
/* 3 pointers, to x/y/z bspline moduli, each of length ngrid[x/y/z] */
std
::
vector
<
double
>
bsplines_theta
[
3
];
/* each of x/y/z has length order*natoms */
std
::
vector
<
double
>
bsplines_dtheta
[
3
];
/* each of x/y/z has length order*natoms */
std
::
vector
<
std
::
array
<
int
,
3
>
>
particleindex
;
/* Array of length natoms. Each element is
* three ints that specify the grid
* indices for that particular atom. Updated every step! */
std
::
vector
<
Vec3
>
particlefraction
;
/* Array of length natoms. Fractional offset in the grid for
* each atom in all three dimensions. */
/* Further explanation of index/fraction:
*
* Assume we have a cell of size 10*10*10nm, and a total grid dimension of 100*100*100 cells.
* In other words, each cell is 0.1*0.1*0.1 nm.
*
* If particle i has coordinates { 0.543 , 6.235 , -0.73 }, we will get:
*
* particleindex[i] = { 5 , 62 , 92 } (-0.73 + 10 = 9.27, we always apply PBC for grid calculations!)
* particlefraction[i] = { 0.43 , 0.35 , 0.7 } (this is the fraction of the cell length where the atom is)
*
* (The reason for precaculating / storing these is that it gets a bit more complex for triclinic cells :-)
*
* In the current code version we might assume that a particle is not more than a whole box length away from
* the central cell, i.e., in this case we would assume all coordinates fall in -10 nm < x,y,z < 20 nm.
*/
/* Release all memory in pme structure */
int
OPENMM_EXPORT
pme_destroy
(
pme_t
pme
);
double
epsilon_r
;
/* Dielectric coefficient to use, typically 1.0 */
};
}
// namespace OpenMM
...
...
platforms/reference/src/SimTKReference/ReferenceConstantPotential.cpp
View file @
74912095
...
...
@@ -29,7 +29,6 @@
#include "ReferenceConstantPotential.h"
#include "ReferenceForce.h"
#include "ReferencePME.h"
#include "SimTKOpenMMUtilities.h"
#include "openmm/OpenMMException.h"
#include "openmm/internal/MSVC_erfc.h"
...
...
@@ -97,22 +96,21 @@ void ReferenceConstantPotentialMatrixSolver::update(
std
::
vector
<
double
>
dUdQ0
(
numElectrodeParticles
);
std
::
vector
<
double
>
dUdQ
(
numElectrodeParticles
);
pme_t
pmeData
;
pme_init
(
&
pmeData
,
conp
.
ewaldAlpha
,
numParticles
,
conp
.
gridSize
,
5
,
1
);
ReferencePME
pme
(
conp
.
ewaldAlpha
,
numParticles
,
conp
.
gridSize
,
5
,
1
);
// Get derivatives when all electrode charges are zeroed.
std
::
vector
<
double
>
q
(
charges
);
for
(
int
ii
=
0
;
ii
<
numElectrodeParticles
;
ii
++
)
{
q
[
elecToSys
[
ii
]]
=
0.0
;
}
conp
.
getDerivatives
(
numParticles
,
numElectrodeParticles
,
posData
,
q
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
dUdQ0
,
pme
Data
);
conp
.
getDerivatives
(
numParticles
,
numElectrodeParticles
,
posData
,
q
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
dUdQ0
,
pme
);
for
(
int
ii
=
0
;
ii
<
numElectrodeParticles
;
ii
++
)
{
int
i
=
elecToSys
[
ii
];
// Get derivatives when one electrode charge is set.
q
[
i
]
=
1.0
;
conp
.
getDerivatives
(
numParticles
,
numElectrodeParticles
,
posData
,
q
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
dUdQ
,
pme
Data
);
conp
.
getDerivatives
(
numParticles
,
numElectrodeParticles
,
posData
,
q
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
dUdQ
,
pme
);
q
[
i
]
=
0.0
;
// Set matrix elements, subtracting zero charge derivatives so that the
...
...
@@ -123,8 +121,6 @@ void ReferenceConstantPotentialMatrixSolver::update(
A
[
ii
][
ii
]
=
dUdQ
[
ii
]
-
dUdQ0
[
ii
];
}
pme_destroy
(
pmeData
);
// Compute Cholesky decomposition representation of the inverse.
capacitance
=
JAMA
::
Cholesky
<
double
>
(
A
);
if
(
!
capacitance
.
is_spd
())
{
...
...
@@ -162,7 +158,7 @@ void ReferenceConstantPotentialMatrixSolver::solve(
const
std
::
vector
<
int
>&
elecToSys
,
const
std
::
vector
<
std
::
array
<
double
,
3
>
>&
electrodeParamArray
,
ReferenceConstantPotential
&
conp
,
pme_t
pmeData
ReferencePME
&
pme
)
{
// Solves for charges using the matrix method.
...
...
@@ -171,7 +167,7 @@ void ReferenceConstantPotentialMatrixSolver::solve(
charges
[
elecToSys
[
ii
]]
=
0.0
;
}
std
::
vector
<
double
>
b
(
numElectrodeParticles
);
conp
.
getDerivatives
(
numParticles
,
numElectrodeParticles
,
posData
,
charges
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
b
,
pme
Data
);
conp
.
getDerivatives
(
numParticles
,
numElectrodeParticles
,
posData
,
charges
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
b
,
pme
);
for
(
int
ii
=
0
;
ii
<
numElectrodeParticles
;
ii
++
)
{
b
[
ii
]
=
-
b
[
ii
];
}
...
...
@@ -236,14 +232,12 @@ void ReferenceConstantPotentialCGSolver::update(
// calculation. This will actually vary slightly with position but only due
// to finite accuracy of the PME splines, so it is fine to assume it will be
// constant for the preconditioner.
pme_t
pmeData
;
pme_init
(
&
pmeData
,
conp
.
ewaldAlpha
,
1
,
conp
.
gridSize
,
5
,
1
);
ReferencePME
pme
(
conp
.
ewaldAlpha
,
1
,
conp
.
gridSize
,
5
,
1
);
std
::
vector
<
Vec3
>
pmePosData
(
1
);
std
::
vector
<
double
>
pmeChargeDerivatives
(
1
);
std
::
vector
<
int
>
pmeElectrodeIndices
(
1
);
std
::
vector
<
double
>
pmeCharges
(
1
,
1.0
);
pme_exec_charge_derivatives
(
pmeData
,
pmePosData
,
pmeChargeDerivatives
,
pmeElectrodeIndices
,
pmeCharges
,
boxVectors
);
pme_destroy
(
pmeData
);
pme
.
exec_charge_derivatives
(
pmePosData
,
pmeChargeDerivatives
,
pmeElectrodeIndices
,
pmeCharges
,
boxVectors
);
// The diagonal has a contribution from reciprocal space, Ewald
// self-interaction, Ewald neutralizing plasma, Gaussian self-interaction,
...
...
@@ -274,7 +268,7 @@ void ReferenceConstantPotentialCGSolver::solve(
const
std
::
vector
<
int
>&
elecToSys
,
const
std
::
vector
<
std
::
array
<
double
,
3
>
>&
electrodeParamArray
,
ReferenceConstantPotential
&
conp
,
pme_t
pmeData
ReferencePME
&
pme
)
{
// Solves for charges using the conjugate gradient method.
...
...
@@ -302,7 +296,7 @@ void ReferenceConstantPotentialCGSolver::solve(
}
// Evaluate the initial gradient Aq - b.
conp
.
getDerivatives
(
numParticles
,
numElectrodeParticles
,
posData
,
charges
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
grad
,
pme
Data
);
conp
.
getDerivatives
(
numParticles
,
numElectrodeParticles
,
posData
,
charges
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
grad
,
pme
);
// Project the initial gradient without preconditioning.
offset
=
0.0
;
...
...
@@ -332,7 +326,7 @@ void ReferenceConstantPotentialCGSolver::solve(
q
[
ii
]
=
charges
[
i
];
charges
[
i
]
=
0.0
;
}
conp
.
getDerivatives
(
numParticles
,
numElectrodeParticles
,
posData
,
charges
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
grad0
,
pme
Data
);
conp
.
getDerivatives
(
numParticles
,
numElectrodeParticles
,
posData
,
charges
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
grad0
,
pme
);
// Project the initial gradient with preconditioning.
if
(
precond
)
{
...
...
@@ -362,7 +356,7 @@ void ReferenceConstantPotentialCGSolver::solve(
for
(
int
ii
=
0
;
ii
<
numElectrodeParticles
;
ii
++
)
{
charges
[
elecToSys
[
ii
]]
=
qStep
[
ii
];
}
conp
.
getDerivatives
(
numParticles
,
numElectrodeParticles
,
posData
,
charges
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
gradStep
,
pme
Data
);
conp
.
getDerivatives
(
numParticles
,
numElectrodeParticles
,
posData
,
charges
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
gradStep
,
pme
);
for
(
int
ii
=
0
;
ii
<
numElectrodeParticles
;
ii
++
)
{
gradStep
[
ii
]
-=
grad0
[
ii
];
}
...
...
@@ -417,7 +411,7 @@ void ReferenceConstantPotentialCGSolver::solve(
for
(
int
ii
=
0
;
ii
<
numElectrodeParticles
;
ii
++
)
{
charges
[
elecToSys
[
ii
]]
=
q
[
ii
];
}
conp
.
getDerivatives
(
numParticles
,
numElectrodeParticles
,
posData
,
charges
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
grad
,
pme
Data
);
conp
.
getDerivatives
(
numParticles
,
numElectrodeParticles
,
posData
,
charges
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
grad
,
pme
);
}
else
{
for
(
int
ii
=
0
;
ii
<
numElectrodeParticles
;
ii
++
)
{
...
...
@@ -542,13 +536,9 @@ void ReferenceConstantPotential::execute(
double
*
energy
,
ReferenceConstantPotentialSolver
*
solver
)
{
pme_t
pmeData
;
pme_init
(
&
pmeData
,
ewaldAlpha
,
numParticles
,
gridSize
,
5
,
1
);
solver
->
solve
(
numParticles
,
numElectrodeParticles
,
posData
,
charges
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
*
this
,
pmeData
);
getEnergyForces
(
numParticles
,
numElectrodeParticles
,
posData
,
forceData
,
charges
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
energy
,
pmeData
);
pme_destroy
(
pmeData
);
ReferencePME
pme
(
ewaldAlpha
,
numParticles
,
gridSize
,
5
,
1
);
solver
->
solve
(
numParticles
,
numElectrodeParticles
,
posData
,
charges
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
*
this
,
pme
);
getEnergyForces
(
numParticles
,
numElectrodeParticles
,
posData
,
forceData
,
charges
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
energy
,
pme
);
}
void
ReferenceConstantPotential
::
getCharges
(
...
...
@@ -562,12 +552,8 @@ void ReferenceConstantPotential::getCharges(
const
std
::
vector
<
std
::
array
<
double
,
3
>
>&
electrodeParamArray
,
ReferenceConstantPotentialSolver
*
solver
)
{
pme_t
pmeData
;
pme_init
(
&
pmeData
,
ewaldAlpha
,
numParticles
,
gridSize
,
5
,
1
);
solver
->
solve
(
numParticles
,
numElectrodeParticles
,
posData
,
charges
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
*
this
,
pmeData
);
pme_destroy
(
pmeData
);
ReferencePME
pme
(
ewaldAlpha
,
numParticles
,
gridSize
,
5
,
1
);
solver
->
solve
(
numParticles
,
numElectrodeParticles
,
posData
,
charges
,
exclusions
,
sysToElec
,
elecToSys
,
electrodeParamArray
,
*
this
,
pme
);
}
void
ReferenceConstantPotential
::
getEnergyForces
(
...
...
@@ -581,7 +567,7 @@ void ReferenceConstantPotential::getEnergyForces(
const
std
::
vector
<
int
>&
elecToSys
,
const
std
::
vector
<
std
::
array
<
double
,
3
>
>&
electrodeParamArray
,
double
*
energy
,
pme_t
pmeData
ReferencePME
&
pme
)
{
const
double
SQRT_PI
=
sqrt
(
PI_M
);
const
double
TWO_OVER_SQRT_PI
=
2.0
/
SQRT_PI
;
...
...
@@ -671,7 +657,7 @@ void ReferenceConstantPotential::getEnergyForces(
// Reciprocal space.
double
pmeEnergy
=
0.0
;
pme
_
exec
(
pmeData
,
posData
,
forceData
,
charges
,
boxVectors
,
&
pmeEnergy
);
pme
.
exec
(
posData
,
forceData
,
charges
,
boxVectors
,
pmeEnergy
);
energyAccum
+=
pmeEnergy
;
// Ewald self-interaction and external field contributions (all particles).
...
...
@@ -710,7 +696,7 @@ void ReferenceConstantPotential::getDerivatives(
const
std
::
vector
<
int
>&
elecToSys
,
const
std
::
vector
<
std
::
array
<
double
,
3
>
>&
electrodeParamArray
,
std
::
vector
<
double
>&
chargeDerivatives
,
pme_t
pmeData
ReferencePME
&
pme
)
{
const
double
SQRT_PI
=
sqrt
(
PI_M
);
const
double
SELF_ALPHA_SCALE
=
2.0
*
ONE_4PI_EPS0
/
SQRT_PI
;
...
...
@@ -757,7 +743,7 @@ void ReferenceConstantPotential::getDerivatives(
}
// Reciprocal space.
pme
_
exec_charge_derivatives
(
pmeData
,
posData
,
chargeDerivatives
,
elecToSys
,
charges
,
boxVectors
);
pme
.
exec_charge_derivatives
(
posData
,
chargeDerivatives
,
elecToSys
,
charges
,
boxVectors
);
// Ewald neutralizing plasma precalculation.
double
qTotal
=
0.0
;
...
...
platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp
View file @
74912095
...
...
@@ -243,33 +243,28 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector<Vec3>& a
// PME
if
(
pme
&&
includeReciprocal
)
{
pme_t
pmedata
;
/* abstract handle for PME data */
pme_init
(
&
pmedata
,
alphaEwald
,
numberOfAtoms
,
meshDim
,
5
,
1
);
ReferencePME
pme
(
alphaEwald
,
numberOfAtoms
,
meshDim
,
5
,
1
);
vector
<
double
>
charges
(
numberOfAtoms
);
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
)
charges
[
i
]
=
atomParameters
[
i
][
QIndex
];
pme
_
exec
(
pmedata
,
atomCoordinates
,
forces
,
charges
,
periodicBoxVectors
,
&
recipEnergy
);
pme
.
exec
(
atomCoordinates
,
forces
,
charges
,
periodicBoxVectors
,
recipEnergy
);
if
(
totalEnergy
)
*
totalEnergy
+=
recipEnergy
;
pme_destroy
(
pmedata
);
if
(
ljpme
)
{
// Dispersion reciprocal space terms
pme_init
(
&
pmedata
,
alphaDispersionEwald
,
numberOfAtoms
,
dispersionMeshDim
,
5
,
1
);
ReferencePME
ljpme
(
alphaDispersionEwald
,
numberOfAtoms
,
dispersionMeshDim
,
5
,
1
);
std
::
vector
<
Vec3
>
dpmeforces
(
numberOfAtoms
);
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
)
charges
[
i
]
=
8.0
*
pow
(
atomParameters
[
i
][
SigIndex
],
3.0
)
*
atomParameters
[
i
][
EpsIndex
];
pme
_
exec_dpme
(
pmedata
,
atomCoordinates
,
dpmeforces
,
charges
,
periodicBoxVectors
,
&
recipDispersionEnergy
);
lj
pme
.
exec_dpme
(
atomCoordinates
,
dpmeforces
,
charges
,
periodicBoxVectors
,
recipDispersionEnergy
);
for
(
int
i
=
0
;
i
<
numberOfAtoms
;
i
++
)
forces
[
i
]
+=
dpmeforces
[
i
];
if
(
totalEnergy
)
*
totalEnergy
+=
recipDispersionEnergy
;
pme_destroy
(
pmedata
);
}
}
// Ewald method
...
...
platforms/reference/src/SimTKReference/ReferencePME.cpp
View file @
74912095
This diff is collapsed.
Click to expand it.
platforms/reference/tests/TestReferenceEwald.cpp
View file @
74912095
...
...
@@ -59,14 +59,13 @@ void testReferencePmeDerivatives() {
double
ewaldAlpha
=
1.752
;
int
gridSize
[
3
]
=
{
54
,
49
,
43
};
pme_t
pme
;
pme_init
(
&
pme
,
ewaldAlpha
,
numParticles
,
gridSize
,
5
,
1
);
ReferencePME
pme
(
ewaldAlpha
,
numParticles
,
gridSize
,
5
,
1
);
double
dummyEnergy
=
0
;
vector
<
Vec3
>
dummyForces
(
numParticles
);
vector
<
Vec3
>
testForces
(
numParticles
);
pme
_
exec
(
pme
,
positions
,
testForces
,
charges
,
boxVectors
,
&
dummyEnergy
);
pme
.
exec
(
positions
,
testForces
,
charges
,
boxVectors
,
dummyEnergy
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
for
(
int
j
=
0
;
j
<
3
;
j
++
)
{
...
...
@@ -74,11 +73,11 @@ void testReferencePmeDerivatives() {
double
energyLess
=
0.0
;
positions
[
i
][
j
]
=
referencePosition
-
DELTA
;
pme
_
exec
(
pme
,
positions
,
dummyForces
,
charges
,
boxVectors
,
&
energyLess
);
pme
.
exec
(
positions
,
dummyForces
,
charges
,
boxVectors
,
energyLess
);
double
energyMore
=
0.0
;
positions
[
i
][
j
]
=
referencePosition
+
DELTA
;
pme
_
exec
(
pme
,
positions
,
dummyForces
,
charges
,
boxVectors
,
&
energyMore
);
pme
.
exec
(
positions
,
dummyForces
,
charges
,
boxVectors
,
energyMore
);
positions
[
i
][
j
]
=
referencePosition
;
...
...
@@ -87,25 +86,23 @@ void testReferencePmeDerivatives() {
}
vector
<
double
>
testDerivatives
(
numParticles
);
pme
_
exec_charge_derivatives
(
pme
,
positions
,
testDerivatives
,
indices
,
charges
,
boxVectors
);
pme
.
exec_charge_derivatives
(
positions
,
testDerivatives
,
indices
,
charges
,
boxVectors
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
double
referenceCharge
=
charges
[
i
];
double
energyLess
=
0.0
;
charges
[
i
]
=
referenceCharge
-
DELTA
;
pme
_
exec
(
pme
,
positions
,
dummyForces
,
charges
,
boxVectors
,
&
energyLess
);
pme
.
exec
(
positions
,
dummyForces
,
charges
,
boxVectors
,
energyLess
);
double
energyMore
=
0.0
;
charges
[
i
]
=
referenceCharge
+
DELTA
;
pme
_
exec
(
pme
,
positions
,
dummyForces
,
charges
,
boxVectors
,
&
energyMore
);
pme
.
exec
(
positions
,
dummyForces
,
charges
,
boxVectors
,
energyMore
);
charges
[
i
]
=
referenceCharge
;
ASSERT_EQUAL_TOL
((
energyMore
-
energyLess
)
/
(
2
*
DELTA
),
testDerivatives
[
i
],
EPSILON
);
}
pme_destroy
(
pme
);
}
void
runPlatformTests
()
{
...
...
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceHippoNonbondedForce.cpp
View file @
74912095
...
...
@@ -2873,8 +2873,7 @@ double AmoebaReferencePmeHippoNonbondedForce::calculateDispersionPairIxn(const M
}
double
AmoebaReferencePmeHippoNonbondedForce
::
computeReciprocalSpaceDispersionForceAndEnergy
(
const
vector
<
MultipoleParticleData
>&
particleData
,
vector
<
Vec3
>&
forces
)
const
{
pme_t
pmedata
;
pme_init
(
&
pmedata
,
_dalphaEwald
,
_numParticles
,
_dpmeGridDimensions
,
5
,
1
);
ReferencePME
pme
(
_dalphaEwald
,
_numParticles
,
_dpmeGridDimensions
,
5
,
1
);
vector
<
double
>
charges
(
_numParticles
);
vector
<
Vec3
>
dpmeforces
(
_numParticles
,
Vec3
()),
coords
;
for
(
int
i
=
0
;
i
<
_numParticles
;
i
++
)
{
...
...
@@ -2882,8 +2881,7 @@ double AmoebaReferencePmeHippoNonbondedForce::computeReciprocalSpaceDispersionFo
coords
.
push_back
(
particleData
[
i
].
position
);
}
double
recipDispersionEnergy
;
pme_exec_dpme
(
pmedata
,
coords
,
dpmeforces
,
charges
,
_periodicBoxVectors
,
&
recipDispersionEnergy
);
pme_destroy
(
pmedata
);
pme
.
exec_dpme
(
coords
,
dpmeforces
,
charges
,
_periodicBoxVectors
,
recipDispersionEnergy
);
for
(
int
i
=
0
;
i
<
_numParticles
;
i
++
)
forces
[
i
]
+=
dpmeforces
[
i
];
return
recipDispersionEnergy
;
...
...
plugins/cpupme/tests/TestCpuPme.cpp
View file @
74912095
...
...
@@ -650,12 +650,10 @@ void testPME(bool triclinic, bool nonNeutral) {
// Get charge derivatives from the reference PME implementation.
pme_t
referencePme
;
int
gridSize
[
3
]
=
{
gridx
,
gridy
,
gridz
};
pme_init
(
&
referencePme
,
alpha
,
numParticles
,
gridSize
,
5
,
1
);
ReferencePME
referencePme
(
alpha
,
numParticles
,
gridSize
,
5
,
1
);
vector
<
double
>
testDerivatives
(
numParticles
);
pme_exec_charge_derivatives
(
referencePme
,
positions
,
testDerivatives
,
testIndices
,
testCharges
,
boxVectors
);
pme_destroy
(
referencePme
);
referencePme
.
exec_charge_derivatives
(
positions
,
testDerivatives
,
testIndices
,
testCharges
,
boxVectors
);
// See if they match.
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment