00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef ADSORPTION_HPP
00020 #define 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 Adsorption: public Reaction {
00041 public:
00047 Adsorption(const Name& name, const Surface::Species& species,
00048 const double preexponential_factor,
00049 const double activation_energy):
00050 name_(name), species_(species),
00051 preexponential_factor_(preexponential_factor),
00052 activation_energy_(activation_energy),
00053 time_(0.0),
00054 adsorption_site_(0)
00055 { }
00056
00057 private:
00059 Adsorption(const Adsorption& other, Surface::Site* adsorption_site):
00060 name_(other.name_), species_(other.species_),
00061 preexponential_factor_(other.preexponential_factor_),
00062 activation_energy_(other.activation_energy_),
00063 time_(other.time_),
00064 adsorption_site_(adsorption_site)
00065 { if (Enabled()) UpdateTime(); }
00066
00067 Adsorption(const Adsorption&);
00068 Adsorption& operator=(const Adsorption&);
00069
00070 public:
00072 ~Adsorption()
00073 { adsorption_site_ = 0; };
00074
00075 Name name() const
00076 { return name_; }
00077
00078 void UpdateTime()
00079 { using std::log; using namespace RandomLib;
00080
00081 const double real_activation_energy = activation_energy_ + adsorption_site_->self_energy();
00082 const double k = Arrhenius(preexponential_factor_, real_activation_energy, Surface::temperature());
00083 double r = Random::Global.Fixed();
00084 while (r == 0.0) r = Random::Global.Fixed();
00085 assert(r != 0 && r != 1);
00086 assert(k != 0.0);
00087 time_ = (-1.0/k)*log(r);
00088 }
00089
00090 double Time() const
00091 { return time_; }
00092
00093 bool Enabled() const
00094 { return adsorption_site_->empty(); }
00095
00096 void operator()() {
00097 if (!Enabled()) return;
00098 adsorption_site_->set_species(species_);
00099 }
00100
00101 EventContainer GetEvents(const Surface::Site* adsorption_site_ptr) const {
00102 EventPtr adsorption_ptr (new Adsorption(*this, const_cast<Surface::Site*>(adsorption_site_ptr)));
00103 return (adsorption_ptr->Enabled() ?
00104 EventContainer(1, adsorption_ptr) :
00105 EventContainer());
00106 }
00107
00108
00109 SitePtrContainer site_container() const
00110 { return SitePtrContainer(1, adsorption_site_); }
00111
00112 private:
00113 Name name_;
00114 Surface::Species species_;
00115 double preexponential_factor_, activation_energy_;
00116
00117 double time_;
00118 Surface::Site* adsorption_site_;
00119 };
00120
00121 }
00122
00123 #endif