46 throw std::runtime_error(
"kmctof cannot be run for state: " +
54 seed_ = options.
get(
".seed").
as<std::uint64_t>();
61 pulse.
width = inj.get(
"width").as<
double>();
63 double period = inj.get(
"period").as<
double>();
64 if (npulses < 1 || pulse.
carriers < 1) {
65 throw std::runtime_error(
"kmctof: pulses and carriers must be positive");
67 if (npulses > 1 && !(period > 0.0)) {
68 throw std::runtime_error(
"kmctof: a pulse train needs period > 0");
71 for (
Index p = 0; p < npulses; ++p) {
72 pulse.
start = double(p) * period;
82 tmin_ = options.
get(
".current.tmin").
as<
double>();
83 tmax_ = options.
get(
".current.tmax").
as<
double>();
86 log_.setMultithreading(
true);
87 log_.setCommonPreface(
"\n ...");
92 "\n KINETIC MONTE CARLO TIME OF FLIGHT"
93 "\n-----------------------------------"
109 std::unique_ptr<WaitingTimeStrategy> strategy =
113 <<
"Waiting times: " << simulation.
StrategyName() << std::flush;
115 <<
runs_ <<
" runs, " <<
pulses_.size() <<
" pulse(s) of "
117 <<
" thread(s)" << std::flush;
118 auto start = std::chrono::steady_clock::now();
121 std::chrono::duration<double>(std::chrono::steady_clock::now() - start)
125 << std::setprecision(6) << result.
hops <<
" hops, " << result.
null_events
126 <<
" null events (occupied site or rejected), " <<
seconds <<
" s"
131 <<
" runs stopped by maxtime/maxevents before all carriers arrived; "
132 "they are left out, which biases the times low"
138 <<
" injections dropped (all source sites occupied)" << std::flush;
140 auto report = [
this](
const std::string& name,
143 << name <<
": " << s.mean <<
" +- " << s.standard_error
144 <<
" s (standard error, " << s.samples <<
" runs), standard deviation "
145 << s.standard_deviation
146 <<
" s, largest 1 % of the runs: " << 100.0 * s.top_percent_share
147 <<
" % of the sum" << std::flush;
149 report(
"First arrival", result.
first);
150 report(
"Mean transit time per carrier", result.
transit);
153 <<
"Warning: heavy tail, the mean is dominated by rare long runs; "
162 <<
"Mobility L/(tau F) from the mean transit time: "
163 <<
L / result.
transit.
mean * 1e4 / std::abs(Fn) <<
" cm^2/Vs"
168 ResultFile out(
"kmctof: time-of-flight kinetic Monte Carlo");
183 out.
Add(
"length",
L,
"m");
184 out.
Add(
"field_normal", Fn,
"V/m");
186 out.
Add(
"mobility_transit",
L / result.
transit.
mean * 1e4 / std::abs(Fn),
193 out <<
"# run, injected, absorbed, censored, first arrival [s], mean "
194 "transit [s], hops, null events, end time [s]\n";
195 out << std::setprecision(10);
206 out <<
"# transient current per injected carrier (Ramo-Shockley): "
207 "I = (sum of the hop displacements along the transport normal "
208 "in the bin) / (L x injected carriers x bin width), in 1/s; the "
209 "circuit current is q x injected carriers x I, and the integral "
210 "of I is the mean displacement per injected carrier in units of "
212 out <<
"# collected fraction: carriers absorbed up to t_high / injected "
214 out <<
"# t_low [s], t_high [s], t_mid (geometric) [s], current [1/s], "
215 "collected fraction at t_high\n";
216 out <<
"# displacement before t_low of the first bin: "
219 out << std::setprecision(10);
223 out << lo <<
" " << hi <<
" " << std::sqrt(lo * hi) <<
" "
static Pulse::Shape ShapeFromString(const std::string &name)
bool Evaluate(Topology &top) override
Eigen::Vector3d field_Vm_
void ParseOptions(const tools::Property &options) override
KMCEngine::Limits limits_
std::vector< KMCEngine::Pulse > pulses_
Small machine-readable result file of a calculator: one "key value unit" line per quantity (unit "-" ...
void Write(const std::string &filename) const
void Add(const std::string &key, double value, const std::string &unit)
the rates stored in the ToFGraph, constant in time
Hopping graph for time-of-flight (ToF) transport.
const Eigen::Vector3d & Normal() const
unit normal of the cut face, pointing from source to sink side
static Options OptionsFromProperty(const tools::Property &tof)
Options from the "tof" subpackage (subpackages/tof.xml), lengths in nm.
std::string Summary() const
human readable summary
Many independent time-of-flight KMC runs on a ToFGraph and their statistics.
const std::string & StrategyName() const
Container for segments and box and atoms.
#define XTP_LOG(level, log)
Charge transport classes.
std::unique_ptr< WaitingTimeStrategy > MakeWaitingTimeStrategy(const std::string &name)
strategy by name: exponential, thinning, inversion
Provides a means for comparing floating point numbers.
static Level current_level
double displacement_after
std::vector< double > collected
std::vector< RunData > runs
std::vector< double > bin_edges
double displacement_before
std::vector< double > current
KMCEngine::RunStatus status
std::vector< KMCEngine::Pulse > pulses
double standard_deviation
double top_percent_share
share of the sum contributed by the largest 1 % of the samples