ReferenceConstantPotential.h 17.8 KB
Newer Older
1
2
3
4
5
6
#ifndef OPENMM_REFERENCECONSTANTPOTENTIAL_H_
#define OPENMM_REFERENCECONSTANTPOTENTIAL_H_

/* -------------------------------------------------------------------------- *
 *                                   OpenMM                                   *
 * -------------------------------------------------------------------------- *
Evan Pretti's avatar
Evan Pretti committed
7
8
 * This is part of the OpenMM molecular simulation toolkit.                   *
 * See https://openmm.org/development.                                        *
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
 *                                                                            *
 * Portions copyright (c) 2025 Stanford University and the Authors.           *
 * Authors: Evan Pretti                                                       *
 * Contributors:                                                              *
 *                                                                            *
 * Permission is hereby granted, free of charge, to any person obtaining a    *
 * copy of this software and associated documentation files (the "Software"), *
 * to deal in the Software without restriction, including without limitation  *
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
 * and/or sell copies of the Software, and to permit persons to whom the      *
 * Software is furnished to do so, subject to the following conditions:       *
 *                                                                            *
 * The above copyright notice and this permission notice shall be included in *
 * all copies or substantial portions of the Software.                        *
 *                                                                            *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
 * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
 * -------------------------------------------------------------------------- */

#include <array>

#include "ReferenceNeighborList.h"
#include "ReferencePME.h"
#include "tnt_array2d.h"
#include "jama_cholesky.h"

namespace OpenMM {

class ReferenceConstantPotential;

/**
 * A generic charge solver for the constant potential method.
 */
class ReferenceConstantPotentialSolver {
protected:
    bool valid;

public:
    /**
     * Creates a ReferenceConstantPotentialSolver.
     */
    ReferenceConstantPotentialSolver();
    virtual ~ReferenceConstantPotentialSolver();
    /**
     * Mark precomputed data stored by the solver as invalid due to a change in
     * electrode parameters.
     */
    void invalidate();
    /**
     * Updates precomputed data stored by the solver.
     * 
     * @param numParticles           the total number of particles
     * @param numElectrodeParticles  the number of electrode (fluctuating-charge) particles
     * @param posData                particle positions
     * @param charges                particle charges
     * @param exclusions             particle exclusions
     * @param sysToElec              mapping from system particle indices to electrode particle indices
     * @param elecToSys              mapping from electrode particle indices to system particle indices
     * @param electrodeParamArray    electrode particle parameters
     * @param conp                   constant potential derivative evaluation class
     */
    virtual void update(int numParticles, int numElectrodeParticles,
        const std::vector<Vec3>& posData, const 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) = 0;
    /**
     * Solves for charges.
     * 
     * @param numParticles           the total number of particles
     * @param numElectrodeParticles  the number of electrode (fluctuating-charge) particles
     * @param posData                particle positions
     * @param charges                output particle charges
     * @param exclusions             particle exclusions
     * @param sysToElec              mapping from system particle indices to electrode particle indices
     * @param elecToSys              mapping from electrode particle indices to system particle indices
     * @param electrodeParamArray    electrode particle parameters
     * @param conp                   constant potential derivative evaluation class
Peter Eastman's avatar
Peter Eastman committed
93
     * @param pme                    reference PME solver
94
95
96
97
98
99
     */
    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,
Peter Eastman's avatar
Peter Eastman committed
100
        ReferenceConstantPotential& conp, ReferencePME& pme) = 0;
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
};

/**
 * A constant potential solver using direct inversion of the Coulomb matrix.
 * Suitable only when electrode particle positions are fixed.
 */
