void LiveWLdiagram :: updateZe_ab () { int online_worms = int(mob_a.online()) + int(mob_b.online()); // No worm in the diagram if (online_worms == 0) { // Insert the first worm: int comp = rand.choice2(); int site = rand.choice (Diagram::SITEN); double time = Wld::Diag::BETA * rand.uniform(); bool up = rand.choice2(); bool creat = rand.choice2(); Iter it_goal = Wld::Diag::find_aft (site, time); int ninit = it_goal->z.nbef(comp); // Check whether cannot creat or annihilate particle anymore if (check_nlimit (ninit, creat, nMAX, nMIN)) { Worm& mob = comp ? mob_b : mob_a; Iter& fix = comp ? fix_b : fix_a; insert (it_goal, comp, time, creat, up, mob, fix); } } else if (online_worms == 1) { Worm& mob_on = mob_a.online() ? mob_a : mob_b; Iter& fix_on = mob_a.online() ? fix_a : fix_b; // 1. Insert another worm: if (rand.uniform() < Pab) { int comp_on = mob_a.online() ? 0 : 1; int comp_off = !comp_on; Worm& mob_off = mob_a.online() ? mob_b : mob_a; Iter& fix_off = mob_a.online() ? fix_b : fix_a; int site = fix_on->site(); double time = fix_on->time(); bool up = rand.choice2(); bool creat = mob_on.it()->z.creat() ? !up : up; // For PSF. Opposite for SCF. Iter it_goal = Wld::Diag::find_aft (site, time); int ninit = it_goal->z.nbef (comp_off); if (check_nlimit (ninit, creat, nMAX, nMIN)) { insert (it_goal, comp_off, time, creat, up, mob_off, fix_off); } } // 2. Worm can global move. else { updateZe_to_halt (mob_on); } } else if (online_worms == 2) { int comp = rand.choice2(); Worm& mob = (comp == 0 ? mob_a : mob_b); Iter& fix = (comp == 0 ? fix_a : fix_b); updateZe_to_halt (mob); } }
inline LiveWLdiagram::Status LiveWLdiagram :: updateZe (Worm& worm) { double Ewalk = walk_energy (worm.it(), worm.up()); double dtime = -log (rand.uniform()) / Ewalk; Iter it_block; Status stat = walk (dtime, worm, it_block); #ifdef PRINT_STATUS cout << _printi << setw(16) << left << " walk "+string(worm.up() ? "up" : "down")+": " << to_str(stat) << endl; #endif ActStatus astat = act (worm, stat, Ewalk, it_block); #ifdef PRINT_STATUS cout << _printi << setw(16) << left << " act: " << to_str(astat) << endl; _printi++; #endif return stat; }
LiveWLdiagram::ActStatus LiveWLdiagram :: act (Worm& worm, Status stat, double Ewalk, const Iter& it_block) // Member-functions used in this function (like hop, relink_hop,...) // should not specify the base class (for example: don't use WLdiagram::hop,...), // so that the higher-level class (InfoWLdiagram) can overload them. { table.clear(); int site = worm.it()->site(); int comp = worm.it()->z.comp(); if (stat == FREE) { // 1.1 bounce table.add (Ewalk); // 1.2 insert interaction for(int nbi = 0; nbi < Wld::Diag::_latt(site).nbs(); ++nbi) { int n = worm.it()->assoc(nbi)->z.nbef(comp); bool creat = (worm.up() != worm.it()->z.creat()); if (check_nlimit (n, creat, nMAX, nMIN)) { // Check whether cannot creat or annihilate particle anymore int dir = _latt(site).nbdir(nbi); double weight = BH_t(comp,dir) * (creat ? n+1 : n); table.add (weight, nbi); } } // 1.3 choose #ifdef LOCAL_OPTIMAL table.locally_optimal(); #endif int choice = table.get_choice (rand.uniform()); if (choice == 0) { bounce (worm); return ACT_BOUNCE; } else { hop (worm, table.nbi(choice)); return ACT_HOP; } } else if (stat == HALTED) { Iter it_to = it_block->conj(); // 'it_to' is the to-node in remove case, or the middle-node in relink case // 2.1 bounce int dir = _latt.dir (site, it_to->site()); double weight = BH_t(comp,dir) * (worm.it()->z.creat() ? worm.it()->z.naft(comp) : worm.it()->z.nbef(comp)); table.add (weight); // 2.2 remove interaction double Ebef = diagonal_energy (it_to, it_to->z.nbef(0), it_to->z.nbef(1)); double Eaft = diagonal_energy (it_to, it_to->z.naft(0), it_to->z.naft(1)); if (worm.up()) weight = shift_energy (Eaft, Ebef); else weight = shift_energy (Ebef, Eaft); table.add (weight); // 2.3 relink interaction for(int nbi = 0; nbi < Wld::Diag::_latt(it_to->site()).nbs(); ++nbi) { Iter it_nb = it_to->assoc(nbi); if (it_nb->site() != worm.it()->site()) { // Check whether relink to the self site int n = it_nb->z.nbef(comp); bool creat = (worm.up() == worm.it()->z.creat()); if (check_nlimit (n, creat, nMAX, nMIN)) { // Check whether cannot creat or annihilate particle anymore int dir = _latt(site).nbdir(nbi); weight = BH_t(comp,dir) * (creat ? n+1 : n); table.add (weight, nbi); } } } // 2.4 choose #ifdef LOCAL_OPTIMAL table.locally_optimal(); #endif int choice = table.get_choice (rand.uniform()); if (choice == 0) { bounce (worm); return ACT_BOUNCE; } else if (choice == 1) { delete_hop (worm); return ACT_DELETE_HOP; } else { relink_hop (worm, table.nbi(choice)); return ACT_RELINK_HOP; } } else if (stat == CRASH) { remove (worm); return ACT_REMOVE_WORMS; } return ACT_NOTHING; }