diff options
Diffstat (limited to 'transformation.hpp')
-rw-r--r-- | transformation.hpp | 58 |
1 files changed, 38 insertions, 20 deletions
diff --git a/transformation.hpp b/transformation.hpp index ad3b49f..717a033 100644 --- a/transformation.hpp +++ b/transformation.hpp @@ -9,10 +9,12 @@ template <class U, int D, class R, class S> class Model; template <class U, int D, class R, class S> class Transformation { public: + const R r; + Transformation(const R& r) : r(r) {} virtual std::set<Spin<U, D, S>*> current() const { return {NULL}; } virtual std::set<Spin<U, D, S>*> toConsider() const { return {}; } virtual double ΔE(const Spin<U, D, S>*) const { return 0; } - virtual Transformation* createNew(double T, std::set<Spin<U, D, S>*>&, Spin<U, D, S>*, Rng& rng) const { return new Transformation(); } + virtual Transformation* createNew(double T, std::set<Spin<U, D, S>*>&, Spin<U, D, S>*, Rng& rng) const { return new Transformation(r); } virtual void apply(){}; }; @@ -23,11 +25,10 @@ template <class U, int D, class R, class S> class SpinFlip : public Transformati private: Model<U, D, R, S>& M; Spin<U, D, S>* sOld; - const R r; Spin<U, D, S> sNew; public: - SpinFlip(Model<U, D, R, S>& M, const R& r, Spin<U, D, S>* s) : M(M), r(r) { + SpinFlip(Model<U, D, R, S>& M, const R& r, Spin<U, D, S>* s) : M(M), Transformation<U, D, R, S>(r) { sOld = s; sNew = r.act(*s); } @@ -72,12 +73,11 @@ private: Model<U, D, R, S>& M; Spin<U, D, S>* s1Old; Spin<U, D, S>* s2Old; - const R r; Spin<U, D, S> s1New; Spin<U, D, S> s2New; public: - PairFlip(Model<U, D, R, S>& M, const R& r, Spin<U, D, S>* s1, Spin<U, D, S>* s2) : M(M), r(r) { + PairFlip(Model<U, D, R, S>& M, const R& r, Spin<U, D, S>* s1, Spin<U, D, S>* s2) : M(M), Transformation<U, D, R, S>(r) { s1Old = s1; s2Old = s2; s1New = r.act(*s1); @@ -133,11 +133,10 @@ public: template <class U, int D, class R, class S> class FieldFlip : public Transformation<U, D, R, S> { private: Model<U, D, R, S>& M; - const R r; R s0New; public: - FieldFlip(Model<U, D, R, S>& M, const R& r) : M(M), r(r), s0New(r.act(M.s0)) {} + FieldFlip(Model<U, D, R, S>& M, const R& r) : M(M), Transformation<U, D, R, S>(r), s0New(r.act(M.s0)) {} std::set<Spin<U, D, S>*> toConsider() const override { std::set<Spin<U, D, S>*> neighbors; @@ -156,16 +155,16 @@ public: } Transformation<double, D, R, S>* createNew(double T, std::set<Spin<U, D, S>*>& v, Spin<double, D, S>* s, Rng&) const { - return new SpinFlip<U, D, R, S>(M, r, s); + return new SpinFlip<U, D, R, S>(M, this->r, s); } Transformation<signed, D, R, S>* createNew(double, std::set<Spin<U, D, S>*>&, Spin<signed, D, S>* s, Rng&) const { - Vector<signed, 2> v = r.act(*s).x; + Vector<signed, 2> v = this->r.act(*s).x; std::set<Spin<U, D, S>*> on_site = M.dict.at(v); if (on_site.empty()) { - return new SpinFlip<U, D, R, S>(M, r, s); + return new SpinFlip<U, D, R, S>(M, this->r, s); } else { - return new PairFlip<U, D, R, S>(M, r, s, *on_site.begin()); + return new PairFlip<U, D, R, S>(M, this->r, s, *on_site.begin()); } } @@ -175,18 +174,37 @@ public: template <class U, int D, class R, class S> Transformation<U, D, R, S>* SpinFlip<U, D, R, S>::createNew(double T, std::set<Spin<U, D, S>*>& v, Spin<U, D, S>* s, Rng& rng) const { if (s == NULL) { - return new FieldFlip<U, D, R, S>(M, r); + return new FieldFlip<U, D, R, S>(M, this->r); } else { - return new SpinFlip<U, D, R, S>(M, r, s); + SpinFlip<U, D, R, S>* t = new SpinFlip<U, D, R, S>(M, this->r, s); + Spin<U, D, S>* sMax = NULL; + double ΔEMax = 0.0; + for (Spin<U, D, S>* ss : t->toConsider()) { + if (ss != NULL && ss != s && !v.contains(ss)) { + double ΔE = t->ΔE(ss); + if (ΔE > ΔEMax) { + sMax = ss; + ΔEMax = ΔE; + } + } + } + if (sMax == NULL || 1.0 - exp(-ΔEMax / T) < rng.uniform<double>(0, 1) || v.contains(sMax)) { + return t; + } else { + delete t; + v.insert(s); + v.insert(sMax); + return new PairFlip<U, D, R, S>(M, this->r, s, sMax); + } } } template <class U, int D, class R, class S> Transformation<U, D, R, S>* PairFlip<U, D, R, S>::createNew(double T, std::set<Spin<U, D, S>*>& v, Spin<double, D, S>* s, Rng& rng) const { if (s == NULL) { - return new FieldFlip<U, D, R, S>(M, r); + return new FieldFlip<U, D, R, S>(M, this->r); } else { - SpinFlip<U, D, R, S>* t = new SpinFlip<U, D, R, S>(M, r, s); + SpinFlip<U, D, R, S>* t = new SpinFlip<U, D, R, S>(M, this->r, s); Spin<U, D, S>* sMax = NULL; double ΔEMax = 0.0; for (Spin<U, D, S>* ss : t->toConsider()) { @@ -204,7 +222,7 @@ Transformation<U, D, R, S>* PairFlip<U, D, R, S>::createNew(double T, std::set<S delete t; v.insert(s); v.insert(sMax); - return new PairFlip<U, D, R, S>(M, r, s, sMax); + return new PairFlip<U, D, R, S>(M, this->r, s, sMax); } } } @@ -212,14 +230,14 @@ Transformation<U, D, R, S>* PairFlip<U, D, R, S>::createNew(double T, std::set<S template <class U, int D, class R, class S> Transformation<U, D, R, S>* PairFlip<U, D, R, S>::createNew(double, std::set<Spin<U, D, S>*>&, Spin<signed, D, S>* s, Rng&) const { if (s == NULL) { - return new FieldFlip<U, D, R, S>(M, r); + return new FieldFlip<U, D, R, S>(M, this->r); } else { - Vector<signed, 2> v = r.act(*s).x; + Vector<signed, 2> v = this->r.act(*s).x; std::set<Spin<U, D, S>*> on_site = M.dict.at(v); if (on_site.empty()) { - return new SpinFlip<U, D, R, S>(M, r, s); + return new SpinFlip<U, D, R, S>(M, this->r, s); } else { - return new PairFlip<U, D, R, S>(M, r, s, *on_site.begin()); + return new PairFlip<U, D, R, S>(M, this->r, s, *on_site.begin()); } } } |