class ReferenceConstantPotentialMatrixSolver : public ReferenceConstantPotentialSolver {
private:
    Vec3 boxVectors[3];
    std::vector<Vec3> electrodePosData;
    JAMA::Cholesky<double> capacitance;
    std::vector<double> constraintVector;

public:
    /**
     * Creates a ReferenceConstantPotentialMatrixSolver.
     * 
     * @param numElectrodeParticles  the number of electrode (fluctuating-charge) particles
     */
    ReferenceConstantPotentialMatrixSolver(int numElectrodeParticles);
    /**
     * Updates precomputed data stored by the solver.
     * 
     * @param numParticles           the total number of particles
     * @param numElectrodeParticles  the number of electrode (fluctuating-charge) particles
     * @param posData                particle positions
     * @param charges                particle charges
     * @param exclusions             particle exclusions
     * @param sysToElec              mapping from system particle indices to electrode particle indices
     * @param elecToSys              mapping from electrode particle indices to system particle indices
     * @param electrodeParamArray    electrode particle parameters
     * @param conp                   constant potential derivative evaluation class
     */
    void update(int numParticles, int numElectrodeParticles,
        const std::vector<Vec3>& posData, const 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);
    /**
     * Solves for charges.
     * 
     * @param numParticles           the total number of particles
     * @param numElectrodeParticles  the number of electrode (fluctuating-charge) particles
     * @param posData                particle positions
     * @param charges                output particle charges
     * @param exclusions             particle exclusions
     * @param sysToElec              mapping from system particle indices to electrode particle indices
     * @param elecToSys              mapping from electrode particle indices to system particle indices
     * @param electrodeParamArray    electrode particle parameters
     * @param conp                   constant potential derivative evaluation class
Peter Eastman's avatar
Peter Eastman committed
152
     * @param pme                    reference PME solver
153
154
155
156
157
158
     */
    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,
Peter Eastman's avatar
Peter Eastman committed
159
        ReferenceConstantPotential& conp, ReferencePME& pme);
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
};

/**
 * A constant potential solver using the conjugate gradient method.  Suitable
 * for both fixed and variable electrode particle positions.
 */
class ReferenceConstantPotentialCGSolver : public ReferenceConstantPotentialSolver {
private:
    Vec3 boxVectors[3];
    bool precond;
    std::vector<double> precondVector;

public:
    /**
     * Creates a ReferenceConstantPotentialCGSolver.
     * 
     * @param numElectrodeParticles  the number of electrode (fluctuating-charge) particles
     * @param precond                whether or not to use a preconditioner
     */
    ReferenceConstantPotentialCGSolver(int numElectrodeParticles, bool precond);
    /**
     * Updates precomputed data stored by the solver.
     * 
     * @param numParticles           the total number of particles
     * @param numElectrodeParticles  the number of electrode (fluctuating-charge) particles
     * @param posData                particle positions
     * @param charges                particle charges
     * @param exclusions             particle exclusions
     * @param sysToElec              mapping from system particle indices to electrode particle indices
     * @param elecToSys              mapping from electrode particle indices to system particle indices
     * @param electrodeParamArray    electrode particle parameters
     * @param conp                   constant potential derivative evaluation class
     */
    void update(int numParticles, int numElectrodeParticles,
        const std::vector<Vec3>& posData, const 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);
    /**
     * Solves for charges.
     * 
     * @param numParticles           the total number of particles
     * @param numElectrodeParticles  the number of electrode (fluctuating-charge) particles
     * @param posData                particle positions
     * @param charges                output particle charges
     * @param exclusions             particle exclusions
     * @param sysToElec              mapping from system particle indices to electrode particle indices
     * @param elecToSys              mapping from electrode particle indices to system particle indices
     * @param electrodeParamArray    electrode particle parameters
     * @param conp                   constant potential derivative evaluation class
Peter Eastman's avatar
Peter Eastman committed
211
     * @param pme                    reference PME solver
212
213
214
215
216
217
     */
    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,
Peter Eastman's avatar
Peter Eastman committed
218
        ReferenceConstantPotential& conp, ReferencePME& pme);
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
};

/**
 * Performs energy, force, and charge derivative calculations for the reference
 * kernel for ConstantPotentialForce.
 */
class ReferenceConstantPotential {
    friend class ReferenceConstantPotentialMatrixSolver;
    friend class ReferenceConstantPotentialCGSolver;

private:
    double nonbondedCutoff, ewaldAlpha, cgErrorTol, chargeTarget;
    const NeighborList* neighborList;
    Vec3 boxVectors[3], externalField;
    bool exceptionsArePeriodic, useChargeConstraint;
    int gridSize[3];

