summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaron Kent-Dobias <jaron@kent-dobias.com>2020-02-16 21:02:25 -0500
committerJaron Kent-Dobias <jaron@kent-dobias.com>2020-02-16 21:02:25 -0500
commit2ebf2f181edac37bfb932dbb353101e37e97223a (patch)
tree29a2d0dbd729c4044063afefa43373fd4e537bcb
parent9437ed889390e04a1e693a5dfa5290cd90ae150e (diff)
downloadspace_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.hpp8
-rw-r--r--spheres_infinite.cpp69
-rw-r--r--transformation.hpp58
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());
}
}
}