votca 2024.1-dev
Loading...
Searching...
No Matches
tabulatedpotential.cc
Go to the documentation of this file.
1/*
2 * Copyright 2009-2020 The VOTCA Development Team (http://www.votca.org)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18#include "tabulatedpotential.h"
20#include "analysistool.h"
21#include "bondedstatistics.h"
22#include <boost/lexical_cast.hpp>
23#include <cmath>
24#include <fstream>
25#include <iostream>
26#include <string>
27#include <vector>
30
31using namespace std;
32using namespace votca::tools;
33
34namespace votca {
35namespace csg {
36/******************************************************************************
37 * Public Facing Methods
38 ******************************************************************************/
43
44void TabulatedPotential::Register(map<string, AnalysisTool *> &lib) {
45 lib["tab"] = this;
46 lib["hist"] = this;
47}
48
50 vector<string> &args) {
51 if (args[0] == "set") {
52 if (cmd == "hist") {
54 } else if (cmd == "tab") {
55 if (!SetOption_(tab_options_, args)) {
56 if (args.size() > 2) {
57 if (args[1] == "smooth_pdf") {
58 tab_smooth1_ = boost::lexical_cast<Index>(args[2]);
59 } else if (args[1] == "smooth_pot") {
60 tab_smooth2_ = boost::lexical_cast<Index>(args[2]);
61 } else if (args[1] == "T") {
62 Temperature_ = boost::lexical_cast<double>(args[2]);
63 } else {
64 cout << "unknown option " << args[2] << endl;
65 return;
66 }
67 }
68 }
69 if (args.size() <= 2) {
70 cout << "smooth_pdf: " << tab_smooth1_ << endl;
71 cout << "smooth_pot: " << tab_smooth2_ << endl;
72 cout << "T: " << Temperature_ << endl;
73 }
74 }
75 } else if (args.size() >= 2) {
76 if (cmd == "hist") {
77 WriteHistogram(bs, args);
78 } else if (cmd == "tab") {
79 WritePotential(bs, args);
80 }
81 } else {
82 cout << "wrong number of arguments" << endl;
83 }
84}
85
86void TabulatedPotential::Help(const string &cmd, vector<string> &args) {
87 if (args.size() == 0) {
88 if (cmd == "tab") {
89 cout << "tab <file> <selection>\n"
90 << "Calculate tabulated potential by inverting the distribution "
91 "function. Statistics is calculated using all interactions in "
92 "selection.\nsee also: help tab set\n\nexample:\ntab set scale "
93 "bond\ntab U_bond.txt *:bond:*\n";
94 }
95 if (cmd == "hist") {
96 cout << "hist <file> <selection>\n"
97 << "Calculate distribution function for selection. Statistics is "
98 "calculated using all interactions in selection.\n see also: help"
99 " hist set\n\nexample:hist U_bond.txt *:bond:*\n";
100 }
101 return;
102 }
103 if (args[0] == "set") {
104 if (args.size() == 1) {
105 cout << cmd << " set <option> <value>\n"
106 << "set option for this command. Use \"" << cmd
107 << " set\" for a list of available options. To get help on a "
108 "specific option use e.g.\n"
109 << cmd << " set periodic\n";
110 return;
111 }
112 if (args[1] == "n") {
113 cout << cmd << "set n <integer>\n"
114 << "set number of bins for table\n";
115 return;
116 }
117 if (args[1] == "min") {
118 cout << cmd << "set min <value>\n"
119 << "minimum value of interval for histogram (see also periodic, "
120 "extend)\n";
121 return;
122 }
123 if (args[1] == "max") {
124 cout << cmd << "set max <value>\n"
125 << "maximum value of interval for histogram (see also periodic, "
126 "extend)\n";
127 return;
128 }
129 if (args[1] == "periodic") {
130 cout << cmd << "set periodic <value>\n"
131 << "can be 1 for periodic interval (e.g. dihedral) or 0 for "
132 "non-periodic (e.g. bond)\n";
133 return;
134 }
135 if (args[1] == "auto") {
136 cout << cmd
137 << "set auto <value>\n"
138 "can be 1 for automatically determine the interval for the table "
139 "(min, max, extend will be ignored) or 0 to use min/max as "
140 "specified\n";
141 return;
142 }
143 if (args[1] == "extend") {
144 cout << cmd
145 << "set extend <value>\n"
146 "should only be used with auto=0. Can be 1 for extend the "
147 "interval if values are out of bounds (min/max) or 0 to "
148 "ignore values which are out of the interal\n";
149 return;
150 }
151 if (args[1] == "scale") {
152 cout << cmd
153 << "set scale <value>\n"
154 "volume normalization of pdf. Can be no (no scaling), bond "
155 "(1/r^2) or angle ( 1/sin(phi) ). See VOTCA manual, section "
156 "theoretical background for details\n";
157 return;
158 }
159 if (args[1] == "normalize") {
160 cout
161 << cmd
162 << "set normalize <value>\n"
163 "can be 1 for a normalized histogram or 0 to skip normalization\n";
164 return;
165 }
166
167 if (cmd == "tab") {
168 if (args[1] == "smooth_pdf") {
169 cout << "tab set smooth_pdf <value>\n"
170 "Perform so many smoothing iterations on the distribution "
171 "function before inverting the potential\n";
172 return;
173 }
174 if (args[1] == "smooth_pot") {
175 cout << "tab set smooth_pot <value>\n"
176 "Perform so many smoothing iterations on tabulated potential "
177 "after inverting the potential\n";
178 return;
179 }
180 if (args[1] == "T") {
181 cout << "tab set T <value>\n"
182 "Temperature in Kelvin the simulation was performed\n";
183 return;
184 }
185 }
186 }
187
188 cout << "no help text available" << endl;
189}
190
192
193pair<Index, Index> TabulatedPotential::getSmoothIterations() const {
194 return pair<Index, Index>(tab_smooth1_, tab_smooth2_);
195}
196
198 vector<string> &args) {
199 ofstream out;
201
202 for (size_t i = 1; i < args.size(); i++) {
203 sel = bs.BondedValues().select(args[i], sel);
204 }
206 h.ProcessData(sel);
207 out.open(args[0]);
208 out << h;
209 out.close();
210 cout << "histogram created using " << sel->size() << " data-rows, written to "
211 << args[0] << endl;
212 delete sel;
213}
214
216 vector<string> &args) {
217 ofstream out;
219
220 // Appends all the interactions that are specified in args to selection
221 // pointer given by sel
222
223 for (size_t i = 1; i < args.size(); i++) {
224 sel = bs.BondedValues().select(args[i], sel);
225 }
226
228
229 h.ProcessData(sel);
230 for (Index i = 0; i < tab_smooth1_; ++i) {
232 }
234 for (Index i = 0; i < tab_smooth2_; ++i) {
236 }
237 out.open(args[0]);
238
239 vector<double> F;
240 assert(h.getInterval() > 0 && "Interval for pdf histogram is 0");
242 for (Index i = 0; i < h.getN(); i++) {
243 out << h.getMin() + h.getInterval() * ((double)i) << " " << h.getPdf()[i]
244 << " " << F[i] << endl;
245 }
246 out.close();
247 cout << "histogram created using " << sel->size() << " data-rows, written to "
248 << args[0] << endl;
249 delete sel;
250}
251
252/******************************************************************************
253 * Private Facing Methods
254 ******************************************************************************/
256 const vector<string> &args) {
257 if (args.size() > 2) {
258 if (args[1] == "n") {
259 op.n_ = boost::lexical_cast<Index>(args[2]);
260 } else if (args[1] == "min") {
261 op.min_ = boost::lexical_cast<double>(args[2]);
262 } else if (args[1] == "max") {
263 op.max_ = boost::lexical_cast<double>(args[2]);
264 } else if (args[1] == "periodic") {
265 op.periodic_ = boost::lexical_cast<bool>(args[2]);
266 } else if (args[1] == "auto") {
267 op.auto_interval_ = boost::lexical_cast<bool>(args[2]);
268 } else if (args[1] == "extend") {
269 op.extend_interval_ = boost::lexical_cast<bool>(args[2]);
270 } else if (args[1] == "normalize") {
271 op.normalize_ = boost::lexical_cast<bool>(args[2]);
272 } else if (args[1] == "scale") {
273 if (args[2] == "no" || args[2] == "bond" || args[2] == "angle") {
274 op.scale_ = args[2];
275 } else {
276 cout << "scale can be: no, bond or angle\n";
277 }
278 } else {
279 return false;
280 }
281 } else {
282 cout << "n: " << op.n_ << endl;
283 cout << "min: " << op.min_ << endl;
284 cout << "max: " << op.max_ << endl;
285 cout << "periodic: " << op.periodic_ << endl;
286 cout << "auto: " << op.auto_interval_ << endl;
287 cout << "extend: " << op.extend_interval_ << endl;
288 cout << "scale: " << op.scale_ << endl;
289 cout << "normalize: " << op.normalize_ << endl;
290 }
291 return true;
292}
293
294void TabulatedPotential::CalcForce_(vector<double> &U, vector<double> &F,
295 double dx, bool bPeriodic) {
296 size_t n = U.size();
297 double f = 0.5 / dx;
298 F.resize(n);
299 if (bPeriodic) {
300 F[n - 1] = F[0] = -(U[1] - U[n - 2]) * f;
301 } else {
302 F[0] = -(U[1] - U[0]) * 2 * f;
303 F[n - 1] = -(U[n - 1] - U[n - 2]) * 2 * f;
304 }
305 for (size_t i = 1; i < n - 1; i++) {
306 F[i] = -(U[i + 1] - U[i - 1]) * f;
307 }
308}
309
310void TabulatedPotential::Smooth_(vector<double> &data, bool bPeriodic) {
311 double old[3];
312 Index n = Index(data.size());
313 if (bPeriodic) {
314 old[0] = data[n - 3];
315 old[1] = data[n - 2];
316 } else {
317 old[0] = data[0];
318 old[1] = data[0];
319 }
320 Index i;
321 for (i = 0; i < Index(data.size()) - 2; i++) {
322 old[2] = data[i];
323 data[i] =
324 (old[0] + 2. * old[1] + 3. * data[i] + 2. * data[i + 1] + data[i + 2]) /
325 9.;
326 old[0] = old[1];
327 old[1] = old[2];
328 }
329 if (bPeriodic) {
330 data[i] =
331 (old[0] + 2. * old[1] + 3. * data[i] + 2. * data[i + 1] + data[0]) / 9.;
332 data[n - 1] = data[0];
333 } else {
334 data[i] = (old[0] + 2. * old[1] + 3. * data[i] + 3. * data[i + 1]) / 9.;
335 old[0] = old[1];
336 old[1] = data[i];
337 i++;
338 data[i] = (old[0] + 2. * old[1] + 6. * data[i]) / 9.;
339 }
340}
341
342void TabulatedPotential::BoltzmannInvert_(vector<double> &data) {
343
344 double min = std::numeric_limits<double>::max();
345 double max = std::numeric_limits<double>::min();
346
347 for (double i : data) {
348 max = std::max(i, max);
349 if (i > 0) {
350 min = std::min(i, min);
351 }
352 }
353 max = -conv::kB * conv::ev2kj_per_mol * Temperature_ * std::log(max);
354 min = -conv::kB * conv::ev2kj_per_mol * Temperature_ * std::log(min) - max;
355
356 for (double &i : data) {
357 if (i == 0) {
358 i = min;
359 } else {
360 i = -conv::kB * conv::ev2kj_per_mol * Temperature_ * std::log(i) - max;
361 }
362 }
363}
364
365} // namespace csg
366} // namespace votca
Class calculates data associated with bond interactions.
tools::DataCollection< double > & BondedValues()
std::pair< Index, Index > getSmoothIterations() const
Method returns the number of smoothing iterations used on the data.
double getTemperature() const
Returns the temperature used during the bolzmann inversion.
void Command(BondedStatistics &bs, const std::string &cmd, std::vector< std::string > &args) override
double Temperature_
Temperature in units of Kelvin.
void Help(const std::string &cmd, std::vector< std::string > &args) override
void WritePotential(BondedStatistics &bs, std::vector< std::string > &args)
votca::tools::Histogram::options_t hist_options_
void BoltzmannInvert_(std::vector< double > &data)
void CalcForce_(std::vector< double > &U, std::vector< double > &F, double dx, bool bPeriodic)
votca::tools::Histogram::options_t tab_options_
bool SetOption_(votca::tools::Histogram::options_t &op, const std::vector< std::string > &args)
void WriteHistogram(BondedStatistics &bs, std::vector< std::string > &args)
void Register(std::map< std::string, AnalysisTool * > &lib) override
void Smooth_(std::vector< double > &data, bool bPeriodic)
Smooths a vector of doubles.
selection * select(std::string strselection, selection *sel_append=nullptr)
select a set of arrays
class to generate histograms
Definition histogram.h:38
double getMin() const
returns the minimum value
Definition histogram.h:54
void ProcessData(DataCollection< double >::selection *data)
Definition histogram.cc:36
double getInterval() const
Definition histogram.h:60
std::vector< double > & getPdf()
Definition histogram.h:59
Index getN() const
return the number of grid points
Definition histogram.h:58
STL namespace.
const double kB
Definition constants.h:40
const double ev2kj_per_mol
Definition constants.h:57
base class for all analysis tools
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26