@@ -20,20 +20,22 @@ Action_Vector::Action_Vector() :
2020void Action_Vector::Help () const {
2121 mprintf (" \t [<name>] <Type> [out <filename> [ptrajoutput]] [<mask1>] [<mask2>]\n "
2222 " \t [magnitude] [ired]\n "
23- " \t <Type> = { mask | minimage | dipole | center | corrplane | \n "
24- " \t box | boxcenter | ucellx | ucelly | ucellz | \n "
25- " \t momentum | principal [x|y|z] }\n "
23+ " \t <Type> = { mask | minimage | dipole | center | corrplane | \n "
24+ " \t box | boxcenter | ucellx | ucelly | ucellz | \n "
25+ " \t momentum | principal [x|y|z] | velocity | force }\n "
2626 " Calculate the specified coordinate vector.\n "
2727 " mask: (Default) Vector from <mask1> to <mask2>.\n "
28- " minimage: Store the minimum image vector between atoms in <mask1> and <mask2>.\n "
29- " dipole: Dipole and center of mass of the atoms specified in <mask1>\n "
30- " center: Store the center of mass of atoms in <mask1>.\n "
31- " corrplane: Vector perpendicular to plane through the atoms in <mask1>.\n "
32- " box: (No mask needed) Store the box lengths of the trajectory.\n "
33- " boxcenter: (No mask needed) Store box center as vector.\n "
34- " ucell{x|y|z}: (No mask needed) Store specified unit cell vector.\n "
35- " momentum : Store total momentum vector of atoms in <mask1> (requires velocities).\n "
36- " principal [x|y|z]: X, Y, or Z principal axis vector for atoms in <mask1>.\n " );
28+ " minimage : Store the minimum image vector between atoms in <mask1> and <mask2>.\n "
29+ " dipole : Dipole and center of mass of the atoms specified in <mask1>\n "
30+ " center : Store the center of mass of atoms in <mask1>.\n "
31+ " corrplane : Vector perpendicular to plane through the atoms in <mask1>.\n "
32+ " box : (No mask needed) Store the box lengths of the trajectory.\n "
33+ " boxcenter : (No mask needed) Store box center as vector.\n "
34+ " ucell{x|y|z} : (No mask needed) Store specified unit cell vector.\n "
35+ " momentum : Store total momentum vector of atoms in <mask1> (requires velocities).\n "
36+ " principal [x|y|z]: X, Y, or Z principal axis vector for atoms in <mask1>.\n "
37+ " velocity : Store velocity of atoms in <mask1> (requires velocities).\n "
38+ " force : Store force of atoms in <mask1> (requires forces).\n " );
3739}
3840
3941// DESTRUCTOR
@@ -45,7 +47,7 @@ const char* Action_Vector::ModeString[] = {
4547 " NO_OP" , " Principal X" , " Principal Y" , " Principal Z" ,
4648 " Dipole" , " Box" , " Mask" , " Ired" ,
4749 " CorrPlane" , " Center" , " Unit cell X" , " Unit cell Y" , " Unit cell Z" ,
48- " Box Center" , " MinImage" , " Momentum"
50+ " Box Center" , " MinImage" , " Momentum" , " Velocity " , " Force "
4951};
5052
5153static Action::RetType WarnDeprecated () {
@@ -96,6 +98,10 @@ Action::RetType Action_Vector::Init(ArgList& actionArgs, ActionInit& init, int d
9698 mode_ = CENTER;
9799 else if (actionArgs.hasKey (" momentum" ))
98100 mode_ = MOMENTUM;
101+ else if (actionArgs.hasKey (" velocity" ))
102+ mode_ = VELOCITY;
103+ else if (actionArgs.hasKey (" force" ))
104+ mode_ = FORCE;
99105 else if (actionArgs.hasKey (" dipole" ))
100106 mode_ = DIPOLE;
101107 else if (actionArgs.hasKey (" box" ))
@@ -184,6 +190,15 @@ Action::RetType Action_Vector::Setup(ActionSetup& setup) {
184190 return Action::ERR;
185191 }
186192 }
193+ // Check for velocity/force
194+ if ((mode_ == MOMENTUM || mode_ == VELOCITY) && !setup.CoordInfo ().HasVel ()) {
195+ mprintf (" Warning: vector %s requires velocity information. Skipping.\n " , ModeString[mode_]);
196+ return Action::SKIP;
197+ }
198+ if (mode_ == FORCE && !setup.CoordInfo ().HasForce ()) {
199+ mprintf (" Warning: vector %s requires force information. Skipping.\n " , ModeString[mode_]);
200+ return Action::SKIP;
201+ }
187202 if (mask_.MaskStringSet ()) {
188203 // Setup mask 1
189204 if (setup.Top ().SetupIntegerMask (mask_)) return Action::ERR;
@@ -407,13 +422,29 @@ void Action_Vector::MinImage(Frame const& frm) {
407422 Vec3 com1 = frm.VCenterOfMass (mask_);
408423 Vec_->AddVxyz ( MinImagedVec (com1, frm.VCenterOfMass (mask2_), ucell, recip), com1 );
409424}
410-
425+
426+ // / \return The center of selected elements in given array.
427+ static inline Vec3 CalcCenter (const double * xyz, AtomMask const & maskIn) {
428+ Vec3 Coord (0.0 );
429+ for (AtomMask::const_iterator at = maskIn.begin (); at != maskIn.end (); ++at)
430+ {
431+ int idx = *at * 3 ;
432+ Coord[0 ] += xyz[idx ];
433+ Coord[1 ] += xyz[idx+1 ];
434+ Coord[2 ] += xyz[idx+2 ];
435+ }
436+ Coord /= (double )maskIn.Nselected ();
437+ return Coord;
438+ }
439+
411440// Action_Vector::DoAction()
412441Action::RetType Action_Vector::DoAction (int frameNum, ActionFrame& frm) {
413442 switch ( mode_ ) {
414443 case MASK : Mask (frm.Frm ()); break ;
415444 case CENTER : Vec_->AddVxyz ( frm.Frm ().VCenterOfMass (mask_) ); break ;
416- case MOMENTUM : Vec_->AddVxyz ( frm.Frm ().VMomentum (mask_) ); break ;
445+ case MOMENTUM : Vec_->AddVxyz ( frm.Frm ().VMomentum (mask_) ); break ;
446+ case VELOCITY : Vec_->AddVxyz ( CalcCenter (frm.Frm ().vAddress (), mask_) ); break ;
447+ case FORCE : Vec_->AddVxyz ( CalcCenter (frm.Frm ().fAddress (), mask_) ); break ;
417448 case DIPOLE : Dipole (frm.Frm ()); break ;
418449 case PRINCIPAL_X :
419450 case PRINCIPAL_Y :
0 commit comments