Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2015-2018 The plumed team
3 : (see the PEOPLE file at the root of the distribution for a list of names)
4 :
5 : See http://www.plumed.org for more information.
6 :
7 : This file is part of plumed, version 2.
8 :
9 : plumed is free software: you can redistribute it and/or modify
10 : it under the terms of the GNU Lesser General Public License as published by
11 : the Free Software Foundation, either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : plumed is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU Lesser General Public License for more details.
18 :
19 : You should have received a copy of the GNU Lesser General Public License
20 : along with plumed. If not, see <http://www.gnu.org/licenses/>.
21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 : #include "ActionWithVirtualAtom.h"
23 : #include "ActionRegister.h"
24 : #include "tools/Vector.h"
25 : #include "tools/Exception.h"
26 :
27 : using namespace std;
28 :
29 : namespace PLMD {
30 : namespace vatom {
31 :
32 : //+PLUMEDOC VATOM FIXEDATOM
33 : /*
34 : Add a virtual atom in a fixed position.
35 :
36 : This action creates a virtual atom at a fixed position.
37 : The coordinates can be specified in cartesian components (by default)
38 : or in scaled coordinats (SCALED_COMPONENTS).
39 : It is also possible to assign a predefined charge or mass to the atom.
40 :
41 : \attention
42 : Similar to \ref POSITION this variable is not invariant for translation
43 : of the system. Adding a force on it can create serious troubles.
44 :
45 : Notice that the distance between to atoms created
46 : using FIXEDATOM is invariant for translation.
47 : Additionally, if one first align atoms to a reference using \ref FIT_TO_TEMPLATE,
48 : then it is safe to add further fixed atoms without breaking translational invariance.
49 :
50 : \par Examples
51 :
52 : The following input instructs plumed to compute the angle between
53 : distance of atoms 15 and 20 and the z axis and keeping it close to zero.
54 : \verbatim
55 : a: FIXEDATOM AT=0,0,0
56 : b: FIXEDATOM AT=0,0,1
57 : an: ANGLE ATOMS=a,b,15,20
58 : RESTRAINT ARG=an AT=0.0 KAPPA=100.0
59 : \endverbatim
60 : (See also \ref ANGLE and \ref RESTRAINT).
61 :
62 : The following input instructs plumed to align a protein on a template
63 : and then compute the distance of one of its atom from the point
64 : (10,20,30).
65 : \verbatim
66 : FIT_TO_TEMPLATE STRIDE=1 REFERENCE=ref.pdb TYPE=SIMPLE
67 : a: FIXEDATOM AT=10,20,30
68 : d: DISTANCE ATOMS=a,20
69 : PRINT ARG=d FILE=colvar
70 : \endverbatim
71 : (See also \ref FIT_TO_TEMPLATE and \ref DISTANCE).
72 :
73 :
74 : */
75 : //+ENDPLUMEDOC
76 :
77 :
78 10 : class FixedAtom:
79 : public ActionWithVirtualAtom
80 : {
81 : Vector coord;
82 : double mass,charge;
83 : bool scaled_components;
84 : public:
85 : explicit FixedAtom(const ActionOptions&ao);
86 : void calculate();
87 : static void registerKeywords( Keywords& keys );
88 : };
89 :
90 2528 : PLUMED_REGISTER_ACTION(FixedAtom,"FIXEDATOM")
91 :
92 6 : void FixedAtom::registerKeywords(Keywords& keys) {
93 6 : ActionWithVirtualAtom::registerKeywords(keys);
94 6 : keys.add("compulsory","AT","coordinates of the virtual atom");
95 6 : keys.add("compulsory","SET_MASS","1","mass of the virtual atom");
96 6 : keys.add("compulsory","SET_CHARGE","0","charge of the virtual atom");
97 6 : keys.addFlag("SCALED_COMPONENTS",false,"use scaled components");
98 6 : }
99 :
100 5 : FixedAtom::FixedAtom(const ActionOptions&ao):
101 : Action(ao),
102 5 : ActionWithVirtualAtom(ao)
103 : {
104 5 : vector<AtomNumber> atoms;
105 5 : parseAtomList("ATOMS",atoms);
106 5 : if(atoms.size()!=0) error("ATOMS should be empty");
107 :
108 5 : parseFlag("SCALED_COMPONENTS",scaled_components);
109 :
110 10 : vector<double> at;
111 5 : parseVector("AT",at);
112 5 : if(at.size()!=3) error("AT should be a list of three real numbers");
113 :
114 5 : parse("SET_MASS",mass);
115 5 : parse("SET_CHARGE",charge);
116 :
117 5 : coord[0]=at[0];
118 5 : coord[1]=at[1];
119 5 : coord[2]=at[2];
120 :
121 5 : checkRead();
122 5 : log<<" AT position "<<coord[0]<<" "<<coord[1]<<" "<<coord[2]<<"\n";
123 10 : if(scaled_components) log<<" position is in scaled components\n";
124 5 : }
125 :
126 13 : void FixedAtom::calculate() {
127 13 : vector<Tensor> deriv(getNumberOfAtoms());
128 13 : if(scaled_components) {
129 5 : setPosition(getPbc().scaledToReal(coord));
130 : } else {
131 8 : setPosition(coord);
132 : }
133 13 : setMass(mass);
134 13 : setCharge(charge);
135 13 : setAtomsDerivatives(deriv);
136 : // Virial contribution
137 13 : if(!scaled_components) setBoxDerivativesNoPbc();
138 : // notice that with scaled components there is no additional virial contribution
139 13 : }
140 :
141 : }
142 2523 : }
|