00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef DISSOCIATIVE_ADSORPTION_HPP
00020 #define DISSOCIATIVE_ADSORPTION_HPP
00021
00022 #include <cassert>
00023 #include <RandomLib/Random.hpp>
00024 #include "Reaction.hpp"
00025 #include "Site.hpp"
00026 #include "Arrhenius.hpp"
00027 #include "Lattice.hpp"
00028
00029 namespace Surface { class Species; }
00030
00031 namespace Reactions {
00032
00040 class DissociativeAdsorption: public Reaction
00041 {
00042 public:
00049 DissociativeAdsorption(const Name& name, const Surface::Species& species,
00050 const Interactions::TwoBody::Geometry& two_body_interactions,
00051 const double preexponential_factor,
00052 const double activation_energy):
00053 name_(name), species_(species),
00054 preexponential_factor_(preexponential_factor),
00055 activation_energy_(activation_energy),
00056 time_(0.0),
00057 two_body_interactions_(two_body_interactions),
00058 adsorption_site_(0), neighbor_adsorption_site_(0)
00059 { }
00060
00061 private:
00063 DissociativeAdsorption(const DissociativeAdsorption& other,
00064 Surface::Site* adsorption_site,
00065 Surface::Site* neighbor_adsorption_site):
00066 name_(other.name_), species_(other.species_),
00067 preexponential_factor_(other.preexponential_factor_),
00068 activation_energy_(other.activation_energy_),
00069 time_(other.time_),
00070 two_body_interactions_(other.two_body_interactions_),
00071 adsorption_site_(adsorption_site), neighbor_adsorption_site_(neighbor_adsorption_site)
00072 { if (Enabled()) UpdateTime(); }
00073
00074 DissociativeAdsorption(const DissociativeAdsorption&);
00075 DissociativeAdsorption& operator=(const DissociativeAdsorption&);
00076
00077 public:
00079 ~DissociativeAdsorption()
00080 { adsorption_site_ = neighbor_adsorption_site_ = 0; };
00081
00082 Name name() const
00083 { return name_; }
00084
00085 void UpdateTime()
00086 { using std::log; using namespace RandomLib;
00087
00088 const double k = Arrhenius(preexponential_factor_, activation_energy_, Surface::temperature());
00089 double r = Random::Global.Fixed();
00090 while (r == 0.0) r = Random::Global.Fixed();
00091 assert(r != 0 && r != 1);
00092 assert(k != 0.0);
00093 time_ = (-1.0/k)*log(r);
00094 }
00095
00096 double Time() const
00097 { return time_; }
00098
00099 bool Enabled() const
00100 { return adsorption_site_->empty() && neighbor_adsorption_site_->empty(); }
00101
00102 void operator()()
00103 {
00104 if (!Enabled()) return;
00105
00106 adsorption_site_->set_species(species_);
00107 neighbor_adsorption_site_->set_species(species_);
00108 }
00109
00110 EventContainer GetEvents(const Surface::Site* adsorption_site_ptr) const
00111 {
00112 const Interactions::TwoBody::Geometry::NeighborContainer&
00113 neighbor_container = adsorption_site_ptr->two_body_interactions(two_body_interactions_).neighbor_container();
00114 Reaction::EventContainer ev;
00115
00116 for (Interactions::TwoBody::Geometry::NeighborContainer::const_iterator
00117 neighbor_container_it = neighbor_container.begin(),
00118 neighbor_container_end = neighbor_container.end();
00119 neighbor_container_it != neighbor_container_end;
00120 ++neighbor_container_it)
00121 {
00122 EventPtr dissociative_adsorption_ptr
00123 (new DissociativeAdsorption(*this, const_cast<Surface::Site*>(adsorption_site_ptr),
00124 *neighbor_container_it));
00125 if (dissociative_adsorption_ptr->Enabled()) ev.push_back(dissociative_adsorption_ptr);
00126 }
00127 return ev;
00128 }
00129
00130 SitePtrContainer site_container() const
00131 {
00132 SitePtrContainer site_ptr_container(1, adsorption_site_);
00133 site_ptr_container.insert(site_ptr_container.end(),
00134 two_body_interactions_.neighbor_container().begin(), two_body_interactions_.neighbor_container().end());
00135 return site_ptr_container;
00136 }
00137
00138 private:
00139 Name name_;
00140 Surface::Species species_;
00141 double preexponential_factor_, activation_energy_;
00142
00143 double time_;
00144 Interactions::TwoBody::Geometry two_body_interactions_;
00145 Surface::Site * adsorption_site_, * neighbor_adsorption_site_;
00146 };
00147
00148 }
00149
00150 #endif
00151