kshakeh.br 8.48 KB
Newer Older
Mark Friedrichs's avatar
Mark Friedrichs committed
1

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
31
/* -------------------------------------------------------------------------- *
 *                                   OpenMM                                   *
 * -------------------------------------------------------------------------- *
 * 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 Stanford University and the Authors.           *
 * Authors: Peter Eastman, Mark Friedrichs, Chris Bruns                       *
 * 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.                                     *
 * -------------------------------------------------------------------------- */
Mark Friedrichs's avatar
Mark Friedrichs committed
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

/*
 * This kernel constrains bonds involving hydrogen using an unrolled
 * shake implementation. We assume that a heavy atom can have at most 
 * 3 hydrogens attached. The hydrogens are expected to be identical
 *
 * For atoms that have ewer than 3 hydrogens
 *
 * Also we don't check the constraints!
 *  
 * We do a fixed number of iterations without checking for convergence
 * to avoid stalling
 * *************************************************************/

/* Fix for precision of terms first order in dt
 * To be used with corresponding update kernels
 * The input posqp is now changes to posq rather than
 * posq+changes
 * */
kernel void
kshakeh_fix1(
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
53
		float maxIterations,      //number of iterations
Mark Friedrichs's avatar
Mark Friedrichs committed
54
		float strwidth, //stream width of posq
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
55
		float inputTolerance,    //tolerance
Mark Friedrichs's avatar
Mark Friedrichs committed
56
		float4 atoms<>, //heavy0, h1, h2, h3
57
58
		float3 posq[][], //positions before update
		float3 posqp[][], //changes to positions
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
59
		float4 params<>, // (1/m0, mu/2, blensq, 1/m1 )
60
61
62
63
		out float3 cposq0<>, //constrained position for heavy atom
		out float3 cposq1<>, //ditto for h1
		out float3 cposq2<>, //ditto for h2
		out float3 cposq3<> //ditto for h3
Mark Friedrichs's avatar
Mark Friedrichs committed
64
65
66
67
68
69
		) {
	float2 ai, aj1, aj2, aj3; //2d indices, can be precalc.
	float i; //iteration count
	float3 xi, xj1, xj2, xj3; //coordinates
	float3 xpi, xpj1, xpj2, xpj3; //coordinates
	float3 rij1, rij2, rij3, rpij, dr;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
70
	float rpsqij, rrpr, acor, tolerance, converged;
Mark Friedrichs's avatar
Mark Friedrichs committed
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
	float mask2, mask3;
	float diff;
	float rij1sq, rij2sq, rij3sq;
	float ld1, ld2, ld3;
	
	// ai.y  = floor( atoms.x / strwidth );
   ai.y  = round( (atoms.x - fmod( atoms.x, strwidth ))/strwidth );
	ai.x  = atoms.x - ai.y * strwidth;

	// aj1.y = floor( atoms.y / strwidth );
   aj1.y  = round( (atoms.y - fmod( atoms.y, strwidth ))/strwidth );
	aj1.x = atoms.y - aj1.y * strwidth;

	//If further hydrogens are absent,
	//just set to the coordinates of the first
	//so we don't have any junk memory accesses
	//or nans/infs in the calcs.	
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
88
89

	if( atoms.z > -0.5f ){
Mark Friedrichs's avatar
Mark Friedrichs committed
90
91
92
		aj2.y = round( (atoms.z - fmod( atoms.z, strwidth ))/strwidth );
		aj2.x = atoms.z - aj2.y * strwidth;
		mask2 = 1.0f;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
93
	} else {
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
94
		aj2   = aj1; 
Mark Friedrichs's avatar
Mark Friedrichs committed
95
96
97
		mask2 = 0.0f;
	}

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
98
	if( atoms.w > -0.5f ){	
Mark Friedrichs's avatar
Mark Friedrichs committed
99
100
101
		aj3.y = round( (atoms.w - fmod( atoms.w, strwidth ))/strwidth );
		aj3.x = atoms.w - aj3.y * strwidth;
		mask3 = 1.0f;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
102
	} else {
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
103
		aj3   = aj1;
Mark Friedrichs's avatar
Mark Friedrichs committed
104
105
106
		mask3 = 0.0f;
	}

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
107
108
109
110
	cposq0       = posq[ai];
	cposq1       = posq[aj1];
	cposq2       = posq[aj2];
	cposq3       = posq[aj3];
Mark Friedrichs's avatar
Mark Friedrichs committed
111
	
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
112
113
114
115
	xi           = cposq0;
	xj1          = cposq1;
	xj2          = cposq2;
	xj3          = cposq3;
Mark Friedrichs's avatar
Mark Friedrichs committed
116
	
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
117
118
119
	rij1         = xi - xj1;
	rij2         = xi - xj2;
	rij3         = xi - xj3;
Mark Friedrichs's avatar
Mark Friedrichs committed
120

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
121
122
123
	rij1sq       = dot( rij1, rij1 );
	rij2sq       = dot( rij2, rij2 );
	rij3sq       = dot( rij3, rij3 );
Mark Friedrichs's avatar
Mark Friedrichs committed
124

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
125
126
127
	ld1          = params.z - rij1sq;
	ld2          = params.z - rij2sq;
	ld3          = params.z - rij3sq;
Mark Friedrichs's avatar
Mark Friedrichs committed
128

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
129
130
131
132
	xpi          = posqp[ai];
	xpj1         = posqp[aj1];
	xpj2         = posqp[aj2];
	xpj3         = posqp[aj3];
Mark Friedrichs's avatar
Mark Friedrichs committed
133
134


Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
135
136
	i           = 0.0f;
   converged   = 1.0f;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
137
138
   //tolerance   = 2.0f*inputTolerance;
   tolerance   = inputTolerance;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
139
	while( i < maxIterations && converged > 0.0f ){
Mark Friedrichs's avatar
Mark Friedrichs committed
140
141
142

		//First hydrogen

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
143
144
145
146
147
148
		rpij       = xpi - xpj1; //This is really rpij - rij
		rpsqij     = dot( rpij, rpij ); //This is really deltar ^ 2
		rrpr       = dot( rij1, rpij ); //This is r.deltar
      acor       = ( ld1 - 2 * rrpr - rpsqij ) * params.y / ( rrpr + rij1sq ) ; 
      diff       = abs( ld1 - 2 * rrpr - rpsqij ) / (params.z * tolerance );
      acor       = (diff < 1.0f) ? 0.0f : acor;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
149
      converged  = abs( acor );
Mark Friedrichs's avatar
Mark Friedrichs committed
150

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
151
152
		dr         = rij1 * acor;
		xpi       += dr * params.x;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
153
		xpj1      -= dr * params.w;
Mark Friedrichs's avatar
Mark Friedrichs committed
154

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
155
		//Second hydrogen
Mark Friedrichs's avatar
Mark Friedrichs committed
156

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
157
158
159
		rpij       = xpi - xpj2;
		rpsqij     = dot( rpij, rpij );
		rrpr       = dot( rij2, rpij );
Mark Friedrichs's avatar
Mark Friedrichs committed
160

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
161
162
163
      diff       = abs( ld2 - 2.0f * rrpr - rpsqij ) / (params.z * tolerance );
      acor       = mask2 * ( ld2 - 2.0f * rrpr - rpsqij ) * params.y / ( rrpr + rij2sq ) ; 
      acor       = (diff < 1.0f) ? 0.0f : acor;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
164
      converged += abs( acor );
Mark Friedrichs's avatar
Mark Friedrichs committed
165

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
166
167
		dr         = rij2 * acor;
		xpi       += dr * params.x;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
168
		xpj2      -= dr * params.w;
Mark Friedrichs's avatar
Mark Friedrichs committed
169
170

		//Third hydrogen
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
171
172
173
174
175
176
177

		rpij       = xpi - xpj3;
		rpsqij     = dot( rpij, rpij );
		rrpr       = dot( rij3, rpij );
      diff       = abs( ld3 - 2.0f * rrpr - rpsqij ) / (params.z * tolerance );
      acor       = mask3 * ( ld3 - 2.0f * rrpr - rpsqij ) * params.y / ( rrpr + rij3sq ) ;
      acor       = (diff < 1.0f) ? 0.0f : acor;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
178
      converged += abs( acor );
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
179
180
181

		dr         = rij3 * acor;
		xpi       += dr * params.x;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
182
		xpj3      -= dr * params.w;
Mark Friedrichs's avatar
Mark Friedrichs committed
183
184
185
186
187
		
		i += 1.0f;
	}

	//Output modified delta's
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
188

189
190
191
192
	cposq0 = xpi;
	cposq1 = xpj1;
	cposq2 = xpj2;
	cposq3 = xpj3;
Mark Friedrichs's avatar
Mark Friedrichs committed
193
194
195

}

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
196
kernel void kshakeh_update1_fix1( 
Mark Friedrichs's avatar
Mark Friedrichs committed
197
198
		float strwidth, //width of cposq streams
		float2 invmap<>,    //shakeh inverse map
199
200
201
202
203
204
		float3 posqp<>,    //deltas from sd2
		float3 cposq0[][], //constrained delta for heavy atom
		float3 cposq1[][], //ditto for h1
		float3 cposq2[][], //ditto for h2
		float3 cposq3[][], //ditto for h3
		out float3 oposq<> //updated deltas
Mark Friedrichs's avatar
Mark Friedrichs committed
205
206
207
208
		){
	float2 atom;
	
   atom.y  = round( (invmap.x - fmod( invmap.x, strwidth ))/strwidth );
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
209
	atom.x  = invmap.x - atom.y * strwidth;
Mark Friedrichs's avatar
Mark Friedrichs committed
210
	
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
211
//	oposq = posq;
Mark Friedrichs's avatar
Mark Friedrichs committed
212
	if ( invmap.y < 0 ){
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
213
214
215
216
217
		oposq = posqp;
	} else if ( invmap.y < 0.5f ){
		oposq += cposq0[ atom ];
	} else if ( invmap.y < 1.5f ){
		oposq += cposq1[ atom ];
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
218
	} else if ( invmap.y < 2.5f ){
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
219
		oposq += cposq2[ atom ];
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
220
	} else if ( invmap.y < 3.5f ){
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
221
		oposq += cposq3[ atom ];
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
222
   }
Mark Friedrichs's avatar
Mark Friedrichs committed
223
224
225

}

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
226
kernel void kshakeh_update2_fix1( 
Mark Friedrichs's avatar
Mark Friedrichs committed
227
228
		float strwidth, //width of cposq streams
		float2 invmap<>,    //shakeh inverse map
229
230
231
232
233
234
235
		float3 posq<>,     //old positions
		float3 posqp<>,    //deltas from sd2
		float3 cposq0[][], //constrained delta for heavy atom
		float3 cposq1[][], //ditto for h1
		float3 cposq2[][], //ditto for h2
		float3 cposq3[][], //ditto for h3
		out float3 oposq<> //updated deltas
Mark Friedrichs's avatar
Mark Friedrichs committed
236
		){
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
237

Mark Friedrichs's avatar
Mark Friedrichs committed
238
239
240
	float2 atom;
	
   atom.y  = round( (invmap.x - fmod( invmap.x, strwidth ))/strwidth );
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
241
	atom.x  = invmap.x - atom.y * strwidth;
Mark Friedrichs's avatar
Mark Friedrichs committed
242
243
244
	
	if ( invmap.y < 0 ){
		oposq = posqp;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
245
246
247
248
	} else if ( invmap.y < 0.5f ){ 
		oposq = cposq0[ atom ];
	} else if ( invmap.y < 1.5f){
		oposq = cposq1[ atom ];
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
249
	} else if ( invmap.y < 2.5f ){
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
250
		oposq = cposq2[ atom ];
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
251
	} else if ( invmap.y < 3.5f ){
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
252
		oposq = cposq3[ atom ];
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
253
   }
Mark Friedrichs's avatar
Mark Friedrichs committed
254

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
255
	oposq += posq;
Mark Friedrichs's avatar
Mark Friedrichs committed
256
}