votca 2024.2-dev
Loading...
Searching...
No Matches
eanalyze.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// Local private VOTCA includes
19#include "eanalyze.h"
20#include "votca/xtp/qmstate.h"
21
22namespace votca {
23namespace xtp {
24
26
27 resolution_pairs_ = options.get(".resolution_pairs").as<double>();
28 resolution_sites_ = options.get(".resolution_sites").as<double>();
29 resolution_spatial_ = options.get(".resolution_spatial").as<double>();
30 seg_pattern_ = options.get(".match_pattern").as<std::string>();
31
32 states_ = options.get(".states").as<std::vector<QMStateType>>();
33
34 doenergy_landscape_ = options.get(".output_energy_landscape").as<bool>();
35
36 if (options.exists(".distancemode")) {
37 std::string distancemode = options.get("distancemode").as<std::string>();
38 if (distancemode == "centerofmass") {
39 atomdistances_ = false;
40 } else {
41 atomdistances_ = true;
42 }
43 }
44}
45
47
48 // Short-list segments according to pattern
49 for (Segment &seg : top.Segments()) {
50 std::string seg_name = seg.getType();
51 if (votca::tools::wildcmp(seg_pattern_, seg_name)) {
52 seg_shortlist_.push_back(&seg);
53 }
54 }
55 std::cout << std::endl
56 << "... ... Short-listed " << seg_shortlist_.size()
57 << " segments (pattern='" << seg_pattern_ << "')" << std::flush;
58 std::cout
59 << std::endl
60 << "... ... ... NOTE Statistics of site energies and spatial"
61 << " correlations thereof are based on the short-listed segments only. "
62 << std::flush;
63 std::cout << std::endl
64 << "... ... ... "
65 << "Statistics of site-energy differences operate on the full list."
66 << std::flush;
67
68 // Calculate
69 // ... Site-energy histogram, mean, width
70 // ... Pair-energy histogram, mean, width
71 // ... Site-energy correlation
72
73 const QMNBList &nblist = top.NBList();
74
75 for (QMStateType state : states_) {
76 std::cout << std::endl
77 << "... ... excited state " << state.ToString() << std::flush;
78
79 if (!seg_shortlist_.size()) {
80 std::cout << std::endl
81 << "... ... ... No segments short-listed. Skip ... "
82 << std::flush;
83 } else {
84 SiteHist(state);
85 SiteCorr(top, state);
86 }
87
88 if (!nblist.size()) {
89 std::cout << std::endl
90 << "... ... ... No pairs in topology. Skip ... " << std::flush;
91 } else {
92 PairHist(top, state);
93 }
94 }
95 std::cout << std::endl;
96 return true;
97}
98
100
101 std::vector<double> Es;
102 Es.reserve(seg_shortlist_.size());
103 for (Segment *seg : seg_shortlist_) {
104 Es.push_back(seg->getSiteEnergy(state) * tools::conv::hrt2ev);
105 }
106
107 double MAX = *std::max_element(Es.begin(), Es.end());
108 double MIN = *std::min_element(Es.begin(), Es.end());
109 double sum = std::accumulate(Es.begin(), Es.end(), 0.0);
110 double AVG = sum / double(Es.size());
111 double sq_sum = std::inner_product(Es.begin(), Es.end(), Es.begin(), 0.0);
112 double STD = std::sqrt(sq_sum / double(Es.size()) - AVG * AVG);
113
114 // Prepare bins
115 Index BIN = Index((MAX - MIN) / resolution_sites_ + 0.5) + 1;
116
118 hist.Initialize(MIN, MAX, BIN);
119 hist.ProcessRange<std::vector<double>::iterator>(Es.begin(), Es.end());
120 tools::Table &tab = hist.data();
121 tab.flags() = std::vector<char>(tab.size(), ' ');
122 std::string comment =
123 (boost::format("EANALYZE: SITE-ENERGY HISTOGRAM[eV] \n # AVG %1$4.7f STD "
124 "%2$4.7f MIN %3$4.7f MAX %4$4.7f") %
125 AVG % STD % MIN % MAX)
126 .str();
127 std::string filename = "eanalyze.sitehist_" + state.ToString() + ".out";
128 tab.set_comment(comment);
129 tab.Save(filename);
130
131 // Write "seg x y z energy" with atomic {x,y,z}
133 std::string filename2 = "eanalyze.landscape_" + state.ToString() + ".out";
134 std::ofstream out;
135 out.open(filename2);
136 if (!out) {
137 throw std::runtime_error("error, cannot open file " + filename2);
138 }
139 for (Segment *seg : seg_shortlist_) {
140 if (seg->getId() < first_seg_) {
141 continue;
142 }
143 if (seg->getId() == last_seg_) {
144 break;
145 }
146 double E = seg->getSiteEnergy(state);
147 for (Atom &atm : *seg) {
148 out << boost::format("%1$3s %2$4.7f %3$4.7f %4$4.7f %5$4.7f\n") %
149 seg->getType() % atm.getPos().x() % atm.getPos().y() %
150 atm.getPos().z() % E;
151 }
152 }
153 out.close();
154 }
155}
156
157void EAnalyze::PairHist(const Topology &top, QMStateType state) const {
158
159 const QMNBList &nblist = top.NBList();
160
161 std::string filenamelist = "eanalyze.pairlist_" + state.ToString() + ".out";
162
163 // Collect site-energy differences from neighbourlist
164 std::vector<double> dE;
165 dE.reserve(2 * nblist.size());
166 std::ofstream out;
167 out.open(filenamelist);
168 if (!out) {
169 throw std::runtime_error("error, cannot open file " + filenamelist);
170 }
171 for (QMPair *pair : nblist) {
172 double deltaE = pair->getdE12(state) * tools::conv::hrt2ev;
173 dE.push_back(deltaE);
174 dE.push_back(-deltaE);
175 out << boost::format("%1$5d %2$5d %3$4.7f \n") % pair->Seg1()->getId() %
176 pair->Seg2()->getId() % deltaE;
177 }
178 out.close();
179
180 double MAX = *std::max_element(dE.begin(), dE.end());
181 double MIN = *std::min_element(dE.begin(), dE.end());
182 double sum = std::accumulate(dE.begin(), dE.end(), 0.0);
183 double AVG = sum / double(dE.size());
184 double sq_sum = std::inner_product(dE.begin(), dE.end(), dE.begin(), 0.0);
185 double STD = std::sqrt(sq_sum / double(dE.size()) - AVG * AVG);
186 Index BIN = Index((MAX - MIN) / resolution_pairs_ + 0.5) + 1;
187
188 std::string filename2 = "eanalyze.pairhist_" + state.ToString() + ".out";
190 hist.Initialize(MIN, MAX, BIN);
191 hist.ProcessRange<std::vector<double>::iterator>(dE.begin(), dE.end());
192 tools::Table &tab = hist.data();
193 std::string comment =
194 (boost::format("EANALYZE: PAIR-ENERGY HISTOGRAM[eV] \n # AVG %1$4.7f STD "
195 "%2$4.7f MIN %3$4.7f MAX %4$4.7f") %
196 AVG % STD % MIN % MAX)
197 .str();
198 tab.set_comment(comment);
199 tab.flags() = std::vector<char>(tab.size(), ' ');
200 tab.Save(filename2);
201}
202
203void EAnalyze::SiteCorr(const Topology &top, QMStateType state) const {
204
205 std::vector<double> Es;
206 Es.reserve(seg_shortlist_.size());
207 for (Segment *seg : seg_shortlist_) {
208 Es.push_back(seg->getSiteEnergy(state) * tools::conv::hrt2ev);
209 }
210
211 double sum = std::accumulate(Es.begin(), Es.end(), 0.0);
212 double AVG = sum / double(Es.size());
213 double sq_sum = std::inner_product(Es.begin(), Es.end(), Es.begin(), 0.0);
214 double VAR = sq_sum / double(Es.size()) - AVG * AVG;
215 double STD = std::sqrt(VAR);
216
217 // Collect inter-site distances, correlation product
218 tools::Table tabcorr;
219 Index length =
220 Index(seg_shortlist_.size()) * Index(seg_shortlist_.size() - 1) / 2;
221 tabcorr.resize(length);
222 Index index = 0;
223 for (Index i = 0; i < Index(seg_shortlist_.size()); i++) {
224 const Segment &segi = *seg_shortlist_[i];
225 for (Index j = i + 1; j < Index(seg_shortlist_.size()); j++) {
226 const Segment &segj = *seg_shortlist_[j];
227 double R = 0;
228 if (atomdistances_) {
229 R = top.GetShortestDist(segi, segj);
230 } else {
231 R = (top.PbShortestConnect(segi.getPos(), segj.getPos())).norm();
232 }
233
234 double C =
235 (segi.getSiteEnergy(state) - AVG) * (segj.getSiteEnergy(state) - AVG);
236 tabcorr.set(index, R * tools::conv::bohr2nm, C);
237 index++;
238 }
239 }
240
241 double MIN = tabcorr.x().minCoeff();
242 double MAX = tabcorr.x().maxCoeff();
243
244 // Prepare bins
245 Index BIN = Index((MAX - MIN) / resolution_spatial_ + 0.5) + 1;
246 std::vector<std::vector<double>> histCs;
247 histCs.resize(BIN);
248
249 for (Index i = 0; i < tabcorr.size(); ++i) {
250 Index bin = Index((tabcorr.x()[i] - MIN) / resolution_spatial_ + 0.5);
251 histCs[bin].push_back(tabcorr.y()[i]);
252 }
253
254 tools::Table histC;
255 histC.SetHasYErr(true);
256 // Calculate spatial correlation
257 histC.resize(BIN);
258 for (Index bin = 0; bin < BIN; ++bin) {
259 double corr = 0.0;
260 double dcorr2 = 0.0;
261 for (double entry : histCs[bin]) {
262 corr += entry / VAR;
263 }
264 corr = corr / double(histCs[bin].size());
265 for (Index i = 0; i < Index(histCs[bin].size()); ++i) {
266 dcorr2 += (histCs[bin][i] / VAR / double(histCs[bin].size()) - corr) *
267 (histCs[bin][i] / VAR / double(histCs[bin].size()) - corr);
268 }
269 // error on mean value
270 dcorr2 =
271 dcorr2 / double(histCs[bin].size()) / double(histCs[bin].size() - 1);
272 double R = MIN + double(bin) * resolution_spatial_;
273 histC.set(bin, R, corr, ' ', std::sqrt(dcorr2));
274 }
275
276 std::string filename = "eanalyze.sitecorr_" + state.ToString() + ".out";
277 std::string comment =
278 (boost::format("EANALYZE: DISTANCE[nm] SPATIAL SITE-ENERGY "
279 "CORRELATION[eV] \n # AVG "
280 "%1$4.7f STD %2$4.7f MIN %3$4.7f MAX %4$4.7f") %
281 AVG % STD % MIN % MAX)
282 .str();
283 histC.set_comment(comment);
284 histC.Save(filename);
285}
286
287} // namespace xtp
288} // namespace votca
Index size() const
Definition pairlist.h:53
class to generate histograms
class to manage program options with xml serialization functionality
Definition property.h:55
Property & get(const std::string &key)
get existing property
Definition property.cc:79
bool exists(const std::string &key) const
check whether property exists
Definition property.cc:122
T as() const
return value as type
Definition property.h:283
class to store tables like rdfs, tabulated potentials, etc
Definition table.h:36
double & x(Index i)
Definition table.h:44
Index size() const
Definition table.h:42
void SetHasYErr(bool has_yerr)
Definition table.h:81
void set(const Index &i, const double &x, const double &y)
Definition table.h:52
char & flags(Index i)
Definition table.h:49
void set_comment(const std::string comment)
Definition table.h:70
void resize(Index N)
Definition table.cc:38
double & y(Index i)
Definition table.h:45
void Save(std::string filename) const
Definition table.cc:59
const Eigen::Vector3d & getPos() const
double resolution_pairs_
Definition eanalyze.h:58
void SiteHist(QMStateType state) const
Definition eanalyze.cc:99
void ParseOptions(const tools::Property &user_options)
Definition eanalyze.cc:25
std::vector< Segment * > seg_shortlist_
Definition eanalyze.h:70
std::vector< QMStateType > states_
Definition eanalyze.h:63
bool Evaluate(Topology &top)
Definition eanalyze.cc:46
std::string seg_pattern_
Definition eanalyze.h:69
void SiteCorr(const Topology &top, QMStateType state) const
Definition eanalyze.cc:203
void PairHist(const Topology &top, QMStateType state) const
Definition eanalyze.cc:157
double resolution_spatial_
Definition eanalyze.h:60
double resolution_sites_
Definition eanalyze.h:59
std::string ToString() const
Definition qmstate.cc:35
double getSiteEnergy(QMStateType state) const
Definition segment.h:79
Container for segments and box and atoms.
Definition topology.h:41
Eigen::Vector3d PbShortestConnect(const Eigen::Vector3d &r1, const Eigen::Vector3d &r2) const
Definition topology.cc:129
std::vector< Segment > & Segments()
Definition topology.h:58
QMNBList & NBList()
Definition topology.h:70
double GetShortestDist(const Segment &seg1, const Segment &seg2) const
Definition topology.cc:134
const double bohr2nm
Definition constants.h:46
const double hrt2ev
Definition constants.h:53
int wildcmp(const char *wild, const char *string)
Definition tokenizer.cc:28
base class for all analysis tools
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26