BrookVelocityCenterOfMassRemoval.cpp 17.5 KB
Newer Older
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
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
/* -------------------------------------------------------------------------- *
 *                                   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: Mark Friedrichs                                                   *
 * 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 <sstream>
#include "BrookVelocityCenterOfMassRemoval.h"
#include "BrookPlatform.h"
#include "OpenMMException.h"
#include "BrookStreamImpl.h"
#include "gpu/kcom.h"

using namespace OpenMM;
using namespace std;

/** 
 *
 * Constructor
 * 
 */

BrookVelocityCenterOfMassRemoval::BrookVelocityCenterOfMassRemoval( ){

// ---------------------------------------------------------------------------------------

   //static const std::string methodName      = "BrookVelocityCenterOfMassRemoval::BrookVelocityCenterOfMassRemoval";

   BrookOpenMMFloat zero                    = (BrookOpenMMFloat)  0.0;

// ---------------------------------------------------------------------------------------

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
58
   _numberOfParticles           = -1;
59
60
61

   // mark stream dimension variables as unset

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
62
63
64
   _particleStreamWidth         = -1;
   _particleStreamHeight        = -1;
   _particleStreamSize          = -1;
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
93
94
95
96
97
98
99
100
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

   _totalInverseMass        = zero;

   for( int ii = 0; ii < LastStreamIndex; ii++ ){
      _streams[ii]   = NULL;
   }

}   
 
/** 
 * Destructor
 * 
 */

BrookVelocityCenterOfMassRemoval::~BrookVelocityCenterOfMassRemoval( ){

// ---------------------------------------------------------------------------------------

   //static const std::string methodName      = "BrookVelocityCenterOfMassRemoval::~BrookVelocityCenterOfMassRemoval";

// ---------------------------------------------------------------------------------------

   for( int ii = 0; ii < LastStreamIndex; ii++ ){
      delete _streams[ii];
   }

}

/** 
 * Get inverse of total mass
 * 
 * @return  inverse of total mass
 *
 */

BrookOpenMMFloat BrookVelocityCenterOfMassRemoval::getTotalInverseMass( void ) const {
   return _totalInverseMass;
}

/** 
 * Get inverse mass stream 
 *
 * @return  inverse mass stream
 *
 */

BrookFloatStreamInternal* BrookVelocityCenterOfMassRemoval::getMassStream( void ) const {
   return _streams[MassStream];
}

/** 
 * Get work stream 
 *
 * @return  work stream
 *
 */

BrookFloatStreamInternal* BrookVelocityCenterOfMassRemoval::getWorkStream( void ) const {
   return _streams[WorkStream];
}

/** 
 * Get linear momentum stream
 *
 * @return   linear momentum stream
 *
 */

BrookFloatStreamInternal* BrookVelocityCenterOfMassRemoval::getLinearMomentumStream( void ) const {
   return _streams[LinearMomentumStream];
}

