Ejemplo n.º 1
0
 def test_flosic_scf(self):
     # FLO-SIC SCF
     xc = 'LDA,PW'  # Exchange-correlation functional in the form: (exchange,correlation)
     grid_level = 3  # Level of the numerical grid. 3 is the standard value
     vsic_every = 1  # Calculate VSIC after 3 iterations
     mf = FLOSIC(mol,
                 xc=xc,
                 fod1=fod1,
                 fod2=fod2,
                 grid_level=grid_level,
                 vsic_every=vsic_every)
     mf.max_cycle = 300  # Number of SCF iterations.
     mf.conv_tol = 1e-6  # Accuracy of the SCF cycle.
     mf.verbose = 4  # Amount of output. 4: full output.
     e_ref = -40.69756811131563
     self.assertAlmostEqual(mf.kernel(), e_ref, 5)
Ejemplo n.º 2
0
mol.max_memory = 2000
mol.build()
xc = 'LDA,PW'

# quick dft calculation
mdft = dft.UKS(mol)
mdft.xc = xc
mdft.kernel()

# build O(N) stuff
myon = ON(mol,[fod1.positions,fod2.positions], grid_level=grid_level)
myon.nshell = 1
myon.build()

# enable ONMSH
m = FLOSIC(mol,xc=xc,fod1=fod1,fod2=fod2,grid_level=grid_level, init_dm=mdft.make_rdm1(),ham_sic='HOOOV')
m.max_cycle = 40
m.set_on(myon)
m.conv_tol = 1e-5

# In-SCF-FOD optimization 
m.preopt = True
m.preopt_start_cycle=0
m.preopt_fix1s = True
m.preopt_fmin = 0.005

m.kernel()
# Some output 
print(m.fod_gradients())
print(m.get_fforces())
Ejemplo n.º 3
0
atoms = read('HHeH_s2.xyz')

# Now, we set up the mole object.

spin = 2 
charge = 0
xc = 'LDA,PW'
b = 'cc-pVQZ'
[geo,nuclei,fod1,fod2,included] =  xyz_to_nuclei_fod(atoms)
mol = gto.M(atom=ase2pyscf(nuclei), basis=b,spin=spin,charge=charge)
#mol.verbose = 4

# Now we set up the calculator.

sic_object = FLOSIC(mol=mol,xc=xc,fod1=fod1,fod2=fod2,ham_sic='HOO')
sic_object.conv_tol = 1e-7
sic_object.max_cycle = 300

# With this, we can calculate the high-spin total ground state energy.

E_HS_SIC = sic_object.kernel()

# Next, we need the low-spin solution. The first steps are completely similar to the high-spin calculation.

atoms = read('HHeH_s0.xyz')
spin = 0
charge = 0
xc = 'LDA,PW'
b = 'cc-pVQZ'
[geo,nuclei,fod1,fod2,included] =  xyz_to_nuclei_fod(atoms)
Ejemplo n.º 4
0
# For this we first need a mole object.
# The test system will be CH4.

sysname = 'CH4'
molecule = read(sysname + '.xyz')
geo, nuclei, fod1, fod2, included = xyz_to_nuclei_fod(molecule)
spin = get_multiplicity(sysname)

# We will use a smaller basis set to keep computational cost low.
# The better the basis set, the nicer the FLO will look.

b = 'sto3g'
mol = gto.M(atom=ase2pyscf(nuclei), basis={'default': b}, spin=spin)

# Now we can initiliaze the SIC object.

sic_object = FLOSIC(mol, fod1=fod1, fod2=fod2, xc='LDA,PW')

# And perform a ground state calculation.

sic_object.max_cycle = 500
sic_object.kernel()

# Now we can call the visualization function. The sysname here only specifies the output name.
# Maxcell coordinates the size of the cell that can be seen in VESTA.

print_flo(sic_object, sic_object.flo, sysname, nuclei, fod1, fod2, maxcell=6.)

