diff options
-rw-r--r-- | space_wolff.hpp | 8 | ||||
-rw-r--r-- | spheres_infinite.cpp | 69 | ||||
-rw-r--r-- | transformation.hpp | 58 |
3 files changed, 94 insertions, 41 deletions
diff --git a/space_wolff.hpp b/space_wolff.hpp index 63bf118..dc06011 100644 --- a/space_wolff.hpp +++ b/space_wolff.hpp @@ -18,11 +18,10 @@ template <class U, int D, class R, class S> class Model; template <class U, int D, class R, class S> class measurement { public: - virtual void pre_cluster(const Model<U, D, R, S>&, unsigned, const R&){}; + virtual void pre_cluster(const Model<U, D, R, S>&, unsigned, const Transformation<double, D, Euclidean<double, D>, double>*){}; virtual void plain_bond_visited(const Model<U, D, R, S>&, const Spin<U, D, S>*, const Spin<U, D, S>*, const Spin<U, D, S>&, double){}; - virtual void plain_site_transformed(const Model<U, D, R, S>&, const Spin<U, D, S>*, - const Spin<U, D, S>&){}; + virtual void plain_site_transformed(const Model<U, D, R, S>&, const Transformation<U, D, R, S>&){}; virtual void ghost_bond_visited(const Model<U, D, R, S>&, const Spin<U, D, S>&, const Spin<U, D, S>&, double){}; @@ -70,6 +69,7 @@ public: } } + A.plain_site_transformed(*this, *t); t->apply(); } delete t; @@ -84,6 +84,8 @@ public: Gen<U, D, R, S>& g = rng.pick(gs); Transformation<U, D, R, S> *t = g(*this, rng); + A.pre_cluster(*this, i, t); + this->step(T, t, A); A.post_cluster(*this); diff --git a/spheres_infinite.cpp b/spheres_infinite.cpp index b39f164..77a3582 100644 --- a/spheres_infinite.cpp +++ b/spheres_infinite.cpp @@ -14,9 +14,10 @@ private: uint64_t t2; unsigned n; unsigned tmp; + Euclidean<double, D> s0_tmp; public: - animation(double L, unsigned w, int argc, char* argv[]) { + animation(double L, unsigned w, int argc, char* argv[]) : s0_tmp(0) { t1 = 0; t2 = 0; n = 0; @@ -31,30 +32,58 @@ public: gluOrtho2D(-L, L, -L, L); } - void pre_cluster(const model&, unsigned, const Euclidean<double, D>&) override { tmp = 0; } - - void plain_site_transformed(const model&, const Spin<double, D, double>*, - const Spin<double, D, double>&) override { + void plain_site_transformed(const model& m, const Transformation<double, D, Euclidean<double, D>, double>& t) override { + if (n > 5000) { + if (t.current().size() > 1) { + glColor3f(0.0f, 0.0f, 1.0f); + } else { + glColor3f(0.0f, 1.0f, 0.0f); + } + for (const Spin<double, 2, double>* s : t.current()) { + if (s != NULL) { + glBegin(GL_POLYGON); + unsigned n_points = 50; + for (unsigned i = 0; i < n_points; i++) { + glVertex2d(s0_tmp.act(*s).x(0) + s->s * cos(2 * i * M_PI / n_points), + s0_tmp.act(*s).x(1) + s->s * sin(2 * i * M_PI / n_points)); + } + glEnd(); + } + } + } tmp++; } - void post_cluster(const model& m) override { + void pre_cluster(const model& m, unsigned, const Transformation<double, D, Euclidean<double, D>, double>* t) override { + s0_tmp = m.s0.inverse(); + tmp = 0; glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); + /* + glBegin(GL_LINE); + Vector<double, 2> r_center = s0_tmp.act({t->r.t, 0}); + glEnd(); + */ for (const Spin<double, 2, double>* s : m.s) { glBegin(GL_POLYGON); unsigned n_points = 50; glColor3f(0.0f, 0.0f, 0.0f); for (unsigned i = 0; i < n_points; i++) { - glVertex2d(m.s0.inverse().act(*s).x(0) + s->s * cos(2 * i * M_PI / n_points), - m.s0.inverse().act(*s).x(1) + s->s * sin(2 * i * M_PI / n_points)); + glVertex2d(s0_tmp.act(*s).x(0) + s->s * cos(2 * i * M_PI / n_points), + s0_tmp.act(*s).x(1) + s->s * sin(2 * i * M_PI / n_points)); } glEnd(); } glFlush(); + } + void post_cluster(const model& m) override { + glFlush(); t1 += tmp; t2 += tmp * tmp; + if (n > 5000) { + sleep(2); + } n++; } @@ -95,17 +124,21 @@ Gen<double, D, Euclidean<double, D>, double> mGen(double ε) { Spin<double, D, double>* s1 = rng.pick(M.s); Spin<double, D, double>* s2 = rng.pick(M.s); - - while (s1 == s2) { - s2 = rng.pick(M.s); - } - Vector<double, D> t1 = s1->x; Vector<double, D> t2 = s2->x; Vector<double, D> t12 = t1 - t2; + + while (s1 == s2 || 1 / t12.norm() < rng.uniform<double>(0, 1)) { + s1 = rng.pick(M.s); + s2 = rng.pick(M.s); + t1 = s1->x; + t2 = s2->x; + t12 = t1 - t2; + } + Vector<double, D> t = (t1 + t2) / 2; - double θ = atan2(t12[1], t12[0]) + rng.variate<double, std::normal_distribution>(0.0, ε); + double θ = atan2(t12[1], t12[0]) + rng.variate<double, std::normal_distribution>(0.0, ε) / t12.norm(); m(0, 0) = -cos(2 * θ); m(1, 1) = cos(2 * θ); @@ -201,9 +234,9 @@ int main(int argc, char* argv[]) { return H * s.x.norm(); }; - auto g1 = eGen(2); - auto g2 = mGen(0.5); - auto g3 = rGen(5); + auto g1 = eGen(0.5); + auto g2 = mGen(0.05); + auto g3 = rGen(1); animation A(L, 750, argc, argv); model sphere(1.0, Z, B); @@ -220,7 +253,7 @@ int main(int argc, char* argv[]) { sphere.dict.insert(ss); } - sphere.wolff(T, {g1, g2, g3}, A, N); + sphere.wolff(T, {g1, g2}, A, N); std::ofstream outfile; outfile.open("test.dat"); 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()); } } } |