summaryrefslogtreecommitdiff
path: root/transformation.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'transformation.hpp')
-rw-r--r--transformation.hpp58
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());
}
}
}