BrookVelocityCenterOfMassRemoval.cpp 17.6 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         = 0;
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
      const float* vArray              = (float*) velV;

      int index                        = 0;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
165
166
167
168
      if( debug > 1 ){
         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] );
         }
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
169
170
171
      }

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

174
175
176
177
   // 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
178
179
180
   kSumLinearMomentum( (float) getComParticleStreamWidth(), (float) getNumberOfParticles(), (float) getTotalInverseMass(),
                        getWorkStream()->getBrookStream(), getLinearMomentumStream()->getBrookStream() );
//   kScale( (float) getTotalInverseMass(), getLinearMomentumStream()->getBrookStream(), getLinearMomentumStream()->getBrookStream() );
181
182
   kRemoveLinearMomentum( getLinearMomentumStream()->getBrookStream(), velocityStream.getBrookStream(), velocityStream.getBrookStream() );

183
184
   if( (0 || debug) && getLog() ){
      BrookOpenMMFloat com[3];
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
185
      getVelocityCenterOfMass( velocityStream, com );
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
186
187
      (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
188
189
190
191
192

      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
193
      BrookStreamInternal* outputVelocityStream = dynamic_cast<BrookStreamInternal*> (velocityStream.getBrookStreamImpl());
194

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

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

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
201
202
203
204
205
206
207
      if( debug > 1 ){
         int index                        = 0;
         for( int ii = 0; ii < getNumberOfParticles(); ii++, index += 3 ){
            (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] );
   
         }
208
      }
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
209

210
      (void) fflush( getLog() );
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
211

212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
//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
228
int BrookVelocityCenterOfMassRemoval::getVelocityCenterOfMass( BrookStreamImpl& vStream, BrookOpenMMFloat velocityCom[3] ){
229
230
231
232
233
234
235
236
237
238
239
240

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

   // 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
241
   BrookStreamInternal* velocityStream  = dynamic_cast<BrookStreamInternal*> (vStream.getBrookStreamImpl());
242
243
244
245

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

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
246
   void* massV                          = getMassStream()->getData( 1 );
247
248
   const float* mArray                  = (float*) massV;

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
249
   int numberOfParticles                = getNumberOfParticles();
250
251
252
253
   int index                            = 0;

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

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

260
261
262
263
   return DefaultReturnValue;
}

/** 
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
264
 * Get Particle stream size
265
 *
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
266
 * @return  Particle stream size
267
268
269
 *
 */

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
270
271
int BrookVelocityCenterOfMassRemoval::getComParticleStreamSize( void ) const {
   return _particleStreamSize;
272
273
274
}

/** 
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
275
 * Get particle stream width
276
 *
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
277
 * @return  particle stream width
278
279
280
 *
 */

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
281
282
int BrookVelocityCenterOfMassRemoval::getComParticleStreamWidth( void ) const {
   return _particleStreamWidth;
283
284
285
}

/** 
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
286
 * Get particle stream height
287
 *
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
288
 * @return particle stream height
289
290
 */

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

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

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

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

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

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

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

   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
335
   BrookOpenMMFloat dangleValue     = (BrookOpenMMFloat) 0.0;
336
337
338

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

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
339
340
   int particleStreamSize           = getComParticleStreamSize();
   int particleStreamWidth          = getComParticleStreamWidth();
341
342

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


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


    _streams[LinearMomentumStream]  = new BrookFloatStreamInternal( "LinearMomentumStream",
353
                                                                    1, 1, BrookStreamInternal::Float3, dangleValue );
354
355
356
357
358
359


   return DefaultReturnValue;
}

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

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;

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

377
378
   // check that masses vector is not larger than expected

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

385
   // setup masses
386

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

   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);
395
         localMasses[index]        = value;
396
397
398
         _totalInverseMass        += value;
      }
   }
399
400
401

   // 1/Sum[masses]

402
403
404
405
   if( _totalInverseMass > zero ){
      _totalInverseMass = one/_totalInverseMass;
   }

406
407
408
   // write masses to board

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

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

   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
436
437
   int numberOfParticles  = (int) masses.size();
   setNumberOfParticles( numberOfParticles );
438
439
440

   // set stream sizes and then create streams

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
441
   _initializeStreamSizes( numberOfParticles, platform );
442
443
444
445
   _initializeStreams( platform );

   _setMasses( masses );

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
446
447
448
449
450
451
   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() );
   }
   
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
483
484
485
   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
486
487
   (void) LOCAL_SPRINTF( value, "%d", getNumberOfParticles() );
   message << _getLine( tab, "Number of particles:", value ); 
488

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

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

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

   (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();
}