diff options
| author | Jaron Kent-Dobias <jaron@kent-dobias.com> | 2020-02-16 21:02:25 -0500 | 
|---|---|---|
| committer | Jaron Kent-Dobias <jaron@kent-dobias.com> | 2020-02-16 21:02:25 -0500 | 
| commit | 2ebf2f181edac37bfb932dbb353101e37e97223a (patch) | |
| tree | 29a2d0dbd729c4044063afefa43373fd4e537bcb | |
| parent | 9437ed889390e04a1e693a5dfa5290cd90ae150e (diff) | |
| download | space_wolff-2ebf2f181edac37bfb932dbb353101e37e97223a.tar.gz space_wolff-2ebf2f181edac37bfb932dbb353101e37e97223a.tar.bz2 space_wolff-2ebf2f181edac37bfb932dbb353101e37e97223a.zip | |
More work on new transformations, and animation of cluster formation
| -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());      }    }  } | 
