66Action_SetVelocity::Action_SetVelocity () : tempi_(0.0 ), zeroMomentum_(false ) {}
77
88void Action_SetVelocity::Help () const {
9- mprintf (" \t [<mask>] [{tempi <temperature> | modify}] [ig <random seed>]\n "
9+ mprintf (" \t [<mask>] [{ tempi <temperature> |\n "
10+ " \t scale [factor <fac>] [sx <xfac>] [sy <yfac>] [sz <zfac>] |\n "
11+ " \t none | \n "
12+ " \t modify}] [ig <random seed>]\n "
1013 " \t [%s] [%s]\n " , Constraints::constraintArgs, Constraints::rattleArgs);
11- mprintf (" \t [zeromomentum]\n " );
14+ mprintf (" \t [zeromomentum] [ig <random seed>] \n " );
1215 mprintf (" Set velocities in frame for atoms in <mask> using Maxwellian distribution\n "
1316 " based on given temperature; default 300.0 K. If tempi is 0.0 set\n "
1417 " velocities of atoms in mask to 0.0.\n "
18+ " If 'scale' is specified scale the velocities by the given factor(s).\n "
19+ " If 'none' or a temperature of 0.0 is specified, velocities will be zeroed.\n "
1520 " If 'modify' is specified do not set; only modify existing velocities.\n "
1621 " This is useful e.g. with 'ntc' or 'zeromomentum'.\n "
1722 " If 'ntc' is specified attempt to correct velocities for constraints.\n "
@@ -24,11 +29,17 @@ Action::RetType Action_SetVelocity::Init(ArgList& actionArgs, ActionInit& init,
2429{
2530 // Keywords
2631 tempi_ = actionArgs.getKeyDouble (" tempi" , 300.0 );
27- if (tempi_ < Constants::SMALL)
32+ if (actionArgs. hasKey ( " none " ) || tempi_ < Constants::SMALL)
2833 mode_ = ZERO;
2934 else if (actionArgs.hasKey (" modify" ))
3035 mode_ = MODIFY;
31- else
36+ else if (actionArgs.hasKey (" scale" )) {
37+ double sf = actionArgs.getKeyDouble (" factor" , 1.0 );
38+ scaleFac_[0 ] = actionArgs.getKeyDouble (" sx" , sf);
39+ scaleFac_[1 ] = actionArgs.getKeyDouble (" sy" , sf);
40+ scaleFac_[2 ] = actionArgs.getKeyDouble (" sz" , sf);
41+ mode_ = SCALE;
42+ } else
3243 mode_ = SET;
3344 int ig_ = actionArgs.getKeyInt (" ig" , -1 );
3445 RN_.rn_set ( ig_ );
@@ -56,6 +67,9 @@ Action::RetType Action_SetVelocity::Init(ArgList& actionArgs, ActionInit& init,
5667 mprintf (" \t Random seed is %i\n " , ig_);
5768 } else if (mode_ == MODIFY)
5869 mprintf (" Modifying any existing velocities for atoms in mask '%s'\n " , Mask_.MaskString ());
70+ else if (mode_ == SCALE)
71+ mprintf (" Scaling velocities by X= %g, Y= %g, Z= %g\n " ,
72+ scaleFac_[0 ], scaleFac_[1 ], scaleFac_[2 ]);
5973 else if (mode_ == ZERO)
6074 mprintf (" Zeroing velocities for atoms in mask '%s'\n " , Mask_.MaskString ());
6175 if (cons_.Type () != Constraints::OFF) {
@@ -101,6 +115,11 @@ Action::RetType Action_SetVelocity::Setup(ActionSetup& setup) {
101115 mprintf (" Warning: 'modify' specified but no velocity info, skipping.\n " );
102116 return Action::SKIP;
103117 }
118+ // If scale need to have existing velocity info
119+ if (mode_ == SCALE && !setup.CoordInfo ().HasVel ()) {
120+ mprintf (" Warning: 'scale' specified but no velocity info, skipping.\n " );
121+ return Action::SKIP;
122+ }
104123 // Always add velocity info even if not strictly necessary
105124 cInfo_ = setup.CoordInfo ();
106125 cInfo_.SetVelocity ( true );
@@ -132,6 +151,14 @@ Action::RetType Action_SetVelocity::DoAction(int frameNum, ActionFrame& frm) {
132151 V[1 ] = RN_.rn_gauss (0.0 , *sd);
133152 V[2 ] = RN_.rn_gauss (0.0 , *sd);
134153 }
154+ } else if (mode_ == SCALE) {
155+ for (AtomMask::const_iterator atom = Mask_.begin (); atom != Mask_.end (); ++atom)
156+ {
157+ double * V = newFrame_.vAddress () + (*atom * 3 );
158+ V[0 ] *= scaleFac_[0 ];
159+ V[1 ] *= scaleFac_[1 ];
160+ V[2 ] *= scaleFac_[2 ];
161+ }
135162 }
136163 // Correct velocities for constraints
137164 if (cons_.Type () != Constraints::OFF)
0 commit comments