Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2016-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 "Colvar.h"
23 : #include "ActionRegister.h"
24 : #include "tools/Pbc.h"
25 :
26 : #include <string>
27 : #include <cmath>
28 :
29 : using namespace std;
30 :
31 : namespace PLMD {
32 : namespace colvar {
33 :
34 : //+PLUMEDOC COLVAR FRET
35 : /*
36 : Calculate the FRET efficiency between a pair of atoms.
37 : The efficiency is calculated using the Forster relation:
38 :
39 : \f[
40 : E=\frac{1}{1+(R/R_0)^6}
41 : \f]
42 :
43 : where \f$R\f$ is the distance and \f$R_0\f$ is the Forster radius.
44 :
45 : By default the distance is computed taking into account periodic
46 : boundary conditions. This behavior can be changed with the NOPBC flag.
47 :
48 :
49 : \par Examples
50 :
51 : The following input tells plumed to print the FRET efficiencies
52 : calculated as a function of the distance between atoms 3 and 5 and
53 : the distance between atoms 2 and 4.
54 : \verbatim
55 : fe1: FRET ATOMS=3,5 R0=5.5
56 : fe2: FRET ATOMS=2,4 R0=5.5
57 : PRINT ARG=fe1,fe2
58 : \endverbatim
59 : (See also \ref PRINT).
60 :
61 : The following input computes the FRET efficiency calculated on the
62 : terminal atoms of a polymer
63 : of 100 atoms and keeps it at a value around 0.5.
64 : \verbatim
65 : WHOLEMOLECULES ENTITY0=1-100
66 : fe: FRET ATOMS=1,100 R0=5.5 NOPBC
67 : RESTRAINT ARG=fe KAPPA=100 AT=0.5
68 : \endverbatim
69 : (See also \ref WHOLEMOLECULES and \ref RESTRAINT).
70 :
71 : Notice that NOPBC is used
72 : to be sure that if the distance is larger than half the simulation
73 : box the distance is compute properly. Also notice that, since many MD
74 : codes break molecules across cell boundary, it might be necessary to
75 : use the \ref WHOLEMOLECULES keyword (also notice that it should be
76 : _before_ FRET).
77 : Just be sure that the ordered list provide to WHOLEMOLECULES has the following
78 : properties:
79 : - Consecutive atoms should be closer than half-cell throughout the entire simulation.
80 : - Atoms required later for the distance (e.g. 1 and 100) should be included in the list
81 :
82 : */
83 : //+ENDPLUMEDOC
84 :
85 0 : class FretEfficiency : public Colvar {
86 : bool pbc;
87 : double R0_;
88 :
89 : public:
90 : static void registerKeywords( Keywords& keys );
91 : explicit FretEfficiency(const ActionOptions&);
92 : // active methods:
93 : virtual void calculate();
94 : };
95 :
96 2523 : PLUMED_REGISTER_ACTION(FretEfficiency,"FRET")
97 :
98 1 : void FretEfficiency::registerKeywords( Keywords& keys ) {
99 1 : Colvar::registerKeywords( keys );
100 1 : keys.add("atoms","ATOMS","the pair of atom that we are calculating the distance between");
101 1 : keys.add("compulsory","R0","The value of the Forster radius.");
102 1 : }
103 :
104 0 : FretEfficiency::FretEfficiency(const ActionOptions&ao):
105 : PLUMED_COLVAR_INIT(ao),
106 0 : pbc(true)
107 : {
108 0 : vector<AtomNumber> atoms;
109 0 : parseAtomList("ATOMS",atoms);
110 0 : if(atoms.size()!=2)
111 0 : error("Number of specified atoms should be 2");
112 0 : parse("R0",R0_);
113 0 : bool nopbc=!pbc;
114 0 : parseFlag("NOPBC",nopbc);
115 0 : pbc=!nopbc;
116 0 : checkRead();
117 :
118 0 : log.printf(" between atoms %d %d\n",atoms[0].serial(),atoms[1].serial());
119 0 : log.printf(" with Forster radius set to %lf\n",R0_);
120 :
121 0 : if(pbc) log.printf(" using periodic boundary conditions\n");
122 0 : else log.printf(" without periodic boundary conditions\n");
123 :
124 0 : addValueWithDerivatives();
125 0 : setNotPeriodic();
126 :
127 0 : requestAtoms(atoms);
128 0 : }
129 :
130 :
131 : // calculator
132 0 : void FretEfficiency::calculate() {
133 :
134 0 : if(pbc) makeWhole();
135 :
136 0 : Vector distance=delta(getPosition(0),getPosition(1));
137 0 : const double dist_mod=distance.modulo();
138 0 : const double inv_dist_mod=1.0/dist_mod;
139 :
140 0 : const double ratiosix=pow(dist_mod/R0_,6);
141 0 : const double fret_eff = 1.0/(1.0+ratiosix);
142 :
143 0 : const double der = -6.0*fret_eff*fret_eff*ratiosix*inv_dist_mod;
144 :
145 0 : setAtomsDerivatives(0,-inv_dist_mod*der*distance);
146 0 : setAtomsDerivatives(1, inv_dist_mod*der*distance);
147 0 : setBoxDerivativesNoPbc();
148 0 : setValue(fret_eff);
149 :
150 0 : }
151 :
152 : }
153 2523 : }
154 :
155 :
156 :
|