// SINGLE.C // Equilibration using single spin flip // © 2021 Peter J. Meyer #include "iss.h" static int process_spin(int i, int j, ...); /*--------------------------------*/ void do_checkerboard_ssf_sweep(void) { int num_sublattices, sublattice_size; int i, j, k, l, i1, i2, j1, j2, k1, k2, l1,l2; // Use "checkerboard algorithm" for order in which to attempt spin flips. // Randomly select a divisor from up to 7 divisors selected in SETPARAM.C. num_sublattices = divisors[(int)(PRNG1()*num_divisors)]; sublattice_size = size/num_sublattices; switch ( dimensionality ) { case 2: for ( i1=0; i1<sublattice_size; i1++ ) { for ( j1=0; j1<sublattice_size; j1++ ) { for ( i2=0; i2<num_sublattices; i2++ ) { i = i2*sublattice_size + i1; for ( j2=0; j2<num_sublattices; j2++ ) { j = j2*sublattice_size + j1; process_spin(i,j); } } } } break; case 3: for ( i1=0; i1<sublattice_size; i1++ ) { for ( j1=0; j1<sublattice_size; j1++ ) { for ( k1=0; k1<sublattice_size; k1++ ) { for ( i2=0; i2<num_sublattices; i2++ ) { i = i2*sublattice_size + i1; for ( j2=0; j2<num_sublattices; j2++ ) { j = j2*sublattice_size + j1; for ( k2=0; k2<num_sublattices; k2 ++ ) { k = k2*sublattice_size + k1; process_spin(i,j,k); } } } } } } break; case 4: for ( i1=0; i1<sublattice_size; i1++ ) { for ( j1=0; j1<sublattice_size; j1++ ) { for ( k1=0; k1<sublattice_size; k1++ ) { for ( l1=0; l1<sublattice_size; l1++ ) { for ( i2=0; i2<num_sublattices; i2++ ) { i = i2*sublattice_size + i1; for ( j2=0; j2<num_sublattices; j2++ ) { j = j2*sublattice_size + j1; for ( k2=0; k2<num_sublattices; k2++ ) { k = k2*sublattice_size + k1; for ( l2=0; l2<num_sublattices; l2++ ) { l = l2*sublattice_size + l1; process_spin(i,j,k,l); } } } } } } } } break; } } // This increases time required (compared to Glauber) by about 75%. /*--------------------------*/ void do_random_ssf_sweep(void) { int n, i, j, k, l; // Pick num_spins sites at random. n = num_spins; do { switch ( dimensionality ) { case 2: i = (int)(PRNG1()*size); j = (int)(PRNG1()*size); n -= process_spin(i,j); // n decremented iff site is occupied break; case 3: i = (int)(PRNG1()*size); j = (int)(PRNG1()*size); k = (int)(PRNG1()*size); n -= process_spin(i,j,k); break; case 4: i = (int)(PRNG1()*size); j = (int)(PRNG1()*size); k = (int)(PRNG1()*size); l = (int)(PRNG1()*size); n -= process_spin(i,j,k,l); break; } } while ( n ); } /*--------------------------------------*/ static int process_spin(int i, int j, ...) { int spin_value, new_spin_value, k, l; num_spins_visited_this_sweep++; switch ( dimensionality ) { case 2: // spin_at_site(i,j) returns 0 if site is unoccupied, // otherwise returns the spin value. if ( spin_value = spin_at_site(i,j) ) { if ( model_is_ising ) { if ( flip_spin(2*spin_value*nn_spin_sum(i,j)) ) do_ising_spin_flip(spin_value,i,j); } else // model is q-state Potts { // Pick another spin value. do { new_spin_value = (int)(PRNG1()*q) + 1; } while ( new_spin_value == spin_value ); if ( flip_spin(sum_kronecker_deltas(spin_value,i,j) - sum_kronecker_deltas(new_spin_value,i,j)) ) do_q_state_potts_spin_flip(spin_value, new_spin_value,i,j); } } break; case 3: k = *(((int *)(&j))+1); if ( spin_value = spin_at_site(i,j,k) ) { if ( model_is_ising ) { if ( flip_spin(2*spin_value*nn_spin_sum(i,j,k)) ) do_ising_spin_flip(spin_value,i,j,k); } else // model is q-state Potts { // Pick another spin value. do { new_spin_value = (int)(PRNG1()*q) + 1; } while ( new_spin_value == spin_value ); if ( flip_spin(sum_kronecker_deltas(spin_value,i,j,k) - sum_kronecker_deltas(new_spin_value,i,j,k)) ) do_q_state_potts_spin_flip(spin_value, new_spin_value,i,j,k); } } break; case 4: k = *(((int *)(&j))+1); l = *(((int *)(&j))+2); if ( spin_value = spin_at_site(i,j,k,l) ) { if ( model_is_ising ) { if ( flip_spin(2*spin_value*nn_spin_sum(i,j,k,l)) ) do_ising_spin_flip(spin_value,i,j,k,l); } else // model is q-state Potts { // Pick another spin value. do { new_spin_value = (int)(PRNG1()*q) + 1; } while ( new_spin_value == spin_value ); if ( flip_spin(sum_kronecker_deltas(spin_value,i,j,k,l) - sum_kronecker_deltas(new_spin_value,i,j,k,l)) ) do_q_state_potts_spin_flip(spin_value, new_spin_value,i,j,k,l); } } } return ( spin_value ); // returns false iff site is not occupied. }