def __init__(self, *args, op_label='c', part_orb=(Range('V', 0, Symbol('nv')), DEFAULT_PART_DUMMS), actv_orb=(Range('A', 0, Symbol('na')), DEFAULT_ACTV_DUMMS), hole_orb=(Range('O', 0, Symbol('no')), DEFAULT_HOLE_DUMMS), all_orb_dumms=DEFAULT_ORB_DUMMS, spin=(), one_body=IndexedBase('h'), two_body=IndexedBase('v'), fock=IndexedBase('f'), rdm=IndexedBase('g'), rdm_max_order=4, dbbar=True, **kwargs): ''' drudge.PartHoleDrudge.__init__ is too complicated for me to call and modify it straightforwardly. ''' self.part_range = part_orb[0] self.actv_range = actv_orb[0] self.hole_range = hole_orb[0] ''' I hope this calls drudge.GenMBDrudge.__init__ ''' super(PartHoleDrudge, self).__init__(*args, exch=FERMI, op_label=op_label, orb=(part_orb, actv_orb, hole_orb), spin=spin, one_body=one_body, two_body=two_body, dbbar=dbbar, **kwargs) self.all_orb_dumms = tuple(all_orb_dumms) self.set_name(*self.all_orb_dumms) self.add_resolver({ i: (self.part_range, self.actv_range, self.hole_range) for i in all_orb_dumms }) self.set_rdm (rdm, rdm_max_order, dbbar) self.set_name(no=self.hole_range.size) self.set_name(na=self.actv_range.size) self.set_name(nv=self.part_range.size) self.set_tensor_method('eval_wev', self.eval_wev) self.set_tensor_method('eval_awev', self.eval_awev) self.fock = fock
def __init__( self, *args, spin_range=Range(r'\uparrow\downarrow', 0, 2), spin_dumms=tuple(Symbol('sigma{}'.format(i)) for i in range(50)), **kwargs ): """Initialize the restricted particle-hole drudge.""" super().__init__( *args, spin=(spin_range, spin_dumms), **kwargs ) self.add_resolver({ UP: spin_range, DOWN: spin_range }) self.spin_range = spin_range self.spin_dumms = self.dumms.value[spin_range] sigma = self.dumms.value[spin_range][0] p = Symbol('p') q = Symbol('q') self.e_ = TensorDef(Vec('E'), (p, q), self.sum( (sigma, spin_range), self.cr[p, sigma] * self.an[q, sigma] )) self.set_name(e_=self.e_)
def __init__( self, *args, part_orb=( Range('V', 0, Symbol('nv')), PartActvHoleDrudge.DEFAULT_PART_DUMMS + symbols('beta gamma') ), actv_orb=( Range('A', 0, Symbol('na')), PartActvHoleDrudge.DEFAULT_ACTV_DUMMS + symbols('mu nu') ), hole_orb=( Range('O', 0, Symbol('no')), PartActvHoleDrudge.DEFAULT_HOLE_DUMMS + symbols('delta epsilon') ), spin=(UP, DOWN), **kwargs ): """Initialize the particle-hole drudge.""" super().__init__( *args, spin=spin, dbbar=False, part_orb=part_orb, actv_orb=actv_orb, hole_orb=hole_orb, **kwargs )
def __init__(self, ctx, all_orb_range=Range('A', 0, Symbol('na')), all_orb_dumms=PartHoleDrudge.DEFAULT_ORB_DUMMS, energies=IndexedBase(r'\epsilon'), interact=IndexedBase('G'), uga=DEFAULT_GEN, **kwargs): """Initialize the drudge object.""" # Initialize the base su2 problem. super().__init__(ctx, **kwargs) # Set the range and dummies. # self.add_resolver_for_dumms() self.all_orb_range = all_orb_range self.all_orb_dumms = tuple(all_orb_dumms) self.set_dumms(all_orb_range, all_orb_dumms) self.set_name(*self.all_orb_dumms) self.add_resolver({i: (all_orb_range) for i in all_orb_dumms}) # Set the operator attributes self.uga = uga # Make additional name definition for the operators. self.set_name(**{ uga.label[0] + '_': uga, 'eps': energies, 'G': interact }) #uga generaters can also be called using just 'uga[p,q]' instead of 'E_[p,q]' self.set_name(uga) # Defining spec for passing to an external function - the Swapper spec = _UGSpec(uga=uga, ) self._spec = spec # Create an instance of the ProjectedBCS or AGP Drudge to map from E_pq # to D_dag, N, D so that normal ordering and vev evaluation can be done self.eta = _eta self.sigma = _sigma self.set_name(**{'eta': self.eta, 'sigma': self.sigma}) # set the Swapper self._swapper = functools.partial(_swap_ug, spec=spec)
def __init__(self, ctx, part_range=Range('V', 0, Symbol('nv')), part_dumms=PartHoleDrudge.DEFAULT_PART_DUMMS, hole_range=Range('O', 0, Symbol('no')), hole_dumms=PartHoleDrudge.DEFAULT_HOLE_DUMMS, all_orb_range=Range('A', 0, Symbol('na')), all_orb_dumms=PartHoleDrudge.DEFAULT_ORB_DUMMS, energies=IndexedBase('epsilon'), interact=IndexedBase('G'), cartan=DEFAULT_CARTAN, raise_=DEFAULT_RAISE, lower=DEFAULT_LOWER, root=Integer(2), norm=Integer(1), shift=Integer(-1), specials=None, **kwargs): """Initialize the drudge object.""" # Initialize the base su2 problem. super().__init__(ctx, cartan=cartan, raise_=raise_, lower=lower, root=root, norm=norm, shift=shift, specials=specials, **kwargs) # Set the range and dummies. self.part_range = part_range self.hole_range = hole_range self.all_orb_range = all_orb_range self.set_dumms(part_range, part_dumms) self.set_dumms(hole_range, hole_dumms) self.raise_ = raise_ self.cartan = cartan self.lower = lower self.shift = shift #------------------------------------------------------------------------# #------GH tweak here to deal with all-orbital-range separately-----------# #------NOTE that this renders the breaking of an arbitrary dummy---------# #------ into a occ and virtual useless ------------------------------# self.all_orb_dumms = tuple(all_orb_dumms) self.set_name(*self.all_orb_dumms) self.set_dumms(all_orb_range, self.all_orb_dumms) self.add_resolver_for_dumms() #------ GH commented the next 3 lines # self.add_resolver({ # i: (self.part_range, self.hole_range) for i in all_orb_dumms # }) #--------------------GH tweak ends here----------------------------------# # Make additional name definition for the operators. self.set_name(cartan, lower, Pdag=raise_) # Create the underlying particle-hole drudge with spin. Note that this # drudge is only use internally for VEV evaluation. ph_dr = SpinOneHalfPartHoleDrudge(ctx, part_orb=(part_range, part_dumms), hole_orb=(hole_range, hole_dumms)) self._ph_dr = ph_dr # Translation from su2 generator to the actual fermion operators. cr = ph_dr.cr an = ph_dr.an up, down = ph_dr.spin_vals gen_idx, gen_idx2 = self.all_orb_dumms[:2] cartan_def = self.define( cartan, gen_idx, cr[gen_idx, up] * an[gen_idx, up] + cr[gen_idx, down] * an[gen_idx, down]) raise_def = self.define(raise_, gen_idx, cr[gen_idx, up] * cr[gen_idx, down]) lower_def = self.define(lower, gen_idx, an[gen_idx, down] * an[gen_idx, up]) self._defs = [cartan_def, raise_def, lower_def] # Define the Hamiltonian. ham = self.einst(energies[gen_idx] * cartan[gen_idx] + interact[gen_idx, gen_idx2] * raise_[gen_idx] * lower[gen_idx2]) self.ham = ham.simplify() # Set additional tensor methods. self.set_tensor_method('eval_vev', self.eval_vev)
def __init__(self, ctx, all_orb_range=Range('A', 0, Symbol('na')), all_orb_dumms=PartHoleDrudge.DEFAULT_ORB_DUMMS, cartan=DEFAULT_CARTAN, raise_=DEFAULT_RAISE, lower=DEFAULT_LOWER, **kwargs): """Initialize the drudge object.""" # Initialize the base su2 problem. super().__init__(ctx, **kwargs) # Set the range and dummies. self.all_orb_range = all_orb_range self.all_orb_dumms = tuple(all_orb_dumms) self.set_dumms(all_orb_range, all_orb_dumms) self.set_name(*self.all_orb_dumms) self.add_resolver({i: (all_orb_range) for i in all_orb_dumms}) # Set the operator attributes self.cartan = cartan self.raise_ = raise_ self.lower = lower self.set_symm(self.raise_, Perm([1, 0], NEG), valence=2) self.set_symm(self.lower, Perm([1, 0], NEG), valence=2) # Set the indexed objects attributes # NOTE: sigma is not assigned any symmetry because # while sigma[p,q] = -sigma[q,p] for p != q, # sigma[p,p] = not defined, and in fact, sigma[p,p] = sigma[p,p] # --------------- self.eta = _eta self.sigma = _sigma # Make additional name definition for the operators. self.set_name( **{ cartan.label[0] + '_': cartan, raise_.label[0] + '_p': raise_, raise_.label[0] + '_dag': raise_, lower.label[0] + '_m': lower, lower.label[0] + '_': lower, 'eta': self.eta, 'sigma': self.sigma }) self.set_name(cartan, lower, Ddag=raise_) # Defining spec for passing to an external function - the Swapper spec = _AGPSpec(cartan=cartan, raise_=raise_, lower=lower, eta=self.eta, sigma=self.sigma) self._spec = spec # set the Swapper self._swapper = functools.partial(_swap_agp, spec=spec) # Definitions for translating to UGA self._uga_dr = UnitaryGroupDrudge(ctx, all_orb_range=self.all_orb_range, all_orb_dumms=self.all_orb_dumms) # Mapping from D to E _uga = self._uga_dr.uga gen_idx1, gen_idx2 = self.all_orb_dumms[:2] dm_pq_def = self.define( lower, gen_idx1, gen_idx2, (self.eta[gen_idx1] * _uga[gen_idx1, gen_idx2] - self.eta[gen_idx2] * _uga[gen_idx2, gen_idx1])) dp_pq_def = self.define( raise_, gen_idx1, gen_idx2, (self.eta[gen_idx1] * _uga[gen_idx2, gen_idx1] - self.eta[gen_idx2] * _uga[gen_idx1, gen_idx2])) np_def = self.define(cartan, gen_idx1, _uga[gen_idx1, gen_idx1]) self._agp2uga_defs = [dm_pq_def, dp_pq_def, np_def]
def __init__( self, ctx, all_orb_range=Range('A' ,0, Symbol('na')), all_orb_dumms=PartHoleDrudge.DEFAULT_ORB_DUMMS, energies=IndexedBase(r'\epsilon'), interact=IndexedBase('G'), uga=DEFAULT_GEN, **kwargs ): """Initialize the drudge object.""" # Initialize the base su2 problem. super().__init__(ctx, **kwargs) # Set the range and dummies. # self.add_resolver_for_dumms() self.all_orb_range = all_orb_range self.all_orb_dumms = tuple(all_orb_dumms) self.set_dumms(all_orb_range, all_orb_dumms) self.set_name(*self.all_orb_dumms) self.add_resolver({ i: (all_orb_range) for i in all_orb_dumms }) # Set the operator attributes self.uga = uga # Make additional name definition for the operators. self.set_name(**{ uga.label[0]+'_':uga, 'eps':energies, 'G':interact }) #uga generaters can also be called using just 'uga[p,q]' instead of 'E_[p,q]' self.set_name(uga) # Defining spec for passing to an external function - the Swapper spec = _UGSpec( uga=uga, ) self._spec = spec # Create an instance of the ProjectedBCS or AGP Drudge to map from E_pq # to D_dag, N, D so that normal ordering and vev evaluation can be done self.eta = _eta self.sigma = _sigma self.set_name(**{ 'eta':self.eta, 'sigma':self.sigma }) self._agp_dr = ProjectedBCSDrudge( ctx, all_orb_range=self.all_orb_range, all_orb_dumms=self.all_orb_dumms ) """Mapping E_pq to D_dag, N, D""" D_p = self._agp_dr.raise_ N_ = self._agp_dr.cartan D_m = self._agp_dr.lower self.D_p = D_p self.N_ = N_ self.D_m = D_m gen_idx1, gen_idx2 = self.all_orb_dumms[:2] epq_def = self.define( uga,gen_idx1,gen_idx2, self._agp_dr.sigma[gen_idx1,gen_idx2]*( self.eta[gen_idx1]*D_m[gen_idx1,gen_idx2] + \ self.eta[gen_idx2]*D_p[gen_idx1,gen_idx2] ) + \ KroneckerDelta(gen_idx1,gen_idx2)*N_[gen_idx1] ) #Tensor Definitions for uga2agp self._uga2agp_defs = [ epq_def ] """Mapping D_dag, N, D to E_pq""" dm_pq_def = self.define( D_m, gen_idx1, gen_idx2, (self.eta[gen_idx1]*uga[gen_idx1,gen_idx2] - self.eta[gen_idx2]*uga[gen_idx2,gen_idx1]) ) dp_pq_def = self.define( D_p, gen_idx1, gen_idx2, (self.eta[gen_idx1]*uga[gen_idx2,gen_idx1] - self.eta[gen_idx2]*uga[gen_idx1,gen_idx2]) ) np_def = self.define( N_, gen_idx1, uga[gen_idx1,gen_idx1] ) #Tensor definitions for agp2uga self._agp2uga_defs = [ dm_pq_def, dp_pq_def, np_def ] # set the Swapper self._swapper = functools.partial(_swap_ug, spec=spec)
def __init__(self, ctx, op_label='c', all_orb_range=Range('A', 0, Symbol(r'M_orb')), all_orb_dumms=DEFAULT_ORB_DUMMS, spin_range=Range(r'\uparrow \downarrow', Integer(0), Integer(2)), spin_dumms=tuple( Symbol('sigma{}'.format(i)) for i in range(50)), bcs_N=PAIRING_CARTAN, bcs_Pdag=PAIRING_RAISE, bcs_P=PAIRING_LOWER, bcs_Nup=NUMBER_UP, bcs_Ndn=NUMBER_DN, su2_Jz=SPIN_CARTAN, su2_Jp=SPIN_RAISE, su2_Jm=SPIN_LOWER, bcs_root=Integer(2), bcs_norm=Integer(1), bcs_shift=Integer(-1), su2_root=Integer(1), su2_norm=Integer(2), su2_shift=Integer(0), **kwargs): # initialize super super().__init__(ctx, **kwargs) # Initialize SpinOneHalfGenDrudge with the described orbital ranges orb = ((all_orb_range, all_orb_dumms), (spin_range, spin_dumms)) fermi_dr = SpinOneHalfGenDrudge(ctx, orb=orb, op_label=op_label, **kwargs) self.fermi_dr = fermi_dr cr = fermi_dr.cr an = fermi_dr.an self.cr = cr self.an = an # set the dummies self.set_dumms(all_orb_range, all_orb_dumms) self.set_dumms(spin_range, spin_dumms) # Add resolver for all orbital dummies self.add_resolver({i: (all_orb_range) for i in all_orb_dumms}) # Define and add the spin range and dummy indices to the drudge module # XXX: Note that the spin dummies are useless in this module and must # be removed eventually self.add_resolver({UP: spin_range, DOWN: spin_range}) self.spin_range = spin_range self.spin_dumms = self.dumms.value[spin_range] # Pairing operators bcs_dr = ReducedBCSDrudge( ctx, all_orb_range=all_orb_range, all_orb_dumms=all_orb_dumms, cartan=bcs_N, raise_=bcs_Pdag, lower=bcs_P, ) self.bcs_dr = bcs_dr N_ = bcs_dr.cartan Pdag_ = bcs_dr.raise_ P_ = bcs_dr.lower self.eval_agp = bcs_dr.eval_agp # SU2 operators su2_dr = SU2LatticeDrudge( ctx, cartan=su2_Jz, raise_=su2_Jp, lower=su2_Jm, ) self.su2_dr = su2_dr Sz_ = su2_dr.cartan Sp_ = su2_dr.raise_ Sm_ = su2_dr.lower # Assign these operators to the self self.all_orb_range = all_orb_range self.all_orb_dumms = tuple(all_orb_dumms) self.Pdag = Pdag_ self.N = N_ self.N_up = bcs_Nup self.N_dn = bcs_Ndn self.P = P_ self.S_z = Sz_ self.S_p = Sp_ self.S_m = Sm_ # Define the unitary group operators p = Symbol('p') q = Symbol('q') self.sigma = self.dumms.value[spin_range][0] self.e_ = TensorDef( Vec('E'), (p, q), self.sum(self.cr[p, UP] * self.an[q, UP] + self.cr[p, DOWN] * self.an[q, DOWN])) self.set_name(e_=self.e_) # set of unique dummies: # The idea is to declare a set of (free) dummy indices to be unique, # i.e. they have unique, different values by construction. # This is a feature of this module / class but has potential to be a # part of the drudge system. # The way I want to implement this is as follows: # 1. User specifies a tuple/list of indices to be set unique # 2. Then we construct a dictionary of all proosible kronecker deltas # which will be zero # 3. in simplify / get_seniority_zero, we use this substitution. # Dictionary of substitutions self.unique_del_lists = [] # XXX: To be doen / can be done # Define the Dpq, Ddag_pq operators # Set the names self.set_name(*self.all_orb_dumms) self.set_name( **{ op_label + '_': an, op_label + '_dag': cr, op_label + 'dag_': cr, Sz_.label[0] + '_z': Sz_, Sp_.label[0] + '_p': Sp_, Sm_.label[0] + '_m': Sm_, N_.label[0]: N_, N_.label[0] + '_': N_, Pdag_.label[0] + 'dag': Pdag_, Pdag_.label[0] + '_dag': Pdag_, P_.label[0]: P_, P_.label[0] + '_': P_, }) # Define spec for all the class methods needed for # extracting the su2 operators spec = _AGPFSpec(c_=self.an, c_dag=self.cr, N=self.N, Nup=self.N_up, Ndn=self.N_dn, P=self.P, Pdag=self.Pdag, agproot=bcs_root, agpnorm=bcs_norm, agpshift=bcs_shift, S_p=self.S_p, S_z=self.S_z, S_m=self.S_m, su2root=su2_root, su2norm=su2_norm, su2shift=su2_shift, unique_ind=self.unique_del_lists) self._spec = spec # Swapper dummy function for commutation rules self._swapper = functools.partial(_swap_agpf, spec=spec) # Extracting SU2 dummy function self._extract_su2 = functools.partial(_get_su2_vecs, spec=spec)
def __init__(self, ctx, op_label='c', all_orb_range=Range('A', 0, Symbol(r'M')), all_orb_dumms=DEFAULT_ORB_DUMMS, part_range=Range('O', 0, Symbol('no')), part_dumms=DEFAULT_PART_DUMMS, hole_range=Range('V', 0, Symbol('nv')), hole_dumms=DEFAULT_HOLE_DUMMS, spin_range=Range(r'\uparrow \downarrow', Integer(0), Integer(2)), spin_dumms=tuple( Symbol('sigma{}'.format(i)) for i in range(50)), bcs_N=PAIRING_CARTAN, bcs_Pdag=PAIRING_RAISE, bcs_P=PAIRING_LOWER, bcs_Nup=NUMBER_UP, bcs_Ndn=NUMBER_DN, su2_Jz=SPIN_CARTAN, su2_Jp=SPIN_RAISE, su2_Jm=SPIN_LOWER, bcs_root=Integer(2), bcs_norm=Integer(1), bcs_shift=Integer(-1), su2_root=Integer(1), su2_norm=Integer(2), su2_shift=Integer(0), **kwargs): # Initialize super super().__init__(ctx, op_label=op_label, all_orb_range=all_orb_range, all_orb_dumms=all_orb_dumms, spin_range=spin_range, spin_dumms=spin_dumms, bcs_N=bcs_N, bcs_Pdag=bcs_Pdag, bcs_P=bcs_P, bcs_Nup=bcs_Nup, bcs_Ndn=bcs_Ndn, su2_Jz=su2_Jz, su2_Jp=su2_Jp, su2_Jm=su2_Jm, bcs_root=bcs_root, bcs_norm=bcs_norm, bcs_shift=bcs_shift, su2_root=su2_root, su2_norm=su2_norm, su2_shift=su2_shift, **kwargs) # Add the part-hole indices and ranges to the class varables self.part_dumms = tuple(part_dumms) self.hole_dumms = tuple(hole_dumms) self.part_range = part_range self.hole_range = hole_range # Add the indices to the name space self.set_name(*self.part_dumms) # Link the dummy indices to their respective ranges self.set_dumms(self.part_range, self.part_dumms) self.set_dumms(self.hole_range, self.hole_dumms) # Clean up the default resolver self._resolvers.var.clear() # Add the resolver self.add_resolver({i: (self.part_range) for i in self.part_dumms}) self.add_resolver({i: (self.hole_range) for i in self.hole_dumms}) self.add_resolver({ i: (self.part_range, self.hole_range) for i in self.all_orb_dumms }) self.add_resolver( {i: (self.all_orb_range) for i in self.all_orb_dumms})