Skip to content
Snippets Groups Projects
Commit e32accaf authored by Giovanni Bussi's avatar Giovanni Bussi
Browse files

Merge remote-tracking branch 'origin/v2.5' into v2.5

parents 5c96bc75 24aca3a2
No related branches found
No related tags found
No related merge requests found
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 2011-2018 The plumed team
(see the PEOPLE file at the root of the distribution for a list of names)
See http://www.plumed.org for more information.
This file is part of plumed, version 2.
plumed is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
plumed is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with plumed. If not, see <http://www.gnu.org/licenses/>.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
#include "ActionWithVirtualAtom.h"
#include "ActionRegister.h"
#include "core/PlumedMain.h"
#include "core/Atoms.h"
#include <cmath>
using namespace std;
namespace PLMD {
namespace vatom {
//+PLUMEDOC VATOM COM
/*
Calculate the center of mass for a group of atoms.
The computed
center of mass is stored as a virtual atom that can be accessed in
an atom list through the label for the COM action that creates it.
For arbitrary weights (e.g. geometric center) see \ref CENTER.
When running with periodic boundary conditions, the atoms should be
in the proper periodic image. This is done automatically since PLUMED 2.2,
by considering the ordered list of atoms and rebuilding PBCs with a procedure
that is equivalent to that done in \ref WHOLEMOLECULES . Notice that
rebuilding is local to this action. This is different from \ref WHOLEMOLECULES
which actually modifies the coordinates stored in PLUMED.
In case you want to recover the old behavior you should use the NOPBC flag.
In that case you need to take care that atoms are in the correct
periodic image.
\par Examples
The following input instructs plumed to print the distance between the
center of mass for atoms 1,2,3,4,5,6,7 and that for atoms 15,20:
\plumedfile
c1: COM ATOMS=1-7
c2: COM ATOMS=15,20
d1: DISTANCE ATOMS=c1,c2
PRINT ARG=d1
\endplumedfile
*/
//+ENDPLUMEDOC
class COM:
public ActionWithVirtualAtom
{
bool nopbc;
bool first;
public:
explicit COM(const ActionOptions&ao);
void calculate();
static void registerKeywords( Keywords& keys );
};
PLUMED_REGISTER_ACTION(COM,"COM")
void COM::registerKeywords(Keywords& keys) {
ActionWithVirtualAtom::registerKeywords(keys);
keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
}
COM::COM(const ActionOptions&ao):
Action(ao),
ActionWithVirtualAtom(ao),
nopbc(false),
first(true)
{
vector<AtomNumber> atoms;
parseAtomList("ATOMS",atoms);
if(atoms.size()==0) error("at least one atom should be specified");
parseFlag("NOPBC",nopbc);
checkRead();
log.printf(" of atoms");
for(unsigned i=0; i<atoms.size(); ++i) {
if(i%25==0) log<<"\n";
log.printf(" %d",atoms[i].serial());
}
log.printf("\n");
if(nopbc) {
log<<" PBC will be ignored\n";
} else {
log<<" broken molecules will be rebuilt assuming atoms are in the proper order\n";
}
requestAtoms(atoms);
}
void COM::calculate() {
Vector pos;
if(!nopbc) makeWhole();
double mass(0.0);
if( first ) {
for(unsigned i=0; i<getNumberOfAtoms(); i++) {
if(std::isnan(getMass(i))) {
error(
"You are trying to compute a COM but masses are not known.\n"
" If you are using plumed driver, please use the --mc option"
);
}
}
first=false;
}
vector<Tensor> deriv(getNumberOfAtoms());
for(unsigned i=0; i<getNumberOfAtoms(); i++) mass+=getMass(i);
if( plumed.getAtoms().chargesWereSet() ) {
double charge(0.0);
for(unsigned i=0; i<getNumberOfAtoms(); i++) charge+=getCharge(i);
setCharge(charge);
} else {
setCharge(0.0);
}
for(unsigned i=0; i<getNumberOfAtoms(); i++) {
pos+=(getMass(i)/mass)*getPosition(i);
deriv[i]=(getMass(i)/mass)*Tensor::identity();
}
setPosition(pos);
setMass(mass);
setAtomsDerivatives(deriv);
}
}
}
......@@ -23,6 +23,7 @@
#include "ActionRegister.h"
#include "core/PlumedMain.h"
#include "core/Atoms.h"
#include <cmath>
using namespace std;
......@@ -81,6 +82,41 @@ PRINT ARG=d1
*/
//+ENDPLUMEDOC
//+PLUMEDOC VATOM COM
/*
Calculate the center of mass for a group of atoms.
The computed
center of mass is stored as a virtual atom that can be accessed in
an atom list through the label for the COM action that creates it.
For arbitrary weights (e.g. geometric center) see \ref CENTER.
When running with periodic boundary conditions, the atoms should be
in the proper periodic image. This is done automatically since PLUMED 2.2,
by considering the ordered list of atoms and rebuilding PBCs with a procedure
that is equivalent to that done in \ref WHOLEMOLECULES . Notice that
rebuilding is local to this action. This is different from \ref WHOLEMOLECULES
which actually modifies the coordinates stored in PLUMED.
In case you want to recover the old behavior you should use the NOPBC flag.
In that case you need to take care that atoms are in the correct
periodic image.
\par Examples
The following input instructs plumed to print the distance between the
center of mass for atoms 1,2,3,4,5,6,7 and that for atoms 15,20:
\plumedfile
c1: COM ATOMS=1-7
c2: COM ATOMS=15,20
d1: DISTANCE ATOMS=c1,c2
PRINT ARG=d1
\endplumedfile
*/
//+ENDPLUMEDOC
class Center:
public ActionWithVirtualAtom
......@@ -90,6 +126,7 @@ class Center:
std::vector<Tensor> dcenter_cos;
bool weight_mass;
bool nopbc;
bool first;
bool phases;
public:
explicit Center(const ActionOptions&ao);
......@@ -98,6 +135,7 @@ public:
};
PLUMED_REGISTER_ACTION(Center,"CENTER")
PLUMED_REGISTER_ACTION(Center,"COM")
void Center::registerKeywords(Keywords& keys) {
ActionWithVirtualAtom::registerKeywords(keys);
......@@ -112,6 +150,7 @@ Center::Center(const ActionOptions&ao):
ActionWithVirtualAtom(ao),
weight_mass(false),
nopbc(false),
first(true),
phases(false)
{
vector<AtomNumber> atoms;
......@@ -121,6 +160,7 @@ Center::Center(const ActionOptions&ao):
parseFlag("MASS",weight_mass);
parseFlag("NOPBC",nopbc);
parseFlag("PHASES",phases);
if( getName()=="COM") weight_mass=true;
checkRead();
log.printf(" of atoms:");
for(unsigned i=0; i<atoms.size(); ++i) {
......@@ -162,6 +202,19 @@ void Center::calculate() {
const bool dophases=(getPbc().isSet() ? phases : false);
if(!nopbc && !dophases) makeWhole();
if( first && weight_mass) {
for(unsigned i=0; i<getNumberOfAtoms(); i++) {
if(std::isnan(getMass(i))) {
error(
"You are trying to compute a CENTER or COM but masses are not known.\n"
" If you are using plumed driver, please use the --mc option"
);
}
}
first=false;
}
vector<Tensor> deriv(getNumberOfAtoms());
for(unsigned i=0; i<getNumberOfAtoms(); i++) mass+=getMass(i);
if( plumed.getAtoms().chargesWereSet() ) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment