votca 2026-dev
Loading...
Searching...
No Matches
networkfit.cc
Go to the documentation of this file.
1/*
2 * Copyright 2009-2026 The VOTCA Development Team
3 * (http://www.votca.org)
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License")
6 *
7 * You may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20// Standard includes
21#include <cmath>
22#include <fstream>
23#include <iomanip>
24#include <numeric>
25#include <sstream>
26
27// VOTCA includes
29
30// Local VOTCA includes
33#include "votca/xtp/tofgraph.h"
35
36// Local private VOTCA includes
37#include "networkfit.h"
38
39namespace votca {
40namespace xtp {
41
42namespace {
43std::vector<Index> Grid(const std::vector<Index>& g, const std::string& name) {
44 if (g.size() != 3 || g[0] < 1 || g[1] < g[0] || g[2] < 1) {
45 throw std::runtime_error("networkfit: " + name +
46 " needs first, last, step with 1 <= first <= "
47 "last and step >= 1");
48 }
49 std::vector<Index> r;
50 for (Index l = g[0]; l <= g[1]; l += g[2]) {
51 r.push_back(l);
52 }
53 return r;
54}
55
56double MeanOf(const std::vector<double>& x) {
57 return std::accumulate(x.begin(), x.end(), 0.0) / double(x.size());
58}
59
61double At(const StochasticNetworkFit::Curve& c, double r) {
62 for (std::size_t k = 0; k < c.r.size(); ++k) {
63 double half = k + 1 < c.r.size() ? 0.5 * (c.r[k + 1] - c.r[k])
64 : 0.5 * (c.r[k] - c.r[k - 1]);
65 if (std::abs(r - c.r[k]) <= half) {
66 return (c.count.empty() || c.count[k] > 0.0)
67 ? c.value[k]
68 : std::numeric_limits<double>::quiet_NaN();
69 }
70 }
71 return std::numeric_limits<double>::quiet_NaN();
72}
73
74struct Log10Stats {
75 double mean = 0.0;
76 double sd = 0.0;
77};
78Log10Stats LogJ(const StochasticNetworkFit::Data& d, Index c) {
79 std::vector<double> y;
80 for (const auto& p : d.pairs) {
81 if (p.J2[c] > 0.0) {
82 y.push_back(
83 std::log10(p.J2[c] * tools::conv::hrt2ev * tools::conv::hrt2ev));
84 }
85 }
86 Log10Stats s;
87 if (y.empty()) {
88 return s;
89 }
90 s.mean = MeanOf(y);
91 double v = 0.0;
92 for (double x : y) {
93 v += (x - s.mean) * (x - s.mean);
94 }
95 s.sd = std::sqrt(v / double(y.size()));
96 return s;
97}
98
99double Sigma(const std::vector<double>& e) {
100 double m = MeanOf(e);
101 double v = 0.0;
102 for (double x : e) {
103 v += (x - m) * (x - m);
104 }
105 return std::sqrt(v / double(e.size()));
106}
107} // namespace
108
110 const double nm = tools::conv::nm2bohr;
111 statefile_ = options.ifExistsReturnElseReturnDefault<std::string>(
112 ".statefile", job_name_ + ".hdf5");
113 frame_ = options.get(".frame").as<Index>();
114 parameterfile_ = options.ifExistsReturnElseReturnDefault<std::string>(
115 ".parameterfile", job_name_ + "_network.xml");
117 options.ifExistsReturnElseReturnDefault<std::string>(".energyfile", "");
118 statsfile_ =
119 options.ifExistsReturnElseReturnDefault<std::string>(".statsfile", "");
120 settings_.carriers.clear();
121 for (const std::string& s :
122 options.get(".carriers").as<std::vector<std::string>>()) {
123 QMStateType type(s);
124 if (!type.isKMCState()) {
125 throw std::runtime_error("networkfit: " + s +
126 " is not a hopping state (e, h, s, t)");
127 }
128 settings_.carriers.push_back(type);
129 }
130 settings_.bin = options.get(".bin").as<double>() * nm;
131 settings_.correlation_cutoff =
132 options.get(".correlationcutoff").as<double>() * nm;
133 settings_.l_b = Grid(options.get(".l_b").as<std::vector<Index>>(), "l_b");
134 settings_.l_c = Grid(options.get(".l_c").as<std::vector<Index>>(), "l_c");
135 settings_.quantiles = options.get(".quantiles").as<Index>();
136 settings_.fit_points = options.get(".points.fit").as<bool>();
137 settings_.realizations = options.get(".points.realizations").as<Index>();
138 settings_.max_evaluations = options.get(".points.evaluations").as<Index>();
139 settings_.candidates = options.get(".points.candidates").as<double>();
140 settings_.max_iterations = options.get(".points.maxiterations").as<Index>();
141 settings_.points.hard_core =
142 options.get(".points.hardcore").as<double>() * nm;
143 settings_.points.radius_mean =
144 options.get(".points.radiusmean").as<double>() * nm;
145 settings_.points.radius_variance =
146 options.get(".points.radiusvariance").as<double>() * nm * nm;
147 settings_.seed = options.get(".seed").as<std::uint64_t>();
148 validate_ = options.get(".validate").as<Index>();
149 find_traps_ = options.get(".traps.find").as<bool>();
150 traps_.threshold = options.get(".traps.threshold").as<double>();
151 traps_.gap = options.get(".traps.gap").as<double>();
152 traps_.max_sites = options.get(".traps.maxsites").as<Index>();
153 traps_.mass = options.get(".traps.mass").as<double>();
154 traps_.max_size = options.get(".traps.maxsize").as<Index>();
155 temperature_ = options.get(".temperature").as<double>();
156}
157
159 log_.setReportLevel(Log::current_level);
160 log_.setMultithreading(true);
161 log_.setCommonPreface("\n... ...");
162 const double nm = tools::conv::bohr2nm;
163 const double ev = tools::conv::hrt2ev;
164 const double kT = tools::conv::kB * temperature_;
165
166 StateSaver reader(statefile_);
167 Index frame = frame_;
168 if (frame < 0) {
169 std::vector<Index> frames = reader.getFrames();
170 if (frames.empty()) {
171 throw std::runtime_error("networkfit: " + statefile_ + " has no frames");
172 }
173 frame = frames.front();
174 }
175 Topology top = reader.ReadFrame(frame);
178 const Index n = Index(data.positions.size());
180 << "Read " << statefile_ << " frame " << frame << ": " << n << " sites, "
181 << data.pairs.size() << " pairs, box " << data.box.x() * nm << " x "
182 << data.box.y() * nm << " x " << data.box.z() * nm << " nm^3"
183 << std::flush;
184
185 // traps of the microscopic system (zero field)
186 auto find_traps = [this](const Topology& t, Index c) {
187 ToFGraph graph(t, ToFGraph::BulkOptions("", ""), settings_.carriers[c],
189 Eigen::Vector3d::Zero());
190 return TrapFinder::Find(graph, traps_);
191 };
192 settings_.traps.clear();
193 if (find_traps_) {
194 for (std::size_t c = 0; c < settings_.carriers.size(); ++c) {
195 TrapFinder::Result tr = find_traps(top, Index(c));
196 std::ostringstream s;
197 s << "Traps for " << settings_.carriers[c].ToString()
198 << " (slow modes of the master equation at " << temperature_
199 << " K): largest eigenvalue ratio " << std::setprecision(3) << tr.gap
200 << " after " << tr.slow_modes << " slow mode(s)";
201 if (tr.traps.empty()) {
202 s << ": no traps";
203 }
204 for (const TrapFinder::Trap& t : tr.traps) {
205 s << "\n trap of " << t.sites.size() << " site(s):";
206 for (Index i : t.sites) {
207 double e = data.energies[c][i];
208 double m = 0.0;
209 for (double x : data.energies[c]) {
210 m += x / double(n);
211 }
212 s << " " << i << " (" << (e - m) * tools::conv::hrt2ev << " eV)";
213 }
214 s << "\n equilibrium weight " << t.weight << "; release rate "
215 << t.release_rate << " 1/s, capture rate " << t.capture_rate
216 << " 1/s (slow mode " << t.relaxation_rate << " 1/s); hops out "
217 << t.hop_rate << " 1/s";
218 settings_.traps.push_back({Index(c), t.sites, t.release_rate});
219 }
220 XTP_LOG(Log::error, log_) << s.str() << std::flush;
221 }
222 }
223
224 StochasticNetworkFit fitter(data, settings_);
225 StochasticNetworkFit::Result res = fitter.Fit();
226 const StochasticNetwork::Options& opt = res.options;
227
229 if (settings_.fit_points) {
231 << "Point process: r_h = " << pp.hard_core * nm
232 << " nm, radius mean = " << pp.radius_mean * nm
233 << " nm, variance = " << pp.radius_variance * nm * nm
234 << " nm^2 (objective " << res.points.objective << ", "
235 << res.points.evaluations << " evaluations)" << std::flush;
236 }
238 << "Connection probability tabulated up to "
239 << opt.connection_r.back() * nm << " nm" << std::flush;
240 for (std::size_t c = 0; c < opt.carriers.size(); ++c) {
241 const auto& e = res.energies[c];
242 const auto& car = opt.carriers[c];
243 const auto& j = res.couplings[c];
244 std::ostringstream s;
245 s << "Carrier " << car.state.ToString() << ": site energies mean "
246 << e.mean * ev << " eV, sigma " << e.sigma * ev << " eV (sample), "
247 << e.sigma_model * ev << " eV = " << e.sigma_model * ev / kT
248 << " kT (model, corrected for the finite system)";
249 if (e.fitted) {
250 s << "\n moving average w_a = " << e.w_a << ", w_b = " << e.w_b
251 << " (l_b = " << e.l_b << "), w_c = " << e.w_c << " (l_c = " << e.l_c
252 << "), rms of kappa " << e.rms << ", mean correlation over all pairs "
253 << e.cbar;
254 if (e.l_b_at_edge) {
255 s << "\n WARNING: l_b is at the end of its grid, extend the grid";
256 }
257 if (e.l_c_at_edge) {
258 s << "\n WARNING: l_c is at the end of its grid: the range of "
259 "the correlation is not determined by this system size (see "
260 "the l_c scan in the stats file); extend the grid or use a "
261 "larger microscopic system";
262 }
263 } else {
264 s << "; no energy disorder (all site energies equal)";
265 }
266 s << "\n log10(J^2/eV^2) = " << j.model.mean_offset << " + "
267 << j.model.mean_slope << " r/nm, variance " << j.model.var_offset << " + "
268 << j.model.var_slope << " r/nm; residual skewness " << j.skewness
269 << ", excess kurtosis " << j.excess_kurtosis << "; " << j.used
270 << " couplings";
271 if (j.excluded > 0) {
272 s << ", " << j.excluded << " zero couplings ignored";
273 }
274 s << "\n lambda = " << (car.U_nX_nN + car.U_xN_xX) * ev
275 << " eV (U_nX_nN " << car.U_nX_nN * ev << ", U_xN_xX " << car.U_xN_xX * ev
276 << "), internal energy U_xX_nN " << car.U_xX_nN * ev << " eV";
277 double s2 = (e.sigma_model * ev / kT) * (e.sigma_model * ev / kT);
278 s << "\n the density of occupied states at " << temperature_
279 << " K needs about " << std::setprecision(2) << std::scientific
280 << std::exp((s2 + 5.7) / 1.05) << " sites" << std::defaultfloat
281 << std::setprecision(6);
282 XTP_LOG(Log::error, log_) << s.str() << std::flush;
283 }
284 if (opt.carriers.size() > 1) {
286 << "Correlation of the site energies of "
287 << opt.carriers[0].state.ToString() << " and "
288 << opt.carriers[1].state.ToString() << ": " << opt.energy_correlation
289 << ", of the coupling residuals: " << opt.coupling_correlation
290 << std::flush;
291 }
292
293 {
294 std::ofstream out(parameterfile_);
295 out << StochasticNetwork::ToXML(opt);
296 }
297 XTP_LOG(Log::error, log_) << "Wrote " << parameterfile_ << std::flush;
298
299 if (!energyfile_.empty()) {
300 const std::size_t ncar = settings_.carriers.size();
301 // per carrier: 1 if the site belongs to a trap of that carrier
302 std::vector<std::vector<int>> trap_of(ncar, std::vector<int>(n, 0));
303 for (const auto& t : settings_.traps) {
304 for (Index i : t.sites) {
305 trap_of[t.carrier][i] = 1;
306 }
307 }
308 std::ofstream out(energyfile_);
309 out << "# segment id, x, y, z [nm] (wrapped), site energies [eV] of";
310 for (const auto& c : settings_.carriers) {
311 out << " " << c.ToString();
312 }
313 out << ", trap site of";
314 for (const auto& c : settings_.carriers) {
315 out << " " << c.ToString();
316 }
317 out << " (1: yes)\n" << std::setprecision(12);
318 for (Index i = 0; i < n; ++i) {
319 Eigen::Vector3d p = data.positions[i] * nm;
320 out << i << " " << p.x() << " " << p.y() << " " << p.z();
321 for (std::size_t c = 0; c < ncar; ++c) {
322 out << " " << data.energies[c][i] * ev;
323 }
324 for (std::size_t c = 0; c < ncar; ++c) {
325 out << " " << trap_of[c][i];
326 }
327 out << "\n";
328 }
329 XTP_LOG(Log::error, log_) << "Wrote " << energyfile_ << std::flush;
330 }
331
332 // validation: model networks of the same size, statistics averaged
333 StochasticNetworkFit::Data model; // the first, for the stats file
334 const bool have_model = validate_ > 0;
335 if (have_model) {
336 const double half = 0.4999 * data.box.minCoeff();
337 const double rk = std::min(half, 2.5 * tools::conv::nm2bohr);
338 const std::size_t ncar = settings_.carriers.size();
339 auto statistics = [&](const StochasticNetworkFit::Data& d) {
340 std::vector<std::pair<std::string, double>> rows;
341 rows.emplace_back("pairs per site",
342 2.0 * double(d.pairs.size()) / double(n));
343 rows.emplace_back(
344 "mean nearest neighbour distance (nm)",
345 MeanOf(StochasticNetworkFit::NearestDistances(d.positions, d.box)) *
346 nm);
347 for (std::size_t c = 0; c < ncar; ++c) {
348 const std::string name = settings_.carriers[c].ToString();
349 double sd = Sigma(d.energies[c]);
350 rows.emplace_back("sigma " + name + " (eV)", sd * ev);
351 Log10Stats l = LogJ(d, Index(c));
352 rows.emplace_back("mean log10(J^2/eV^2) " + name, l.mean);
353 rows.emplace_back("sd log10(J^2/eV^2) " + name, l.sd);
354 if (res.energies[c].fitted) {
355 double md = MeanOf(d.energies[c]);
356 std::vector<double> z;
357 for (double x : d.energies[c]) {
358 z.push_back((x - md) / sd);
359 }
360 auto k = StochasticNetworkFit::Correlation(d.positions, d.box, z,
361 settings_.bin, rk);
362 for (double r : {0.75, 1.0, 1.5, 2.0}) {
363 std::ostringstream q;
364 q << "kappa " << name << " at " << std::fixed
365 << std::setprecision(2) << r << " nm";
366 rows.emplace_back(q.str(), At(k, r * tools::conv::nm2bohr));
367 }
368 }
369 }
370 if (ncar > 1 && res.energies[0].fitted && res.energies[1].fitted) {
371 const std::vector<double>& a = d.energies[0];
372 const std::vector<double>& b = d.energies[1];
373 double ma = MeanOf(a), mb = MeanOf(b);
374 double sab = 0.0, saa = 0.0, sbb = 0.0;
375 for (Index i = 0; i < n; ++i) {
376 sab += (a[i] - ma) * (b[i] - mb);
377 saa += (a[i] - ma) * (a[i] - ma);
378 sbb += (b[i] - mb) * (b[i] - mb);
379 }
380 rows.emplace_back("site energy correlation",
381 sab / std::sqrt(saa * sbb));
382 }
383 return rows;
384 };
385 // transport and traps of a network: exact zero-field diffusion and the
386 // number of traps found, per carrier
387 auto trap_rows = [&](const Topology& t,
388 std::vector<std::pair<std::string, double>>& rows) {
389 for (std::size_t c = 0; c < ncar; ++c) {
390 const std::string name = settings_.carriers[c].ToString();
391 // transport: exact zero-field diffusion of one carrier
392 ToFGraph graph(t, ToFGraph::BulkOptions("", ""), settings_.carriers[c],
394 Eigen::Vector3d::Zero());
396 if (ex.available) {
397 double d = ex.diffusion.trace() / 3.0 * tools::conv::bohr2nm *
398 tools::conv::bohr2nm * 1e-18; // m^2/s
399 rows.emplace_back("log10 D zero field " + name + " (m^2/s)",
400 std::log10(d));
401 }
402 if (!find_traps_) {
403 continue;
404 }
406 rows.emplace_back("traps found " + name, double(tr.traps.size()));
407 }
408 };
409 auto micro = statistics(data);
410 trap_rows(top, micro);
411 std::vector<double> mean(micro.size(), 0.0), var(micro.size(), 0.0);
412 Index inserted = 0;
413 for (Index k = 0; k < validate_; ++k) {
415 o.seed = opt.seed + std::uint64_t(k);
416 StochasticNetwork net(o);
417 inserted += Index(net.Traps().size());
420 auto rows = statistics(d);
421 {
422 Topology t;
423 net.BuildTopology(t);
424 trap_rows(t, rows);
425 }
426 for (std::size_t q = 0; q < rows.size(); ++q) {
427 mean[q] += rows[q].second / double(validate_);
428 var[q] += rows[q].second * rows[q].second / double(validate_);
429 }
430 if (k == 0) {
431 model = std::move(d);
432 }
433 }
434 std::ostringstream s;
435 s << std::setprecision(4);
436 s << "Validation: " << validate_ << " model network(s) of " << n
437 << " sites (seeds " << opt.seed << " to "
438 << opt.seed + std::uint64_t(validate_) - 1
439 << "), mean and standard deviation over the networks; " << inserted
440 << " trap(s) inserted in total:\n";
441 s << " " << std::left << std::setw(38) << "quantity" << std::setw(14)
442 << "microscopic" << std::setw(14) << "model" << "sd\n";
443 for (std::size_t q = 0; q < micro.size(); ++q) {
444 double sd = std::sqrt(std::max(0.0, var[q] - mean[q] * mean[q]));
445 s << " " << std::left << std::setw(38) << micro[q].first
446 << std::setw(14) << micro[q].second << std::setw(14) << mean[q] << sd
447 << "\n";
448 }
449 XTP_LOG(Log::error, log_) << s.str() << std::flush;
450 }
451
452 if (!statsfile_.empty()) {
453 std::ofstream out(statsfile_);
454 out << std::setprecision(8);
455 using Curve = StochasticNetworkFit::Curve;
456 auto block = [&out](const std::string& title, const std::string& columns,
457 const Curve& a, const Curve* b) {
458 out << "# " << title << "\n# " << columns << "\n";
459 for (std::size_t k = 0; k < a.r.size(); ++k) {
460 bool empty = !a.count.empty() && a.count[k] <= 0.0;
461 out << a.r[k] * tools::conv::bohr2nm << " "
462 << (empty ? std::numeric_limits<double>::quiet_NaN() : a.value[k]);
463 if (b != nullptr) {
464 bool bempty = !b->count.empty() && b->count[k] <= 0.0;
465 out << " "
466 << (bempty ? std::numeric_limits<double>::quiet_NaN()
467 : b->value[k]);
468 }
469 out << "\n";
470 }
471 out << "\n\n";
472 };
473 if (settings_.fit_points) {
474 block("nearest neighbour distance distribution D(r)",
475 "r [nm], microscopic, model", res.points.D, &res.points.D_model);
476 block("spherical contact distribution H(r)", "r [nm], microscopic, model",
477 res.points.H, &res.points.H_model);
478 block("pair correlation function g(r)", "r [nm], microscopic, model",
479 res.points.g, &res.points.g_model);
480 }
481 block("connection probability f(r)", "r [nm], f", res.connection, nullptr);
482 double rmax = res.connection.r.back();
483 if (have_model) {
484 Curve pd = StochasticNetworkFit::PairsPerSite(data, settings_.bin, rmax);
485 Curve pm = StochasticNetworkFit::PairsPerSite(model, settings_.bin, rmax);
486 pd.count.clear();
487 pm.count.clear();
488 block("pairs per site in distance bins", "r [nm], microscopic, model", pd,
489 &pm);
490 }
491 for (std::size_t c = 0; c < settings_.carriers.size(); ++c) {
492 const std::string name = settings_.carriers[c].ToString();
493 if (res.energies[c].fitted) {
494 block("energy correlation kappa(r), carrier " + name,
495 "r [nm], microscopic, fitted moving average",
496 res.energies[c].kappa, &res.energies[c].kappa_model);
497 out << "# rms of the best kappa fit for each l_c, carrier " << name
498 << "\n# l_c, rms\n";
499 const Curve& scan = res.energies[c].l_c_scan;
500 for (std::size_t k = 0; k < scan.r.size(); ++k) {
501 out << scan.r[k] << " " << scan.value[k] << "\n";
502 }
503 out << "\n\n";
504 }
505 Curve jd = StochasticNetworkFit::MeanLog10J2(data, Index(c),
506 settings_.bin, rmax);
507 if (have_model) {
508 Curve jm = StochasticNetworkFit::MeanLog10J2(model, Index(c),
509 settings_.bin, rmax);
510 block("mean log10(J^2/eV^2), carrier " + name,
511 "r [nm], microscopic, model", jd, &jm);
512 } else {
513 block("mean log10(J^2/eV^2), carrier " + name, "r [nm], microscopic",
514 jd, nullptr);
515 }
516 }
517 XTP_LOG(Log::error, log_) << "Wrote " << statsfile_ << std::flush;
518 }
519 return true;
520}
521
522} // namespace xtp
523} // namespace votca
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
T as() const
return value as type
Definition property.h:283
T ifExistsReturnElseReturnDefault(const std::string &key, T defaultvalue) const
Definition property.h:332
static ExactResult Exact(const ToFGraph &graph, Index direct_limit=20000, double tolerance=1e-12)
direct sparse LU up to direct_limit sites, BiCGSTAB with ILUT above
std::string parameterfile_
Definition networkfit.h:51
TrapFinder::Settings traps_
Definition networkfit.h:57
std::string statefile_
Definition networkfit.h:49
std::string energyfile_
Definition networkfit.h:53
bool Run() override
StochasticNetworkFit::Settings settings_
Definition networkfit.h:54
void ParseOptions(const tools::Property &options) override
std::string statsfile_
Definition networkfit.h:52
bool isKMCState() const
Definition qmstate.h:78
std::string job_name_
Definition qmtool.h:50
Topology ReadFrame(Index frameid) const
Definition statesaver.cc:76
std::vector< Index > getFrames() const
Definition statesaver.cc:33
Fits the parameters of a StochasticNetwork to a microscopic system (a state file with site energies a...
static std::vector< double > NearestDistances(const std::vector< Eigen::Vector3d > &points, const Eigen::Vector3d &box)
nearest neighbour distances
static Curve PairsPerSite(const Data &data, double bin, double rmax)
pairs per site in distance bins (connected pairs of the data)
static Data FromNetwork(const StochasticNetwork &net, const std::vector< QMStateType > &carriers, const Eigen::Vector3d &box)
the same data from a model network (validation)
static Curve MeanLog10J2(const Data &data, Index carrier, double bin, double rmax)
mean of log10(J^2/eV^2) in distance bins
static Curve Correlation(const std::vector< Eigen::Vector3d > &points, const Eigen::Vector3d &box, const std::vector< double > &z, double bin, double rmax, const std::vector< char > &skip={})
static Data FromTopology(const Topology &top, const std::vector< QMStateType > &carriers)
Stochastic network model of a molecular charge transport network (Baumeier, Stenzel,...
void BuildTopology(Topology &top) const
fill an empty topology (segments with one pseudo atom, box, pairs)
static std::string ToXML(const Options &opt)
the parameter file (root element "stochasticnetwork")
const std::vector< InsertedTrap > & Traps() const
Hopping graph for time-of-flight (ToF) transport.
Definition tofgraph.h:77
static Options BulkOptions(const std::string &injection_pattern, const std::string &ignore_types)
Definition tofgraph.cc:61
Container for segments and box and atoms.
Definition topology.h:41
static Result Find(const ToFGraph &graph, const Settings &settings)
Definition trapfinder.cc:48
#define XTP_LOG(level, log)
Definition logger.h:40
const double ev2hrt
Definition constants.h:54
const double kB
Definition constants.h:40
const double bohr2nm
Definition constants.h:46
const double hrt2ev
Definition constants.h:53
const double nm2bohr
Definition constants.h:47
Charge transport classes.
Definition ERIs.h:28
Provides a means for comparing floating point numbers.
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26
static Level current_level
Definition globals.h:30
std::vector< Eigen::Vector3d > positions
std::vector< std::vector< double > > energies
std::vector< double > connection_r
connection probability table: f at distances r (ascending, bohr)
std::vector< Trap > traps
Definition trapfinder.h:104
std::vector< Index > sites
Definition trapfinder.h:86