diff --git a/my_pyscf/lassi/lassis.py b/my_pyscf/lassi/lassis.py index 3418c2c9..613604e9 100644 --- a/my_pyscf/lassi/lassis.py +++ b/my_pyscf/lassi/lassis.py @@ -12,6 +12,11 @@ def prepare_states (lsi, nmax_charge=0, sa_heff=True, deactivate_vrv=False, cras las = lsi._las las1 = spin_shuffle (las) las1.ci = spin_shuffle_ci (las1, las1.ci) + log = logger.new_logger (lsi, lsi.verbose) + log.info ("LASSIS reference spaces: 0-%d", las1.nroots-1) + for ix, (c, m, s, w) in enumerate (zip (*get_space_info (las1))): + log.info ("Reference space %d:", ix) + SingleLASRootspace (las1, m, s, c, 0).table_printlog () # TODO: make states_energy_elec capable of handling lroots and address inconsistency # between definition of e_states array for neutral and charge-separated rootspaces las1.e_states = las1.energy_nuc () + np.array (las1.states_energy_elec ()) @@ -41,12 +46,23 @@ def single_excitations_ci (lsi, las2, las1, nmax_charge=0, sa_heff=True, deactiv h0, h1, h2 = lsi.ham_2q () t0 = (logger.process_clock (), logger.perf_counter ()) converged = True + log.info ("LASSIS electron hop spaces: %d-%d", las1.nroots, las2.nroots-1) for i in range (las1.nroots, las2.nroots): psref = [] ciref = [[] for j in range (nfrags)] excfrags = np.zeros (nfrags, dtype=bool) + log.info ("Electron hop space %d:", i) + spaces[i].table_printlog () + log.info ("is connected to reference spaces:") for j in range (las1.nroots): if not spaces[i].is_single_excitation_of (spaces[j]): continue + src_frag = np.where ((spaces[i].nelec-spaces[j].nelec)==-1)[0][0] + dest_frag = np.where ((spaces[i].nelec-spaces[j].nelec)==1)[0][0] + e_spin = 'a' if np.any (spaces[i].neleca!=spaces[j].neleca) else 'b' + src_ds = 'u' if spaces[i].smults[src_frag]>spaces[j].smults[src_frag] else 'd' + dest_ds = 'u' if spaces[i].smults[dest_frag]>spaces[j].smults[dest_frag] else 'd' + log.info ('%d: %d(%s) --%s--> %d(%s)', j, src_frag, src_ds, e_spin, + dest_frag, dest_ds) excfrags[spaces[i].excited_fragments (spaces[j])] = True psref.append (psrefs[j]) for k in range (nfrags): diff --git a/my_pyscf/lassi/states.py b/my_pyscf/lassi/states.py index 33b3b738..da822130 100644 --- a/my_pyscf/lassi/states.py +++ b/my_pyscf/lassi/states.py @@ -3,6 +3,7 @@ from pyscf.fci import cistring from pyscf.lib import logger from pyscf.lo.orth import vec_lowdin +from pyscf import symm from mrh.my_pyscf.fci.spin_op import contract_sdown, contract_sup from mrh.my_pyscf.fci.csfstring import CSFTransformer from mrh.my_pyscf.fci.csfstring import ImpossibleSpinError @@ -219,6 +220,20 @@ def excited_fragments (self, other): idx_same = (dneleca==0) & (dnelecb==0) & (dsmults==0) return ~idx_same + def table_printlog (self): + log = logger.new_logger (self, self.verbose) + fmt_str = " {:4s} {:>11s} {:>4s} {:>3s}" + header = fmt_str.format ("Frag", "Nelec,Norb", "2S+1", "Ir") + log.info (header) + fmt_str = " {:4d} {:>11s} {:>4d} {:>3s}" + for ifrag in range (self.nfrag): + na, nb = self.neleca[ifrag], self.nelecb[ifrag] + sm, no = self.smults[ifrag], self.nlas[ifrag] + irid = 0 # TODO: symmetry + nelec_norb = '{}a+{}b,{}o'.format (na,nb,no) + irname = symm.irrep_id2name (self.las.mol.groupname, irid) + log.info (fmt_str.format (ifrag, nelec_norb, sm, irname)) + def all_single_excitations (las, verbose=None): '''Add states characterized by one electron hopping from one fragment to another fragment in all possible ways. Uses all states already present as reference states, so that calling