def waves_particle_hole(config, m): m_ph = m.copy() m_ph[:m.shape[0] // 2, :m.shape[1] // 2] = models.apply_TBC( config, config.twist, deepcopy(m_ph[:m.shape[0] // 2, :m.shape[1] // 2]), inverse=False) m_ph[m.shape[0] // 2:, m.shape[1] // 2:] = -models.apply_TBC( config, config.twist, deepcopy(m_ph[m.shape[0] // 2:, m.shape[1] // 2:]).T, inverse=True) return m_ph
def __init__(self, config, K_up=None, K_down=None): self.config = config t = time() K_matrix_up = K_up if K_up is not None else models.apply_TBC( self.config, self.config.twist, deepcopy(self.config.K_0), inverse=False) K_matrix_down = K_down if K_down is not None else models.apply_TBC( self.config, self.config.twist, deepcopy(self.config.K_0).T, inverse=True) print('apply pbc takes {:.15f}'.format(time() - t)) self.edges_quadratic = scipy.linalg.block_diag(K_matrix_up, -K_matrix_down)
def test_BC_twist(config): twist = np.exp(2.0j * np.pi * np.random.uniform(0, 1, size=2)) print('Testing BC twist is invertable, with twist ' + str(twist), flush=True) for name, gap in zip(config.pairings_list_names, config.pairings_list_unwrapped): assert np.allclose(gap, models.apply_TBC(config, twist, models.apply_TBC(config, twist, deepcopy(gap), inverse = False), inverse=True)) print('Passed {:s}'.format(name)) twist_2 = np.exp(2.0j * np.pi * np.random.uniform(0, 1, size=2)) print('Testing BC twist is U(1) representation, with twists ' + str(twist) + ' ' + str(twist_2), flush=True) for name, gap in zip(config.pairings_list_names, config.pairings_list_unwrapped): assert np.allclose(models.apply_TBC(config, twist_2, models.apply_TBC(config, twist, deepcopy(gap), inverse = False), inverse=False), \ models.apply_TBC(config, twist, models.apply_TBC(config, twist_2, deepcopy(gap), inverse = False), inverse=False)) print('Passed {:s}'.format(name)) print('Passed', flush=True) return True
def test_FT_BC_twist(config): K0 = config.K_0 nbands = config.n_orbitals * config.n_sublattices for _ in range(100): #twist = np.array([0.5, 0.5]) # twist = np.random.uniform(0, 1, size=2) fft_plus = get_fft(config.Ls, nbands // 2, twist) fft_minus = get_fft(config.Ls, nbands // 2, np.array([-twist[0], -twist[1]])) K0_twisted = models.apply_TBC(config, np.exp(1.0j * 2.0 * np.pi * twist), deepcopy(K0), inverse = False) K0_twisted_plus = K0_twisted[np.arange(0, K0_twisted.shape[0], 2), :]; K0_twisted_plus = K0_twisted_plus[:, np.arange(0, K0_twisted.shape[0], 2)] K0_twisted_minus = K0_twisted[np.arange(1, K0_twisted.shape[0], 2), :]; K0_twisted_minus = K0_twisted_minus[:, np.arange(1, K0_twisted.shape[0], 2)] K0_twisted_plus = fft_plus.conj().T.dot(K0_twisted_plus.dot(fft_plus)) K0_twisted_minus = fft_minus.conj().T.dot(K0_twisted_minus.dot(fft_minus)) K0_check = K0_twisted_plus.copy() for i in range(K0.shape[0] // nbands): K0_check[i * nbands // 2:i * nbands // 2 + nbands // 2,i * nbands // 2:i * nbands // 2 + nbands // 2] = 0.0 if not np.isclose(np.sum(np.abs(K0_check)), 0.0): print('plus valley twist BC test failed with twist', twist) exit(-1) return False K0_check = K0_twisted_minus.copy() for i in range(K0.shape[0] // nbands): K0_check[i * nbands // 2:i * nbands // 2 + nbands // 2,i * nbands // 2:i * nbands // 2 + nbands // 2] = 0.0 if not np.isclose(np.sum(np.abs(K0_check)), 0.0): print('minus valley twist BC test failed with twist', twist) exit(-1) return False print('Passed', flush=True) return True
def get_kinetic_orbitals(config, filling): Ls = config.Ls K0 = config.K_0 assert config.twist_mesh == 'PBC' Tx, Ty = pairings.Tx_symmetry_map, pairings.Ty_symmetry_map C3z = np.argmax(np.abs(pairings.C3z_symmetry_map_chiral), axis=0) C2y = np.argmax(np.abs(pairings.C2y_symmetry_map_chiral), axis=0) tx, ty = [], [] for i in range(Tx.shape[0]): assert len(np.where(Tx[i, :] == 1)[0]) == 1 assert len(np.where(Ty[i, :] == 1)[0]) == 1 tx.append(np.where(Tx[i, :] == 1)[0][0]) ty.append(np.where(Ty[i, :] == 1)[0][0]) tx, ty = np.array(tx), np.array(ty) np.save('tx.npy', tx) np.save('ty.npy', ty) assert np.allclose(tx[ty], ty[tx]) tx_valley = tx[::2] // 2 ty_valley = ty[::2] // 2 assert np.allclose(tx_valley[ty_valley], ty_valley[tx_valley]) valley = np.concatenate( [np.array([2 * i + 1, 2 * i]) for i in range(config.Ls**2 * 2)]) path = '/home/astronaut/Documents/all_Imada_formats/' ########### writing the spin locations (none) ########## f = open(os.path.join(path, 'locspn_{:d}.def'.format(Ls)), 'w') f.write('================================\n') f.write('NlocalSpin 0\n') f.write('================================\n') f.write('========i_0LocSpn_1IteElc ======\n') f.write('================================\n') for i in range(Ls**2 * 4): f.write(' {:d} 0\n'.format(i)) f.close() symmetries = [np.arange(Ls**2 * 4)] ########### writing the translational symmetries ########## f = open(os.path.join(path, 'qptransidx_{:d}.def'.format(Ls)), 'w') f.write('=============================================\n') f.write('NQPTrans {:d}\n'.format(len(symmetries))) f.write('=============================================\n') f.write('======== TrIdx_TrWeight_and_TrIdx_i_xi ======\n') f.write('=============================================\n') for i in range(len(symmetries)): f.write('{:d} 1.00000\n'.format(i)) for i, symm in enumerate(symmetries): for i_from in range(symm.shape[0]): f.write(' {:d} {:d} {:d}\n'.format( i, i_from, symm[i_from])) f.close() from copy import deepcopy ########### writing the jastrows ########## all_translations = [np.arange(Ls**2 * 4)] curr_trans = tx.copy() all_new_translations = [] for kx in range(config.Ls - 1): new_translations = [symm[curr_trans] for symm in all_translations] all_new_translations.append(deepcopy(new_translations)) curr_trans = curr_trans[tx] for d in all_new_translations: all_translations += d curr_trans = ty.copy() all_new_translations = [] for kx in range(config.Ls - 1): new_translations = [symm[curr_trans] for symm in all_translations] all_new_translations.append(deepcopy(new_translations)) curr_trans = curr_trans[ty] for d in all_new_translations: all_translations += d f = open(os.path.join(path, 'jastrowidx_TRSbroken_{:d}.def'.format(Ls)), 'w') jastrow_ij, jastrow_k, n_jastrows, matrix_jastrows = get_jastrow_fromshift( all_translations, config.Ls, np.around(np.array(config.all_distances), decimals=5), dist_threshold=5.) np.save('check.npy', matrix_jastrows) # G) assert np.allclose(matrix_jastrows, matrix_jastrows.T) matrix_jastrows_trans = matrix_jastrows.copy() matrix_jastrows_trans = matrix_jastrows_trans[:, tx] matrix_jastrows_trans = matrix_jastrows_trans[tx, :] assert np.allclose(matrix_jastrows_trans, matrix_jastrows) matrix_jastrows_trans = matrix_jastrows.copy() matrix_jastrows_trans = matrix_jastrows_trans[:, ty] matrix_jastrows_trans = matrix_jastrows_trans[ty, :] assert np.allclose(matrix_jastrows_trans, matrix_jastrows) f.write('=============================================\n') f.write('NJastrowIdx {:d}\n'.format(n_jastrows + 1)) f.write('ComplexType {:d}\n'.format(0)) f.write('=============================================\n') f.write('=============================================\n') uniques = [] for i in range(config.Ls**2 * 4): for j in range(config.Ls**2 * 4): if i == j: continue f.write(' {:d} {:d} {:d}\n'.format( i, j, matrix_jastrows[i, j])) for i in range(n_jastrows + 1): f.write(' {:d} 1\n'.format(i)) f.close() f = open(os.path.join(path, 'InJastrow_TRSbroken_{:d}.def'.format(Ls)), 'w') f.write('======================\n') f.write('NJastrowIdx {:d}\n'.format(n_jastrows + 1)) f.write('======================\n') f.write('== i_j_JastrowIdx ===\n') f.write('======================\n') for i in range(n_jastrows): f.write('{:d} {:.10f} {:.10f}\n'.format(i, \ np.random.uniform(0.0, 1.0) * 0, np.random.uniform(0.0, 1.0) * 0)) f.write('{:d} {:.10f} {:.10f}\n'.format(n_jastrows, 0, 0)) f.close() f = open(os.path.join(path, 'gutzwilleridx_{:d}.def'.format(Ls)), 'w') f.write('=============================================\n') f.write('NGutzwillerIdx {:d}\n'.format(1)) f.write('ComplexType {:d}\n'.format(0)) f.write('=============================================\n') f.write('=============================================\n') for i in range(4 * Ls**2): f.write(' {:d} {:d}\n'.format(i, 0)) #idx)) for i in range(1): f.write(' {:d} 1\n'.format(i)) f.close() f = open(os.path.join(path, 'InGutzwiller.def'), 'w') f.write('======================\n') f.write('NGutzwillerIdx {:d}\n'.format(1)) f.write('======================\n') f.write('== i_j_GutzwillerIdx ===\n') f.write('======================\n') for i in range(1): f.write('{:d} {:.10f} {:.10f}\n'.format( i, np.random.uniform(0.0, 1.0) * 0, np.random.uniform(0.0, 1.0) * 0)) f.close() ########### writing the modpara ########## f = open(os.path.join(path, 'modpara_{:d}_{:d}.def'.format(Ls, filling)), 'w') f.write('--------------------\n') f.write('Model_Parameters 0\n') f.write('--------------------\n') f.write('VMC_Cal_Parameters\n') f.write('--------------------\n') f.write('CDataFileHead zvo\n') f.write('CParaFileHead zqp\n') f.write('--------------------\n') f.write('NVMCCalMode 0\n') f.write('--------------------\n') f.write('NDataIdxStart 1\n') f.write('NDataQtySmp 1\n') f.write('--------------------\n') f.write('Nsite {:d}\n'.format(Ls**2 * 4)) f.write('Ncond {:d}\n'.format(filling)) f.write('2Sz 0\n') f.write('NSPGaussLeg 8\n') f.write('NSPStot 0\n') f.write('NMPTrans {:d}\n'.format(1)) f.write('NSROptItrStep 400\n') f.write('NSROptItrSmp 40\n') f.write('DSROptRedCut 0.0000001000\n') f.write('DSROptStaDel 0.0200000000\n') f.write('DSROptStepDt 0.0000020000\n') f.write('NVMCWarmUp 400\n') f.write('NVMCInterval 1\n') f.write('NVMCSample 4000\n') f.write('NExUpdatePath 0\n') f.write('RndSeed 1\n') f.write('NSplitSize 1\n') f.write('NStore 0\n') f.write('NSRCG 1\n') f.close() twist = (0, 0.5) twist_exp = [ np.exp(2 * np.pi * 1.0j * twist[0]), np.exp(2 * np.pi * 1.0j * twist[1]) ] fft = get_fft_APBCy(config.Ls) for gap_idx in [40, 9, 36, 14]: #[0, 32, 43, 17, 11, 19]: # 40, 43, 9, 36[!!] print('gap_idx = ', gap_idx) #if config.idx_map[gap_idx] != 13: # continue for gap_val in [0.0, 0.003, 0.02]: #g = gap_val * np.load('the_wave_extended_{:d}.npy'.format(config.Ls)) g = gap_val * np.load( '/home/astronaut/Documents/DQMC_TBG/gaps_8x8/gap_{:d}.npy'. format(gap_idx)) # = gap_val * np.load('/home/astronaut/Documents/XQMC/gaps_6x6_extended/twist_0/gap_{:d}.npy'.format(gap_idx)) #gap_val * np.load('/home/astronaut/Documents/DQMC_TBG/gaps_8x8/gap_{:d}.npy'.format(gap_idx)) if config.Ls == 6: g = models.xy_to_chiral(g, 'pairing', config, True) TRS = np.concatenate( [np.array([2 * i + 1, 2 * i]) for i in range(g.shape[0] // 2)]) g_TRS = g[:, TRS] g_TRS = g_TRS[TRS, :] g = g + g_TRS # * (0.1 if gap_val == 0.02 else 1.) #np.save('sheck.npy', g) if gap_idx in [11, 19]: g = g / 1.0j # g = (g + g.conj()) / np.sqrt(2) print(g[0], 'g[0]') print(g[1], 'g[1]') assert np.allclose(g, g.T) swave = 1e-5 * models.xy_to_chiral( pairings.combine_product_terms( config, pairings.twoorb_hex_all[1]), 'pairing', config, True) assert np.allclose(swave, swave.T) print(swave[0], swave[1], 'swave in chiral basis') g = g + swave gap = models.apply_TBC(config, twist_exp, deepcopy(g), inverse=False) #np.save('the_wave_extended_twisted_{:d}.npy'.format(config.Ls), models.apply_TBC(config, twist_exp, deepcopy(np.load('the_wave_extended_{:d}.npy'.format(config.Ls))), inverse = False)) #exit(-1) gapT = models.apply_TBC(config, twist_exp, deepcopy(g).T, inverse=True) gap_fft = fft.T.conj().dot(gap).dot(fft) gap_check = gap_fft.copy() for i in range(gap_check.shape[0] // 4): #print(i % 4, i // 4) #(np.abs(np.linalg.eig(gap_check[i * 4:i * 4 + 4,i * 4:i * 4 + 4])[0]), i) # print(gap_check[i * 4:i * 4 + 4,i * 4:i * 4 + 4]) #assert np.allclose(gap_check[i * 4:i * 4 + 4,i * 4:i * 4 + 4], gap_check[i * 4:i * 4 + 4,i * 4:i * 4 + 4].conj().T) gap_check[i * 4:i * 4 + 4, i * 4:i * 4 + 4] = 0.0 assert np.isclose(np.sum(np.abs(gap_check)), 0.0) ############ determine required mu_BCS to start ################ K0_up = models.apply_TBC(config, twist_exp, deepcopy(K0), inverse=False) K0_down = models.apply_TBC(config, twist_exp, deepcopy(K0), inverse=True) K0_downT = models.apply_TBC(config, twist_exp, deepcopy(K0), inverse=True).T K0_upT = models.apply_TBC(config, twist_exp, deepcopy(K0), inverse=False).T #print('energies {:d}'.format(config.Ls), np.linalg.eigh(K0_up)[0]) #exit(-1) #### check twist is correct ### K0_fft_plus = fft.conj().T.dot(K0_up).dot(fft) K0_fft_minus = fft.T.dot(K0_up).dot(fft.conj()) K0_check = K0_fft_plus.copy() for i in range(K0_check.shape[0] // 4): K0_check[i * 4:i * 4 + 4, i * 4:i * 4 + 4] = 0.0 assert np.isclose(np.sum(np.abs(K0_check)), 0.0) K0_check = K0_fft_minus.copy() for i in range(K0_check.shape[0] // 4): K0_check[i * 4:i * 4 + 4, i * 4:i * 4 + 4] = 0.0 assert np.isclose(np.sum(np.abs(K0_check)), 0.0) assert np.allclose(K0_up, K0_up.conj().T) assert np.allclose(K0_down, K0_down.conj().T) L = K0.shape[0] totalM = np.zeros((4 * L, 4 * L), dtype=np.complex128) totalM[:L, :L] = K0_up totalM[L:2 * L, L:2 * L] = K0_down totalM[2 * L:3 * L, 2 * L:3 * L] = -K0_upT totalM[3 * L:, 3 * L:] = -K0_downT totalM[:L, 3 * L:] = gap totalM[L:2 * L, 2 * L:3 * L] = -gapT totalM[2 * L:3 * L, L:2 * L] = -gapT.conj().T totalM[3 * L:, :L] = gap.conj().T energies = np.linalg.eigh(totalM)[ 0] # energies with BC twist and gap #print(energies) mu_BCS = (energies[filling * 2] + energies[filling * 2 - 1]) / 2. print(energies[filling * 2], energies[filling * 2 - 1]) #assert not np.isclose(energies[filling * 2], energies[filling * 2 - 1]) print('mu_BCS = ', mu_BCS) K0_up = K0_up - np.eye(K0_up.shape[0]) * mu_BCS K0_upT = K0_upT - np.eye(K0_upT.shape[0]) * mu_BCS K0_down = K0_down - np.eye(K0_down.shape[0]) * mu_BCS K0_downT = K0_downT - np.eye(K0_downT.shape[0]) * mu_BCS L = K0.shape[0] totalM = np.zeros((4 * L, 4 * L), dtype=np.complex128) totalM[:L, :L] = K0_up totalM[L:2 * L, L:2 * L] = K0_down totalM[2 * L:3 * L, 2 * L:3 * L] = -K0_upT totalM[3 * L:, 3 * L:] = -K0_downT totalM[:L, 3 * L:] = gap totalM[L:2 * L, 2 * L:3 * L] = -gapT totalM[2 * L:3 * L, L:2 * L] = -gapT.conj().T totalM[3 * L:, :L] = gap.conj().T selected_idxs = np.concatenate( [np.arange(0, L), np.arange(3 * L, 4 * L)]) totalM_updown = totalM[:, selected_idxs] totalM_updown = totalM_updown[selected_idxs, ...] #totalM_updown = np.zeros((2 * L, 2 * L), dtype=np.complex128) #totalM_updown[:L, :L] = K0; totalM_updown[L:, L:] = -K0.T; #totalM_updown[:L, L:] = gap; totalM_updown[L:, :L] = gap.conj().T; selected_idxs = np.arange(L, 3 * L) totalM_downup = totalM[:, selected_idxs] totalM_downup = totalM_downup[selected_idxs, ...] TRS = np.concatenate([ np.array([2 * i + 1, 2 * i], dtype=np.int64) for i in range(L) ]) #totalM_downup = np.zeros((2 * L, 2 * L), dtype=np.complex128) #totalM_downup[:L, :L] = K0; totalM_downup[L:, L:] = -K0.T; #totalM_downup[:L, L:] = -gap.T; totalM_downup[L:, :L] = -gap.conj(); en_updown, W_updown = np.linalg.eigh(totalM_updown) totalM_updown_TRS = totalM_updown[TRS, ...] totalM_updown_TRS = totalM_updown_TRS[..., TRS] totalM_updown_TRS = totalM_updown_TRS.conj() print('after TRS, discrepancy', np.sum(np.abs(totalM_updown_TRS - totalM_updown))) en_downup, W_downup = np.linalg.eigh(totalM_downup) assert np.allclose(en_updown, np.sort(-en_updown)) assert np.allclose(en_downup, np.sort(-en_downup)) en_total, W = np.linalg.eigh(totalM) #print('energies with gap', gap_val, en_total) #print('updown energies', en_updown) #print('downup energies', en_downup) #for en, state in zip(en_downup, W_downup.T): # if np.abs(en + 0.03085819) < 1e-6: # print(en, state) #exit(-1) for i in range(W_updown.shape[1] // 2): v = W_updown[:, i] en = en_updown[i] v_conj = v * 0.0 v_conj[:len(v) // 2] = v[len(v) // 2:].conj() v_conj[len(v) // 2:] = v[:len(v) // 2].conj() en_conj = np.dot(v_conj.conj(), totalM_updown.dot(v_conj)) / np.dot( v_conj.conj(), v_conj) #print(en_conj, en, np.dot(v_conj.conj(), v_conj), np.dot(v.conj(), totalM_updown.dot(v))) #W_conj.append(v_conj) #assert np.isclose(en_conj, -en) #exit(-1) W_conj = [] for i in range(W.shape[1] // 2): v = W[:, i] en = en_total[i] v_conj = v * 0.0 v_conj[:len(v) // 2] = v[len(v) // 2:].conj() v_conj[len(v) // 2:] = v[:len(v) // 2].conj() en_conj = np.dot(v_conj.conj(), totalM.dot(v_conj)) #print(en_conj, en) W_conj.append(v_conj) assert np.isclose(en_conj, -en) W_conj = np.array(W_conj).T W[:, W.shape[1] // 2:] = W_conj # make the right form -- but this makes no difference: this is only rearrangement of 2nd part of the array, while we only use the 1st part # why W does not protect that block form? -- or do we even need this form? assert np.allclose( np.diag(W.conj().T.dot(totalM).dot(W)).real, np.diag(W.conj().T.dot(totalM).dot(W))) assert np.allclose( np.sort(np.diag(W.conj().T.dot(totalM).dot(W)).real), np.linalg.eigh(totalM)[0]) # with gap 6, W_pieces does not diagonalize totalM! why? W_pieces = np.zeros((4 * L, 4 * L), dtype=np.complex128) W_pieces[:L, :L] = W_updown[:L, :L] W_pieces[3 * L:, 3 * L:] = W_updown[L:, L:] W_pieces[3 * L:, :L] = W_updown[L:, :L] W_pieces[:L, 3 * L:] = W_updown[:L, L:] W_pieces[L:2 * L, L:2 * L] = W_downup[:L, :L] W_pieces[2 * L:3 * L, 2 * L:3 * L] = W_downup[L:, L:] W_pieces[2 * L:3 * L, L:2 * L] = W_downup[L:, :L] W_pieces[L:2 * L, 2 * L:3 * L] = W_downup[:L, L:] #assert np.allclose(np.sort(np.diag(W_pieces.conj().T.dot(totalM).dot(W_pieces)).real), np.sort(np.diag(W_pieces.conj().T.dot(totalM).dot(W_pieces)))) #assert np.isclose(np.sum(np.abs(W_pieces.conj().T.dot(totalM).dot(W_pieces) - np.diag(np.diag(W_pieces.conj().T.dot(totalM).dot(W_pieces))))), 0.0) assert np.isclose( np.sum( np.abs(W.conj().T.dot(totalM).dot(W) - np.diag(np.diag(W.conj().T.dot(totalM).dot(W))))), 0.0) #print(np.sort(np.diag(W.conj().T.dot(totalM).dot(W)).real) - np.sort(np.diag(W_pieces.conj().T.dot(totalM).dot(W_pieces)).real)) #assert np.allclose(np.sort(np.diag(W.conj().T.dot(totalM).dot(W)).real), \ # np.sort(np.diag(W_pieces.conj().T.dot(totalM).dot(W_pieces)).real)) #print(np.linalg.det(W_updown), np.linalg.det(W_downup), np.linalg.det(W_updown) * np.linalg.det(W_downup)) #print(np.linalg.det(W_pieces)) #print(np.linalg.det(W)) for i in range(W_updown.shape[1]): v = W_updown[:, i] en = en_updown[i] v_conj = v * 0.0 v_conj[:len(v) // 2] = v[len(v) // 2:].conj() v_conj[len(v) // 2:] = v[:len(v) // 2].conj() en_conj = np.dot(v_conj.conj(), totalM_updown.dot(v_conj)) # print(en_conj, en) #assert en_conj == -en mask = np.zeros((4 * L, 4 * L), dtype=np.complex128) mask[:L, :L] = np.ones((L, L)) mask[L:2 * L, L:2 * L] = np.ones((L, L)) mask[2 * L:3 * L, 2 * L:3 * L] = np.ones((L, L)) mask[3 * L:, 3 * L:] = np.ones((L, L)) mask[3 * L:, :L] = np.ones((L, L)) mask[2 * L:3 * L, L:2 * L] = np.ones((L, L)) mask[L:2 * L, 2 * L:3 * L] = np.ones((L, L)) mask[:L, 3 * L:] = np.ones((L, L)) #totalM[:L, :L] = K0; totalM[L:2 * L, L:2 * L] = K0; totalM[2 * L:3 * L, 2 * L:3 * L] = -K0.T; totalM[3 * L:, 3 * L:] = -K0.T #totalM[:L, 2 * L:3 * L] = gap; totalM[L: 2 * L, 3 * L:] = -gap.T; totalM[3 * L:, L: 2 * L] = -gap.conj(); totalM[2 * L:3 * L, :L] = gap.conj().T; assert np.allclose(totalM, totalM.conj().T) # W = np.linalg.eigh(totalM / 2.)[1] #print(np.linalg.eigh(totalM / 2.)[0]) #assert np.sum(np.abs(W - W * mask)) == 0 #assert np.allclose(W[:W.shape[0] // 2, :W.shape[0] // 2], W[W.shape[0] // 2:, W.shape[0] // 2:].conj()) #assert np.allclose(W[W.shape[0] // 2:, :W.shape[0] // 2], W[:W.shape[0] // 2, W.shape[0] // 2:].conj()) Q, V = W[:W.shape[0] // 2, :W.shape[0] // 2], \ W[W.shape[0] // 2:, :W.shape[0] // 2] Z = (Q.dot(np.linalg.inv(V))) print('max U^{-1} = ', np.max(np.abs(np.linalg.inv(Q))), gap_val, gap_idx) np.save('Z_fast.npy', Z) result = Z[Z.shape[0] // 2:, :Z.shape[0] // 2] Z = Z / np.max(np.abs(Z)) print( np.sum( np.abs(Z[Z.shape[0] // 2:, :Z.shape[0] // 2] + Z[:Z.shape[0] // 2, Z.shape[0] // 2:].T))) print( np.sum( np.abs( np.real(Z[Z.shape[0] // 2:, :Z.shape[0] // 2] + Z[:Z.shape[0] // 2, Z.shape[0] // 2:].T)))) print( np.sum( np.abs( np.imag(Z[Z.shape[0] // 2:, :Z.shape[0] // 2] + Z[:Z.shape[0] // 2, Z.shape[0] // 2:].T)))) assert np.allclose(Z[Z.shape[0] // 2:, :Z.shape[0] // 2], -Z[:Z.shape[0] // 2, Z.shape[0] // 2:].T) assert np.allclose(Z[Z.shape[0] // 2:, Z.shape[0] // 2:], Z[Z.shape[0] // 2:, Z.shape[0] // 2:] * 0.0) assert np.allclose(Z[:Z.shape[0] // 2, :Z.shape[0] // 2], Z[:Z.shape[0] // 2, :Z.shape[0] // 2] * 0.0) ##### preparing orbital idxs and teir initial values #### vol = 4 * Ls**2 orbital_idxs = -np.ones((vol, vol), dtype=np.int64) f_ij = result f_ij = f_ij / np.abs(np.max(f_ij)) np.save('f_ij_fast.npy', f_ij) current_orb_idx = 0 for xshift in range(Ls): for yshift in range(Ls): for iorb in range(4): for jorb in range(4): if yshift > 0: for ipos in range(Ls**2): i = ipos * 4 + iorb oi, si, xi, yi = models.from_linearized_index( i, config.Ls, config.n_orbitals, config.n_sublattices) j = models.to_linearized_index( (xi + xshift) % Ls, (yi + yshift) % Ls, jorb % 2, jorb // 2, Ls, 2, 2) if yi + yshift > Ls - 1: orbital_idxs[i, j] = current_orb_idx current_orb_idx += 1 for ipos in range(Ls**2): i = ipos * 4 + iorb oi, si, xi, yi = models.from_linearized_index( i, config.Ls, config.n_orbitals, config.n_sublattices) j = models.to_linearized_index( (xi + xshift) % Ls, (yi + yshift) % Ls, jorb % 2, jorb // 2, Ls, 2, 2) if yi + yshift <= Ls - 1: orbital_idxs[i, j] = current_orb_idx current_orb_idx += 1 print('FAST: orbitals after enforcing APBCy remaining:', current_orb_idx) for i in range(current_orb_idx): values = f_ij.flatten()[orbital_idxs.flatten() == i] assert np.isclose(np.std(values - values.mean()), 0.0) if np.allclose(f_ij, f_ij.T): print( 'FAST: symmetric f_ij = f_ji (singlet): restricting su(2) parameters' ) for i in range(vol): for j in range(vol): orb_ij = orbital_idxs[i, j] orb_ji = orbital_idxs[j, i] orbital_idxs[i, j] = np.min([orb_ij, orb_ji]) orbital_idxs[j, i] = np.min([orb_ij, orb_ji]) new_orbitals = np.unique(orbital_idxs.flatten()) mapping = list(np.sort(new_orbitals)) for i in range(vol): for j in range(vol): orbital_idxs[i, j] = mapping.index(orbital_idxs[i, j]) for i in range(len(mapping)): values = f_ij.flatten()[orbital_idxs.flatten() == i] assert np.isclose(np.std(values - values.mean()), 0.0) print('FAST: total orbitals su(2) with APBCy', len(mapping)) current_orb_idx = len(mapping) TRS = np.concatenate([[2 * i + 1, 2 * i] for i in range(vol // 2)]) f_trs = f_ij[:, TRS] f_trs = f_trs[TRS, :] if np.allclose(f_trs, f_ij): print('FAST: f_ij = TRS f_ij: resticting TRS parameters') for i in range(vol): for j in range(vol): orb_ij = orbital_idxs[i, j] i_trs = ((i // 2) * 2) + (((i % 2) + 1) % 2) j_trs = ((j // 2) * 2) + (((j % 2) + 1) % 2) orb_ij_trs = orbital_idxs[i_trs, j_trs] #print(f_ij[i, j], f_ij[i_trs, j_trs]) assert np.isclose(f_ij[i, j], f_ij[i_trs, j_trs]) orbital_idxs[i, j] = np.min([orb_ij, orb_ij_trs]) orbital_idxs[i_trs, j_trs] = np.min([orb_ij, orb_ij_trs]) #for i in range(current_orb_idx): # if np.sum(orbital_idxs.flatten() == i) == 0: # print('orbital', i, 'is missing') new_orbitals = np.unique(orbital_idxs.flatten()) mapping = list(np.sort(new_orbitals)) for i in range(vol): for j in range(vol): orbital_idxs[i, j] = mapping.index(orbital_idxs[i, j]) for i in range(len(mapping)): values = f_ij.flatten()[orbital_idxs.flatten() == i] assert np.isclose(np.std(values - values.mean()), 0.0) print('FAST: total orbitals su(2) with APBCy and TRS!', len(mapping) + 1) current_orb_idx = len(mapping) np.save('orbital_idxs_fast.npy', orbital_idxs) f = open( os.path.join( path, 'InOrbital_extended_{:d}_{:d}_{:d}_{:.4f}.def'.format( Ls, gap_idx, filling, gap_val)), 'w') f.write('======================\n') f.write('NOrbitalIdx {:d}\n'.format(current_orb_idx)) f.write('======================\n') f.write('== i_j_OrbitalIdx ===\n') f.write('======================\n') for k in range(current_orb_idx): mask = (orbital_idxs == k) val = np.sum(f_ij * mask) / np.sum(mask) f.write('{:d} {:.20f} {:.20f}\n'.format( k, val.real, val.imag)) f.close() ########### writing the orbitals indexes ########## f = open( os.path.join( path, 'orbitalidx_extended_{:d}_{:d}_{:d}.def'.format( Ls, gap_idx, filling)), 'w') f.write('=============================================\n') f.write('NOrbitalIdx {:d}\n'.format(current_orb_idx)) f.write('ComplexType {:d}\n'.format(1)) f.write('=============================================\n') f.write('=============================================\n') for i in range(config.Ls**2 * 4): for j in range(config.Ls**2 * 4): f.write(' {:d} {:d} {:d}\n'.format( i, j, orbital_idxs[i, j])) for i in range(current_orb_idx): f.write(' {:d} 1\n'.format(i)) f.close() twist_exp = [ np.exp(2.0j * np.pi * twist[0]), np.exp(2.0j * np.pi * twist[1]) ] K_0_twisted = models.apply_TBC(config, twist_exp, deepcopy(K0), inverse=False) ########### writing the K--matrix ########## K0_up_int = K0_up - np.diag(np.diag(K0_up)) K0_down_int = K0_down - np.diag(np.diag(K0_down)) f = open( os.path.join(path, 'trans_{:d}_{:.3f}_{:.3f}.def'.format(Ls, *twist)), 'w') f.write('========================\n') f.write('NTransfer {:d}\n'.format( 2 * np.sum(np.abs(K0_up_int) > 1e-7))) f.write('========================\n') f.write('========i_j_s_tijs======\n') f.write('========================\n') for i in range(K_0_twisted.shape[0]): for j in range(K_0_twisted.shape[1]): if np.abs(K0_up_int[i, j]) > 1e-7: f.write( ' {:d} 0 {:d} 0 {:.6f} {:.6f}\n'. format(i, j, np.real(-K0_up_int[i, j]), np.imag(-K0_up_int[i, j]))) f.write( ' {:d} 1 {:d} 1 {:.6f} {:.6f}\n'. format(i, j, np.real(-K0_down_int[i, j]), np.imag(-K0_down_int[i, j]))) f.close() return
def run_simulation(delta_reg, previous_params): config_vmc_file = import_config(sys.argv[1]) config_vmc_import = config_vmc_file.MC_parameters(int(sys.argv[2]), int(sys.argv[3]), rank) config_vmc = cv_module.MC_parameters(int(sys.argv[2]), int(sys.argv[3]), rank) config_vmc.__dict__ = config_vmc_import.__dict__.copy() print_model_summary(config_vmc) if previous_params is not None: config_vmc.initial_parameters = previous_params config_vmc.workdir = config_vmc.workdir + '/irrep_{:d}_Ne_{:d}/'.format( rank, int(sys.argv[3])) os.makedirs(config_vmc.workdir, exist_ok=True) with open(os.path.join(config_vmc.workdir, 'config.py'), 'w') as target, \ open(sys.argv[1], 'r') as source: # save config file to workdir (to remember!!) target.write(source.read()) if config_vmc.visualisation: # config_vmc.twist = [np.exp(2.0j * np.pi * 0.1904), np.exp(2.0j * np.pi * (0.1904 + 0.1))] visualisation.plot_levels_evolution_mu(config_vmc) visualisation.plot_all_waves(config_vmc) visualisation.plot_DOS(config_vmc) visualisation.plot_fermi_surface(config_vmc) visualisation.plot_all_waves(config_vmc) visualisation.plot_all_Jastrow(config_vmc) visualisation.plot_MF_spectrum_profile(config_vmc) config_vmc.twist = [ 1, 1 ] #[np.exp(2.0j * np.pi * 0.1904), np.exp(2.0j * np.pi * (0.1904 + 0.10))] if config_vmc.tests: if rank == 0: if tests.perform_all_tests(config_vmc): print('\033[92m All tests passed successfully \033[0m', flush=True) else: print('\033[91m Warning: some of the tests failed! \033[0m', flush=True) comm.Barrier() n_cpus_max = psutil.cpu_count(logical=True) print('max available CPUs:', n_cpus_max) n_cpus = config_vmc.n_cpus if config_vmc.n_cpus == -1: n_cpus = n_cpus_max print('performing simulation at', n_cpus, 'CPUs') ### generate twists once and for all (Sandro's suggestion) ### if config_vmc.twist_mesh == 'Baldereschi': print('Working with the Baldereschi mesh') if config_vmc.n_sublattices == 2: twists = [[ np.exp(2.0j * np.pi * 0.1904), np.exp(2.0j * np.pi * (0.1904 + 0.1)) ] for _ in range(config_vmc.n_chains)] if config_vmc.n_sublattices == 1: twists = [[1., -1.] for _ in range(config_vmc.n_chains)] # FIXME twists_per_cpu = config_vmc.n_chains / n_cpus elif config_vmc.twist_mesh == 'PBC': twists = [[1., 1.] for _ in range(config_vmc.n_chains)] twists_per_cpu = config_vmc.n_chains / n_cpus elif config_vmc.twist_mesh == 'APBCy': twists = [[1., -1.] for _ in range(config_vmc.n_chains)] twists_per_cpu = config_vmc.n_chains / n_cpus elif config_vmc.twist_mesh == 'reals': assert config_vmc.n_chains == 4 twists = [[1, 1], [1, -1], [-1, 1], [-1, -1]] twists_per_cpu = config_vmc.n_chains / n_cpus assert twists_per_cpu == 1 elif config_vmc.twist_mesh == 'uniform': L = config_vmc.L_twists_uniform twists = [] for i_x in range(L): for i_y in range(L): twists.append([ np.exp(1.0j * np.pi * (-1. + 1. / L + 2. * i_x / L)), np.exp(1.0j * np.pi * (-1. + 1. / L + 2. * i_y / L)) ]) twists_per_cpu = len(twists) // n_cpus if twists_per_cpu * n_cpus < len(twists): twists_per_cpu += 1 else: print('Twist {:s} is not supported'.format(config_vmc.twist_mesh)) exit(-1) print(twists) print( 'Number of twists: {:d}, number of chains {:d}, twists per cpu {:2f}'. format(len(twists), config_vmc.n_chains, twists_per_cpu)) K_matrices_up = [ models.apply_TBC(config_vmc, twist, deepcopy(config_vmc.K_0), inverse=False) for twist in twists ] print(repr(K_matrices_up[0])) print(config_vmc.K_0) #exit(-1) K_matrices_down = [ models.apply_TBC(config_vmc, twist, deepcopy(config_vmc.K_0).T, inverse=True) for twist in twists ] reg_terms = [models.apply_TBC(config_vmc, twist, deepcopy(config_vmc.reg_gap_term), inverse = False) * \ config_vmc.reg_gap_val for twist in twists] config_vmc.MC_chain = config_vmc.MC_chain // len( twists) # the MC_chain contains the total required number of samples pairings_list = config_vmc.pairings_list pairings_names = config_vmc.pairings_list_names # template = 'e_{:.2f}_Ne_{:d}'.format(config_vmc.epsilon, config_vmc.Ne) if config_vmc.PN_projection else \ # 'e_{:.2f}_mu_{:.2f}'.format(config_vmc.epsilon, config_vmc.mu) local_workdir = config_vmc.workdir obs_files = [] loaded_from_external = False if config_vmc.load_parameters: if config_vmc.load_parameters_path is not None: loaded_from_external = True filename = config_vmc.load_parameters_path parameters, last_step = load_parameters(filename) elif os.path.isfile(os.path.join(local_workdir, 'last_opt_params.p')): filename = os.path.join(local_workdir, 'last_opt_params.p') parameters, last_step = load_parameters(filename) else: parameters = config_vmc.initial_parameters last_step = 0 else: parameters = config_vmc.initial_parameters last_step = 0 if config_vmc.condensation_energy_check_regime: parameters[config_vmc.layout[:3].sum():config_vmc.layout[:4].sum( )] = 0. log_file = open(os.path.join(local_workdir, 'general_log.dat'), 'a+') force_file = open(os.path.join(local_workdir, 'force_log.dat'), 'a+') gaps_file = open(os.path.join(local_workdir, 'gaps_log.dat'), 'a+') force_SR_file = open(os.path.join(local_workdir, 'force_SR_log.dat'), 'a+') spectral_file = open(os.path.join(local_workdir, 'spectral_log.dat'), 'a+') final_states = [False] * len(twists) orbitals_in_use = [None] * len(twists) ### write log header only if we start from some random parameters ### if last_step == 0 or loaded_from_external: write_initial_logs(log_file, force_file, force_SR_file, config_vmc) #for n_step in range(last_step, config_vmc.optimisation_steps): n_step = last_step while n_step < config_vmc.optimisation_steps: t = time() if twists_per_cpu > 1: with parallel_backend("loky", inner_max_num_threads=1): results_batched = Parallel(n_jobs=n_cpus)(delayed(get_MC_chain_result)( \ n_step, \ deepcopy(config_vmc), \ pairings_list, \ parameters, \ twists = twists[i * twists_per_cpu:np.min([(i + 1) * twists_per_cpu, len(twists)])], \ final_states = final_states[i * twists_per_cpu:np.min([(i + 1) * twists_per_cpu, len(twists)])], \ orbitals_in_use = orbitals_in_use[i * twists_per_cpu:np.min([(i + 1) * twists_per_cpu, len(twists)])], \ K_matrices_up = K_matrices_up[i * twists_per_cpu:np.min([(i + 1) * twists_per_cpu, len(twists)])], \ K_matrices_down = K_matrices_down[i * twists_per_cpu:np.min([(i + 1) * twists_per_cpu, len(twists)])], \ regs = reg_terms[i * twists_per_cpu:np.min([(i + 1) * twists_per_cpu, len(twists)])], \ ) for i in range(n_cpus)) #for i in range(n_cpus): # print(i * twists_per_cpu, np.min([(i + 1) * twists_per_cpu, len(twists)])) results = [] for i, r in enumerate(results_batched): results = results + r print('obtained {:d} results from {:d} cpu'.format( len(r), i)) print('obtained in total {:d} results'.format(len(results))) #print(len(twists)) else: with parallel_backend("loky", inner_max_num_threads=1): results = Parallel(n_jobs=config_vmc.n_chains)(delayed(_get_MC_chain_result)( \ n_step, \ deepcopy(config_vmc), \ pairings_list, \ parameters, \ twists[i], \ final_states[i], \ orbitals_in_use[i], \ K_matrices_up[i], \ K_matrices_down[i], \ reg_terms[i], \ ) for i in range(config_vmc.n_chains)) print('MC chain generationof {:d} no {:d} took {:f}'.format( rank, n_step, time() - t)) t = time() ### print-out current energy levels ### E = results[0][7] spectral_file.write( str(n_step) + ' ' + ("{:.7f} " * len(E) + '\n').format(*E)) spectral_file.flush() ### MC chains data extraction ### gaps, gap, energies, mean_variance, Os, acceptance, \ final_states, densities, orbitals_in_use, occupied_numbers = \ extract_MC_data(results, config_vmc, config_vmc.n_chains) energies_merged = np.concatenate(energies) n_above_FS = len( np.setdiff1d(occupied_numbers[0], np.arange(config_vmc.total_dof // 2))) ### gradient step ### if config_vmc.generator_mode: # evolve parameters only if it's necessary mask = np.ones(np.sum(config_vmc.layout)) factor_stages = 1 if n_step < 100: # jastrows and mu_BCS have not converged yet mask = np.zeros(np.sum(config_vmc.layout)) mask[-config_vmc.layout[4]:] = 1. factor_stages = 30. # # mask[:config_vmc.layout[0]] = 1. # mask[config_vmc.layout[0] + config_vmc.layout[1] + config_vmc.layout[2]:config_vmc.layout[0] + \ # config_vmc.layout[1] + config_vmc.layout[2] + config_vmc.layout[3]] = 0. #mask[1] = 0.0 # fugacity is not optimized in the meantime # Os = [np.einsum('ik,k->ik', Os_theta, config_vmc.mask) for Os_theta in Os] step, forces = make_SR_step(Os, energies, config_vmc, twists, gaps, n_step, mask) write_intermediate_log(log_file, force_file, force_SR_file, n_step, config_vmc.total_dof // 2, energies, densities, \ mean_variance, acceptance, forces, step, gap, n_above_FS, parameters) # write parameters before step not to lose the initial values write_gaps_log(gaps_file, gaps, n_step) #if np.abs(gap) < 1e-4: # if the gap is too small, SR will make gradient just 0 # step = forces #step = forces * config_vmc.opt_parameters[1] step = step * config_vmc.opt_parameters[1] #step = clip_forces(config_vmc.all_clips, step) parameters += step * mask * factor_stages # lr better be ~0.01..0.1 #if parameters[0] < config_vmc.mu_BCS_min: # parameters[0] = config_vmc.mu_BCS_min #if parameters[0] > config_vmc.mu_BCS_max: # parameters[0] = config_vmc.mu_BCS_max save_parameters(parameters, config_vmc.workdir, n_step) ### END SR STEP ### observables = np.concatenate([np.array(x[4]) for x in results], axis=0) observables_names = results[0][5] n_step += 1 if len(observables_names) == 0: continue if n_step == config_vmc.thermalization + 1: create_obs_files(observables_names, config_vmc) write_observables(n_step, obs_files, observables, config_vmc) if rank == 0: print('SR and logging {:d} took {:f}'.format(n_step, time() - t)) log_file.close() force_file.close() force_SR_file.close() spectral_file.close() [file.close() for file in obs_files] return parameters
def select_initial_muBCS_Koshino(self, Ne, parameters=[]): if len(parameters) == 0: parameters = self.initial_parameters #_, _, waves, gap, _ = self.unpack_parameters(parameters, mode_setting = True) # T = wfv.construct_HMF(self, self.K_0, self.K_0.T, self.pairings_list_unwrapped, gap, waves, self.reg_gap_term) # assert np.allclose(T, T.conj().T) if self.twist_mesh == 'Baldereschi': twist = [ np.exp(2.0j * np.pi * 0.1904), np.exp(2.0j * np.pi * (0.1904 + 0.1)) ] elif self.twist_mesh == 'APBCy': twist = [1, -1] else: twist = [1, 1] #twist = [1.0j, -1.0j] print(twist) #if twist[0] != 1 or twist[1] != 1: K_0_twisted = models.apply_TBC(self, twist, deepcopy(self.K_0), inverse=False) energies = np.linalg.eigh(K_0_twisted)[0] #print(energies) print(twist) print( 'energy_free_theory = ', np.sum( np.sort(energies)[:self.total_dof // 2 // 2] * 2 / (self.total_dof // 2))) assert np.allclose(K_0_twisted, K_0_twisted.T.conj()) print('energy_free_theory = ', np.sum(energies[:self.Ne // 2] * 2) / 16.) K_0_twisted_holes = -models.apply_TBC( self, twist, deepcopy(self.K_0).T, inverse=True) assert np.allclose(K_0_twisted, K_0_twisted.conj().T) assert np.allclose(K_0_twisted_holes, K_0_twisted_holes.conj().T) assert np.allclose( np.linalg.eigh(K_0_twisted_holes)[0], np.sort(-np.linalg.eigh(K_0_twisted)[0])) for i in range(K_0_twisted.shape[0]): for j in range(K_0_twisted.shape[1]): if (i + j) % 2 == 1 and np.abs(K_0_twisted[i, j]) > 1e-12: print(i, j) exit(-1) # chiral basis check failed K_0_plus = K_0_twisted[:, np.arange(0, self.total_dof // 2, 2)] K_0_plus = K_0_plus[np.arange(0, self.total_dof // 2, 2), :] K_0_minus = K_0_twisted[:, np.arange(1, self.total_dof // 2, 2)] K_0_minus = K_0_minus[np.arange(1, self.total_dof // 2, 2), :] assert np.allclose(np.conj(K_0_plus), K_0_minus) print(np.linalg.eigh(K_0_plus)[0]) print(np.linalg.eigh(K_0_minus)[0]) # K_0_plus_holes = K_0_twisted_holes[:, np.arange(0, self.total_dof // 2, 2)] K_0_plus_holes = K_0_plus_holes[np.arange(0, self.total_dof // 2, 2), :] K_0_minus_holes = K_0_twisted_holes[:, np.arange(1, self.total_dof // 2, 2)] K_0_minus_holes = K_0_minus_holes[np.arange(1, self.total_dof // 2, 2), :] #print(np.linalg.eigh(K_0_plus)[0] - np.sort(-np.linalg.eigh(K_0_minus_holes)[0])) assert np.allclose( np.linalg.eigh(K_0_plus)[0], np.sort(-np.linalg.eigh(K_0_minus_holes)[0])) assert np.allclose( np.linalg.eigh(K_0_minus)[0], np.sort(-np.linalg.eigh(K_0_plus_holes)[0])) #exit(-1) nu = self.valley_imbalance // 4 delta = (self.total_dof // 2 - Ne) // 4 Ep, _ = np.linalg.eigh(K_0_plus) # particle energies Ep = np.sort(Ep) Em, _ = np.linalg.eigh(K_0_minus) # particle energies Em = np.sort(Em) N_particles_plus_below = np.sum( Ep < 0) # current number of + particle energies below zero xi = N_particles_plus_below - ( self.total_dof // 8 - delta + nu ) # this many levels must be put up above FS print('xi_plus = {:d}'.format(xi)) dEp = (Ep[N_particles_plus_below - xi - 1] * 0.5 + Ep[N_particles_plus_below - xi] * 0.5) / 1 mu_BCS_min = (Ep[N_particles_plus_below - xi - 1] * 0.999 + Ep[N_particles_plus_below - xi] * 0.001) mu_BCS_max = (Ep[N_particles_plus_below - xi - 1] * 0.001 + Ep[N_particles_plus_below - xi] * 0.999) print(Ep, Ep[N_particles_plus_below - xi - 1], Ep[N_particles_plus_below - xi]) print('initial mu_BCS = {:.10f}'.format(dEp)) #exit(-1) print('N_particles_plus_below before = {:d}'.format( N_particles_plus_below)) #print(Ep) #print('N_holes_minus_below before = {:d}'.format(np.sum(np.linalg.eigh(K_0_minus_holes)[0] < 0))) Ep, _ = np.linalg.eigh( K_0_plus - np.eye(K_0_plus.shape[0]) * dEp) # particle energies N_particles_plus_below = np.sum( Ep < 0) # number after proper mu_BCS subtraction print('N_particles_plus_below after = {:d}'.format( N_particles_plus_below)) #print('N_holes_minus_below after = {:d}'.format(np.sum(np.linalg.eigh(K_0_minus_holes + np.eye(K_0_plus.shape[0]) * dEp)[0] < 0))) # print('holes', np.linalg.eigh(-K_0_plus_holes.T + np.eye(K_0_plus.shape[0]) * dEp)[0]) # print('particles', Ep) #N_particles_minus_below = np.sum(Em < 0) # current number of + particle energies below zero #xi = N_particles_minus_below - (self.total_dof // 8 - delta - nu) # this many levels must be put up above FS #dEm = (Em[N_particles_minus_below - xi - 1] * 0.49 + Em[N_particles_minus_below - xi] * 0.51) / 1 #print(Em, Em[N_particles_minus_below - xi - 1], Em[N_particles_minus_below - xi]) #print('initial mu_BCS_2 = {:.10f}'.format(dEm)) #print('N_particles_minus_below before = {:d}'.format(N_particles_minus_below)) #print('N_holes_minus_below before = {:d}'.format(np.sum(np.linalg.eigh(K_0_plus_holes)[0] < 0))) #Em, _ = np.linalg.eigh(K_0_minus - np.eye(K_0_minus.shape[0]) * dEm) # particle energies #N_particles_minus_below = np.sum(Em < 0) # number after proper mu_BCS subtraction #print('N_particles_minus_below after = {:d}'.format(N_particles_minus_below)) #print('N_holes_plus_below after = {:d}'.format(np.sum(np.linalg.eigh(K_0_plus_holes + np.eye(K_0_minus.shape[0]) * dEm)[0] < 0))) #print('!!!!', np.sort(np.concatenate([Em, Ep]))) #print('but I wanted particles_+ {:d}, holes_+ {:d}, particles_-{:d}, holes_- {:d}'.format(self.total_dof // 8 - delta + nu, self.total_dof // 8 + delta - nu, self.total_dof // 8 - delta - nu, self.total_dof // 8 + delta + nu)) print(dEp) return dEp, mu_BCS_min, mu_BCS_max
#assert config.mu == 0 #assert np.allclose(K_matrix.imag, K_matrix * 0.) assert np.allclose(K_matrix, K_matrix.conj().T) K_matrix = -K_matrix # this is to agree with ED, this is just unitary transform in terms of particle-hole transformation print(repr(K_matrix)) energies = np.linalg.eigh(K_matrix)[0] print(energies) print(np.sum(energies[energies < 0]) / 16.) K_matrix = models.apply_TBC(config, twist, deepcopy(K_matrix), inverse=False) config.pairings_list_unwrapped = [ models.apply_TBC(config, twist, deepcopy(gap), inverse=False) for gap in config.pairings_list_unwrapped ] ### creating precomputed exponents ### K_operator = scipy.linalg.expm(config.dt * K_matrix) K_operator_inverse = scipy.linalg.expm(-config.dt * K_matrix) assert np.allclose(np.linalg.inv(K_operator), K_operator_inverse) K_operator_half = scipy.linalg.expm(0.5 * config.dt * K_matrix) K_operator_half_inverse = scipy.linalg.expm(-0.5 * config.dt * K_matrix) local_workdir = config.workdir #,#os.path.join(config.workdir, 'U_{:.2f}_V_{:.2f}_mu_{:.2f}_Nt_{:d}_c_{:d}'.format(U, V, mu, int(Nt), rank + config.offset))
def get_MFH(config, mu_given=None, gap_given=None, only_free=False): K_up = config.model(config, config.mu, spin=+1.0)[0] K_up = models.xy_to_chiral(K_up, 'K_matrix', config, config.chiral_basis) K_up = models.apply_TBC(config, config.twist, deepcopy(K_up), inverse=False) K_down = config.model(config, config.mu, spin=-1.0)[0].T K_down = models.xy_to_chiral(K_down, 'K_matrix', config, config.chiral_basis) K_down = models.apply_TBC(config, config.twist, deepcopy(K_down), inverse=True) mu, fugacity, waves, gap, jastrow = config.unpack_parameters( config.initial_parameters) C2y = pairings.C2y_symmetry_map_chiral C2y = np.kron(np.eye(2), C2y) C3z = pairings.C3z_symmetry_map_chiral C3z = np.kron(np.eye(2), C3z) if mu_given is not None: Deltas_twisted = [ models.apply_TBC(config, config.twist, deepcopy(gap), inverse=False) for gap in config.pairings_list_unwrapped ] Delta = pairings.get_total_pairing_upwrapped(config, Deltas_twisted, gap) reg = models.apply_TBC( config, config.twist, deepcopy( config.reg_gap_term), inverse=False) * config.reg_gap_val Ts = [] for dmu in mu_given: T = scipy.linalg.block_diag( K_up - np.eye(K_up.shape[0]) * (mu + dmu), -(K_down - np.eye(K_down.shape[0]) * (mu + dmu))) + 0.0j T[:config.total_dof // 2, config.total_dof // 2:] = Delta + reg T[config.total_dof // 2:, :config.total_dof // 2] = Delta.conj().T + reg.conj().T Ts.append(T.copy() * 1.) Deltaonly = T * 0.0 Deltaonly[:config.total_dof // 2, config.total_dof // 2:] = Delta Deltaonly[config.total_dof // 2:, :config.total_dof // 2] = Delta.conj().T eigenvalues, eigenvectors = np.linalg.eigh(Ts[-1]) idxs = np.argsort(np.abs(eigenvalues))[:2] # print(eigenvalues[idxs]) vplus = eigenvectors[:, idxs[0]] vminus = eigenvectors[:, idxs[1]] print(np.dot(vplus.conj(), C3z.dot(vplus))) print(np.dot(vminus.conj(), C3z.dot(vminus))) #print(C3z.shape) #print(Deltaonly.shape) print(np.trace(Delta.T.conj().dot(pairings.C3z_symmetry_map_chiral.dot(Delta.dot(pairings.C3z_symmetry_map_chiral.T)))) \ / np.trace(np.dot(Delta, Delta.conj().T))) print(np.abs(np.dot(vplus.conj(), np.dot(Deltaonly, vminus))), np.abs(np.dot(vplus.conj(), vminus)), eigenvalues[idxs], idxs, dmu, \ np.trace(np.dot(Deltaonly, Deltaonly.T.conj()))) #exit(-1) return Ts K_up -= np.eye(K_up.shape[0]) * mu K_down -= np.eye(K_down.shape[0]) * mu T = scipy.linalg.block_diag(K_up, -K_down) + 0.0j if only_free: return T if gap_given is None: Delta = pairings.get_total_pairing_upwrapped( config, config.pairings_list_unwrapped, gap) T[:config.total_dof // 2, config.total_dof // 2:] = Delta T[config.total_dof // 2:, :config.total_dof // 2] = Delta.conj().T return T else: Ts = [] Delta = pairings.get_total_pairing_upwrapped( config, config.pairings_list_unwrapped, [1]) for gap in gap_given: T_gap = T.copy() * 1.0 T_gap[:config.total_dof // 2, config.total_dof // 2:] = Delta * gap T_gap[config.total_dof // 2:, :config.total_dof // 2] = Delta.conj().T * gap Ts.append(T_gap.copy() * 1.0) return Ts