# The .cube files will appear in this folder. An example .png of how they should look is provided as CH4.png
Ejemplo n.º 5
0
flosic_values = flosic(mol, mf, fod1, fod2)
flo = flosic_values['flo']

# Get the FLOSIC OS density.

dm_flo = dynamic_rdm(flo, mf.mo_occ)
rho_flo_os = dft.numint.eval_rho(mol, ao, dm_flo[0], None, 'LDA', 0, None)

# Get the mesh.

mesh = mf.grids.coords

# Do the FLOSIC SCF.

print('Starting FLOSIC calculation in SCF mode.')
mf2 = FLOSIC(mol, xc=xc, fod1=fod1, fod2=fod2)
mf2.max_cycle = maxcycle
mf2.conv_tol = convtol
mf2.grids.level = 4
e = mf2.kernel()

# Get the FLOSIC density.

flo = mf2.flo
ao = dft.numint.eval_ao(mol, mf.grids.coords, deriv=0)
dm_flo = dynamic_rdm(flo, mf2.mo_occ)
rho_flo_scf = dft.numint.eval_rho(mol, ao, dm_flo[0], None, 'LDA', 0, None)

# Plot the densities.
# Init the arrays.
Ejemplo n.º 6
0
            spin=spin,
            charge=charge)

# We further need to specify the numerical grid level used in the self-consistent FLO-SIC calculation.

grid_level = 4

# We need to choose an exchange-correlation functional.

xc = 'LDA,PW'  # Exchange-correlation functional in the form: (exchange,correlation)
# NOTE: As there exists only one way to express the exchange for LDA, there is only one identifier.
# For LDA correlation there exist several.

# Now we can initiliaze the SIC object.

sic_object = FLOSIC(mol, xc=xc, fod1=fod1, fod2=fod2, grid_level=grid_level)

# We can the modify the SIC object now if wished.

sic_object.max_cycle = 300  # Number of SCF iterations.
sic_object.conv_tol = 1e-7  # Accuracy of the SCF cycle.
sic_object.verbose = 4  # Amount of output. 4: full output.

# Now we can start the SIC calculation. The main output, the total energy, is the direct return value.

total_energy_sic = sic_object.kernel()

# We can get further output by accessing the attributes of the SIC object.

homo_flosic = sic_object.homo_flosic
Ejemplo n.º 7
0
# Drawing on these, the PySCF intrinsic functions .newton() and .scanner() allow the usage of a Newton optimization algorithm.
# Such an algorithm constructs the Hessian from these derivatives and uses it to perform anoptimization that is faster than the regular SCF solver.
# Unfortunately, it can ONLY BE USED WITH LDA OR GGA.
# PySCF currently DOES NOT SUPPORT MGGAs with this second order solver.
# To show the speedup, the calculations below will be timed.

# To use this solver, we first have to simply define a regular calculator.
# The testing system is a Li atom.
molecule = read('Li.xyz')
geo, nuclei, fod1, fod2, included = xyz_to_nuclei_fod(molecule)
spin = 1
charge = 0
b = 'sto3g'
xc = 'LDA,PW'
mol = gto.M(atom=ase2pyscf(nuclei), basis=b, spin=spin, charge=charge)
sic_object = FLOSIC(mol, xc=xc, fod1=fod1, fod2=fod2)
sic_object.max_cycle = 400

# Perform a calculation with the regular sovler.

start_regular = time.time()
sic_object.kernel()
end_regular = time.time()
duration_regular = end_regular - start_regular

# Now enable the second order solver.

sic_object = sic_object.as_scanner()
sic_object = sic_object.newton()

# And perform a calculation with the second order solver.
Ejemplo n.º 8
0
              spin=spin_2,
              charge=charge)

# We further need to specify the numerical grid level used in the self-consistent FLO-SIC calculation.

grid_level = 4

# We need to choose an exchange-correlation functional.

xc = 'LDA,PW'  # Exchange-correlation functional in the form: (exchange,correlation)
# NOTE: As there exists only one way to express the exchange for LDA, there is only one identifier.
# For LDA correlation there exist several.