/**
 * Remove velocity-COM
 *
 * @param velocities velocities
 *
 * @return DefaultReturnValue
 *
 */
   
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
146
int BrookVelocityCenterOfMassRemoval::removeVelocityCenterOfMass( BrookStreamImpl& velocityStream ){
147
148
149

   // ---------------------------------------------------------------------------------------

150
   static const char* methodName  = "BrookVelocityCenterOfMassRemoval::removeVelocityCenterOfMass";
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
151
   static const int debug         = 1;
152
153
154

   // ---------------------------------------------------------------------------------------

155
156
   if( debug && getLog() ){
      BrookOpenMMFloat com[3];
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
157
      getVelocityCenterOfMass( velocityStream, com );
158
      (void) fprintf( getLog(), "\n%s Pre removal com: [%12.5e %12.5e %12.5e]\n", methodName, com[0], com[1], com[2] );
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
159
      BrookStreamInternal* outputVelocityStream = dynamic_cast<BrookStreamInternal*> (velocityStream.getBrookStreamImpl());
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
160

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
161
      void* velV                       = outputVelocityStream->getData( 1 );
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
162
163
164
165
166
167
168
169
170
      const float* vArray              = (float*) velV;

      int index                        = 0;
      for( int ii = 0; ii < getNumberOfParticles(); ii++, index += 3 ){
         (void) fprintf( getLog(), "V %d [%12.5e %12.5e %12.5e]\n", ii, vArray[index], vArray[index+1], vArray[index+2] );

      }

      (void) fflush( getLog() );
171
172
   }

173
174
175
176
   // calculate linear momentum via reduction
   // subtract it (/totalMass) from velocities

   kCalculateLinearMomentum( getMassStream()->getBrookStream(), velocityStream.getBrookStream(), getWorkStream()->getBrookStream() );
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
177
178
179
   kSumLinearMomentum( (float) getComParticleStreamWidth(), (float) getNumberOfParticles(), (float) getTotalInverseMass(),
                        getWorkStream()->getBrookStream(), getLinearMomentumStream()->getBrookStream() );
//   kScale( (float) getTotalInverseMass(), getLinearMomentumStream()->getBrookStream(), getLinearMomentumStream()->getBrookStream() );
180
181
   kRemoveLinearMomentum( getLinearMomentumStream()->getBrookStream(), velocityStream.getBrookStream(), velocityStream.getBrookStream() );

182
183
   if( (0 || debug) && getLog() ){
      BrookOpenMMFloat com[3];
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
184
      getVelocityCenterOfMass( velocityStream, com );
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
185
186
      (void) fprintf( getLog(), "%s strW=%d iatm=%d invMass=%.4e Post removal com: [%12.5e %12.5e %12.5e]", methodName,
                      getComParticleStreamWidth(), getNumberOfParticles(), getTotalInverseMass(),  com[0], com[1], com[2] );
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
187
188
189
190
191

      void* linMoV = getLinearMomentumStream()->getData( 1 );
      float* linMo = (float*) linMoV;
      (void) fprintf( getLog(), "LM [%12.5e %12.5e %12.5e]\n", linMo[0], linMo[1], linMo[2] );

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
192
      BrookStreamInternal* outputVelocityStream = dynamic_cast<BrookStreamInternal*> (velocityStream.getBrookStreamImpl());
193

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
194
      void* velV                       = outputVelocityStream->getData( 1 );
195
196
197
198
199
200
      const float* vArray              = (float*) velV;

      void* w1                        = getWorkStream()->getData( 1 );
      const float* w2                 = (float*) w1;

      int index                        = 0;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
201
      for( int ii = 0; ii < getNumberOfParticles(); ii++, index += 3 ){
202
203
         (void) fprintf( getLog(), "V %d [%12.5e %12.5e %12.5e] [%12.5e %12.5e %12.5e]\n", ii,
                         vArray[index], vArray[index+1], vArray[index+2], w2[index], w2[index+1], w2[index+2] );
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
204

205
      }
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
206

207
      (void) fflush( getLog() );
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
208

209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
//exit(0);
   }

   return DefaultReturnValue;
}

/**
 * Get velocity-COM
 *
 * @param velocities velocities
 * @param  velocityCom                 output velocity com
 *
 * @return DefaultReturnValue
 *
 */
   
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
225
int BrookVelocityCenterOfMassRemoval::getVelocityCenterOfMass( BrookStreamImpl& vStream, BrookOpenMMFloat velocityCom[3] ){
226
227
228
229
230
231
232
233
234
235
236
237

   // ---------------------------------------------------------------------------------------

   // static const char* methodName  = "\nBrookVelocityCenterOfMassRemoval::getVelocityCenterOfMass";

   BrookOpenMMFloat zero    = (BrookOpenMMFloat) 0.0;

   // ---------------------------------------------------------------------------------------

   // calculate linear momentum via reduction
   // subtract it (/totalMass) from velocities

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
238
   BrookStreamInternal* velocityStream  = dynamic_cast<BrookStreamInternal*> (vStream.getBrookStreamImpl());
239
240
241
242

   void* velV                           = velocityStream->getData( 1 );
   const float* vArray                  = (float*) velV;

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
243
   void* massV                          = getMassStream()->getData( 1 );
244
245
   const float* mArray                  = (float*) massV;

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
246
   int numberOfParticles                = getNumberOfParticles();
247
248
249
250
   int index                            = 0;

   velocityCom[0] = velocityCom[1] = velocityCom[2] = zero;

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
251
   for( int ii = 0; ii < numberOfParticles; ii++, index += 3 ){
252
253
254
255
256
      velocityCom[0] += mArray[ii]*vArray[index];
      velocityCom[1] += mArray[ii]*vArray[index+1];
      velocityCom[2] += mArray[ii]*vArray[index+2];
   }

257
258
259
260
   return DefaultReturnValue;
}

/** 
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
261
 * Get Particle stream size
262
 *
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
263
 * @return  Particle stream size
264
265
266
 *
 */

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
267
268
int BrookVelocityCenterOfMassRemoval::getComParticleStreamSize( void ) const {
   return _particleStreamSize;
269
270
271
}

