Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2014-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 "core/ActionRegister.h"
23 : #include "tools/SwitchingFunction.h"
24 : #include "MultiColvarFilter.h"
25 :
26 : //+PLUMEDOC MTRANSFORMS MTRANSFORM_MORE
27 : /*
28 : This action can be useed to transform the colvar values calculated by a multicolvar using one minus a \ref switchingfunction
29 :
30 : In this action each colvar, \f$s_i\f$, calculated by multicolvar is transformed by a \ref switchingfunction function that
31 : is equal to one if the colvar is greater than a certain target value and which is equal to zero otherwise.
32 : It is important to understand the distinction between what is done here and what is done by \ref MFILTER_MORE.
33 : In \ref MFILTER_MORE a weight, \f$w_i\f$ for the colvar is calculated using the \ref histogrambead. If one calculates the
34 : MEAN for \ref MFILTER_MORE one is thus calculating:
35 :
36 : \f[
37 : \mu = \frac{ \sum_i [1 - \sigma(s_i) ] s_i }{\sum_i [1 - \sigma(s_i)] }
38 : \f]
39 :
40 : where \f$\sigma\f$ is the \ref switchingfunction. In this action by contrast the colvar is being transformed by the \ref switchingfunction.
41 : If one thus calculates a MEAN for this action one computes:
42 :
43 : \f[
44 : \mu = \frac{ \sum_{i=1}^N 1 - \sigma(s_i) }{ N }
45 : \f]
46 :
47 : In other words, you are calculating the mean for the transformed colvar.
48 :
49 : \par Examples
50 :
51 : The following input gives an example of how a MTRANSFORM_MORE action can be used to duplicate
52 : functionality that is elsehwere in PLUMED.
53 :
54 : \plumedfile
55 : DISTANCES ...
56 : GROUPA=1-10 GROUPB=11-20
57 : LABEL=d1
58 : ... DISTANCES
59 : MTRANSFORM_MORE DATA=d1 SWITCH={GAUSSIAN D_0=1.5 R_0=0.00001}
60 : \endplumedfile
61 :
62 : In this case you can achieve the same result by using:
63 :
64 : \plumedfile
65 : DISTANCES ...
66 : GROUPA=1-10 GROUPB=11-20
67 : MORE_THAN={GAUSSIAN D_0=1.5 R_0=0.00001}
68 : ... DISTANCES
69 : \endplumedfile
70 : (see \ref DISTANCES)
71 :
72 : The advantage of MTRANSFORM_MORE comes, however, if you want to use transformed colvars as input
73 : for \ref MULTICOLVARDENS
74 :
75 : */
76 : //+ENDPLUMEDOC
77 :
78 : //+PLUMEDOC MFILTERS MFILTER_MORE
79 : /*
80 : This action can be used to filter the distribution of colvar values in a multicolvar
81 : so that one can compute the mean and so on for only those multicolvars more than a tolerance.
82 :
83 : This action can be used to create a dynamic group of atom based on the value of a multicolvar.
84 : In this action a multicolvar is within the dynamic group if its value is greater than a target.
85 : In practise a weight, \f$w_i\f$ is ascribed to each colvar, \f$s_i\f$ calculated by a multicolvar
86 : and this weight measures the degree to which a colvar is a member of the group. This weight is
87 : calculated using a \ref switchingfunction , \f$\sigma\f$ so it is given by:
88 :
89 : \f[
90 : w_i = 1 - \sigma(s_i)
91 : \f]
92 :
93 : If one calculates a function of the set of multicolvars
94 : these weights are included in the calculation. As such if one calculates the MEAN, \f$\mu\f$ of a filtered
95 : multicolvar what is computed is the following:
96 :
97 : \f[
98 : \mu = \frac{ \sum_i w_i s_i }{ \sum_i w_i}
99 : \f]
100 :
101 : One is thus calculating the mean for those colvars that are greater than the target.
102 :
103 : \par Examples
104 :
105 : The example shown below calculates the mean for those distances that greater than 1.5 nm in length
106 :
107 : \plumedfile
108 : DISTANCES GROUPA=1 GROUPB=2-50 MEAN LABEL=d1
109 : MFILTER_MORE DATA=d1 SWITCH={GAUSSIAN D_0=1.5 R_0=0.00001} MEAN LABEL=d4
110 : \endplumedfile
111 :
112 : More complicated things can be done by using the label of a filter as input to a new multicolvar as shown
113 : in the example below. Here the coordination numbers of all atoms are computed. The atoms with a coordination
114 : number greater than 2 are then identified using the filter. This reduced list of atoms is then used as input
115 : to a second coordination number calculation. This second coordination number thus measures the number of
116 : two-coordinated atoms that each of the two-coordinated atoms is bound to.
117 :
118 : \plumedfile
119 : 1: COORDINATIONNUMBER SPECIES=1-150 SWITCH={EXP D_0=4.0 R_0=0.5 D_MAX=6.0}
120 : cf: MFILTER_MORE DATA=c1 SWITCH={RATIONAL D_0=2.0 R_0=0.1} LOWMEM
121 : c2: COORDINATIONNUMBER SPECIES=cf SWITCH={EXP D_0=4.0 R_0=0.5 D_MAX=6.0} MORE_THAN={RATIONAL D_0=2.0 R_0=0.1}
122 : \endplumedfile
123 :
124 : */
125 : //+ENDPLUMEDOC
126 :
127 : namespace PLMD {
128 : namespace multicolvar {
129 :
130 14 : class FilterMore : public MultiColvarFilter {
131 : private:
132 : SwitchingFunction sf;
133 : public:
134 : static void registerKeywords( Keywords& keys );
135 : explicit FilterMore(const ActionOptions& ao);
136 : double applyFilter( const double& val, double& df ) const ;
137 : };
138 :
139 6458 : PLUMED_REGISTER_ACTION(FilterMore,"MFILTER_MORE")
140 6453 : PLUMED_REGISTER_ACTION(FilterMore,"MTRANSFORM_MORE")
141 :
142 9 : void FilterMore::registerKeywords( Keywords& keys ) {
143 9 : MultiColvarFilter::registerKeywords( keys );
144 45 : keys.add("compulsory","NN","6","The n parameter of the switching function ");
145 45 : keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
146 45 : keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
147 36 : keys.add("compulsory","R_0","The r_0 parameter of the switching function");
148 36 : keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous swiching function defined above. "
149 : "The following provides information on the \\ref switchingfunction that are available. "
150 : "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
151 9 : }
152 :
153 7 : FilterMore::FilterMore(const ActionOptions& ao):
154 : Action(ao),
155 7 : MultiColvarFilter(ao)
156 : {
157 : // Read in the switching function
158 14 : std::string sw, errors; parse("SWITCH",sw);
159 7 : if(sw.length()>0) {
160 7 : sf.set(sw,errors);
161 7 : if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
162 : } else {
163 0 : double r_0=-1.0, d_0; int nn, mm;
164 0 : parse("NN",nn); parse("MM",mm);
165 0 : parse("R_0",r_0); parse("D_0",d_0);
166 0 : if( r_0<0.0 ) error("you must set a value for R_0");
167 0 : sf.set(nn,mm,r_0,d_0);
168 : }
169 21 : log.printf(" filtering colvar values and focussing only on those more than %s\n",( sf.description() ).c_str() );
170 :
171 7 : checkRead();
172 7 : }
173 :
174 16806 : double FilterMore::applyFilter( const double& val, double& df ) const {
175 16806 : double f = 1.0 - sf.calculate( val, df ); df*=-val;
176 16806 : return f;
177 : }
178 :
179 : }
180 4839 : }
|