votca 2024.2-dev
Loading...
Searching...
No Matches
kmccalculator.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// Standard includes
19#include <locale>
20
21// Third party includes
22#include <boost/format.hpp>
23
24// VOTCA includes
27
28// Local VOTCA includes
29#include "votca/xtp/gnode.h"
31#include "votca/xtp/logger.h"
32#include "votca/xtp/qmstate.h"
34#include "votca/xtp/topology.h"
35
36using namespace std;
37
38namespace votca {
39namespace xtp {
40
42 seed_ = options.get(".seed").as<Index>();
43
44 numberofcarriers_ = options.get(".numberofcarriers").as<Index>();
45 injection_name_ = options.get(".injectionpattern").as<std::string>();
46 maxrealtime_ = options.get(".maxrealtime").as<double>();
47 trajectoryfile_ = options.get(".trajectoryfile").as<std::string>();
48 temperature_ = options.get(".temperature").as<double>();
49
51 occfile_ = options.get(".occfile").as<std::string>();
52 ratefile_ = options.get(".ratefile").as<std::string>();
53
54 injectionmethod_ = options.get(".injectionmethod").as<std::string>();
55 ignoresegments_ = options.get(".ignoresegments").as<std::string>();
56}
57
59
60 std::vector<Segment>& segs = top.Segments();
61
62 if (segs.size() < 1) {
63 throw std::runtime_error("Your state file contains no segments!");
64 }
65 nodes_.reserve(segs.size());
66 for (Segment& seg : segs) {
67 bool injectable = false;
68 if (tools::wildcmp(injection_name_, seg.getType())) {
69 injectable = true;
70 }
71 nodes_.push_back(GNode(seg, carriertype_, injectable));
72 }
73
74 QMNBList& nblist = top.NBList();
75 if (nblist.size() < 1) {
76 throw std::runtime_error("neighborlist contains no pairs!");
77 }
78 if (temperature_ <= 0) {
79 throw std::runtime_error(
80 "Your Temperature is negative or zero, please specify the temperature "
81 "in Kelvin.");
82 }
83
84 Rate_Engine rate_engine(temperature_, field_);
85 XTP_LOG(Log::error, log_) << "\nCalculating initial rates." << std::flush;
86 XTP_LOG(Log::error, log_) << rate_engine << std::flush;
88 << " carriertype: " << carriertype_.ToLongString() << std::flush;
89
90 for (const QMPair* pair : nblist) {
91 Rate_Engine::PairRates rates = rate_engine.Rate(*pair, carriertype_);
92 nodes_[pair->Seg1()->getId()].AddEventfromQmPair(*pair, nodes_,
93 rates.rate12);
94 nodes_[pair->Seg2()->getId()].AddEventfromQmPair(*pair, nodes_,
95 rates.rate21);
96 }
98 XTP_LOG(Log::error, log_) << " Rates for " << nodes_.size()
99 << " sites are computed." << std::flush;
101
102 Index events = 0;
103 Index max = std::numeric_limits<Index>::min();
104 Index min = std::numeric_limits<Index>::max();
105 double minlength = std::numeric_limits<double>::max();
106 double maxlength = 0;
107 for (const auto& node : nodes_) {
108
109 Index size = Index(node.Events().size());
110 for (const auto& event : node.Events()) {
111 if (event.isDecayEvent()) {
112 continue;
113 }
114 double dist = event.getDeltaR().norm();
115 if (dist > maxlength) {
116 maxlength = dist;
117 } else if (dist < minlength) {
118 minlength = dist;
119 }
120 }
121
122 events += size;
123 if (size == 0) {
125 << "Node " << node.getId() << " has 0 jumps" << std::flush;
126 } else if (size < min) {
127 min = size;
128 } else if (size > max) {
129 max = size;
130 }
131 }
132 double avg = double(events) / double(nodes_.size());
133 double deviation = 0.0;
134 for (const auto& node : nodes_) {
135 double size = double(node.Events().size());
136 deviation += (size - avg) * (size - avg);
137 }
138 deviation = std::sqrt(deviation / double(nodes_.size()));
139
141 << "Nblist has " << nblist.size() << " pairs. Nodes contain " << events
142 << " jump events\n"
143 << "with avg=" << avg << " std=" << deviation << " max=" << max
144 << " min=" << min << " jumps per site\n"
145 << "Minimum jumpdistance =" << minlength * tools::conv::bohr2nm
146 << " nm Maximum distance =" << maxlength * tools::conv::bohr2nm << " nm\n"
147 << std::flush;
148 double conv = std::pow(tools::conv::bohr2nm, 3);
150 << "spatial carrier density: "
151 << double(numberofcarriers_) / (top.BoxVolume() * conv) << " nm^-3"
152 << std::flush;
153
154 tools::Tokenizer toignore(ignoresegments_, ", \t\n");
155 std::vector<std::string> ignored_segtypes = toignore.ToVector();
156
157 for (auto& node : nodes_) {
158 std::string this_segtype = segs[node.getId()].getType();
159 if (std::find(ignored_segtypes.begin(), ignored_segtypes.end(),
160 this_segtype) == ignored_segtypes.end()) {
161 node.InitEscapeRate();
162 node.MakeHuffTree();
163 }
164 }
165 return;
166}
167
169 std::vector<GNode*>& forbiddenlist) const {
170 forbiddenlist.clear();
171 return;
172}
173
175 GNode& node, std::vector<GNode*>& forbiddenlist) const {
176 forbiddenlist.push_back(&node);
177 return;
178}
179
181 const GNode& node, const std::vector<GNode*>& forbiddenlist) const {
182 bool forbidden = false;
183 for (const GNode* fnode : forbiddenlist) {
184 if (&node == fnode) {
185 forbidden = true;
186 break;
187 }
188 }
189 return forbidden;
190}
191
193 const GNode& node, const std::vector<GNode*>& forbiddendests) const {
194 bool surrounded = true;
195 for (const auto& event : node.Events()) {
196 bool thisevent_possible = true;
197 for (const GNode* fnode : forbiddendests) {
198 if (event.getDestination() == fnode) {
199 thisevent_possible = false;
200 break;
201 }
202 }
203 if (thisevent_possible == true) {
204 surrounded = false;
205 break;
206 }
207 }
208 return surrounded;
209}
210
212
213 XTP_LOG(Log::error, log_) << "looking for injectable nodes..." << std::flush;
214 for (Index i = 0; i < numberofcarriers_; i++) {
215 Chargecarrier newCharge(i);
217
219 << "starting position for charge " << i << ": segment "
220 << newCharge.getCurrentNodeId() << std::flush;
221 carriers_.push_back(newCharge);
222 }
223 return;
224}
225
227 Index nodeId_guess = -1;
228 do {
229 nodeId_guess = RandomVariable_.rand_uniform_int();
230 } while (nodes_[nodeId_guess].isOccupied() ||
231 nodes_[nodeId_guess].isInjectable() ==
232 false); // maybe already occupied? or maybe not injectable?
233 if (Charge.hasNode()) {
234 Charge.ReleaseNode();
235 }
236 Charge.settoNote(&nodes_[nodeId_guess]);
237
238 return;
239}
240
241double KMCCalculator::Promotetime(double cumulated_rate) {
242 double dt = 0;
243 double rand_u = 1 - RandomVariable_.rand_uniform();
244 dt = -1 / cumulated_rate * std::log(rand_u);
245 return dt;
246}
247
249 double u = 1 - RandomVariable_.rand_uniform();
250 return *(node.findHoppingDestination(u));
251}
252
254 if (carriers_.size() == 1) {
255 return &carriers_[0];
256 }
257 Chargecarrier* carrier = nullptr;
258 double u = 1 - RandomVariable_.rand_uniform();
259 for (Index i = 0; i < numberofcarriers_; i++) {
260 u -= carriers_[i].getCurrentEscapeRate() / cumulated_rate;
261 if (u <= 0 || i == numberofcarriers_ - 1) {
262 carrier = &carriers_[i];
263 break;
264 }
265 }
266 return carrier;
267}
268void KMCCalculator::WriteRatestoFile(std::string filename,
269 const QMNBList& nblist) {
271 << "\nRates are written to " << filename << std::flush;
272 fstream ratefs;
273 ratefs.open(filename, fstream::out);
274 ratefs << "#PairID,SiteID1,SiteID2, ,rate12[1/s],rate21[1/s] at "
276 << "K for carrier:" << carriertype_.ToString() << endl;
277
278 Rate_Engine rate_engine(temperature_, field_);
279 for (const QMPair* pair : nblist) {
280 Rate_Engine::PairRates rates = rate_engine.Rate(*pair, carriertype_);
281 ratefs << pair->getId() << " " << pair->Seg1()->getId() << " "
282 << pair->Seg2()->getId() << " " << rates.rate12 << " "
283 << rates.rate21 << "\n";
284 }
285 ratefs << std::flush;
286 ratefs.close();
287}
288
290 std::string filename) {
292 << "\nOccupations are written to " << filename << std::flush;
293 fstream probs;
294 probs.open(filename, fstream::out);
295 probs << "#SiteID, Occupation prob at "
297 << "K for carrier:" << carriertype_.ToString() << endl;
298 for (const GNode& node : nodes_) {
299 double occupationprobability = node.OccupationTime() / simtime;
300 probs << node.getId() << "\t" << occupationprobability << endl;
301 }
302 probs.close();
303}
304
305} // namespace xtp
306} // namespace votca
Index size() const
Definition pairlist.h:53
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
void setMaxInt(Index maxint)
Definition random.h:41
double rand_uniform()
Definition random.h:39
Index rand_uniform_int()
Definition random.h:45
break string into words
Definition tokenizer.h:72
std::vector< T > ToVector()
store all words in a vector of type T, does type conversion.
Definition tokenizer.h:109
Index getCurrentNodeId() const
const std::vector< GLink > & Events() const
Definition gnode.h:47
GLink * findHoppingDestination(double p) const
Definition gnode.cc:44
void ResetForbiddenlist(std::vector< GNode * > &forbiddenid) const
void LoadGraph(Topology &top)
std::vector< Chargecarrier > carriers_
void WriteRatestoFile(std::string filename, const QMNBList &nblist)
double Promotetime(double cumulated_rate)
Chargecarrier * ChooseAffectedCarrier(double cumulated_rate)
const GLink & ChooseHoppingDest(const GNode &node)
void AddtoForbiddenlist(GNode &node, std::vector< GNode * > &forbiddenid) const
void RandomlyAssignCarriertoSite(Chargecarrier &Charge)
void ParseCommonOptions(const tools::Property &options)
bool CheckSurrounded(const GNode &node, const std::vector< GNode * > &forbiddendests) const
tools::Random RandomVariable_
std::vector< GNode > nodes_
void WriteOccupationtoFile(double simtime, std::string filename)
bool CheckForbidden(const GNode &node, const std::vector< GNode * > &forbiddenlist) const
std::string ToLongString() const
Definition qmstate.cc:69
std::string ToString() const
Definition qmstate.cc:35
PairRates Rate(const QMPair &pair, QMStateType carriertype) const
Container for segments and box and atoms.
Definition topology.h:41
std::vector< Segment > & Segments()
Definition topology.h:58
QMNBList & NBList()
Definition topology.h:70
double BoxVolume() const
Definition topology.h:65
#define XTP_LOG(level, log)
Definition logger.h:40
STL namespace.
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
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