/** 
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
272
 * Get particle stream width
273
 *
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
274
 * @return  particle stream width
275
276
277
 *
 */

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
278
279
int BrookVelocityCenterOfMassRemoval::getComParticleStreamWidth( void ) const {
   return _particleStreamWidth;
280
281
282
}

/** 
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
283
 * Get particle stream height
284
 *
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
285
 * @return particle stream height
286
287
 */

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
288
289
int BrookVelocityCenterOfMassRemoval::getComParticleStreamHeight( void ) const {
   return _particleStreamHeight;
290
291
292
293
294
}

/** 
 * Initialize stream dimensions
 * 
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
295
 * @param numberOfParticles             number of particles
296
297
298
299
300
301
 * @param platform                  platform
 *      
 * @return ErrorReturnValue if error, else DefaultReturnValue
 *
 */

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
302
int BrookVelocityCenterOfMassRemoval::_initializeStreamSizes( int numberOfParticles, const Platform& platform ){
303
304
305
306
307
308
309

// ---------------------------------------------------------------------------------------

   //static const std::string methodName      = "BrookVelocityCenterOfMassRemoval::_initializeStreamSizes";

// ---------------------------------------------------------------------------------------

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
310
311
312
   _particleStreamSize     = getParticleStreamSize( platform );
   _particleStreamWidth    = getParticleStreamWidth( platform );
   _particleStreamHeight   = getParticleStreamHeight( platform );
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331

   return DefaultReturnValue;
}

/** 
 * Initialize streams
 * 
 * @param platform                  platform
 *
 * @return ErrorReturnValue if error, else DefaultReturnValue
 *
 */

int BrookVelocityCenterOfMassRemoval::_initializeStreams( const Platform& platform ){

// ---------------------------------------------------------------------------------------

   //static const std::string methodName      = "BrookVelocityCenterOfMassRemoval::_initializeStreams";

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
332
   BrookOpenMMFloat dangleValue     = (BrookOpenMMFloat) 0.0;
333
334
335

// ---------------------------------------------------------------------------------------

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
336
337
   int particleStreamSize           = getComParticleStreamSize();
   int particleStreamWidth          = getComParticleStreamWidth();
338
339

    _streams[WorkStream]            = new BrookFloatStreamInternal( BrookCommon::BrookVelocityCenterOfMassRemovalWorkStream,
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
340
                                                                    particleStreamSize, particleStreamWidth,
341
                                                                    BrookStreamInternal::Float3, dangleValue );
342
343
344


    _streams[MassStream]            = new BrookFloatStreamInternal( BrookCommon::BrookVelocityCenterOfMassRemovalMassStream,
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
345
                                                                    particleStreamSize, particleStreamWidth,
346
347
348
349
                                                                    BrookStreamInternal::Float, dangleValue );


    _streams[LinearMomentumStream]  = new BrookFloatStreamInternal( "LinearMomentumStream",
350
                                                                    1, 1, BrookStreamInternal::Float3, dangleValue );
351
352
353
354
355
356


   return DefaultReturnValue;
}

/** 
357
 * Set masses & _totalInverseMass 
358
 * 
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
359
 * @param masses             particle masses
360
361
362
363
364
365
366
367
368
369
370
371
372
373
 *
 */

int BrookVelocityCenterOfMassRemoval::_setMasses( const std::vector<double>& masses ){

// ---------------------------------------------------------------------------------------

   static const std::string methodName      = "BrookVelocityCenterOfMassRemoval::_setMasses";

   BrookOpenMMFloat zero                    = (BrookOpenMMFloat)  0.0;
   BrookOpenMMFloat one                     = (BrookOpenMMFloat)  1.0;

// ---------------------------------------------------------------------------------------

374
375
   // check that masses vector is not larger than expected

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
376
   if( (int) masses.size() > getComParticleStreamSize() ){
377
      std::stringstream message;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
378
      message << methodName << " mass array size=" << masses.size() << " is larger than stream size=" << getComParticleStreamSize();
379
380
381
      throw OpenMMException( message.str() );
   }

382
   // setup masses
383

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
384
385
   BrookOpenMMFloat* localMasses = new BrookOpenMMFloat[getComParticleStreamSize()];
   memset( localMasses, 0, sizeof( BrookOpenMMFloat )*getComParticleStreamSize() );
386
387
388
389
390
391

   int index          = 0;
   _totalInverseMass  = (BrookOpenMMFloat) 0.0;
   for( std::vector<double>::const_iterator ii = masses.begin(); ii != masses.end(); ii++, index++ ){
      if( *ii != 0.0 ){
         BrookOpenMMFloat value    = static_cast<BrookOpenMMFloat>(*ii);
392
         localMasses[index]        = value;
393
394
395
         _totalInverseMass        += value;
      }
   }
396
397
398

   // 1/Sum[masses]

399
400
401
402
   if( _totalInverseMass > zero ){
      _totalInverseMass = one/_totalInverseMass;
   }

403
404
405
   // write masses to board

   _streams[MassStream]->loadFromArray( localMasses );
406

407
   delete[] localMasses;
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432

   return DefaultReturnValue;
}   
 
