14 #include "montecarlo.h"
29 double MonteCarlo::s_cutoff_real_radius;
35 double MonteCarlo::s_cutoff_rec_radius;
37 std::vector<MonteCarlo::Vector3<MonteCarlo::Spin> > MonteCarlo::s_fields_rec_generic[16];
39 std::vector<std::complex<MonteCarlo::Spin> > MonteCarlo::s_exp_ph[16];
42 MonteCarlo::MonteCarlo(
int num_threads)
45 m_sec_cache_enabled(false),
46 m_third_cache_enabled(false),
47 m_sec_cache_firsttime(true),
48 m_third_cache_firsttime(true)
50 int lsize = s_num_spins/16;
52 for(
int site1 = 0; site1 < 16; site1++) {
54 m_spins_real[site1].resize(spins_real_index(0,0,s_L)/4);
56 m_spins_real[site1].resize(3*lsize);
59 m_field_pri_cached[site1].resize(lsize, 0.0);
60 m_field_pri_cached_sane.resize(lsize, 0);
61 for(
int site2 = 0; site2 < 16; site2++) {
62 m_field_sec_cached[site2][site1].resize(lsize, 0.0);
63 m_field_sec_cached_sane[site2].resize(lsize, 0);
64 m_field_third_cached[site2][site1].resize(lsize, 0.0);
65 m_field_third_cached_sane[site2].resize(lsize, 0);
67 m_probability_buffers[0][site1].resize(lsize, 0.0);
68 m_probability_buffers[1][site1].resize(lsize, 0.0);
71 fprintf(stderr,
"# of spins = %d\n", 16*lsize);
74 for(
int i = 0; i < num_threads - 1; i++) {
77 pthread_create(&tid, NULL, xthread_start_routine,
this);
79 m_threads.push_back(tid);
82 MonteCarlo::~MonteCarlo()
87 m_thread_pool_cond.broadcast();
89 for(deque<pthread_t>::iterator it = m_threads.begin(); it != m_threads.end(); it++)
92 int ret = pthread_join(*it, &retv);
99 if(!is.good())
throw "input io error\n";
103 }
while(str[0] !=
'#');
104 while(str[0] ==
'#') {
108 sscanf(str.c_str(),
"size=%d", &size);
109 if(size != s_L)
throw "size mismatch\n";
111 if(str !=
"[")
throw "ill format\n";
112 for(
int site1 = 0; site1 < 16; site1++) {
114 if(str !=
"[")
throw "ill format\n";
115 for(
int k1 = 0; k1 < s_L; k1++) {
117 if(str !=
"[")
throw "ill format\n";
118 for(
int j1 = 0; j1 < s_L; j1++) {
120 if(str !=
"[")
throw "ill format\n";
121 for(
int i1 = 0; i1 < s_L; i1++) {
123 if(str !=
"[")
throw "ill format\n";
125 int x = atoi(str.c_str());
126 if(abs(x) != 1)
throw "value be +-1\n";
127 int sidx = spins_real_index(i1,j1,k1);
128 writeSpin(x, site1, sidx);
131 int lidx = lattice_index(i1,j1,k1);
132 m_field_pri_cached[site1][lidx] = atof(str.c_str());
133 m_field_pri_cached_sane[lidx] |= 1u << site1;
136 if(str !=
"]")
throw "ill format\n";
139 if(str !=
"]")
throw "ill format\n";
142 if(str !=
"]")
throw "ill format\n";
145 if(str !=
"]")
throw "ill format\n";
148 if(str !=
"]")
throw "ill format\n";
150 makeReciprocalImage();
156 if(!os.good())
throw "output io error\n";
157 os <<
"# MonteCarlo calculation for pyrochlore. Kentaro Kitagawa." << endl;
158 os <<
"# ver. 1.0." << endl;
159 os <<
"# Spin configuration below." << endl;
160 os <<
"size=" << s_L << endl;
162 for(
int site1 = 0; site1 < 16; site1++) {
164 for(
int k1 = 0; k1 < s_L; k1++) {
166 for(
int j1 = 0; j1 < s_L; j1++) {
168 for(
int i1 = 0; i1 < s_L; i1++) {
170 int lidx = lattice_index(i1,j1,k1);
171 os << readSpin(site1, spins_real_index(lidx));
172 if(m_field_pri_cached_sane[lidx] & (1u << site1)) {
174 snprintf(buf, 30,
"%.16g", m_field_pri_cached[site1][lidx]);
195 fprintf(stderr,
"Randomize spins\n");
196 for(
int site1 = 0; site1 < 16; site1++) {
197 m_ext_field[site1] = 0.0;
199 for(
int site1 = 0; site1 < 16; site1++) {
200 for(
int k1 = 0; k1 < s_L; k1++) {
201 for(
int j1 = 0; j1 < s_L; j1++) {
202 for(
int i1 = 0; i1 < s_L; i1++) {
203 int sidx = spins_real_index(i1,j1,k1);
204 int val = (randMT19937() < 0.5) ? 1 : -1;
205 writeSpin(val, site1, sidx);
210 makeReciprocalImage();
213 MonteCarlo::siteMagnetization()
216 for(
int k1 = 0; k1 < s_L; k1++) {
217 for(
int j1 = 0; j1 < s_L; j1++) {
218 for(
int i1 = 0; i1 < s_L; i1++) {
219 int sidx = spins_real_index(i1,j1,k1);
220 for(
int trans = 0; trans < 4; trans++) {
222 for(
int site_wo_trans = 0; site_wo_trans < 4; site_wo_trans++) {
223 int site1 = site_wo_trans + 4*trans;
224 Spin spin = readSpin(site1, sidx);
225 quartet.sites[site1 % 4] += spin;
226 in += (spin == 1) ? 1 : 0;
228 quartet.twotwo += (in == 2) ? 1 : 0;
229 quartet.onethree += ((in == 1) || (in == 3)) ? 1 : 0;
234 quartet.twotwo /= (s_num_spins/4);
235 quartet.onethree /= (s_num_spins/4);
236 for(
int site1 = 0; site1 < 4; site1++) {
237 quartet.sites[site1] /= (s_num_spins/4);
238 quartet.sites[site1] *= A_MOMENT;
246 Quartet quartet = siteMagnetization();
247 for(
int site1 = 0; site1 < 4; site1++) {
249 v *= quartet.sites[site1];
256 MonteCarlo::takeThermalAverage(
long double tests_after_check)
258 m_SumDeltaU += m_DeltaU * tests_after_check;
260 for(
int site = 0; site < 16; site++) {
261 m_SumSpin[site] += real(m_spins_rec[site][reciprocal_index(0,0,0)]) * tests_after_check;
264 m_SumTests += tests_after_check;
271 m_beta = 1.0/K_B/temp;
273 for(
int site1 = 0; site1 < 16; site1++) {
274 m_ext_field[site1] = field.innerProduct(s_ASiteIsingVector[site1]);
279 for(
int site = 0; site < 16; site++) {
280 m_SumSpin[site] = 0.0;
283 m_SumTestsAtLastFlip = 0.0;
285 m_flipHistory.clear();
287 doTests(flips, *tests);
289 *DUav = m_SumDeltaU / s_num_spins / m_SumTests;
291 for(
int site1 = 0; site1 < 16; site1++) {
293 v *= (double)(m_SumSpin[site1]);
296 m *= A_MOMENT / s_num_spins / m_SumTests;
299 return m_DeltaU/s_num_spins;
302 MonteCarlo::flippingProbability(
int site,
int lidx,
double h,
double *pdu)
304 int sidx = spins_real_index(lidx);
305 double du = 2 * readSpin(site, sidx) * A_MOMENT * MU_B * (
306 h + m_ext_field[site]);
309 if(du <= 0.0)
return 1.0;
312 return exp(-m_beta*du);
318 m_sec_cache_enabled =
true;
323 if(m_last_flipped_lattice_index >= 0) {
325 current_buffer = 1 - m_last_probability_buffer;
329 m_play_back_buffer =
false;
331 if(m_play_back_buffer) {
332 for(
int site1 = 0; site1 < 16; site1++) {
333 double *pprob = &m_probability_buffers[current_buffer][site1][0];
334 for(
int i = 0; i < s_num_spins/16; i++) {
341 for(
int site1 = 0; site1 < 16; site1++) {
342 double *pprob = &m_probability_buffers[current_buffer][site1][0];
343 int cnt = s_num_spins/16;
344 for(
int lidx = 0; lidx < cnt; lidx++) {
345 double h = hinteraction(site1, lidx);
347 double probability = flippingProbability(site1, lidx, h, &du);
348 *pprob = probability;
350 sum_p += probability;
354 m_play_back_buffer =
false;
355 m_last_probability_buffer = current_buffer;
357 double p_av = sum_p / s_num_spins;
358 if(p_av <= 0.0)
return -1;
360 long double cnt_d = ceill(log2l(1.0 - randMT19937()) / log2l((
long double)1.0 - p_av));
361 if(cnt_d <= 0.0)
return -1;
366 double p = randMT19937()*sum_p;
367 int lidx = s_num_spins/16 - 1;
370 for(
int site = 0; site < 16; site++) {
371 double *pprob = &m_probability_buffers[current_buffer][site][0];
372 for(
int i = 0; i < s_num_spins/16; i++) {
382 assert(pit < sum_p * 1.00001);
385 flippingProbability(site1, lidx, hinteraction(site1, lidx), &du);
386 flipSpin(site1, lidx, du, cnt_d);
389 if((m_last_flipped_lattice_index == lidx) && (m_last_flipped_site == site1)) {
390 m_play_back_buffer =
true;
391 fprintf(stderr,
"0");
394 if(m_last_flipped_lattice_index >= 0) {
402 n = m_last_flipped_lattice_index;
408 VectorInt v = distance(site1, m_last_flipped_site,
409 (i1 - i2 + size) % size, (j1 - j2 + size) % size, (k1 - k2 + size) % size);
410 int d = v.x*v.x + v.y*v.y + v.z*v.z;
412 for(
int i = 0; i < 10; i++) {
414 assert(d >= s_4r2_neighbor[i]);
415 fprintf(stderr,
".");
418 if(s_4r2_neighbor[i] == d) {
419 fprintf(stderr,
"%d", i + 1);
425 m_last_probability_buffer = -1;
429 m_last_flipped_lattice_index = lidx;
430 m_last_flipped_site = site1;
435 bool abondon_cache = (randMT19937() < 0.05);
437 fprintf(stderr,
"Abondon cache.\n");
438 fill(m_field_pri_cached_sane.begin(), m_field_pri_cached_sane.end(), 0);
443 for(
int site1 = 0; site1 < 16; site1++) {
444 for(
int lidx = 0; lidx < s_num_spins/16; lidx++) {
446 h = hinteraction(site1, lidx);
449 h += m_ext_field[site1];
450 U += -readSpin(site1, spins_real_index(lidx)) * A_MOMENT * MU_B * h;
460 int flipped_checked = 0;
462 m_third_cache_hit = 0;
463 m_hinteractions_called = 0;
465 long tests_after_check = 0;
466 long double tests_accel_flip = 0;
467 long double tests_accel_flip_started = 0;
468 int flipped_accel_flip_started = 0;
469 bool accel_flip =
false;
471 if((flipped >= *flips) && (m_SumTests + tests_after_check >= tests))
break;
473 fprintf(stderr,
"Signal caught! Aborting...\n");
478 takeThermalAverage(tests_after_check);
479 tests_after_check = 0;
480 long double adv = accelFlipping();
482 fprintf(stderr,
"Spins are completely freezed!.\n");
485 tests_accel_flip += adv;
487 if(m_last_probability_buffer < 0) {
488 fprintf(stderr,
"\nSkipped tests = %Lg. Flipped = %d\n",
489 (
long double)(tests_accel_flip - tests_accel_flip_started), flipped - flipped_accel_flip_started);
497 int idx = (int)floor(randMT19937() * s_num_spins);
502 double h = hinteraction(site, lidx);
505 double probability = flippingProbability(site, lidx, h, &du);
510 if((probability >= 1) || (randMT19937() < probability)) {
511 flipSpin(site, lidx, du, tests_after_check);
512 tests_after_check = 0;
516 if((tested % s_num_spins == 0) && (tested != 0)) {
517 int flips = flipped - flipped_checked;
520 fprintf(stderr,
"Flipping Acceleration...");
522 tests_accel_flip_started = tests_accel_flip;
523 flipped_accel_flip_started = flipped;
524 m_last_flipped_lattice_index = -1;
527 if(m_third_cache_enabled) {
528 if(m_hinteractions_called > m_sec_cache_hit) {
529 double hit_prob = (double)m_third_cache_hit / (m_hinteractions_called - m_sec_cache_hit) / 16;
530 if(!m_third_cache_firsttime && (hit_prob < THIRD_CACHE_OFF_FACTOR)) {
531 m_third_cache_enabled =
false;
532 for(
int i = 0; i < 16; i++) {
533 fill(m_field_third_cached_sane[i].begin(), m_field_third_cached_sane[i].end(), 0);
535 fprintf(stderr,
"Flip = %f %%\n", (
double)100.0*flips / m_hinteractions_called);
536 fprintf(stderr,
"Disable 3rd cache. hit = %f%%\n", 100.0*hit_prob);
538 m_third_cache_firsttime =
false;
542 double hit_prob_estimate =
543 pow(1.0 - (
double)flips / m_hinteractions_called /16 / (s_L*s_L*s_L)
544 * (4.0*M_PI/3.0*s_cutoff_real/2*s_cutoff_real/2*s_cutoff_real/2), (
double)s_num_spins);
545 if(hit_prob_estimate > THIRD_CACHE_ON_FACTOR) {
546 m_third_cache_enabled =
true;
547 m_third_cache_firsttime =
true;
548 fprintf(stderr,
"Flip = %f %%\n", (
double)100.0*flips / m_hinteractions_called);
549 fprintf(stderr,
"Enable 3rd cache. estimate = %f%%\n", 100.0*hit_prob_estimate);
552 m_third_cache_hit = 0;
554 if(m_sec_cache_enabled) {
555 double hit_prob = (double)m_sec_cache_hit / (m_hinteractions_called) / 16;
556 if(!m_sec_cache_firsttime && (hit_prob < SEC_CACHE_OFF_FACTOR)) {
557 m_sec_cache_enabled =
false;
558 for(
int i = 0; i < 16; i++) {
559 fill(m_field_sec_cached_sane[i].begin(), m_field_sec_cached_sane[i].end(), 0);
561 fprintf(stderr,
"Flip = %f %%\n", (
double)100.0*flips / m_hinteractions_called);
562 fprintf(stderr,
"Disable secondary cache. hit = %f%%\n", 100.0*hit_prob);
565 m_sec_cache_firsttime =
false;
568 double hit_prob_estimate =
569 pow(1.0 - (
double)flips / m_hinteractions_called /16, (
double)s_num_spins);
570 if(hit_prob_estimate > SEC_CACHE_ON_FACTOR) {
571 m_sec_cache_enabled =
true;
572 m_sec_cache_firsttime =
true;
573 fprintf(stderr,
"Flip = %f %%\n", (
double)100.0*flips / m_hinteractions_called);
574 fprintf(stderr,
"Enable secondary cache. estimate = %f%%\n", 100.0*hit_prob_estimate);
579 flipped_checked = flipped;
580 m_hinteractions_called = 0;
584 fprintf(stderr,
"\nSkipped tests = %Lg. Flipped = %d\n",
585 (
long double)(tests_accel_flip - tests_accel_flip_started), flipped - flipped_accel_flip_started);
588 takeThermalAverage(tests_after_check);
594 int cutoff = s_cutoff_rec;
595 int cnt = 2*cutoff + 1;
596 complex<Spin> *pspin = &m_spins_rec[site1][0];
599 pos1 *= LATTICE_CONST / 4.0;
600 double phx = -2*M_PI / (LATTICE_CONST * s_L) * (i * LATTICE_CONST + pos1.x);
601 double phy = -2*M_PI / (LATTICE_CONST * s_L) * (j * LATTICE_CONST + pos1.y);
602 double phz = -2*M_PI / (LATTICE_CONST * s_L) * (k * LATTICE_CONST + pos1.z);
603 complex<Spin> exp_i_rx = exp(complex<Spin>(0.0, phx));
604 complex<Spin> exp_i_ry = exp(complex<Spin>(0.0, phy));
605 complex<Spin> exp_i_rz = exp(complex<Spin>(0.0, phz));
607 complex<Spin> exp_ikrz = ((Spin)diff)
608 * exp(complex<Spin>(0.0, -cutoff * (phx + phy)));
609 for(
int kz = 0; kz <= cutoff; kz++) {
610 complex<Spin> exp_ikryz = exp_ikrz;
611 for(
int ky = -cutoff; ky <= cutoff; ky++) {
612 complex<Spin> exp_ikr = exp_ikryz;
613 for(
int n = 0; n < cnt; n++) {
618 exp_ikryz *= exp_i_ry;
620 exp_ikrz *= exp_i_rz;
622 assert(pspin == &*m_spins_rec[site1].end());
625 MonteCarlo::makeReciprocalImage()
627 int cutoff = s_cutoff_rec;
629 for(
int site = 0; site < 16; site++) {
630 m_spins_rec[site].clear();
631 m_spins_rec[site].resize((2*cutoff+1)*(2*cutoff+1)*(cutoff+1), 0.0);
632 for(
int k = 0; k < s_L; k++) {
633 for(
int j = 0; j < s_L; j++) {
634 for(
int i = 0; i < s_L; i++) {
635 modifyReciprocalImage(readSpin(site, spins_real_index(i,j,k)), site, i, j, k);
642 MonteCarlo::flipSpin(
int site1,
int lidx,
double du,
long double tests_after_check)
644 takeThermalAverage(tests_after_check);
648 int sidx = spins_real_index(lidx);
649 Spin oldv = readSpin(site1, sidx);
656 modifyReciprocalImage(-2*oldv, site1, i, j, k);
658 writeSpin(-oldv, site1, sidx);
659 assert(spins_real_index(i,j,k) == sidx);
664 hist.delta = -2*oldv;
665 hist.tests = (m_SumTests - m_SumTestsAtLastFlip);
666 m_flipHistory.push_back(hist);
667 m_SumTestsAtLastFlip = m_SumTests;
670 fill(m_field_pri_cached_sane.begin(), m_field_pri_cached_sane.end(), 0);
671 if(m_sec_cache_enabled) {
672 fill(m_field_sec_cached_sane[site1].begin(), m_field_sec_cached_sane[site1].end(), 0);
674 if(m_third_cache_enabled) {
676 int dist = s_cutoff_real;
677 int r2bound = dist*dist;
678 uint16_t *p0 = &m_field_third_cached_sane[site1][0];
679 for(
int dk = -dist; dk <= dist; dk++) {
680 int dk2 = abs(dk) - 1;
682 uint16_t *p_k = p0 + lattice_index(0, 0, (k + dk + size) % size);
683 for(
int dj = -dist; dj <= dist; dj++) {
684 int dj2 = abs(dj) - 1;
686 uint16_t *p_j = p_k + lattice_index(0, (j + dj + size) % size, 0);
687 for(
int di = -dist; di <= dist; di++) {
688 int di2 = abs(di) - 1;
689 int r2 = dj2 + di2*di2;
691 p_j[lattice_index((i + di + size) % size, 0, 0)] = 0;
702 for(
int site = 0; site < 16; site++) {
703 for(
int k1 = 0; k1 < s_L; k1++) {
704 for(
int j1 = 0; j1 < s_L; j1++) {
705 for(
int i1 = 0; i1 < s_L; i1++) {
706 *(data++) = lrint(readSpin(site, spins_real_index(i1,j1,k1)));
708 int lidx = lattice_index(i1,j1,k1);
709 double h = hinteraction(site, lidx);
713 double probability = flippingProbability(site, lidx, h, &du);
714 *(probabilities++) = probability;
723 MonteCarlo::write_bsite(Vector3<double> *fields)
725 for(
int site = 0; site < 16; site++) {
726 for(
int k1 = 0; k1 < s_L; k1++) {
727 for(
int j1 = 0; j1 < s_L; j1++) {
728 for(
int i1 = 0; i1 < s_L; i1++) {
730 h += iterate_real_generic(s_fields_real_B[site], i1, j1, k1);
731 Vector3<double> pos(cg_BSitePositions[site]);
733 h += iterate_rec_generic(pos, i1, j1, k1);
741 MonteCarlo::write_8asite(Vector3<double> *fields)
743 for(
int site = 0; site < 8; site++) {
744 for(
int k1 = 0; k1 < s_L; k1++) {
745 for(
int j1 = 0; j1 < s_L; j1++) {
746 for(
int i1 = 0; i1 < s_L; i1++) {
748 h += iterate_real_generic(s_fields_real_8a[site], i1, j1, k1);
749 Vector3<double> pos(cg_8aSitePositions[site]);
751 h += iterate_rec_generic(pos, i1, j1, k1);
759 MonteCarlo::write_48fsite(Vector3<double> *fields)
761 for(
int site = 0; site < 48; site++) {
762 for(
int k1 = 0; k1 < s_L; k1++) {
763 for(
int j1 = 0; j1 < s_L; j1++) {
764 for(
int i1 = 0; i1 < s_L; i1++) {
766 h += iterate_real_generic(s_fields_real_48f[site], i1, j1, k1);
767 Vector3<double> pos(cg_48fSitePositions[site]);
769 h += iterate_rec_generic(pos, i1, j1, k1);
777 MonteCarlo::write_flips(std::deque<FlipHistory> &buf) {
778 buf.resize(m_flipHistory.size());
779 std::copy(m_flipHistory.begin(), m_flipHistory.end(), buf.begin());
785 m_beta = 1.0/K_B/temp;
787 for(
int site1 = 0; site1 < 16; site1++) {
788 m_ext_field[site1] = field.innerProduct(s_ASiteIsingVector[site1]);
791 for(
int site = 0; site < 16; site++) {
792 for(
int k1 = 0; k1 < s_L; k1++) {
793 for(
int j1 = 0; j1 < s_L; j1++) {
794 for(
int i1 = 0; i1 < s_L; i1++) {
795 writeSpin(*(data++), site, spins_real_index(i1,j1,k1));
799 if(m_sec_cache_enabled)
800 fill(m_field_sec_cached_sane[site].begin(), m_field_sec_cached_sane[site].end(), 0);
801 if(m_third_cache_enabled)
802 fill(m_field_third_cached_sane[site].begin(), m_field_third_cached_sane[site].end(), 0);
804 fill(m_field_pri_cached_sane.begin(), m_field_pri_cached_sane.end(), 0);
805 makeReciprocalImage();