Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2015-2019 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 : \plumedfile
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 : \endplumedfile
60 :
61 : The following input instructs plumed to align a protein on a template
62 : and then compute the distance of one of its atom from the point
63 : (10,20,30).
64 : \plumedfile
65 : FIT_TO_TEMPLATE STRIDE=1 REFERENCE=ref.pdb TYPE=SIMPLE
66 : a: FIXEDATOM AT=10,20,30
67 : d: DISTANCE ATOMS=a,20
68 : PRINT ARG=d FILE=colvar
69 : \endplumedfile
70 :
71 :
72 : */
73 : //+ENDPLUMEDOC
74 :
75 :
76 6 : class FixedAtom:
77 : public ActionWithVirtualAtom
78 : {
79 : Vector coord;
80 : double mass,charge;
81 : bool scaled_components;
82 : public:
83 : explicit FixedAtom(const ActionOptions&ao);
84 : void calculate();
85 : static void registerKeywords( Keywords& keys );
86 : };
87 :
88 6458 : PLUMED_REGISTER_ACTION(FixedAtom,"FIXEDATOM")
89 :
90 7 : void FixedAtom::registerKeywords(Keywords& keys) {
91 7 : ActionWithVirtualAtom::registerKeywords(keys);
92 28 : keys.add("compulsory","AT","coordinates of the virtual atom");
93 35 : keys.add("compulsory","SET_MASS","1","mass of the virtual atom");
94 35 : keys.add("compulsory","SET_CHARGE","0","charge of the virtual atom");
95 21 : keys.addFlag("SCALED_COMPONENTS",false,"use scaled components");
96 7 : }
97 :
98 6 : FixedAtom::FixedAtom(const ActionOptions&ao):
99 : Action(ao),
100 6 : ActionWithVirtualAtom(ao)
101 : {
102 : vector<AtomNumber> atoms;
103 12 : parseAtomList("ATOMS",atoms);
104 6 : if(atoms.size()!=0) error("ATOMS should be empty");
105 :
106 12 : parseFlag("SCALED_COMPONENTS",scaled_components);
107 :
108 : vector<double> at;
109 12 : parseVector("AT",at);
110 6 : if(at.size()!=3) error("AT should be a list of three real numbers");
111 :
112 12 : parse("SET_MASS",mass);
113 12 : parse("SET_CHARGE",charge);
114 :
115 6 : coord[0]=at[0];
116 6 : coord[1]=at[1];
117 6 : coord[2]=at[2];
118 :
119 6 : checkRead();
120 6 : log<<" AT position "<<coord[0]<<" "<<coord[1]<<" "<<coord[2]<<"\n";
121 6 : if(scaled_components) log<<" position is in scaled components\n";
122 6 : }
123 :
124 34 : void FixedAtom::calculate() {
125 34 : vector<Tensor> deriv(getNumberOfAtoms());
126 34 : if(scaled_components) {
127 10 : setPosition(getPbc().scaledToReal(coord));
128 : } else {
129 : setPosition(coord);
130 : }
131 34 : setMass(mass);
132 34 : setCharge(charge);
133 : setAtomsDerivatives(deriv);
134 : // Virial contribution
135 34 : if(!scaled_components) setBoxDerivativesNoPbc();
136 : // notice that with scaled components there is no additional virial contribution
137 34 : }
138 :
139 : }
140 4839 : }
|