AmoebaTorsionTorsionForceImpl.cpp 7.14 KB
Newer Older
Mark Friedrichs's avatar
Mark Friedrichs committed
1
/* -------------------------------------------------------------------------- *
2
 *                               OpenMMAmoeba                                 *
Mark Friedrichs's avatar
Mark Friedrichs committed
3
 * -------------------------------------------------------------------------- *
Evan Pretti's avatar
Evan Pretti committed
4
5
 * This is part of the OpenMM molecular simulation toolkit.                   *
 * See https://openmm.org/development.                                        *
Mark Friedrichs's avatar
Mark Friedrichs committed
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
 *                                                                            *
 * Portions copyright (c) 2008 Stanford University and the Authors.           *
 * Authors:                                                                   *
 * 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 "openmm/internal/ContextImpl.h"
31
32
#include "openmm/internal/AmoebaTorsionTorsionForceImpl.h"
#include "openmm/amoebaKernels.h"
33
#include <cstdio>
Mark Friedrichs's avatar
Mark Friedrichs committed
34
35
36
37
38
39
40

using namespace OpenMM;

using std::pair;
using std::vector;
using std::set;

41
AmoebaTorsionTorsionForceImpl::AmoebaTorsionTorsionForceImpl(const AmoebaTorsionTorsionForce& owner) : owner(owner) {
Mark Friedrichs's avatar
Mark Friedrichs committed
42
43
44
45
46
47
48
}

AmoebaTorsionTorsionForceImpl::~AmoebaTorsionTorsionForceImpl() {
}

void AmoebaTorsionTorsionForceImpl::initialize(ContextImpl& context) {
    kernel = context.getPlatform().createKernel(CalcAmoebaTorsionTorsionForceKernel::Name(), context);
49
    kernel.getAs<CalcAmoebaTorsionTorsionForceKernel>().initialize(context.getSystem(), owner);
Mark Friedrichs's avatar
Mark Friedrichs committed
50
51
}

52
53
double AmoebaTorsionTorsionForceImpl::calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups) {
    if ((groups&(1<<owner.getForceGroup())) != 0)
54
        return kernel.getAs<CalcAmoebaTorsionTorsionForceKernel>().execute(context, includeForces, includeEnergy);
Peter Eastman's avatar
Peter Eastman committed
55
    return 0.0;
Mark Friedrichs's avatar
Mark Friedrichs committed
56
57
}

58
59
60
61
62
63
64
65
66
67
68
69
70
struct IntPair {
    unsigned int index1;
    unsigned int index2;
};

typedef std::map< double, struct IntPair > Map_Double_IntPair;
typedef Map_Double_IntPair::iterator Map_Double_IntPairI;
typedef Map_Double_IntPair::const_iterator Map_Double_IntPairCI;

typedef std::map< double, Map_Double_IntPair > Map_Double_MapDoubleIntPair;
typedef Map_Double_MapDoubleIntPair::iterator Map_Double_MapDoubleIntPairI;
typedef Map_Double_MapDoubleIntPair::const_iterator Map_Double_MapDoubleIntPairCI;

71
void AmoebaTorsionTorsionForceImpl::reorderGrid(const TorsionTorsionGrid& grid, TorsionTorsionGrid& reorderedGrid) {
72

73
74
    reorderedGrid.resize(grid.size());
    std::vector<Map_Double_IntPair> map_Double_IntPair_Vector(grid.size());
75
76
77
78
79
80
81
82
83
    Map_Double_MapDoubleIntPair mapAngles;

    // (1) set dimensions for reorderd grid
    // (2) build map:
    //         map[angleX][angleY] = <ii, jj> indices
    //         assume map keys are sorted from least to greatest

    for (unsigned int ii = 0; ii < grid.size(); ii++) {
    
84
        reorderedGrid[ii].resize(grid[ii].size());
85
        for (unsigned int jj = 0; jj < grid[ii].size(); jj++) {
86
            reorderedGrid[ii][jj].resize(grid[ii][jj].size());
87
88
89
90

            double angleX =  grid[ii][jj][0]; 
            double angleY =  grid[ii][jj][1]; 

91
92
            if (mapAngles.find(angleX) == mapAngles.end()) {
                if (map_Double_IntPair_Vector[ii].size() > 0) {
93
                    char buffer[1024];
94
95
                    (void) sprintf(buffer, "TorsionTorsion grid reorder: x-angle not set correctly: x=%15.7e y=%15.7e size=%u should be zero; ii/jj indies=%u %u.\n",
                                    angleX, angleY, static_cast<unsigned int>(map_Double_IntPair_Vector[ii].size()), ii, jj);
96
97
98
99
100
101
                    throw OpenMMException(buffer);
                 }
                 mapAngles[angleX] = map_Double_IntPair_Vector[ii];
            }

            Map_Double_IntPair& map_Double_IntPair  = mapAngles[angleX];
102
            if (map_Double_IntPair.find(angleY) != map_Double_IntPair.end()) {
103
                char buffer[1024];
104
                (void) sprintf(buffer, "TorsionTorsion grid reorder: angle pair found twice: %15.7e %15.7e %u\n", angleX, angleY, static_cast<unsigned int>(map_Double_IntPair.size()));
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
                throw OpenMMException(buffer);
            }
            struct IntPair pair; 
            pair.index1 = ii;
            pair.index2 = jj;
            map_Double_IntPair[angleY] = pair; 
        }
    }

    // load reordered entries

    Map_Double_MapDoubleIntPairCI mapII    = mapAngles.begin();
    Map_Double_IntPair map_Double_IntPair  = mapII->second;
    Map_Double_IntPairCI mapJJ             = map_Double_IntPair.begin();

    for (unsigned int ii = 0; ii < grid.size(); ii++) {
        for (unsigned int jj = 0; jj < grid[ii].size(); jj++) {

            struct IntPair pair  = mapJJ->second;
            int index1           = pair.index1;
            int index2           = pair.index2;

            for (unsigned int kk = 0; kk < grid[ii][jj].size(); kk++) {
                reorderedGrid[ii][jj][kk] = static_cast<float>(grid[index1][index2][kk]);
            }

            // increment map iterators

133
            ++mapJJ;
134
            if (mapJJ == map_Double_IntPair.end()) {
135
                ++mapII;
136
137
                if (mapII == mapAngles.end()) {
                    if ((jj != (grid[ii].size()-1)) && (ii != (grid.size()-1))) {
138
                        char buffer[1024];
139
                        (void) sprintf(buffer, "AmoebaTorsionTorsionForceImpl::reorderGrid: error detected with map iterators.\n");
140
141
                        throw OpenMMException(buffer);
                    }
Peter Eastman's avatar
Peter Eastman committed
142
143
                }
                else {
144
145
146
147
148
149
150
151
152
153
                    map_Double_IntPair  = mapII->second;
                    mapJJ               = map_Double_IntPair.begin();
                }
            }
        }
    }

    return;
}

Mark Friedrichs's avatar
Mark Friedrichs committed
154
std::vector<std::string> AmoebaTorsionTorsionForceImpl::getKernelNames() {
Peter Eastman's avatar
Peter Eastman committed
155
    return {CalcAmoebaTorsionTorsionForceKernel::Name()};
Mark Friedrichs's avatar
Mark Friedrichs committed
156
157
}