# Now we can initiliaze the SIC objects.

sic_0 = FLOSIC(mol_0, xc=xc, fod1=fod1, fod2=fod2, grid_level=grid_level)

# For spin = 2 we have to adjust the FOD geometry by moving the FOD for the second spin channel into the first one.

fod1_spin2 = fod1.copy()
fod2_spin2 = fod2.copy()
fod1_spin2.append(fod2_spin2[0])
del fod2_spin2[0]
sic_2 = FLOSIC(mol_2,
               xc=xc,
               fod1=fod1_spin2,
               fod2=fod2_spin2,
               grid_level=grid_level)

# To enable a variable spin configuration, we simply have to load the routine sic_occ_
Ejemplo n.º 9
0
    from ase.io import read
except ImportError:
    raise SystemExit('The package \'ase\' is required for this example!')
try:
    from flosic_os import ase2pyscf, xyz_to_nuclei_fod
    from flosic_scf import FLOSIC
except ImportError:
    raise SystemExit('The package \'pyflosic\' is required for this example!')
from pyscf import gto
from var_mesh import var_mesh

# Set up calculation details
molecule = read('H2.xyz')
geo, nuclei, fod1, fod2, included = xyz_to_nuclei_fod(molecule)
mol = gto.M(atom=ase2pyscf(nuclei), basis='6-311++Gss', spin=0, charge=0)
sic_object = FLOSIC(mol, xc='lda,pw', fod1=fod1, fod2=fod2, ham_sic='HOO')
sic_object.max_cycle = 300
sic_object.conv_tol = 1e-7

# By default a grid level of 3 is used, save its size
mesh_size = len(sic_object.calc_uks.grids.coords)
sic_object.calc_uks.grids = var_mesh(sic_object.calc_uks.grids)

# Start the calculation
total_energy_sic = sic_object.kernel()
homo_flosic = sic_object.homo_flosic