    static const int PotentialIndex = 0;
    static const int GaussianWidthIndex = 1;
    static const int ThomasFermiScaleIndex = 2;

public:
    /**
     * Creates a ReferenceConstantPotential.
     * 
     * @param nonbondedCutoff        direct space cutoff
     * @param neighborList           neighbor list for direct space calculation
     * @param boxVectors             periodic box vectors
     * @param exceptionsArePeriodic  whether or not exceptions use periodic boundary conditions
     * @param ewaldAlpha             Ewald reciprocal Gaussian width parameter
     * @param gridSize               Ewald mesh dimensions
     * @param cgErrorTol             constant potential conjugate gradient error tolerance
     * @param useChargeConstraint    whether or not to constrain total charge
     * @param chargeTarget           target sum of charges on electrode particles only
     * @param externalField          electric field vector
     */
    ReferenceConstantPotential(double nonbondedCutoff,
        const NeighborList* neighborList, const Vec3* boxVectors,
        bool exceptionsArePeriodic, double ewaldAlpha, const int* gridSize,
        double cgErrorTol, bool useChargeConstraint, double chargeTarget,
        Vec3 externalField);
    /**
     * Solves for charges and computes energies and forces.
     * 
     * @param numParticles           the total number of particles
     * @param numElectrodeParticles  the number of electrode (fluctuating-charge) particles
     * @param posData                particle positions
     * @param forceData              output forces on particles
     * @param charges                output particle charges
     * @param exclusions             particle exclusions
     * @param sysToElec              mapping from system particle indices to electrode particle indices
     * @param elecToSys              mapping from electrode particle indices to system particle indices
     * @param electrodeParamArray    electrode particle parameters
     * @param energy                 output system energy
     * @param solver                 charge solver implementation
     */
    void execute(int numParticles, int numElectrodeParticles,
        const std::vector<Vec3>& posData, std::vector<Vec3>& forceData,
        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,
        double* energy, ReferenceConstantPotentialSolver* solver);
    /**
     * Solves for charges without computing energies and forces.
     * 
     * @param numParticles           the total number of particles
     * @param numElectrodeParticles  the number of electrode (fluctuating-charge) particles
     * @param posData                particle positions
     * @param charges                output particle charges
     * @param exclusions             particle exclusions
     * @param sysToElec              mapping from system particle indices to electrode particle indices
     * @param elecToSys              mapping from electrode particle indices to system particle indices
     * @param electrodeParamArray    electrode particle parameters
     * @param solver                 charge solver implementation
     */
    void getCharges(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,
        ReferenceConstantPotentialSolver* solver);

private:
    /**
     * Computes energies and forces for fixed (solved) charges.
     * 
     * @param numParticles           the total number of particles
     * @param numElectrodeParticles  the number of electrode (fluctuating-charge) particles
     * @param posData                particle positions
     * @param forceData              output forces on particles
     * @param charges                particle charges
     * @param exclusions             particle exclusions
     * @param sysToElec              mapping from system particle indices to electrode particle indices
     * @param elecToSys              mapping from electrode particle indices to system particle indices
     * @param electrodeParamArray    electrode particle parameters
     * @param energy                 output system energy
Peter Eastman's avatar
Peter Eastman committed
316
     * @param pme                    reference PME solver
317
318
319
320
321
322
323
     */
    void getEnergyForces(int numParticles, int numElectrodeParticles,
        const std::vector<Vec3>& posData, std::vector<Vec3>& forceData,
        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,
Peter Eastman's avatar
Peter Eastman committed
324
        double* energy, ReferencePME& pme);
325
326
327
328
329
330
331
332
333
334
335
336
    /**
     * Computes energy derivatives with respect to charges.
     * 
     * @param numParticles           the total number of particles
     * @param numElectrodeParticles  the number of electrode (fluctuating-charge) particles
     * @param posData                particle positions
     * @param charges                particle charges
     * @param exclusions             particle exclusions
     * @param sysToElec              mapping from system particle indices to electrode particle indices
     * @param elecToSys              mapping from electrode particle indices to system particle indices
     * @param electrodeParamArray    electrode particle parameters
     * @param chargeDerivatives      output charge derivatives
Peter Eastman's avatar
Peter Eastman committed
337
     * @param pme                    reference PME solver
338
339
340
341
342
343
     */
    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,
Peter Eastman's avatar
Peter Eastman committed
344
        std::vector<double>& chargeDerivatives, ReferencePME& pme);
345
346
347
348
349
};

} // namespace OpenMM

#endif // OPENMM_REFERENCECONSTANTPOTENTIAL_H_