CpuCustomManyParticleForce.h 7.45 KB
Newer Older
1
/* Portions copyright (c) 2009-2021 Stanford University and Simbios.
peastman's avatar
peastman committed
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 * Contributors: Peter Eastman
 *
 * 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.
 */

#ifndef OPENMM_CPU_CUSTOM_MANY_PARTICLE_FORCE_H__
#define OPENMM_CPU_CUSTOM_MANY_PARTICLE_FORCE_H__

#include "ReferenceForce.h"
#include "ReferenceBondIxn.h"
#include "CpuNeighborList.h"
#include "openmm/CustomManyParticleForce.h"
31
#include "openmm/internal/CompiledExpressionSet.h"
peastman's avatar
peastman committed
32
33
34
35
#include "openmm/internal/ThreadPool.h"
#include "openmm/internal/vectorize.h"
#include "lepton/CompiledExpression.h"
#include "lepton/ParsedExpression.h"
peastman's avatar
peastman committed
36
#include <atomic>
peastman's avatar
peastman committed
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <map>
#include <set>
#include <utility>
#include <vector>

namespace OpenMM {

class CpuCustomManyParticleForce {
private:

    class ParticleTermInfo;
    class ThreadData;
    int numParticles, numParticlesPerSet, numPerParticleParameters, numTypes;
50
    bool useCutoff, usePeriodic, triclinic, centralParticleMode;
peastman's avatar
peastman committed
51
    double cutoffDistance;
52
    float recipBoxSize[3];
peastman's avatar
peastman committed
53
    Vec3 periodicBoxVectors[3];
54
    Vec3* boxVectorsRef;
55
    AlignedArray<fvec4> periodicBoxVec4;
peastman's avatar
peastman committed
56
57
58
59
60
61
62
63
64
65
    CpuNeighborList* neighborList;
    ThreadPool& threads;
    std::vector<std::set<int> > exclusions;
    std::vector<int> particleTypes;
    std::vector<int> orderIndex;
    std::vector<std::vector<int> > particleOrder;
    std::vector<std::vector<int> > particleNeighbors;
    std::vector<ThreadData*> threadData;
    // The following variables are used to make information accessible to the individual threads.
    float* posq;
66
    std::vector<double>* particleParameters;        
peastman's avatar
peastman committed
67
68
69
    const std::map<std::string, double>* globalParameters;
    std::vector<AlignedArray<float> >* threadForce;
    bool includeForces, includeEnergy;
peastman's avatar
peastman committed
70
    std::atomic<int> atomicCounter;
peastman's avatar
peastman committed
71
72
73
74
75
76
77
78
79
80
81

    /**
     * This routine contains the code executed by each thread.
     */
    void threadComputeForce(ThreadPool& threads, int threadIndex);

    /**
     * This is called recursively to loop over all possible combination of a set of particles and evaluate the
     * interaction for each one.
     */
    void loopOverInteractions(std::vector<int>& availableParticles, std::vector<int>& particleSet, int loopIndex, int startIndex,
82
                              std::vector<double>* particleParameters, float* forces, ThreadData& data, const fvec4& boxSize, const fvec4& invBoxSize);
peastman's avatar
peastman committed
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

    /**---------------------------------------------------------------------------------------

       Calculate custom interaction for one set of particles

       @param particleSet        the indices of the particles
       @param posq               atom coordinates in float format
       @param particleParameters particle parameter values (particleParameters[particleIndex][parameterIndex])
       @param forces             force array (forces added)
       @param totalEnergy        total energy

       --------------------------------------------------------------------------------------- */

    /**
     * Calculate the interaction for one set of particles
     * 
     * @param particleSet        the indices of the particles
     * @param particleParameters particle parameter values (particleParameters[particleIndex][parameterIndex])
     * @param data               information and workspace for the current thread
     * @param boxSize            the size of the periodic box
     * @param invBoxSize         the inverse size of the periodic box
     */
105
    void calculateOneIxn(std::vector<int>& particleSet, std::vector<double>* particleParameters, float* forces, ThreadData& data, const fvec4& boxSize, const fvec4& invBoxSize);
peastman's avatar
peastman committed
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

    /**
     * Compute the displacement and squared distance between two points, optionally using
     * periodic boundary conditions.
     */
    void computeDelta(const fvec4& posI, const fvec4& posJ, fvec4& deltaR, float& r2, const fvec4& boxSize, const fvec4& invBoxSize) const;

public:
    /**
     * Create a new CpuCustomManyParticleForce.
     *
     * @param force      the CustomManyParticleForce to create it for
     * @param threads    the thread pool to use
     */
    CpuCustomManyParticleForce(const OpenMM::CustomManyParticleForce& force, ThreadPool& threads);

    ~CpuCustomManyParticleForce();

    /**
     * Set the force to use a cutoff.
     * 
     * @param distance   the cutoff distance
     */
peastman's avatar
peastman committed
129
    void setUseCutoff(double distance);
peastman's avatar
peastman committed
130
131
132
133
134
135

    /**
     * Set the force to use periodic boundary conditions.  This requires that a cutoff has
     * already been set, and the smallest side of the periodic box is at least twice the cutoff
     * distance.
     * 
136
     * @param periodicBoxVectors    the vectors defining the periodic box
peastman's avatar
peastman committed
137
     */
peastman's avatar
peastman committed
138
    void setPeriodic(Vec3* periodicBoxVectors);
peastman's avatar
peastman committed
139
140
141
142
143
144
145
146
147
148
149
150

    /**
     * Calculate the interaction.
     * 
     * @param posq               atom coordinates in float format
     * @param particleParameters particle parameter values (particleParameters[particleIndex][parameterIndex])
     * @param globalParameters   the values of global parameters
     * @param threadForce        the collection of arrays for each thread to add forces to
     * @param includeForce       whether to compute forces
     * @param includeEnergy      whether to compute energy
     * @param energy             the total energy is added to this
     */
151
    void calculateIxn(AlignedArray<float>& posq, std::vector<std::vector<double> >& particleParameters, const std::map<std::string, double>& globalParameters,
peastman's avatar
peastman committed
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
                      std::vector<AlignedArray<float> >& threadForce, bool includeForces, bool includeEnergy, double& energy);
};

class CpuCustomManyParticleForce::ParticleTermInfo {
public:
    std::string name;
    int atom, component, variableIndex;
    Lepton::CompiledExpression forceExpression;
    ParticleTermInfo(const std::string& name, int atom, int component, const Lepton::CompiledExpression& forceExpression, ThreadData& data);
};

class CpuCustomManyParticleForce::ThreadData {
public:
    CompiledExpressionSet expressionSet;
    Lepton::CompiledExpression energyExpression;
    std::vector<std::vector<int> > particleParamIndices;
    std::vector<int> permutedParticles;
    std::vector<ParticleTermInfo> particleTerms;
    AlignedArray<fvec4> f;
    double energy;
172
    ThreadData(const CustomManyParticleForce& force, Lepton::ParsedExpression& energyExpr);
peastman's avatar
peastman committed
173
174
175
176
177
};

} // namespace OpenMM

#endif // OPENMM_CPU_CUSTOM_MANY_PARTICLE_FORCE_H__