# Display mesh sizes and energy values
print('Mesh size before: %d' % mesh_size)
print('Mesh size after: %d' % len(sic_object.calc_uks.grids.coords))
print('Total energy of H2 (FLO-SIC SCF): %0.5f (should be %0.5f)' %
# Unfortunately, it can ONLY BE USED WITH LDA OR GGA.
# PySCF currently DOES NOT SUPPORT MGGAs with this second order solver.
# To show the speedup, the calculations below will be timed.

# 1) Standard example WITHOUT usage of fixed VSIC properties 

# To use this solver, we first have to simply define a regular calculator.
# The testing system is a Li atom.
molecule = read('Li.xyz')
geo,nuclei,fod1,fod2,included =  xyz_to_nuclei_fod(molecule)
spin = 1
charge = 0
b = 'sto3g'
xc = 'LDA,PW'
mol = gto.M(atom=ase2pyscf(nuclei), basis=b,spin=spin,charge=charge)
mf = FLOSIC(mol,xc=xc,fod1=fod1,fod2=fod2)

# Perform a calculation with the regular sovler.

t1_start = time.time()
e1 = mf.kernel()
t1_end = time.time()
delta_t1 = t1_end-t1_start


# 2) Standard example WITH usage of fixed VSIC properties 

# To use this solver, we first have to simply define a regular calculator.
# The testing system is a Li atom.
molecule = read('Li.xyz')
geo,nuclei,fod1,fod2,included =  xyz_to_nuclei_fod(molecule)
Ejemplo n.º 11
0
    def calculate(self,
                  atoms,
                  properties=['energy'],
                  system_changes=['positions']):
        self.num_iter += 1
        atoms = self.get_atoms()
        self.atoms = atoms
        Calculator.calculate(self, atoms, properties, system_changes)
        if self.mode == 'dft':
            # DFT only mode
            from pyscf import gto, scf, grad, dft
            [geo, nuclei, fod1, fod2, included] = xyz_to_nuclei_fod(self.atoms)
            nuclei = ase2pyscf(nuclei)
            mol = gto.M(atom=nuclei,
                        basis=self.basis,
                        spin=self.spin,
                        charge=self.charge)
            mf = scf.UKS(mol)
            mf.xc = self.xc
            # Verbosity of the mol object (o lowest output, 4 might enough output for debugging)
            mf.verbose = self.verbose
            mf.max_cycle = self.max_cycle
            mf.conv_tol = self.conv_tol
            mf.grids.level = self.grid
            if self.n_rad is not None and self.n_ang is not None:
                mf.grids.atom_grid = (self.n_rad, self.n_ang)
            mf.grids.prune = prune_dict[self.prune]
            e = mf.kernel()
            self.mf = mf
            self.results['energy'] = e * Ha
            self.results['dipole'] = dipole = mf.dip_moment(verbose=0)
            self.results['evalues'] = mf.mo_energy
        if self.mode == 'flosic-os':
            # FLOSIC SCF mode
            from pyscf import gto, scf
            [geo, nuclei, fod1, fod2, included] = xyz_to_nuclei_fod(self.atoms)
            # FLOSIC one shot mode
            #mf = flosic(self.atoms,charge=self.charge,spin=self.spin,xc=self.xc,basis=self.basis,debug=False,verbose=self.verbose)
            # Effective core potentials need so special treatment.
            if self.ecp == None:
                if self.ghost == False:
                    mol = gto.M(atom=ase2pyscf(nuclei),
                                basis=self.basis,
                                spin=self.spin,
                                charge=self.charge)
                if self.ghost == True:
                    mol = gto.M(atom=ase2pyscf(nuclei),
                                basis=self.basis,
                                spin=self.spin,
                                charge=self.charge)
                    mol.basis = {
                        'default': self.basis,
                        'GHOST1': gto.basis.load('sto3g', 'H'),
                        'GHOST2': gto.basis.load('sto3g', 'H')
                    }
            if self.ecp != None:
                mol = gto.M(atom=ase2pyscf(nuclei),
                            basis=self.basis,
                            spin=self.spin,
                            charge=self.charge,
                            ecp=self.ecp)
            mf = scf.UKS(mol)
            mf.xc = self.xc
            # Verbosity of the mol object (o lowest output, 4 might enough output for debugging)
            mf.verbose = self.verbose
            # Binary output format of pyscf.
            # Save MOs, orbital energies, etc.
            if self.use_chk == True and self.use_newton == False:
                mf.chkfile = 'pyflosic.chk'
            # Load from previous run, if exist, the checkfile.
            # Hopefully this will speed up the calculation.
            if self.use_chk == True and self.use_newton == False and os.path.isfile(
                    'pyflosic.chk'):
                mf.init_guess = 'chk'
                mf.update('pyflosic.chk')
            if self.use_newton == True:
                mf = mf.as_scanner()
                mf = mf.newton()
            mf.max_cycle = self.max_cycle
            mf.conv_tol = self.conv_tol
            mf.grids.level = self.grid
            if self.n_rad is not None and self.n_ang is not None:
                mf.grids.atom_grid = (self.n_rad, self.n_ang)
            mf.grids.prune = prune_dict[self.prune]
            e = mf.kernel()
            self.mf = mf
            mf = flosic(mol,
                        mf,
                        fod1,
                        fod2,
                        sysname=None,
                        datatype=np.float64,
                        print_dm_one=False,
                        print_dm_all=False,
                        debug=self.debug,
                        calc_forces=True,
                        ham_sic=self.ham_sic)
            self.results['energy'] = mf['etot_sic'] * Ha
            # unit conversion from Ha/Bohr to eV/Ang
            #self.results['fodforces'] = -1*mf['fforces']/(Ha/Bohr)
            self.results['fodforces'] = -1 * mf['fforces'] * (Ha / Bohr)
            print('Analytical FOD force [Ha/Bohr]')
            print(mf['fforces'])
            print('fmax = %0.6f [Ha/Bohr]' % np.sqrt(
                (mf['fforces']**2).sum(axis=1).max()))
            self.results['dipole'] = mf['dipole']
            self.results['evalues'] = mf['evalues']
        if self.mode == 'flosic-scf':
            #if self.mf is None:
            # FLOSIC SCF mode
            from pyscf import gto
            [geo, nuclei, fod1, fod2, included] = xyz_to_nuclei_fod(self.atoms)
            # Effective core potentials need so special treatment.
            if self.ecp == None:
                if self.ghost == False:
                    mol = gto.M(atom=ase2pyscf(nuclei),
                                basis=self.basis,
                                spin=self.spin,
                                charge=self.charge)
                if self.ghost == True:
                    mol = gto.M(atom=ase2pyscf(nuclei),
                                basis=self.basis,
                                spin=self.spin,
                                charge=self.charge)
                    mol.basis = {
                        'default': self.basis,
                        'GHOST1': gto.basis.load('sto3g', 'H'),
                        'GHOST2': gto.basis.load('sto3g', 'H')
                    }
            if self.ecp != None:
                mol = gto.M(atom=ase2pyscf(nuclei),
                            basis=self.basis,
                            spin=self.spin,
                            charge=self.charge,
                            ecp=self.ecp)
            if self.efield != None:
                m0 = FLOSIC(mol=mol,
                            xc=self.xc,
                            fod1=fod1,
                            fod2=fod2,
                            grid_level=self.grid,
                            debug=self.debug,
                            l_ij=self.l_ij,
                            ods=self.ods,
                            fixed_vsic=self.fixed_vsic,
                            num_iter=self.num_iter,
                            vsic_every=self.vsic_every,
                            ham_sic=self.ham_sic)
                # test efield to enforce some pseudo chemical environment
                # and break symmetry of density
                m0.grids.level = self.grid
                m0.conv_tol = self.conv_tol
                # small efield
                m0.max_cycle = 1
                h = -0.0001  #-0.1
                apply_field(mol, m0, E=(0, 0, 0 + h))
                m0.kernel()
            mf = FLOSIC(mol=mol,
                        xc=self.xc,
                        fod1=fod1,
                        fod2=fod2,
                        grid_level=self.grid,
                        calc_forces=self.calc_forces,
                        debug=self.debug,
                        l_ij=self.l_ij,
                        ods=self.ods,
                        fixed_vsic=self.fixed_vsic,
                        num_iter=self.num_iter,
                        vsic_every=self.vsic_every,
                        ham_sic=self.ham_sic)
            # Verbosity of the mol object (o lowest output, 4 might enough output for debugging)
            mf.verbose = self.verbose
            # Binary output format of pyscf.
            # Save MOs, orbital energies, etc.
            if self.use_chk == True and self.use_newton == False:
                mf.chkfile = 'pyflosic.chk'
            # Load from previous run, if exist, the checkfile.
            # Hopefully this will speed up the calculation.
            if self.use_chk == True and self.use_newton == False and os.path.isfile(
                    'pyflosic.chk'):
                mf.init_guess = 'chk'
                mf.update('pyflosic.chk')
            if self.use_newton == True:
                mf = mf.as_scanner()
                mf = mf.newton()
            mf.max_cycle = self.max_cycle
            mf.conv_tol = self.conv_tol
            mf.grids.level = self.grid
            if self.n_rad is not None and self.n_ang is not None:
                mf.grids.atom_grid = (self.n_rad, self.n_ang)
                mf.calc_uks.grids.atom_grid = (self.n_rad, self.n_ang)
            mf.grids.prune = prune_dict[self.prune]
            mf.calc_uks.grids.prune = prune_dict[self.prune]
            e = mf.kernel()
            self.mf = mf
            # Return some results to the pyflosic_ase_caculator object.
            self.results['esic'] = mf.esic * Ha
            self.results['energy'] = e * Ha
            self.results['fixed_vsic'] = mf.fixed_vsic

            # if self.mf is not None:
            #     from pyscf import gto
            #     [geo,nuclei,fod1,fod2,included] =  xyz_to_nuclei_fod(self.atoms)
            #     # Effective core potentials need so special treatment.
            #     if self.ecp == None:
            #         if self.ghost == False:
            #             mol = gto.M(atom=ase2pyscf(nuclei), basis=self.basis,spin=self.spin,charge=self.charge)
            #         if self.ghost == True:
            #             mol = gto.M(atom=ase2pyscf(nuclei), basis=self.basis,spin=self.spin,charge=self.charge)
            #             mol.basis ={'default':self.basis,'GHOST1':gto.basis.load('sto3g', 'H'),'GHOST2':gto.basis.load('sto3g', 'H')}
            #     if self.ecp != None:
            #         mol = gto.M(atom=ase2pyscf(nuclei), basis=self.basis,spin=self.spin,charge=self.charge,ecp=self.ecp)
            #     self.mf.num_iter = self.num_iter
            #     self.mf.max_cycle = self.max_cycle
            #     self.mf.mol = mol
            #     self.mf.fod1 = fod1
            #     self.mf.fod2 = fod2
            #     e = self.mf.kernel()
            #     # Return some results to the pyflosic_ase_caculator object.
            #     self.results['esic'] = self.mf.esic*Ha
            #     self.results['energy'] = e*Ha
            #     self.results['fixed_vsic'] = self.mf.fixed_vsic
            #
            if self.fopt == 'force' or self.fopt == 'esic-force':
                #
                # The standard optimization uses
                # the analytical FOD forces
                #
                fforces = self.mf.get_fforces()
                #fforces = -1*fforce
                # unit conversion Hartree/Bohr to eV/Angstroem
                #self.results['fodforces'] = -1*fforces*(Ha/Bohr)
                self.results['fodforces'] = fforces * (Ha / Bohr)
                print('Analytical FOD force [Ha/Bohr]')
                print(fforces)
                print('fmax = %0.6f [Ha/Bohr]' % np.sqrt(
                    (fforces**2).sum(axis=1).max()))

            if self.fopt == 'lij':
                #
                # This is under development.
                # Trying to replace the FOD forces.
                #
                self.lambda_ij = self.mf.lambda_ij
                self.results['lambda_ij'] = self.mf.lambda_ij
                #fforces = []
                #nspin = 2
                #for s in range(nspin):
                #	# printing the lampda_ij matrix for both spin channels
                #	print 'lambda_ij'
                #	print lambda_ij[s,:,:]
                #	print 'RMS lambda_ij'
                #	M = lambda_ij[s,:,:]
                #	fforces_tmp =  (M-M.T)[np.triu_indices((M-M.T).shape[0])]
                #	fforces.append(fforces_tmp.tolist())
                #print np.array(fforces).shape
                try:
                    #
                    # Try to calculate the FOD forces from the differences
                    # of SIC eigenvalues
                    #
                    evalues_old = self.results['evalues']
                    print(evalues_old)
                    evalues_new = self.mf.evalues
                    print(evalues_new)
                    delta_evalues_up = (evalues_old[0][0:len(fod1)] -
                                        evalues_new[0][0:len(fod1)]).tolist()
                    delta_evalues_dn = (evalues_old[1][0:len(fod2)] -
                                        evalues_new[1][0:len(fod2)]).tolist()
                    print(delta_evalues_up)
                    print(delta_evalues_dn)
                    lij_force = delta_evalues_up
                    lij_force.append(delta_evalues_dn)
                    lij_force = np.array(lij_force)
                    lij_force = np.array(lij_force,
                                         (np.shape(lij_force)[0], 3))
                    print('FOD force evalued from evalues')
                    print(lij_force)
                    self.results['fodforces'] = lij_force
                except:
                    #
                    # If we are in the first iteration
                    # we can still use the analystical FOD forces
                    # as starting values
                    #
                    fforces = self.mf.get_fforces()
                    print(fforces)
                    #self.results['fodforces'] = -1*fforces*(Ha/Bohr)
                    self.results['fodforces'] = fforces * (Ha / Bohr)
                    print('Analytical FOD force [Ha/Bohr]')
                    print(fforces)
                    print('fmax = %0.6f [Ha/Bohr]' % np.sqrt(
                        (fforces**2).sum(axis=1).max()))

            self.results['dipole'] = self.mf.dip_moment()
            self.results['evalues'] = self.mf.evalues

        if atoms is not None:
            self.atoms = atoms.copy()
Ejemplo n.º 12
0
    grid_level = 5
    mol.verbose = 4
    mol.max_memory = 2000
    mol.build()
    xc = 'LDA,PW'

    # quick dft calculation
    mdft = dft.UKS(mol)
    mdft.xc = xc
    mdft.kernel()

    # build FLOSIC object
    mflosic = FLOSIC(mol,
                     xc=xc,
                     fod1=fodup,
                     fod2=foddn,
                     grid_level=grid_level,
                     init_dm=mdft.make_rdm1())
    mflosic.max_cycle = 40
    mflosic.conv_tol = 1e-5  # just for testing

    calc = BasicFLOSICC(atoms=fod, mf=mflosic)
    #print(fod.get_potential_energy())
    #print(fod.get_forces())

    print(" >>>>>>>>>>>> OPTIMIZER TEST <<<<<<<<<<<<<<<<<<<<")

    # test the calculator by optimizing a bit
    from ase.optimize import FIRE
    dyn = FIRE(
        atoms=fod,
Ejemplo n.º 13
0
xc = 'LDA,PW'
x = 'LDA,'

# Now we can build the mole object.

mol = gto.M(atom=ase2pyscf(nuclei), basis=b, spin=spin, charge=charge)

# The next part is the definition of the calculator objects.
# For both xc and x we create a separate calculator object.

dftx = dft.UKS(mol)
dftx.xc = x
dftxc = dft.UKS(mol)
dftxc.xc = xc
sicx = FLOSIC(mol, xc=x, fod1=fod1, fod2=fod2)
sicxc = FLOSIC(mol, xc=xc, fod1=fod1, fod2=fod2)

# Now we need to do the ground state calculations.

etot_dftx = dftx.kernel()
etot_dftxc = dftxc.kernel()
etot_sicx = sicx.kernel()
etot_sicxc = sicxc.kernel()

# Then we can access the xc energies.

veffdftx = dftx.get_veff(mol=mol)
exc_dftx = veffdftx.__dict__['exc']
veffdftxc = dftxc.get_veff(mol=mol)
exc_dftxc = veffdftxc.__dict__['exc']
Ejemplo n.º 14
0
# The testing system will be an H4 structure (two H2 molecules.)
# First, we need the calculator objects and therefore mole objects.

molecule = read('H4.xyz')
geo, nuclei, fod1, fod2, included = xyz_to_nuclei_fod(molecule)
spin = 0
charge = 0
b = 'cc-pVQZ'
xc = 'LDA,PW'
mol = gto.M(atom=ase2pyscf(nuclei), basis=b, spin=spin, charge=charge)

# Now we can initiliaze the calculator objects.

dft_object = dft.UKS(mol)
dft_object.xc = xc
sic_object = FLOSIC(mol, xc=xc, fod1=fod1, fod2=fod2, ham_sic='HOO')

# To calculate alpha we first calculate mu WITHOUT an electric field.

dft_object.kernel()
dft_mu0 = dft_object.dip_moment()[-1]
sic_object.kernel()
sic_mu0 = sic_object.dip_moment()[-1]

# Now we apply the electric field to the DFT and FLO-SIC calculator objects.
# For this we first set the gauge origin for the dipole integral.

mol.set_common_orig([0., 0., 0.])

# Then we calculate the new external potential.