votca 2026-dev
Loading...
Searching...
No Matches
grw.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 <fstream>
22#include <iomanip>
23
24// VOTCA includes
27
28// Local VOTCA includes
30#include "votca/xtp/topology.h"
31
32// Local private VOTCA includes
33#include "grw.h"
34
35namespace votca {
36namespace xtp {
37
38void GRW::ParseOptions(const tools::Property& options) {
39 carriertype_ = QMStateType(options.get(".carriertype").as<std::string>());
40 if (!carriertype_.isKMCState()) {
41 throw std::runtime_error("grw cannot be run for state: " +
42 carriertype_.ToLongString());
43 }
44 temperature_ = options.get(".temperature").as<double>() * tools::conv::kB *
46 field_Vm_ = options.get(".field").as<Eigen::Vector3d>();
47 // V/m -> Hartree/bohr
49 tof_ = ToFGraph::OptionsFromProperty(options.get(".tof"));
50 carriers_ = options.get(".numberofcarriers").as<Index>();
52 options.get(".observable").as<std::string>());
53 settings_.max_states = options.get(".maxstates").as<Index>();
55 options.get(".solver").as<std::string>());
56 settings_.direct_limit = options.get(".directlimit").as<Index>();
57 settings_.tolerance = options.get(".tolerance").as<double>();
58 settings_.max_iterations = options.get(".maxiterations").as<Index>();
59 sourcefile_ = options.get(".sourcefile").as<std::string>();
60 occupationfile_ = options.get(".occupationfile").as<std::string>();
61 resultfile_ = options.get(".resultfile").as<std::string>();
62 log_.setReportLevel(Log::current_level);
63 log_.setMultithreading(true);
64 log_.setCommonPreface("\n ...");
65}
66
68 XTP_LOG(Log::error, log_) << "\n-----------------------------------"
69 "\n GRAPH RANDOM WALK TIME OF FLIGHT"
70 "\n-----------------------------------"
71 << std::flush;
72 if (carriers_ != 1 && carriers_ != 2) {
73 throw std::runtime_error(
74 "grw: numberofcarriers must be 1 or 2 (the state space grows as "
75 "n^N/N!; use kinetic Monte Carlo for more carriers)");
76 }
78 XTP_LOG(Log::error, log_) << graph.Summary() << std::flush;
79 for (Index s : graph.DisconnectedSources()) {
81 << "source segment " << s << " has no path to a sink, excluded"
82 << std::flush;
83 }
84
85 GraphRandomWalk grw(graph);
90 bool transit =
92 if (carriers_ == 2) {
94 << "Two carriers with site exclusion, observable: "
95 << (transit ? "mean transit time per carrier (carriers removed at "
96 "the sink)"
97 : "time until the first carrier reaches the sink")
98 << std::flush;
99 }
100
102 << "Solver: " << result.solver << ", " << result.unknowns << " unknowns, "
103 << result.iterations << " iterations, backward error "
104 << result.backward_error << " after " << result.refinement_steps
105 << " refinement steps" << std::flush;
106 if (!result.converged) {
108 << "Warning: not converged (iteration limit or backward error above "
109 "1e-10)"
110 << std::flush;
111 }
113 << std::setprecision(6) << "Time of flight (uniform injection over "
114 << result.sources.size() << " source "
115 << (carriers_ == 1 ? "sites" : "pairs") << "): mean " << result.tau_mean
116 << " s" << std::flush;
117 if (!transit) {
118 XTP_LOG(Log::error, log_) << "Standard deviation of the hitting time: "
119 << result.tau_std_injection << " s" << std::flush;
120 }
122 << "Harmonic mean over the injection states: " << result.tau_harmonic
123 << " s" << std::flush;
124
125 double Fn = field_Vm_.dot(graph.Normal()); // V/m along the normal
126 double L = graph.Length() * tools::conv::bohr2nm * 1e-9; // m
127 if (Fn != 0.0) {
128 double charge = 0.0;
130 charge = 1.0;
131 } else if (carriertype_ == QMStateType::Electron) {
132 charge = -1.0;
133 }
134 if (charge * Fn <= 0.0) {
136 << "Warning: the field does not drive the carriers towards the sink"
137 << std::flush;
138 }
139 double factor = 1e4 / std::abs(Fn); // m^2/Vs -> cm^2/Vs
141 << "Mobility L/(tau F): " << L / result.tau_mean * factor
142 << " cm^2/Vs (mean), " << L / result.tau_harmonic * factor
143 << " cm^2/Vs (harmonic), with L = " << L * 1e9 << " nm and F = " << Fn
144 << " V/m along the normal" << std::flush;
145 }
146
147 if (!resultfile_.empty()) {
148 ResultFile out("grw: mean hitting times of the sink (graph random walk)");
149 out.Add("carriers", result.carriers);
150 out.Add("observable",
151 transit ? std::string("transit") : std::string("first"));
152 out.Add("unknowns", result.unknowns);
153 out.Add("sources", Index(result.sources.size()));
154 out.Add("tau_mean", result.tau_mean, "s");
155 out.Add("tau_harmonic", result.tau_harmonic, "s");
156 if (!transit) {
157 out.Add("tau_std", result.tau_std_injection, "s");
158 }
159 out.Add("length", L, "m");
160 out.Add("field_normal", Fn, "V/m");
161 if (Fn != 0.0) {
162 out.Add("mobility_mean", L / result.tau_mean * 1e4 / std::abs(Fn),
163 "cm^2/Vs");
164 out.Add("mobility_harmonic", L / result.tau_harmonic * 1e4 / std::abs(Fn),
165 "cm^2/Vs");
166 }
167 out.Add("backward_error", result.backward_error, "-");
168 out.Add("converged", Index(result.converged));
169 out.Write(resultfile_);
170 }
171 if (!sourcefile_.empty()) {
172 WriteSources(graph, result);
173 }
174 if (!occupationfile_.empty()) {
175 WriteOccupation(graph, result);
176 }
177 std::cout << log_;
178 return true;
179}
180
181void GRW::WriteSources(const ToFGraph& graph,
182 const GraphRandomWalk::Result& result) const {
183 std::ofstream out(sourcefile_);
184 out << "# per injection state: for each carrier segment id, x along the "
185 "normal [nm], site energy [eV]; then the mean time [s] and, if "
186 "available, the standard deviation of the hitting time [s]\n";
187 out << std::setprecision(10);
188 for (Index k = 0; k < Index(result.sources.size()); ++k) {
189 for (Index s : result.sources[k]) {
190 const ToFGraph::Site& site = graph.getSite(s);
191 out << site.segment << " " << site.x * tools::conv::bohr2nm << " "
192 << site.energy * tools::conv::hrt2ev << " ";
193 }
194 out << result.tau[k];
195 if (result.tau_std.size() == result.tau.size()) {
196 out << " " << result.tau_std[k];
197 }
198 out << "\n";
199 }
200}
201
203 const GraphRandomWalk::Result& result) const {
204 std::ofstream out(occupationfile_);
205 out << "# expected time each segment is occupied before the carriers reach "
206 "the sink, uniform injection\n";
207 out << "# segment id, x along the normal [nm], site energy [eV], role, "
208 "time [s], fraction of the total occupation time\n";
209 out << std::setprecision(10);
210 const char* roles[] = {"bulk", "source", "sink"};
211 for (const ToFGraph::Site& site : graph.Sites()) {
212 double t = result.occupation_time[site.segment];
213 out << site.segment << " " << site.x * tools::conv::bohr2nm << " "
214 << site.energy * tools::conv::hrt2ev << " "
215 << roles[static_cast<int>(site.role)] << " " << t << " "
216 << t / (double(result.carriers) * result.tau_mean) << "\n";
217 }
218}
219
220} // namespace xtp
221} // 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
std::string occupationfile_
Definition grw.h:67
QMStateType carriertype_
Definition grw.h:57
GraphRandomWalk::Settings settings_
Definition grw.h:64
Index carriers_
Definition grw.h:62
void WriteOccupation(const ToFGraph &graph, const GraphRandomWalk::Result &result) const
Definition grw.cc:202
void WriteSources(const ToFGraph &graph, const GraphRandomWalk::Result &result) const
Definition grw.cc:181
void ParseOptions(const tools::Property &options) override
Definition grw.cc:38
bool Evaluate(Topology &top) override
Definition grw.cc:67
ToFGraph::Options tof_
Definition grw.h:61
GraphRandomWalk::Observable observable_
Definition grw.h:65
Logger log_
Definition grw.h:56
Eigen::Vector3d field_Vm_
Definition grw.h:60
Eigen::Vector3d field_
Definition grw.h:59
double temperature_
Definition grw.h:58
std::string sourcefile_
Definition grw.h:66
std::string resultfile_
Definition grw.h:68
GraphRandomWalk::Solver solver_
Definition grw.h:63
Expected time of flight from hitting times of a continuous-time random walk on a ToFGraph,...
Result TwoCarriers(Observable observable, Solver solver=Solver::Auto) const
void setSettings(const Settings &settings)
static Solver SolverFromString(const std::string &name)
Result SingleCarrier(Solver solver=Solver::Auto) const
static Observable ObservableFromString(const std::string &name)
Small machine-readable result file of a calculator: one "key value unit" line per quantity (unit "-" ...
Definition resultfile.h:42
void Write(const std::string &filename) const
Definition resultfile.h:59
void Add(const std::string &key, double value, const std::string &unit)
Definition resultfile.h:49
Hopping graph for time-of-flight (ToF) transport.
Definition tofgraph.h:77
const Site & getSite(Index i) const
Definition tofgraph.h:151
const std::vector< Index > & DisconnectedSources() const
source sites from which no sink can be reached (excluded above)
Definition tofgraph.h:168
const std::vector< Site > & Sites() const
Definition tofgraph.h:150
double Length() const
Definition tofgraph.h:184
const Eigen::Vector3d & Normal() const
unit normal of the cut face, pointing from source to sink side
Definition tofgraph.h:179
static Options OptionsFromProperty(const tools::Property &tof)
Options from the "tof" subpackage (subpackages/tof.xml), lengths in nm.
Definition tofgraph.cc:73
std::string Summary() const
human readable summary
Definition tofgraph.cc:360
Container for segments and box and atoms.
Definition topology.h:41
#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< std::vector< Index > > sources
Index iterations
iterative solvers: total iterations
double tau_harmonic
harmonic mean over the injection states (eq. 3.4 of the paper)
double energy
site energy of the carrier
Definition tofgraph.h:118
double x
coordinate along the transport normal, in [0, thickness)
Definition tofgraph.h:113