diff --git a/CHANGELOG.md b/CHANGELOG.md index e04e71f..eb582d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 -------------------------------------------------------------------------------------------------------------------------------- +## [v1.0.0-rc.3]- 2019-04-01 - Density of States Integration Bugfix + +### Added +- OSC_Sim - Steady_DOS_sampling_count and Steady_DOOS_sampling_counter to keep track of how many times the DOS and DOOS are sampled during the simulation +- test.cpp (SteadyTransportTests) - tests to check the integral of the DOS and DOOS with and without including Coulomb interactions + +### Changed +- main.cpp - Version string to v1.0.0-rc.3 +- OSC_Sim (updateSteadyData) - To increment the new DOS and DOOS sampling counters and removed calculation of the DOS because the DOS is does not change during the simulation when not including Coulomb interactions +- OSC_Sim (getSteadyDOS) - Function is not longer const +- parameters_default.txt - Version string to v1.0.0-rc.3 + +### Removed + +### Fixed +- main.cpp - Output of density of states and density of occupied states data to have the correct units +- OSC_Sim (getSteadyDOOS) - To use the new sampling counter to avoid errors averaging over multiple samplings +- OSC_Sim (getSteadyDOOS_Coulomb) - To use the new sampling counter to avoid errors averaging over multiple samplings +- OSC_Sim (getSteadyDOS) - To calculate the DOS using only one sample at call time because the DOS (without Coulomb) does not change during the simulation +- OSC_Sim (getSteadyDOS_Coulomb) - To use the new sampling counter to avoid errors averaging over multiple samplings + + ## [v1.0.0-rc.2]- 2019-02-09 - Steady State Charge Transport Test Update ### Added diff --git a/docs/_o_s_c___sim_8h_source.html b/docs/_o_s_c___sim_8h_source.html index af816b0..2ffe1d3 100644 --- a/docs/_o_s_c___sim_8h_source.html +++ b/docs/_o_s_c___sim_8h_source.html @@ -91,12 +91,13 @@
OSC_Sim.h
-Go to the documentation of this file.
1 // Copyright (c) 2017-2019 Michael C. Heiber
2 // This source file is part of the Excimontec project, which is subject to the MIT License.
3 // For more information, see the LICENSE file that accompanies this software.
4 // The Excimontec project can be found on Github at https://github.com/MikeHeiber/Excimontec
5 
6 #ifndef EXCIMONTEC_OSC_SIM_H
7 #define EXCIMONTEC_OSC_SIM_H
8 
9 #include "Simulation.h"
10 #include "Site.h"
11 #include "Exciton.h"
12 #include "Parameters.h"
13 #include "Polaron.h"
14 #include "Version.h"
15 #include <algorithm>
16 #include <fstream>
17 #include <iostream>
18 #include <list>
19 #include <numeric>
20 #include <random>
21 #include <string>
22 #include <utility>
23 #include <vector>
24 
25 namespace Excimontec {
26 
32  public:
33 
35  OSC_Sim();
36 
38  virtual ~OSC_Sim();
39 
45  bool init(const Parameters& params, const int id);
46 
48  void calculateAllEvents();
49 
54  std::vector<std::pair<double, double>> calculateTransitTimeHist(const std::vector<double>& data, const int counts) const;
55 
59  std::vector<double> calculateMobilityData(const std::vector<double>& transit_times) const;
60 
64  bool checkFinished() const;
65 
68  void createExciton(const bool spin);
69 
74  void createExciton(const KMC_Lattice::Coords& coords, const bool spin);
75 
79  void createElectron(const KMC_Lattice::Coords& coords);
80 
84  void createHole(const KMC_Lattice::Coords& coords);
85 
90  bool executeNextEvent();
91 
94  void exportEnergies(std::string filename);
95 
99  void exportEnergies(std::string filename, bool charge);
100 
104  std::vector<std::string> getChargeExtractionMap(const bool charge) const;
105 
108  std::vector<std::pair<double, double>> getDOSCorrelationData() const;
109 
112  std::vector<double> getDynamicsExcitonEnergies() const;
113 
116  std::vector<double> getDynamicsElectronEnergies() const;
117 
120  std::vector<double> getDynamicsHoleEnergies() const;
121 
124  std::vector<int> getDynamicsTransientSinglets() const;
125 
128  std::vector<int> getDynamicsTransientTriplets() const;
129 
132  std::vector<int> getDynamicsTransientElectrons() const;
133 
136  std::vector<int> getDynamicsTransientHoles() const;
137 
140  std::vector<double> getDynamicsTransientTimes() const;
141 
145  std::vector<double> getDynamicsExcitonMSDV() const;
146 
151  std::vector<double> getDynamicsElectronMSDV() const;
152 
157  std::vector<double> getDynamicsHoleMSDV() const;
158 
161  std::vector<double> getExcitonDiffusionData() const;
162 
165  std::vector<int> getExcitonHopLengthData() const;
166 
169  std::vector<double> getExcitonLifetimeData() const;
170 
173  double getInternalField() const;
174 
177  int getN_excitons_created() const;
178 
182  int getN_excitons_created(const short site_type) const;
183 
187 
191 
195 
199 
203 
207 
211 
215 
219 
222  int getN_electrons_created() const;
223 
226  int getN_electrons_collected() const;
227 
230  int getN_electrons_recombined() const;
231 
234  long int getN_events_executed() const;
235 
238  int getN_holes_created() const;
239 
242  int getN_holes_collected() const;
243 
246  int getN_holes_recombined() const;
247 
251  int getN_geminate_recombinations() const;
252 
257 
262  int getN_transient_cycles() const;
263 
266  std::string getPreviousEventType() const;
267 
271  std::vector<float> getSiteEnergies(const short site_type) const;
272 
278  float getSiteEnergy(const KMC_Lattice::Coords& coords);
279 
285  short getSiteType(const KMC_Lattice::Coords& coords);
286 
289  double getSteadyCurrentDensity() const;
290 
293  std::vector<std::pair<double, double>> getSteadyDOOS() const;
294 
296  // This function calculates the state energies including the Coulomb potential due to interactions between the polarons.
298  std::vector<std::pair<double, double>> getSteadyDOOS_Coulomb() const;
299 
302  std::vector<std::pair<double, double>> getSteadyDOS() const;
303 
305  // This function calculates the state energies including the Coulomb potential due to interactions between the polarons.
307  std::vector<std::pair<double, double>> getSteadyDOS_Coulomb() const;
308 
312  double getSteadyEquilibrationEnergy() const;
313 
319 
322  double getSteadyMobility() const;
323 
326  double getSteadyTransportEnergy() const;
327 
331  double getSteadyTransportEnergy_Coulomb() const;
332 
335  std::vector<int> getToFTransientCounts() const;
336 
339  std::vector<double> getToFTransientEnergies() const;
340 
343  std::vector<double> getToFTransientTimes() const;
344 
348  std::vector<double> getToFTransientVelocities() const;
349 
352  std::vector<double> getTransitTimeData() const;
353 
355  void outputStatus();
356 
358  void reassignSiteEnergies();
359 
360  protected:
361 
362  private:
363 
364  class Site_OSC : public KMC_Lattice::Site {
365  public:
366  float getEnergy() const { return energy; }
367  short getType() const { return type; }
368  void setEnergy(const float energy_input) { energy = energy_input; }
369  void setType(const short site_type) { type = (char)site_type; }
370  private:
371  float energy;
372  char type = 0; // type 1 represent donor, type 2 represents acceptor
373  };
374 
375  struct ExcitonEventCalcVars {
376  int range;
377  int dim;
378  Exciton::Hop hop_event;
379  std::vector<Exciton::Hop> hops_temp;
380  Exciton::Dissociation diss_event;
381  std::vector<Exciton::Dissociation> dissociations_temp;
382  Exciton::Exciton_Annihilation ee_annihilation_event;
383  std::vector<Exciton::Exciton_Annihilation> ee_annihilations_temp;
384  Exciton::Polaron_Annihilation ep_annihilation_event;
385  std::vector<Exciton::Polaron_Annihilation> ep_annihilations_temp;
386  std::vector<bool> hops_valid;
387  std::vector<bool> dissociations_valid;
388  std::vector<bool> ee_annihilations_valid;
389  std::vector<bool> ep_annihilations_valid;
390  // precalculated distances vector that contains the distances to nearby sites used for event execution time calculations
391  std::vector<double> distances;
392  // precalculated isInDissRange and isInFRETRange vectors that contains booleans to indicate whether the nearby sites are within range for the different exciton events to be possible.
393  std::vector<bool> isInDissRange;
394  std::vector<bool> isInFRETRange;
395 
396  ExcitonEventCalcVars() {}
397 
398  ExcitonEventCalcVars(OSC_Sim* sim_ptr) {
399  range = (int)ceil(((sim_ptr->params.FRET_cutoff > sim_ptr->params.Exciton_dissociation_cutoff) ? (sim_ptr->params.FRET_cutoff) : (sim_ptr->params.Exciton_dissociation_cutoff)) / sim_ptr->lattice.getUnitSize());
400  dim = (2 * range + 1);
401  hop_event = Exciton::Hop(sim_ptr);
402  hops_temp.assign(dim*dim*dim, hop_event);
403  diss_event = Exciton::Dissociation(sim_ptr);
404  dissociations_temp.assign(dim*dim*dim, diss_event);
405  ee_annihilation_event = Exciton::Exciton_Annihilation(sim_ptr);
406  ee_annihilations_temp.assign(dim*dim*dim, ee_annihilation_event);
407  ep_annihilation_event = Exciton::Polaron_Annihilation(sim_ptr);
408  ep_annihilations_temp.assign(dim*dim*dim, ep_annihilation_event);
409  hops_valid.assign(dim*dim*dim, false);
410  dissociations_valid.assign(dim*dim*dim, false);
411  ee_annihilations_valid.assign(dim*dim*dim, false);
412  ep_annihilations_valid.assign(dim*dim*dim, false);
413  // precalculated distances vector that contains the distances to nearby sites used for event execution time calculations
414  distances.assign(dim*dim*dim, 0.0);
415  // precalculated isInDissRange and isInFRETRange vectors that contains booleans to indicate whether the nearby sites are within range for the different exciton events to be possible.
416  isInDissRange.assign(dim*dim*dim, false);
417  isInFRETRange.assign(dim*dim*dim, false);
418  // Initialize distances, isInDissRange, and isInFRETRange vectors
419  for (int i = -range; i <= range; i++) {
420  for (int j = -range; j <= range; j++) {
421  for (int k = -range; k <= range; k++) {
422  int index = (i + range)*dim*dim + (j + range)*dim + (k + range);
423  distances[index] = sim_ptr->lattice.getUnitSize()*sqrt((double)(i*i + j * j + k * k));
424  if (!((distances[index] - 0.0001) > sim_ptr->params.Exciton_dissociation_cutoff)) {
425  isInDissRange[index] = true;
426  }
427  if (!((distances[index] - 0.0001) > sim_ptr->params.FRET_cutoff)) {
428  isInFRETRange[index] = true;
429  }
430  }
431  }
432  }
433  }
434  };
435  ExcitonEventCalcVars exciton_event_calc_vars;
436 
437  struct PolaronEventCalcVars {
438  int range;
439  int dim;
440  Polaron::Hop hop_event;
441  std::vector<Polaron::Hop> hops_temp;
442  Polaron::Recombination rec_event;
443  std::vector<Polaron::Recombination> recombinations_temp;
444  std::vector<bool> hops_valid;
445  std::vector<bool> recombinations_valid;
446  // precalculated distances vector that contains the distances to nearby sites used for event execution time calculations
447  std::vector<double> distances;
448  std::vector<double> E_deltas;
449  // precalculated isInRange vector that contains booleans to indicate if the nearby sites are within range for polaron events to be possible.
450  std::vector<bool> isInRange;
451 
452  PolaronEventCalcVars() {}
453 
454  PolaronEventCalcVars(OSC_Sim* sim_ptr) {
455  range = (int)ceil(sim_ptr->params.Polaron_hopping_cutoff / sim_ptr->lattice.getUnitSize());
456  dim = (2 * range + 1);
457  hop_event = Polaron::Hop(sim_ptr);
458  hops_temp.assign(dim*dim*dim, hop_event);
459  rec_event = Polaron::Recombination(sim_ptr);
460  recombinations_temp.assign(dim*dim*dim, rec_event);
461  hops_valid.assign(dim*dim*dim, false);
462  recombinations_valid.assign(dim*dim*dim, false);
463  // precalculated distances vector that contains the distances to nearby sites used for event execution time calculations
464  distances.assign(dim*dim*dim, 0.0);
465  E_deltas.assign(dim*dim*dim, 0.0);
466  // precalculated isInRange vector that contains booleans to indicate if the nearby sites are within range for polaron events to be possible.
467  isInRange.assign(dim*dim*dim, false);
468  // Initialize distances and isInRange vectors
469  for (int i = -range; i <= range; i++) {
470  for (int j = -range; j <= range; j++) {
471  for (int k = -range; k <= range; k++) {
472  int index = (i + range)*dim*dim + (j + range)*dim + (k + range);
473  distances[index] = sim_ptr->lattice.getUnitSize()*sqrt((double)(i*i + j * j + k * k));
474  if (!((distances[index] - 0.0001) > sim_ptr->params.Polaron_hopping_cutoff)) {
475  isInRange[index] = true;
476  }
477  }
478  }
479  }
480  }
481  };
482  PolaronEventCalcVars polaron_event_calc_vars;
483  // Input Parameters
484  Parameters params;
485  // Additional Derived Parameters
486  double Transient_start;
487  double Transient_end;
488  int Transient_pnts_per_decade;
489  bool isLightOn;
490  double R_exciton_generation_donor;
491  double R_exciton_generation_acceptor;
492  double Transient_step_size;
493  double Transient_creation_time;
494  int Transient_index_prev;
495  int Transient_singlet_counts_prev;
496  int Transient_triplet_counts_prev;
497  int Transient_electron_counts_prev;
498  int Transient_hole_counts_prev;
499  int Coulomb_range;
500  double AvgDielectric;
501  double Image_interaction_prefactor;
502  int N_initial_excitons;
503  // Site Data Structure
504  std::vector<Site_OSC> sites;
505  // Object Data Structures
506  std::list<Exciton> excitons;
507  std::list<Polaron> electrons;
508  std::list<Polaron> holes;
509  // Event Data Structures
510  std::string previous_event_type = "";
511  double previous_event_time = 0;
512  std::list<Exciton::Creation> exciton_creation_events;
513  std::list<KMC_Lattice::Event*>::const_iterator exciton_creation_it;
514  std::list<Exciton::Hop> exciton_hop_events;
515  std::list<Exciton::Recombination> exciton_recombination_events;
516  std::list<Exciton::Dissociation> exciton_dissociation_events;
517  std::list<Exciton::Exciton_Annihilation> exciton_exciton_annihilation_events;
518  std::list<Exciton::Polaron_Annihilation> exciton_polaron_annihilation_events;
519  std::list<Exciton::Intersystem_Crossing> exciton_intersystem_crossing_events;
520  std::list<Polaron::Hop> electron_hop_events;
521  std::list<Polaron::Hop> hole_hop_events;
522  std::list<Polaron::Recombination> polaron_recombination_events;
523  std::list<Polaron::Extraction> electron_extraction_events;
524  std::list<Polaron::Extraction> hole_extraction_events;
525  // Additional Data Structures
526  std::vector<double> Coulomb_table;
527  std::vector<double> E_potential;
528  std::vector<std::pair<double, double>> DOS_correlation_data;
529  std::vector<double> exciton_lifetimes;
530  std::vector<double> exciton_diffusion_distances;
531  std::vector<int> exciton_hop_distances; // saved in lattice units squared
532  std::vector<int> transient_exciton_tags;
533  std::vector<int> transient_electron_tags;
534  std::vector<int> transient_hole_tags;
535  std::vector<int> ToF_positions_prev;
536  std::vector<double> transient_exciton_energies_prev;
537  std::vector<double> transient_electron_energies_prev;
538  std::vector<double> transient_hole_energies_prev;
539  std::vector<double> transient_exciton_msdv;
540  std::vector<double> transient_electron_msdv;
541  std::vector<double> transient_hole_msdv;
542  std::vector<int> electron_extraction_data;
543  std::vector<int> hole_extraction_data;
544  std::vector<std::pair<double, double>> steady_DOOS;
545  std::vector<std::pair<double, double>> steady_DOOS_Coulomb;
546  std::vector<std::pair<double, double>> steady_DOS;
547  std::vector<std::pair<double, double>> steady_DOS_Coulomb;
548  std::vector<double> transient_times;
549  std::vector<double> transient_velocities;
550  std::vector<double> transient_exciton_energies;
551  std::vector<double> transient_electron_energies;
552  std::vector<double> transient_hole_energies;
553  std::vector<double> transit_times;
554  std::vector<int> transient_singlet_counts;
555  std::vector<int> transient_triplet_counts;
556  std::vector<int> transient_electron_counts;
557  std::vector<int> transient_hole_counts;
558  int Steady_hops_per_DOS_sample = 1000000;
559  int Steady_hops_per_DOOS_sample = 1000;
560  double DOS_bin_size = 1e-2;
561  double Steady_equilibration_time = 0.0;
562  double Steady_equilibration_energy_sum = 0.0;
563  double Steady_equilibration_energy_sum_Coulomb = 0.0;
564  double Transport_energy_weighted_sum = 0.0;
565  double Transport_energy_weighted_sum_Coulomb = 0.0;
566  double Transport_energy_sum_of_weights = 0.0;
567  // Additional Counters
568  int N_donor_sites = 0;
569  int N_acceptor_sites = 0;
570  int N_excitons_created = 0;
571  int N_excitons_created_donor = 0;
572  int N_excitons_created_acceptor = 0;
573  int N_singlet_excitons_recombined = 0;
574  int N_triplet_excitons_recombined = 0;
575  int N_singlet_excitons_dissociated = 0;
576  int N_triplet_excitons_dissociated = 0;
577  int N_singlet_singlet_annihilations = 0;
578  int N_singlet_triplet_annihilations = 0;
579  int N_triplet_triplet_annihilations = 0;
580  int N_singlet_polaron_annihilations = 0;
581  int N_triplet_polaron_annihilations = 0;
582  int N_exciton_intersystem_crossings = 0;
583  int N_exciton_reverse_intersystem_crossings = 0;
584  int N_excitons_quenched = 0;
585  int N_excitons = 0;
586  int N_singlets = 0;
587  int N_triplets = 0;
588  int N_electrons_created = 0;
589  int N_electrons_recombined = 0;
590  int N_electrons_collected = 0;
591  int N_electrons = 0;
592  long int N_events_executed = 0;
593  int N_holes_created = 0;
594  int N_holes_recombined = 0;
595  int N_holes_collected = 0;
596  int N_holes = 0;
597  int N_geminate_recombinations = 0;
598  int N_bimolecular_recombinations = 0;
599  int N_electron_surface_recombinations = 0;
600  int N_hole_surface_recombinations = 0;
601  int N_transient_cycles = 0;
602  // Additional Functions
603  double calculateCoulomb(const std::list<Polaron>::const_iterator polaron_it, const KMC_Lattice::Coords& coords) const;
604  double calculateCoulomb(const bool charge, const KMC_Lattice::Coords& coords) const;
605  void calculateDOSCorrelation();
606  void calculateDOSCorrelation(const double cutoff_radius);
607  KMC_Lattice::Coords calculateRandomExcitonCreationCoords();
608  void calculateExcitonEvents(Exciton* exciton_ptr);
609  void calculateObjectListEvents(const std::vector<KMC_Lattice::Object*>& object_ptr_vec);
610  void calculatePolaronEvents(Polaron* polaron_ptr);
611  void createCorrelatedDOS(const double correlation_length);
612  bool createImportedMorphology();
613  void deleteObject(KMC_Lattice::Object* object_ptr);
614  // Exciton Event Execution Functions
615  bool executeExcitonCreation();
616  bool executeExcitonHop(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
617  bool executeExcitonRecombination(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
618  bool executeExcitonDissociation(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
619  bool executeExcitonIntersystemCrossing(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
620  bool executeExcitonExcitonAnnihilation(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
621  bool executeExcitonPolaronAnnihilation(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
622  // General Event Functions
623  bool executeObjectHop(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
624  // Polaron Event Execution Functions
625  bool executePolaronHop(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
626  bool executePolaronRecombination(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
627  bool executePolaronExtraction(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
628  KMC_Lattice::Coords generateExciton();
629  void generateExciton(const KMC_Lattice::Coords& coords, const bool spin, int tag = 0);
630  void generateElectron(const KMC_Lattice::Coords& coords, int tag);
631  void generateHole(const KMC_Lattice::Coords& coords, int tag);
632  void generateDynamicsExcitons();
633  void generateSteadyPolarons();
634  void generateToFPolarons();
635  std::list<Exciton>::iterator getExcitonIt(const KMC_Lattice::Object* object_ptr);
636  std::list<Polaron>::iterator getPolaronIt(const KMC_Lattice::Object* object_ptr);
637  bool initializeArchitecture();
638  void removeExciton(std::list<Exciton>::iterator exciton_it);
639  bool siteContainsHole(const KMC_Lattice::Coords& coords);
640  void updateSteadyData();
641  void updateSteadyDOS(std::vector<std::pair<double, double>>& density_of_states, double state_energy);
642  void updateTransientData();
643  };
644 
645 }
646 
647 #endif // EXCIMONTEC_OSC_SIM_H
int getN_triplet_excitons_recombined() const
Gets the number of triplet excitons that have recombined.
Definition: OSC_Sim.cpp:2275
+Go to the documentation of this file.
1 // Copyright (c) 2017-2019 Michael C. Heiber
2 // This source file is part of the Excimontec project, which is subject to the MIT License.
3 // For more information, see the LICENSE file that accompanies this software.
4 // The Excimontec project can be found on Github at https://github.com/MikeHeiber/Excimontec
5 
6 #ifndef EXCIMONTEC_OSC_SIM_H
7 #define EXCIMONTEC_OSC_SIM_H
8 
9 #include "Simulation.h"
10 #include "Site.h"
11 #include "Exciton.h"
12 #include "Parameters.h"
13 #include "Polaron.h"
14 #include "Version.h"
15 #include <algorithm>
16 #include <fstream>
17 #include <iostream>
18 #include <list>
19 #include <numeric>
20 #include <random>
21 #include <string>
22 #include <utility>
23 #include <vector>
24 
25 namespace Excimontec {
26 
32  public:
33 
35  OSC_Sim();
36 
38  virtual ~OSC_Sim();
39 
45  bool init(const Parameters& params, const int id);
46 
48  void calculateAllEvents();
49 
54  std::vector<std::pair<double, double>> calculateTransitTimeHist(const std::vector<double>& data, const int counts) const;
55 
59  std::vector<double> calculateMobilityData(const std::vector<double>& transit_times) const;
60 
64  bool checkFinished() const;
65 
68  void createExciton(const bool spin);
69 
74  void createExciton(const KMC_Lattice::Coords& coords, const bool spin);
75 
79  void createElectron(const KMC_Lattice::Coords& coords);
80 
84  void createHole(const KMC_Lattice::Coords& coords);
85 
90  bool executeNextEvent();
91 
94  void exportEnergies(std::string filename);
95 
99  void exportEnergies(std::string filename, bool charge);
100 
104  std::vector<std::string> getChargeExtractionMap(const bool charge) const;
105 
108  std::vector<std::pair<double, double>> getDOSCorrelationData() const;
109 
112  std::vector<double> getDynamicsExcitonEnergies() const;
113 
116  std::vector<double> getDynamicsElectronEnergies() const;
117 
120  std::vector<double> getDynamicsHoleEnergies() const;
121 
124  std::vector<int> getDynamicsTransientSinglets() const;
125 
128  std::vector<int> getDynamicsTransientTriplets() const;
129 
132  std::vector<int> getDynamicsTransientElectrons() const;
133 
136  std::vector<int> getDynamicsTransientHoles() const;
137 
140  std::vector<double> getDynamicsTransientTimes() const;
141 
145  std::vector<double> getDynamicsExcitonMSDV() const;
146 
151  std::vector<double> getDynamicsElectronMSDV() const;
152 
157  std::vector<double> getDynamicsHoleMSDV() const;
158 
161  std::vector<double> getExcitonDiffusionData() const;
162 
165  std::vector<int> getExcitonHopLengthData() const;
166 
169  std::vector<double> getExcitonLifetimeData() const;
170 
173  double getInternalField() const;
174 
177  int getN_excitons_created() const;
178 
182  int getN_excitons_created(const short site_type) const;
183 
187 
191 
195 
199 
203 
207 
211 
215 
219 
222  int getN_electrons_created() const;
223 
226  int getN_electrons_collected() const;
227 
230  int getN_electrons_recombined() const;
231 
234  long int getN_events_executed() const;
235 
238  int getN_holes_created() const;
239 
242  int getN_holes_collected() const;
243 
246  int getN_holes_recombined() const;
247 
251  int getN_geminate_recombinations() const;
252 
257 
262  int getN_transient_cycles() const;
263 
266  std::string getPreviousEventType() const;
267 
271  std::vector<float> getSiteEnergies(const short site_type) const;
272 
278  float getSiteEnergy(const KMC_Lattice::Coords& coords);
279 
285  short getSiteType(const KMC_Lattice::Coords& coords);
286 
289  double getSteadyCurrentDensity() const;
290 
293  std::vector<std::pair<double, double>> getSteadyDOOS() const;
294 
296  // This function calculates the state energies including the Coulomb potential due to interactions between the polarons.
298  std::vector<std::pair<double, double>> getSteadyDOOS_Coulomb() const;
299 
302  std::vector<std::pair<double, double>> getSteadyDOS();
303 
305  // This function calculates the state energies including the Coulomb potential due to interactions between the polarons.
307  std::vector<std::pair<double, double>> getSteadyDOS_Coulomb() const;
308 
312  double getSteadyEquilibrationEnergy() const;
313 
319 
322  double getSteadyMobility() const;
323 
326  double getSteadyTransportEnergy() const;
327 
331  double getSteadyTransportEnergy_Coulomb() const;
332 
335  std::vector<int> getToFTransientCounts() const;
336 
339  std::vector<double> getToFTransientEnergies() const;
340 
343  std::vector<double> getToFTransientTimes() const;
344 
348  std::vector<double> getToFTransientVelocities() const;
349 
352  std::vector<double> getTransitTimeData() const;
353 
355  void outputStatus();
356 
358  void reassignSiteEnergies();
359 
360  protected:
361 
362  private:
363 
364  class Site_OSC : public KMC_Lattice::Site {
365  public:
366  float getEnergy() const { return energy; }
367  short getType() const { return type; }
368  void setEnergy(const float energy_input) { energy = energy_input; }
369  void setType(const short site_type) { type = (char)site_type; }
370  private:
371  float energy;
372  char type = 0; // type 1 represent donor, type 2 represents acceptor
373  };
374 
375  struct ExcitonEventCalcVars {
376  int range;
377  int dim;
378  Exciton::Hop hop_event;
379  std::vector<Exciton::Hop> hops_temp;
380  Exciton::Dissociation diss_event;
381  std::vector<Exciton::Dissociation> dissociations_temp;
382  Exciton::Exciton_Annihilation ee_annihilation_event;
383  std::vector<Exciton::Exciton_Annihilation> ee_annihilations_temp;
384  Exciton::Polaron_Annihilation ep_annihilation_event;
385  std::vector<Exciton::Polaron_Annihilation> ep_annihilations_temp;
386  std::vector<bool> hops_valid;
387  std::vector<bool> dissociations_valid;
388  std::vector<bool> ee_annihilations_valid;
389  std::vector<bool> ep_annihilations_valid;
390  // precalculated distances vector that contains the distances to nearby sites used for event execution time calculations
391  std::vector<double> distances;
392  // precalculated isInDissRange and isInFRETRange vectors that contains booleans to indicate whether the nearby sites are within range for the different exciton events to be possible.
393  std::vector<bool> isInDissRange;
394  std::vector<bool> isInFRETRange;
395 
396  ExcitonEventCalcVars() {}
397 
398  ExcitonEventCalcVars(OSC_Sim* sim_ptr) {
399  range = (int)ceil(((sim_ptr->params.FRET_cutoff > sim_ptr->params.Exciton_dissociation_cutoff) ? (sim_ptr->params.FRET_cutoff) : (sim_ptr->params.Exciton_dissociation_cutoff)) / sim_ptr->lattice.getUnitSize());
400  dim = (2 * range + 1);
401  hop_event = Exciton::Hop(sim_ptr);
402  hops_temp.assign(dim*dim*dim, hop_event);
403  diss_event = Exciton::Dissociation(sim_ptr);
404  dissociations_temp.assign(dim*dim*dim, diss_event);
405  ee_annihilation_event = Exciton::Exciton_Annihilation(sim_ptr);
406  ee_annihilations_temp.assign(dim*dim*dim, ee_annihilation_event);
407  ep_annihilation_event = Exciton::Polaron_Annihilation(sim_ptr);
408  ep_annihilations_temp.assign(dim*dim*dim, ep_annihilation_event);
409  hops_valid.assign(dim*dim*dim, false);
410  dissociations_valid.assign(dim*dim*dim, false);
411  ee_annihilations_valid.assign(dim*dim*dim, false);
412  ep_annihilations_valid.assign(dim*dim*dim, false);
413  // precalculated distances vector that contains the distances to nearby sites used for event execution time calculations
414  distances.assign(dim*dim*dim, 0.0);
415  // precalculated isInDissRange and isInFRETRange vectors that contains booleans to indicate whether the nearby sites are within range for the different exciton events to be possible.
416  isInDissRange.assign(dim*dim*dim, false);
417  isInFRETRange.assign(dim*dim*dim, false);
418  // Initialize distances, isInDissRange, and isInFRETRange vectors
419  for (int i = -range; i <= range; i++) {
420  for (int j = -range; j <= range; j++) {
421  for (int k = -range; k <= range; k++) {
422  int index = (i + range)*dim*dim + (j + range)*dim + (k + range);
423  distances[index] = sim_ptr->lattice.getUnitSize()*sqrt((double)(i*i + j * j + k * k));
424  if (!((distances[index] - 0.0001) > sim_ptr->params.Exciton_dissociation_cutoff)) {
425  isInDissRange[index] = true;
426  }
427  if (!((distances[index] - 0.0001) > sim_ptr->params.FRET_cutoff)) {
428  isInFRETRange[index] = true;
429  }
430  }
431  }
432  }
433  }
434  };
435  ExcitonEventCalcVars exciton_event_calc_vars;
436 
437  struct PolaronEventCalcVars {
438  int range;
439  int dim;
440  Polaron::Hop hop_event;
441  std::vector<Polaron::Hop> hops_temp;
442  Polaron::Recombination rec_event;
443  std::vector<Polaron::Recombination> recombinations_temp;
444  std::vector<bool> hops_valid;
445  std::vector<bool> recombinations_valid;
446  // precalculated distances vector that contains the distances to nearby sites used for event execution time calculations
447  std::vector<double> distances;
448  std::vector<double> E_deltas;
449  // precalculated isInRange vector that contains booleans to indicate if the nearby sites are within range for polaron events to be possible.
450  std::vector<bool> isInRange;
451 
452  PolaronEventCalcVars() {}
453 
454  PolaronEventCalcVars(OSC_Sim* sim_ptr) {
455  range = (int)ceil(sim_ptr->params.Polaron_hopping_cutoff / sim_ptr->lattice.getUnitSize());
456  dim = (2 * range + 1);
457  hop_event = Polaron::Hop(sim_ptr);
458  hops_temp.assign(dim*dim*dim, hop_event);
459  rec_event = Polaron::Recombination(sim_ptr);
460  recombinations_temp.assign(dim*dim*dim, rec_event);
461  hops_valid.assign(dim*dim*dim, false);
462  recombinations_valid.assign(dim*dim*dim, false);
463  // precalculated distances vector that contains the distances to nearby sites used for event execution time calculations
464  distances.assign(dim*dim*dim, 0.0);
465  E_deltas.assign(dim*dim*dim, 0.0);
466  // precalculated isInRange vector that contains booleans to indicate if the nearby sites are within range for polaron events to be possible.
467  isInRange.assign(dim*dim*dim, false);
468  // Initialize distances and isInRange vectors
469  for (int i = -range; i <= range; i++) {
470  for (int j = -range; j <= range; j++) {
471  for (int k = -range; k <= range; k++) {
472  int index = (i + range)*dim*dim + (j + range)*dim + (k + range);
473  distances[index] = sim_ptr->lattice.getUnitSize()*sqrt((double)(i*i + j * j + k * k));
474  if (!((distances[index] - 0.0001) > sim_ptr->params.Polaron_hopping_cutoff)) {
475  isInRange[index] = true;
476  }
477  }
478  }
479  }
480  }
481  };
482  PolaronEventCalcVars polaron_event_calc_vars;
483  // Input Parameters
484  Parameters params;
485  // Additional Derived Parameters
486  double Transient_start;
487  double Transient_end;
488  int Transient_pnts_per_decade;
489  bool isLightOn;
490  double R_exciton_generation_donor;
491  double R_exciton_generation_acceptor;
492  double Transient_step_size;
493  double Transient_creation_time;
494  int Transient_index_prev;
495  int Transient_singlet_counts_prev;
496  int Transient_triplet_counts_prev;
497  int Transient_electron_counts_prev;
498  int Transient_hole_counts_prev;
499  int Coulomb_range;
500  double AvgDielectric;
501  double Image_interaction_prefactor;
502  int N_initial_excitons;
503  // Site Data Structure
504  std::vector<Site_OSC> sites;
505  // Object Data Structures
506  std::list<Exciton> excitons;
507  std::list<Polaron> electrons;
508  std::list<Polaron> holes;
509  // Event Data Structures
510  std::string previous_event_type = "";
511  double previous_event_time = 0;
512  std::list<Exciton::Creation> exciton_creation_events;
513  std::list<KMC_Lattice::Event*>::const_iterator exciton_creation_it;
514  std::list<Exciton::Hop> exciton_hop_events;
515  std::list<Exciton::Recombination> exciton_recombination_events;
516  std::list<Exciton::Dissociation> exciton_dissociation_events;
517  std::list<Exciton::Exciton_Annihilation> exciton_exciton_annihilation_events;
518  std::list<Exciton::Polaron_Annihilation> exciton_polaron_annihilation_events;
519  std::list<Exciton::Intersystem_Crossing> exciton_intersystem_crossing_events;
520  std::list<Polaron::Hop> electron_hop_events;
521  std::list<Polaron::Hop> hole_hop_events;
522  std::list<Polaron::Recombination> polaron_recombination_events;
523  std::list<Polaron::Extraction> electron_extraction_events;
524  std::list<Polaron::Extraction> hole_extraction_events;
525  // Additional Data Structures
526  std::vector<double> Coulomb_table;
527  std::vector<double> E_potential;
528  std::vector<std::pair<double, double>> DOS_correlation_data;
529  std::vector<double> exciton_lifetimes;
530  std::vector<double> exciton_diffusion_distances;
531  std::vector<int> exciton_hop_distances; // saved in lattice units squared
532  std::vector<int> transient_exciton_tags;
533  std::vector<int> transient_electron_tags;
534  std::vector<int> transient_hole_tags;
535  std::vector<int> ToF_positions_prev;
536  std::vector<double> transient_exciton_energies_prev;
537  std::vector<double> transient_electron_energies_prev;
538  std::vector<double> transient_hole_energies_prev;
539  std::vector<double> transient_exciton_msdv;
540  std::vector<double> transient_electron_msdv;
541  std::vector<double> transient_hole_msdv;
542  std::vector<int> electron_extraction_data;
543  std::vector<int> hole_extraction_data;
544  std::vector<std::pair<double, double>> steady_DOOS;
545  std::vector<std::pair<double, double>> steady_DOOS_Coulomb;
546  std::vector<std::pair<double, double>> steady_DOS;
547  std::vector<std::pair<double, double>> steady_DOS_Coulomb;
548  std::vector<double> transient_times;
549  std::vector<double> transient_velocities;
550  std::vector<double> transient_exciton_energies;
551  std::vector<double> transient_electron_energies;
552  std::vector<double> transient_hole_energies;
553  std::vector<double> transit_times;
554  std::vector<int> transient_singlet_counts;
555  std::vector<int> transient_triplet_counts;
556  std::vector<int> transient_electron_counts;
557  std::vector<int> transient_hole_counts;
558  int Steady_hops_per_DOS_sample = 1000000;
559  int Steady_hops_per_DOOS_sample = 1000;
560  int Steady_DOS_sampling_counter = 0;
561  int Steady_DOOS_sampling_counter = 0;
562  double DOS_bin_size = 1e-2;
563  double Steady_equilibration_time = 0.0;
564  double Steady_equilibration_energy_sum = 0.0;
565  double Steady_equilibration_energy_sum_Coulomb = 0.0;
566  double Transport_energy_weighted_sum = 0.0;
567  double Transport_energy_weighted_sum_Coulomb = 0.0;
568  double Transport_energy_sum_of_weights = 0.0;
569  // Additional Counters
570  int N_donor_sites = 0;
571  int N_acceptor_sites = 0;
572  int N_excitons_created = 0;
573  int N_excitons_created_donor = 0;
574  int N_excitons_created_acceptor = 0;
575  int N_singlet_excitons_recombined = 0;
576  int N_triplet_excitons_recombined = 0;
577  int N_singlet_excitons_dissociated = 0;
578  int N_triplet_excitons_dissociated = 0;
579  int N_singlet_singlet_annihilations = 0;
580  int N_singlet_triplet_annihilations = 0;
581  int N_triplet_triplet_annihilations = 0;
582  int N_singlet_polaron_annihilations = 0;
583  int N_triplet_polaron_annihilations = 0;
584  int N_exciton_intersystem_crossings = 0;
585  int N_exciton_reverse_intersystem_crossings = 0;
586  int N_excitons_quenched = 0;
587  int N_excitons = 0;
588  int N_singlets = 0;
589  int N_triplets = 0;
590  int N_electrons_created = 0;
591  int N_electrons_recombined = 0;
592  int N_electrons_collected = 0;
593  int N_electrons = 0;
594  long int N_events_executed = 0;
595  int N_holes_created = 0;
596  int N_holes_recombined = 0;
597  int N_holes_collected = 0;
598  int N_holes = 0;
599  int N_geminate_recombinations = 0;
600  int N_bimolecular_recombinations = 0;
601  int N_electron_surface_recombinations = 0;
602  int N_hole_surface_recombinations = 0;
603  int N_transient_cycles = 0;
604  // Additional Functions
605  double calculateCoulomb(const std::list<Polaron>::const_iterator polaron_it, const KMC_Lattice::Coords& coords) const;
606  double calculateCoulomb(const bool charge, const KMC_Lattice::Coords& coords) const;
607  void calculateDOSCorrelation();
608  void calculateDOSCorrelation(const double cutoff_radius);
609  KMC_Lattice::Coords calculateRandomExcitonCreationCoords();
610  void calculateExcitonEvents(Exciton* exciton_ptr);
611  void calculateObjectListEvents(const std::vector<KMC_Lattice::Object*>& object_ptr_vec);
612  void calculatePolaronEvents(Polaron* polaron_ptr);
613  void createCorrelatedDOS(const double correlation_length);
614  bool createImportedMorphology();
615  void deleteObject(KMC_Lattice::Object* object_ptr);
616  // Exciton Event Execution Functions
617  bool executeExcitonCreation();
618  bool executeExcitonHop(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
619  bool executeExcitonRecombination(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
620  bool executeExcitonDissociation(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
621  bool executeExcitonIntersystemCrossing(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
622  bool executeExcitonExcitonAnnihilation(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
623  bool executeExcitonPolaronAnnihilation(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
624  // General Event Functions
625  bool executeObjectHop(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
626  // Polaron Event Execution Functions
627  bool executePolaronHop(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
628  bool executePolaronRecombination(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
629  bool executePolaronExtraction(const std::list<KMC_Lattice::Event*>::const_iterator event_it);
630  KMC_Lattice::Coords generateExciton();
631  void generateExciton(const KMC_Lattice::Coords& coords, const bool spin, int tag = 0);
632  void generateElectron(const KMC_Lattice::Coords& coords, int tag);
633  void generateHole(const KMC_Lattice::Coords& coords, int tag);
634  void generateDynamicsExcitons();
635  void generateSteadyPolarons();
636  void generateToFPolarons();
637  std::list<Exciton>::iterator getExcitonIt(const KMC_Lattice::Object* object_ptr);
638  std::list<Polaron>::iterator getPolaronIt(const KMC_Lattice::Object* object_ptr);
639  bool initializeArchitecture();
640  void removeExciton(std::list<Exciton>::iterator exciton_it);
641  bool siteContainsHole(const KMC_Lattice::Coords& coords);
642  void updateSteadyData();
643  void updateSteadyDOS(std::vector<std::pair<double, double>>& density_of_states, double state_energy);
644  void updateTransientData();
645  };
646 
647 }
648 
649 #endif // EXCIMONTEC_OSC_SIM_H
std::vector< std::pair< double, double > > getSteadyDOS()
Gets the density of states calculated during the steady state charge transport test.
Definition: OSC_Sim.cpp:2446
+
int getN_triplet_excitons_recombined() const
Gets the number of triplet excitons that have recombined.
Definition: OSC_Sim.cpp:2275
This class extends the KMC_Lattice::Event class to create an exciton-exciton annihilation event.
Definition: Exciton.h:198
void exportEnergies(std::string filename)
Exports the relative lattice site energies to a text file.
Definition: OSC_Sim.cpp:1794
std::string getPreviousEventType() const
Gets the name of event type that was last performed.
Definition: OSC_Sim.cpp:2348
This base class contains the basic properties of a KMC simulation object and the functions needed to ...
Definition: Object.h:24
-
double getSteadyMobility() const
Gets the average steady state charge carrier mobility calculated during the steady state charge trans...
Definition: OSC_Sim.cpp:2482
+
double getSteadyMobility() const
Gets the average steady state charge carrier mobility calculated during the steady state charge trans...
Definition: OSC_Sim.cpp:2504
void createHole(const KMC_Lattice::Coords &coords)
Attempts to create a hole (positively charged Polaron) on the specified lattice site....
Definition: OSC_Sim.cpp:1077
Definition: Exciton.cpp:10
@@ -107,7 +108,7 @@
std::vector< double > calculateMobilityData(const std::vector< double > &transit_times) const
Calculate the mobility data using the transit time data generated by the time-of-flight charge transp...
Definition: OSC_Sim.cpp:306
int getN_transient_cycles() const
Gets the number of transient test cycles that have been performed. During the time-of-flight charge t...
Definition: OSC_Sim.cpp:2315
int getN_bimolecular_recombinations() const
Gets the number of bimolecular electron-hole recombination events that have occurred in the simulatio...
Definition: OSC_Sim.cpp:2230
-
std::vector< double > getToFTransientEnergies() const
Gets the transient average polaron energy data generated during the time-of-flight charge transport t...
Definition: OSC_Sim.cpp:2518
+
std::vector< double > getToFTransientEnergies() const
Gets the transient average polaron energy data generated during the time-of-flight charge transport t...
Definition: OSC_Sim.cpp:2540
int getN_geminate_recombinations() const
Gets the number of geminate electron-hole recombination events that have occurred in the simulation....
Definition: OSC_Sim.cpp:2299
std::vector< double > getDynamicsExcitonMSDV() const
Gets the transient exciton mean squared displacement velocity data generated during the dynamics test...
Definition: OSC_Sim.cpp:2160
int getN_singlet_excitons_recombined() const
Gets the number of singlet excitons that have recombined.
Definition: OSC_Sim.cpp:2271
@@ -120,11 +121,11 @@
bool checkFinished() const
Checks whether the simulation test specified by the input parameters is finished.
Definition: OSC_Sim.cpp:873
std::vector< int > getDynamicsTransientSinglets() const
Gets the transient singlet exciton counts data generated by the dynamics test.
Definition: OSC_Sim.cpp:2184
-
std::vector< std::pair< double, double > > getSteadyDOS_Coulomb() const
Gets the density of states calculated during the steady state charge transport test.
Definition: OSC_Sim.cpp:2455
+
std::vector< std::pair< double, double > > getSteadyDOS_Coulomb() const
Gets the density of states calculated during the steady state charge transport test.
Definition: OSC_Sim.cpp:2477
This class extends the KMC_Lattice::Event class to create an exciton-polaron annihilation event.
Definition: Exciton.h:236
int getN_electrons_collected() const
Gets the number of electrons (negatively charged polarons) that have been collected (extracted) at el...
Definition: OSC_Sim.cpp:2234
int getN_singlet_polaron_annihilations() const
Gets the number of singlet-polaron annihilation events that have occurred.
Definition: OSC_Sim.cpp:2291
-
std::vector< double > getToFTransientTimes() const
Gets the transient time data generated during the time-of-flight charge transport test.
Definition: OSC_Sim.cpp:2527
+
std::vector< double > getToFTransientTimes() const
Gets the transient time data generated during the time-of-flight charge transport test.
Definition: OSC_Sim.cpp:2549
This class extends the KMC_Lattice::Parameters_Simulation class to create a parameters object that ho...
Definition: Parameters.h:19
void createExciton(const bool spin)
Creates an Exciton on a randomly selected unoccupied site.
Definition: OSC_Sim.cpp:1049
This class extends the KMC_Lattice::Object class to create an exciton object that represents a single...
Definition: Exciton.h:21
@@ -137,25 +138,24 @@
std::vector< float > getSiteEnergies(const short site_type) const
Gets the energies of the lattice sites with the specified type.
Definition: OSC_Sim.cpp:2352
std::vector< double > getDynamicsElectronMSDV() const
Gets the transient electron (negatively charged Polaron) mean squared displacement velocity data gene...
Definition: OSC_Sim.cpp:2164
std::vector< double > getDynamicsTransientTimes() const
Gets the transient time data generated during the dynamics test.
Definition: OSC_Sim.cpp:2200
-
double getSteadyTransportEnergy_Coulomb() const
Gets the average transport energy of the polarons calculated during the steady state charge transport...
Definition: OSC_Sim.cpp:2500
+
double getSteadyTransportEnergy_Coulomb() const
Gets the average transport energy of the polarons calculated during the steady state charge transport...
Definition: OSC_Sim.cpp:2522
std::vector< int > getDynamicsTransientTriplets() const
Gets the transient triplet exciton counts data generated by the dynamics test.
Definition: OSC_Sim.cpp:2188
-
double getSteadyTransportEnergy() const
Gets the average transport energy of the polarons calculated during the steady state charge transport...
Definition: OSC_Sim.cpp:2491
+
double getSteadyTransportEnergy() const
Gets the average transport energy of the polarons calculated during the steady state charge transport...
Definition: OSC_Sim.cpp:2513
std::vector< std::pair< double, double > > calculateTransitTimeHist(const std::vector< double > &data, const int counts) const
Calculates the transit time probability histogram using the data generated by the time-of-flight char...
Definition: OSC_Sim.cpp:315
This abstract base class contains the basic properties of a KMC simulation and the functions needed t...
Definition: Simulation.h:32
-
void outputStatus()
Prints a message to the command line about the current status of the simulation test.
Definition: OSC_Sim.cpp:2596
+
void outputStatus()
Prints a message to the command line about the current status of the simulation test.
Definition: OSC_Sim.cpp:2618
bool executeNextEvent()
Attempts to execute the next event in the KMC simulation. An error is generated if an event cannot be...
Definition: OSC_Sim.cpp:1527
This class extends the KMC_Lattice::Event class to create an exciton dissociation event.
Definition: Exciton.h:120
-
double getSteadyEquilibrationEnergy_Coulomb() const
Gets the average equilibration energy of the polarons calculated during the steady state charge trans...
Definition: OSC_Sim.cpp:2473
-
std::vector< std::pair< double, double > > getSteadyDOS() const
Gets the density of states calculated during the steady state charge transport test.
Definition: OSC_Sim.cpp:2446
+
double getSteadyEquilibrationEnergy_Coulomb() const
Gets the average equilibration energy of the polarons calculated during the steady state charge trans...
Definition: OSC_Sim.cpp:2495
int getN_singlet_triplet_annihilations() const
Gets the number of singlet-triplet annihilation events that have occurred.
Definition: OSC_Sim.cpp:2283
int getN_holes_collected() const
Gets the number of holes (positively charged polarons) that have been collected (extracted) at electr...
Definition: OSC_Sim.cpp:2303
virtual ~OSC_Sim()
Default virtual destructor.
Definition: OSC_Sim.cpp:15
This simple struct contains Cartesian coordinates specified by integers x,y,z.
Definition: Utils.h:29
double getSteadyCurrentDensity() const
Gets the average steady state current density calculated during the steady state charge transport tes...
Definition: OSC_Sim.cpp:2419
-
std::vector< double > getToFTransientVelocities() const
Gets the transient average polaron velocity data generated during the time-of-flight charge transport...
Definition: OSC_Sim.cpp:2531
-
double getSteadyEquilibrationEnergy() const
Gets the average equilibration energy of the polarons calculated during the steady state charge trans...
Definition: OSC_Sim.cpp:2464
-
std::vector< int > getToFTransientCounts() const
Gets the transient polaron counts data generated during the time-of-flight charge transport test.
Definition: OSC_Sim.cpp:2509
+
std::vector< double > getToFTransientVelocities() const
Gets the transient average polaron velocity data generated during the time-of-flight charge transport...
Definition: OSC_Sim.cpp:2553
+
double getSteadyEquilibrationEnergy() const
Gets the average equilibration energy of the polarons calculated during the steady state charge trans...
Definition: OSC_Sim.cpp:2486
+
std::vector< int > getToFTransientCounts() const
Gets the transient polaron counts data generated during the time-of-flight charge transport test.
Definition: OSC_Sim.cpp:2531
std::vector< double > getExcitonLifetimeData() const
Gets the exciton lifetime data generated during the exciton diffusion test.
Definition: OSC_Sim.cpp:2212
int getN_triplet_excitons_dissociated() const
Gets the number of triplet excitons that have dissociated.
Definition: OSC_Sim.cpp:2267
std::vector< std::string > getChargeExtractionMap(const bool charge) const
Gets the charge extraction map data generated by the time-of-flight charge transport or internal quan...
Definition: OSC_Sim.cpp:2388
@@ -177,12 +177,12 @@
long int getN_events_executed() const
Gets the number of events that have been executed.
Definition: OSC_Sim.cpp:2246
OSC_Sim()
Constructs an empty simulation object that is uninitialized.
Definition: OSC_Sim.cpp:13
int getN_triplet_triplet_annihilations() const
Gets the number of triplet-triplet annihilation events that have occurred.
Definition: OSC_Sim.cpp:2287
-
std::vector< double > getTransitTimeData() const
Gets the transit time data generate during the time-of-flight charge transport test.
Definition: OSC_Sim.cpp:2535
+
std::vector< double > getTransitTimeData() const
Gets the transit time data generate during the time-of-flight charge transport test.
Definition: OSC_Sim.cpp:2557
std::vector< double > getExcitonDiffusionData() const
Gets the exciton diffusion distance data generated during the exciton diffusion test.
Definition: OSC_Sim.cpp:2204
std::vector< int > getDynamicsTransientHoles() const
Gets the transient hole (positively charged Polaron) counts data generated during the dynamics test.
Definition: OSC_Sim.cpp:2196
int getN_singlet_excitons_dissociated() const
Gets the number of singlet excitons that have dissociated.
Definition: OSC_Sim.cpp:2263
This class extends the KMC_Lattice::Event class to create a polaron hop event.
Definition: Polaron.h:27
-
void reassignSiteEnergies()
Regenerates the site energies for all sites in the lattice.
Definition: OSC_Sim.cpp:2651
+
void reassignSiteEnergies()
Regenerates the site energies for all sites in the lattice.
Definition: OSC_Sim.cpp:2673
int Polaron_hopping_cutoff
Defines the cutoff radius of all polaron hopping events in units of nm.
Definition: Parameters.h:281
This class extends the KMC_Lattice::Object class to create a polaron object that represents an electr...
Definition: Polaron.h:20
std::vector< std::pair< double, double > > getSteadyDOOS_Coulomb() const
Gets the density of occupied states calculated during the steady state charge transport test.
Definition: OSC_Sim.cpp:2437
diff --git a/docs/class_excimontec_1_1_o_s_c___sim-members.html b/docs/class_excimontec_1_1_o_s_c___sim-members.html index eb1991e..022d8c8 100644 --- a/docs/class_excimontec_1_1_o_s_c___sim-members.html +++ b/docs/class_excimontec_1_1_o_s_c___sim-members.html @@ -165,7 +165,7 @@ getSteadyCurrentDensity() constExcimontec::OSC_Sim getSteadyDOOS() constExcimontec::OSC_Sim getSteadyDOOS_Coulomb() constExcimontec::OSC_Sim - getSteadyDOS() constExcimontec::OSC_Sim + getSteadyDOS()Excimontec::OSC_Sim getSteadyDOS_Coulomb() constExcimontec::OSC_Sim getSteadyEquilibrationEnergy() constExcimontec::OSC_Sim getSteadyEquilibrationEnergy_Coulomb() constExcimontec::OSC_Sim diff --git a/docs/class_excimontec_1_1_o_s_c___sim.html b/docs/class_excimontec_1_1_o_s_c___sim.html index 3cfb1fe..2a749ee 100644 --- a/docs/class_excimontec_1_1_o_s_c___sim.html +++ b/docs/class_excimontec_1_1_o_s_c___sim.html @@ -282,9 +282,9 @@ std::vector< std::pair< double, double > > getSteadyDOOS_Coulomb () const  Gets the density of occupied states calculated during the steady state charge transport test. More...
  -std::vector< std::pair< double, double > > getSteadyDOS () const - Gets the density of states calculated during the steady state charge transport test. More...
-  +std::vector< std::pair< double, double > > getSteadyDOS () + Gets the density of states calculated during the steady state charge transport test. More...
+  std::vector< std::pair< double, double > > getSteadyDOS_Coulomb () const  Gets the density of states calculated during the steady state charge transport test. More...
  @@ -1747,8 +1747,8 @@

-

◆ getSteadyDOS()

+ +

◆ getSteadyDOS()

diff --git a/docs/class_excimontec_1_1_o_s_c___sim.js b/docs/class_excimontec_1_1_o_s_c___sim.js index 91c7573..22eb8b4 100644 --- a/docs/class_excimontec_1_1_o_s_c___sim.js +++ b/docs/class_excimontec_1_1_o_s_c___sim.js @@ -58,7 +58,7 @@ var class_excimontec_1_1_o_s_c___sim = [ "getSteadyCurrentDensity", "class_excimontec_1_1_o_s_c___sim.html#a1e2d85af55f9898fc4beaea3c09b2ab2", null ], [ "getSteadyDOOS", "class_excimontec_1_1_o_s_c___sim.html#a502194201bd4e045760149bd006112c4", null ], [ "getSteadyDOOS_Coulomb", "class_excimontec_1_1_o_s_c___sim.html#a7bba196811f642f683570240ceb77e62", null ], - [ "getSteadyDOS", "class_excimontec_1_1_o_s_c___sim.html#a6440b290be26622c04ea89cf7293575b", null ], + [ "getSteadyDOS", "class_excimontec_1_1_o_s_c___sim.html#a15e362e4b5b2c065e29f1cdf36235784", null ], [ "getSteadyDOS_Coulomb", "class_excimontec_1_1_o_s_c___sim.html#ad819d76bf42693993bb392c48327ebf6", null ], [ "getSteadyEquilibrationEnergy", "class_excimontec_1_1_o_s_c___sim.html#a451e3ea3667f84d6841ad91355a618df", null ], [ "getSteadyEquilibrationEnergy_Coulomb", "class_excimontec_1_1_o_s_c___sim.html#ab726ddf220bbef11061b802df50c0188", null ], diff --git a/docs/functions_func_g.html b/docs/functions_func_g.html index fc5638a..571271a 100644 --- a/docs/functions_func_g.html +++ b/docs/functions_func_g.html @@ -324,7 +324,7 @@

- g -

    : Excimontec::OSC_Sim
  • getSteadyDOS() -: Excimontec::OSC_Sim +: Excimontec::OSC_Sim
  • getSteadyDOS_Coulomb() : Excimontec::OSC_Sim diff --git a/docs/functions_g.html b/docs/functions_g.html index 40c12c0..19ca744 100644 --- a/docs/functions_g.html +++ b/docs/functions_g.html @@ -327,7 +327,7 @@

    - g -

      : Excimontec::OSC_Sim
    • getSteadyDOS() -: Excimontec::OSC_Sim +: Excimontec::OSC_Sim
    • getSteadyDOS_Coulomb() : Excimontec::OSC_Sim diff --git a/docs/navtreeindex0.js b/docs/navtreeindex0.js index 61465b4..4cbe6ba 100644 --- a/docs/navtreeindex0.js +++ b/docs/navtreeindex0.js @@ -164,6 +164,7 @@ var NAVTREEINDEX0 = "class_excimontec_1_1_o_s_c___sim.html#a0b56db2ae5db69979f2d52ae4e6026ba":[1,0,0,1,72], "class_excimontec_1_1_o_s_c___sim.html#a10492db50c54e36a401beb119165243b":[1,0,0,1,6], "class_excimontec_1_1_o_s_c___sim.html#a1090d447104236755708cb812569cb3c":[1,0,0,1,31], +"class_excimontec_1_1_o_s_c___sim.html#a15e362e4b5b2c065e29f1cdf36235784":[1,0,0,1,58], "class_excimontec_1_1_o_s_c___sim.html#a18785a34bd36bb28de60f4668a06d21f":[1,0,0,1,23], "class_excimontec_1_1_o_s_c___sim.html#a1b49d7df062b9184c84685fadcf944bb":[1,0,0,1,10], "class_excimontec_1_1_o_s_c___sim.html#a1c18548ebea94e905839f4d824d77935":[1,0,0,1,46], @@ -191,7 +192,6 @@ var NAVTREEINDEX0 = "class_excimontec_1_1_o_s_c___sim.html#a53a0123e8db1299519874ca6bed8bd2b":[1,0,0,1,40], "class_excimontec_1_1_o_s_c___sim.html#a576de9d88dafa1a085fa9d6ae269ca87":[1,0,0,1,51], "class_excimontec_1_1_o_s_c___sim.html#a63bb36ed57ab8f0029ada80a20be6ed7":[1,0,0,1,70], -"class_excimontec_1_1_o_s_c___sim.html#a6440b290be26622c04ea89cf7293575b":[1,0,0,1,58], "class_excimontec_1_1_o_s_c___sim.html#a6e51664e1d78a6f2afffbc9663f437a7":[1,0,0,1,22], "class_excimontec_1_1_o_s_c___sim.html#a72f724474d75a9864014bd0896b8fdf2":[1,0,0,1,3], "class_excimontec_1_1_o_s_c___sim.html#a7420ce8e9f8634ab98483fa9ea6b7972":[1,0,0,1,62], diff --git a/docs/navtreeindex2.js b/docs/navtreeindex2.js index 3e8c8a8..9e9a5a0 100644 --- a/docs/navtreeindex2.js +++ b/docs/navtreeindex2.js @@ -10,8 +10,8 @@ var NAVTREEINDEX2 = "dir_6f62b451fe0710dc1584a1c9c5fb6ce0.html":[2,0,0], "dir_d1ce2567778c05124d22b8b3609ec9ea.html":[2,0,0,0], "files.html":[2,0], -"functions.html":[1,3,0,0], "functions.html":[1,3,0], +"functions.html":[1,3,0,0], "functions_c.html":[1,3,0,1], "functions_d.html":[1,3,0,2], "functions_e.html":[1,3,0,3], diff --git a/docs/search/all_5.js b/docs/search/all_5.js index c52dbe3..4d38650 100644 --- a/docs/search/all_5.js +++ b/docs/search/all_5.js @@ -74,7 +74,7 @@ var searchData= ['getsteadycurrentdensity',['getSteadyCurrentDensity',['../class_excimontec_1_1_o_s_c___sim.html#a1e2d85af55f9898fc4beaea3c09b2ab2',1,'Excimontec::OSC_Sim']]], ['getsteadydoos',['getSteadyDOOS',['../class_excimontec_1_1_o_s_c___sim.html#a502194201bd4e045760149bd006112c4',1,'Excimontec::OSC_Sim']]], ['getsteadydoos_5fcoulomb',['getSteadyDOOS_Coulomb',['../class_excimontec_1_1_o_s_c___sim.html#a7bba196811f642f683570240ceb77e62',1,'Excimontec::OSC_Sim']]], - ['getsteadydos',['getSteadyDOS',['../class_excimontec_1_1_o_s_c___sim.html#a6440b290be26622c04ea89cf7293575b',1,'Excimontec::OSC_Sim']]], + ['getsteadydos',['getSteadyDOS',['../class_excimontec_1_1_o_s_c___sim.html#a15e362e4b5b2c065e29f1cdf36235784',1,'Excimontec::OSC_Sim']]], ['getsteadydos_5fcoulomb',['getSteadyDOS_Coulomb',['../class_excimontec_1_1_o_s_c___sim.html#ad819d76bf42693993bb392c48327ebf6',1,'Excimontec::OSC_Sim']]], ['getsteadyequilibrationenergy',['getSteadyEquilibrationEnergy',['../class_excimontec_1_1_o_s_c___sim.html#a451e3ea3667f84d6841ad91355a618df',1,'Excimontec::OSC_Sim']]], ['getsteadyequilibrationenergy_5fcoulomb',['getSteadyEquilibrationEnergy_Coulomb',['../class_excimontec_1_1_o_s_c___sim.html#ab726ddf220bbef11061b802df50c0188',1,'Excimontec::OSC_Sim']]], diff --git a/docs/search/functions_5.js b/docs/search/functions_5.js index e309818..6f11d89 100644 --- a/docs/search/functions_5.js +++ b/docs/search/functions_5.js @@ -73,7 +73,7 @@ var searchData= ['getsteadycurrentdensity',['getSteadyCurrentDensity',['../class_excimontec_1_1_o_s_c___sim.html#a1e2d85af55f9898fc4beaea3c09b2ab2',1,'Excimontec::OSC_Sim']]], ['getsteadydoos',['getSteadyDOOS',['../class_excimontec_1_1_o_s_c___sim.html#a502194201bd4e045760149bd006112c4',1,'Excimontec::OSC_Sim']]], ['getsteadydoos_5fcoulomb',['getSteadyDOOS_Coulomb',['../class_excimontec_1_1_o_s_c___sim.html#a7bba196811f642f683570240ceb77e62',1,'Excimontec::OSC_Sim']]], - ['getsteadydos',['getSteadyDOS',['../class_excimontec_1_1_o_s_c___sim.html#a6440b290be26622c04ea89cf7293575b',1,'Excimontec::OSC_Sim']]], + ['getsteadydos',['getSteadyDOS',['../class_excimontec_1_1_o_s_c___sim.html#a15e362e4b5b2c065e29f1cdf36235784',1,'Excimontec::OSC_Sim']]], ['getsteadydos_5fcoulomb',['getSteadyDOS_Coulomb',['../class_excimontec_1_1_o_s_c___sim.html#ad819d76bf42693993bb392c48327ebf6',1,'Excimontec::OSC_Sim']]], ['getsteadyequilibrationenergy',['getSteadyEquilibrationEnergy',['../class_excimontec_1_1_o_s_c___sim.html#a451e3ea3667f84d6841ad91355a618df',1,'Excimontec::OSC_Sim']]], ['getsteadyequilibrationenergy_5fcoulomb',['getSteadyEquilibrationEnergy_Coulomb',['../class_excimontec_1_1_o_s_c___sim.html#ab726ddf220bbef11061b802df50c0188',1,'Excimontec::OSC_Sim']]], diff --git a/parameters_default.txt b/parameters_default.txt index 0d5e83d..aeef5e7 100644 --- a/parameters_default.txt +++ b/parameters_default.txt @@ -1,4 +1,4 @@ -## OPV Parameters for Excimontec v1.0.0-rc.1 +## OPV Parameters for Excimontec v1.0.0-rc.3 -------------------------------------------------------------- ## Kinetic Monte Carlo Algorithm Parameters false //Enable_FRM diff --git a/src/OSC_Sim.cpp b/src/OSC_Sim.cpp index 08a97d5..e78c67f 100644 --- a/src/OSC_Sim.cpp +++ b/src/OSC_Sim.cpp @@ -2429,7 +2429,7 @@ namespace Excimontec { auto hist = steady_DOOS; // Normalize histogram counts to produce density for (auto& item : hist) { - item.second /= ((params.N_tests / Steady_hops_per_DOOS_sample) + 1)*lattice.getVolume()*DOS_bin_size; + item.second /= Steady_DOOS_sampling_counter * lattice.getVolume()*DOS_bin_size; } return hist; } @@ -2438,16 +2438,38 @@ namespace Excimontec { auto hist = steady_DOOS_Coulomb; // Normalize histogram counts to produce density for (auto& item : hist) { - item.second /= ((params.N_tests / Steady_hops_per_DOOS_sample) + 1)*lattice.getVolume()*DOS_bin_size; + item.second /= Steady_DOOS_sampling_counter * lattice.getVolume()*DOS_bin_size; } return hist; } - vector> OSC_Sim::getSteadyDOS() const { + vector> OSC_Sim::getSteadyDOS() { + steady_DOS.clear(); + for (long int i = 0; i < lattice.getNumSites(); i++) { + double energy; + auto site_coords = lattice.getSiteCoords(i); + if (lattice.isOccupied(site_coords)) { + if (getSiteType(site_coords) == 1) { + energy = params.Homo_donor + getSiteEnergy(site_coords); + } + else { + energy = params.Homo_acceptor + getSiteEnergy(site_coords); + } + } + else { + if (getSiteType(site_coords) == 1) { + energy = params.Homo_donor + getSiteEnergy(site_coords); + } + else { + energy = params.Homo_acceptor + getSiteEnergy(site_coords); + } + } + updateSteadyDOS(steady_DOS, energy); + } auto hist = steady_DOS; // Normalize histogram counts to produce density for (auto& item : hist) { - item.second /= ((params.N_tests / Steady_hops_per_DOS_sample) + 1)*lattice.getVolume()*DOS_bin_size; + item.second /= lattice.getVolume()*DOS_bin_size; } return hist; } @@ -2456,7 +2478,7 @@ namespace Excimontec { auto hist = steady_DOS_Coulomb; // Normalize histogram counts to produce density for (auto& item : hist) { - item.second /= (((params.N_tests / Steady_hops_per_DOS_sample) + 1))*lattice.getVolume()*DOS_bin_size; + item.second /= Steady_DOS_sampling_counter * lattice.getVolume()*DOS_bin_size; } return hist; } @@ -2901,39 +2923,33 @@ namespace Excimontec { Steady_equilibration_energy_sum += energy; Steady_equilibration_energy_sum_Coulomb += energy_C; } + Steady_DOOS_sampling_counter++; } // Sample the density of states if ((N_events_executed - params.N_equilibration_events) % Steady_hops_per_DOS_sample == 0) { for (long int i = 0; i < lattice.getNumSites(); i++) { - double energy; double energy_C; auto site_coords = lattice.getSiteCoords(i); if (lattice.isOccupied(site_coords)) { auto it = getPolaronIt((*lattice.getSiteIt(site_coords))->getObjectPtr()); if (getSiteType(site_coords) == 1) { - energy = params.Homo_donor + getSiteEnergy(site_coords); energy_C = params.Homo_donor + getSiteEnergy(site_coords) + calculateCoulomb(it, site_coords); } else { - energy = params.Homo_acceptor + getSiteEnergy(site_coords); energy_C = params.Homo_acceptor + getSiteEnergy(site_coords) + calculateCoulomb(it, site_coords); } - updateSteadyDOS(steady_DOS, energy); - updateSteadyDOS(steady_DOS_Coulomb, energy_C); } else { if (getSiteType(site_coords) == 1) { - energy = params.Homo_donor + getSiteEnergy(site_coords); energy_C = params.Homo_donor + getSiteEnergy(site_coords) + calculateCoulomb(true, site_coords); } else { - energy = params.Homo_acceptor + getSiteEnergy(site_coords); energy_C = params.Homo_acceptor + getSiteEnergy(site_coords) + calculateCoulomb(true, site_coords); } - updateSteadyDOS(steady_DOS, energy); - updateSteadyDOS(steady_DOS_Coulomb, energy_C); } + updateSteadyDOS(steady_DOS_Coulomb, energy_C); } + Steady_DOS_sampling_counter++; } } } @@ -2976,7 +2992,7 @@ namespace Excimontec { } // Calculate start of data range double min_val = smallest_bin_int * DOS_bin_size - 0.5*DOS_bin_size; - // Add to state_energy to histogram + // Add the state_energy to histogram int index = (int)floor((state_energy - min_val) / DOS_bin_size); density_of_states[index].second += 1.0; return; diff --git a/src/OSC_Sim.h b/src/OSC_Sim.h index 2fa1384..4ac9d6d 100644 --- a/src/OSC_Sim.h +++ b/src/OSC_Sim.h @@ -299,7 +299,7 @@ namespace Excimontec { //! \brief Gets the density of states calculated during the steady state charge transport test. //! \return A pair vector where the first value is the state energy and the second in the density of states. - std::vector> getSteadyDOS() const; + std::vector> getSteadyDOS(); //! \brief Gets the density of states calculated during the steady state charge transport test. // This function calculates the state energies including the Coulomb potential due to interactions between the polarons. @@ -557,6 +557,8 @@ namespace Excimontec { std::vector transient_hole_counts; int Steady_hops_per_DOS_sample = 1000000; int Steady_hops_per_DOOS_sample = 1000; + int Steady_DOS_sampling_counter = 0; + int Steady_DOOS_sampling_counter = 0; double DOS_bin_size = 1e-2; double Steady_equilibration_time = 0.0; double Steady_equilibration_energy_sum = 0.0; diff --git a/src/main.cpp b/src/main.cpp index a2d7db6..82936e7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,7 +18,7 @@ using namespace Excimontec; using namespace KMC_Lattice; int main(int argc, char *argv[]) { - string version = "v1.0.0-rc.2"; + string version = "v1.0.0-rc.3"; // Parameters bool End_sim = false; // File declaration @@ -602,25 +602,25 @@ int main(int argc, char *argv[]) { if (procid == 0) { // Output the DOOS and DOS data ofstream doos_file1("DOOS_data.txt"); - doos_file1 << "Energy (eV),Density (cm^-3)\n"; + doos_file1 << "Energy (eV),Density (cm^-3 eV^-1)\n"; for (auto& item : doos_avg1) { doos_file1 << item.first << "," << item.second << "\n"; } doos_file1.close(); ofstream doos_file2("DOOS_Coulomb_data.txt"); - doos_file2 << "Energy (eV),Density (cm^-3)\n"; + doos_file2 << "Energy (eV),Density (cm^-3 eV^-1)\n"; for (auto& item : doos_avg2) { doos_file2 << item.first << "," << item.second << "\n"; } doos_file2.close(); ofstream dos_file1("DOS_data.txt"); - dos_file1 << "Energy (eV),Density (cm^-3)\n"; + dos_file1 << "Energy (eV),Density (cm^-3 eV^-1)\n"; for (auto& item : dos_avg1) { dos_file1 << item.first << "," << item.second << "\n"; } dos_file1.close(); ofstream dos_file2("DOS_Coulomb_data.txt"); - dos_file2 << "Energy (eV),Density (cm^-3)\n"; + dos_file2 << "Energy (eV),Density (cm^-3 eV^-1)\n"; for (auto& item : dos_avg2) { dos_file2 << item.first << "," << item.second << "\n"; } diff --git a/test/test.cpp b/test/test.cpp index 7066c4c..026af43 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1376,22 +1376,31 @@ namespace OSC_SimTests { auto DOS_data = sim.getSteadyDOS(); // Check the DOS peak double peak_position = (*max_element(DOS_data.begin(), DOS_data.end(), [](pair& a, pair& b) {return (a.second < b.second); })).first; - EXPECT_NEAR(peak_position, params.Homo_donor, 1e-2*params.Homo_donor);// Check the DOS + EXPECT_NEAR(peak_position, params.Homo_donor, 1e-2*params.Homo_donor); + // Check the DOS integral + double expected_DOS = 1.0 / intpow(params.Params_lattice.Unit_size*1e-7, 3); + EXPECT_NEAR(expected_DOS, integrateData(DOS_data), 1e-2*expected_DOS); // Check the DOS w/ Coulomb potential DOS_data = sim.getSteadyDOS_Coulomb(); // Check the DOS peak peak_position = (*max_element(DOS_data.begin(), DOS_data.end(), [](pair& a, pair& b) {return (a.second < b.second); })).first; EXPECT_NEAR(peak_position, params.Homo_donor, 1e-2*params.Homo_donor); + // Check the DOS integral + EXPECT_NEAR(expected_DOS, integrateData(DOS_data), 1e-2*expected_DOS); // Check the DOOS auto DOOS_data = sim.getSteadyDOOS(); // Check the DOOS peak peak_position = (*max_element(DOOS_data.begin(), DOOS_data.end(), [](pair& a, pair& b) {return (a.second < b.second); })).first; EXPECT_NEAR(peak_position, expected_energy, 1e-2*params.Homo_donor); + // Check the DOOS integral + EXPECT_NEAR(params.Steady_carrier_density, integrateData(DOOS_data), 5e-2*params.Steady_carrier_density); // Check the DOOS w/ Coulomb potential DOOS_data = sim.getSteadyDOOS_Coulomb(); // Check the DOOS peak peak_position = (*max_element(DOOS_data.begin(), DOOS_data.end(), [](pair& a, pair& b) {return (a.second < b.second); })).first; EXPECT_NEAR(peak_position, expected_energy, 1e-2*params.Homo_donor); + // Check the DOOS integral + EXPECT_NEAR(params.Steady_carrier_density, integrateData(DOOS_data), 5e-2*params.Steady_carrier_density); // Steady transport test with Gaussian disorder at medium field sim = OSC_Sim(); params = params_default;