/*  
 * Setup of StochasticDynamics parameters
 *
 * @param masses                masses
 * @param platform              Brook platform
 *
 * @return nonzero value if error
 *
 * */
    
int BrookVelocityCenterOfMassRemoval::setup( const std::vector<double>& masses, const Platform& platform ){
    
// ---------------------------------------------------------------------------------------

   static const std::string methodName      = "BrookVelocityCenterOfMassRemoval::setup";

// ---------------------------------------------------------------------------------------

   const BrookPlatform brookPlatform        = dynamic_cast<const BrookPlatform&> (platform);
   setLog( brookPlatform.getLog() );

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
433
434
   int numberOfParticles  = (int) masses.size();
   setNumberOfParticles( numberOfParticles );
435
436
437

   // set stream sizes and then create streams

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
438
   _initializeStreamSizes( numberOfParticles, platform );
439
440
441
442
   _initializeStreams( platform );

   _setMasses( masses );

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
443
444
445
446
447
448
   if( 1 && getLog() ){
      std::string contents = getContentsString( 0 );
      (void) fprintf( getLog(), "%s contents:\n%s\n", methodName.c_str(), contents.c_str() );
      (void) fflush( getLog() );
   }
   
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
   return DefaultReturnValue;
}

/* 
 * Get contents of object
 *
 * @param level   level of dump
 *
 * @return string containing contents
 *
 * */

std::string BrookVelocityCenterOfMassRemoval::getContentsString( int level ) const {

// ---------------------------------------------------------------------------------------

   static const std::string methodName      = "BrookVelocityCenterOfMassRemoval::getContentsString";

   static const unsigned int MAX_LINE_CHARS = 256;
   char value[MAX_LINE_CHARS];
   static const char* Set                   = "Set";
   static const char* NotSet                = "Not set";

// ---------------------------------------------------------------------------------------

   std::stringstream message;
   std::string tab   = "   ";

#ifdef WIN32
#define LOCAL_SPRINTF(a,b,c) sprintf_s( (a), MAX_LINE_CHARS, (b), (c) );   
#else
#define LOCAL_SPRINTF(a,b,c) sprintf( (a), (b), (c) );   
#endif

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
483
484
   (void) LOCAL_SPRINTF( value, "%d", getNumberOfParticles() );
   message << _getLine( tab, "Number of particles:", value ); 
485

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
486
487
   (void) LOCAL_SPRINTF( value, "%d", getComParticleStreamWidth() );
   message << _getLine( tab, "Particle stream width:", value ); 
488

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
489
490
   (void) LOCAL_SPRINTF( value, "%d", getComParticleStreamHeight() );
   message << _getLine( tab, "Particle stream height:", value ); 
491

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
492
493
   (void) LOCAL_SPRINTF( value, "%d", getComParticleStreamSize() );
   message << _getLine( tab, "Particle stream size:", value ); 
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514

   (void) LOCAL_SPRINTF( value, "%.5f", getTotalInverseMass() );
   message << _getLine( tab, "TotalInverseMass:", value ); 

   message << _getLine( tab, "Log:",                  (getLog()                  ? Set : NotSet) ); 

   message << _getLine( tab, "Mass:",                 (getMassStream()           ? Set : NotSet) ); 
   message << _getLine( tab, "Work:",                 (getWorkStream()           ? Set : NotSet) ); 
   message << _getLine( tab, "LinearMomentum:",       (getLinearMomentumStream() ? Set : NotSet) ); 
 
   for( int ii = 0; ii < LastStreamIndex; ii++ ){
      message << std::endl;
      if( _streams[ii] ){
         message << _streams[ii]->getContentsString( );
      }
   }

#undef LOCAL_SPRINTF

   return message.str();
}