def format_currentstate_for_input(func, name, allButMol=False, **kwargs): """Function to return an input file in preprocessed psithon. Captures memory, molecule, options, function, method, and kwargs. Used to write distributed (sow/reap) input files. """ warnings.warn( "Using `psi4.driver.p4util.format_currentstate_for_input` is deprecated, and in 1.4 it will stop working\n", category=FutureWarning, stacklevel=2) commands = """\n# This is a psi4 input file auto-generated from the %s() wrapper.\n\n""" % ( inspect.stack()[1][3]) commands += """memory %d mb\n\n""" % (int(0.000001 * core.get_memory())) if not allButMol: molecule = core.get_active_molecule() molecule.update_geometry() commands += format_molecule_for_input(molecule) commands += '\n' commands += prepare_options_for_modules(changedOnly=True, commandsInsteadDict=True) commands += """\n%s('%s', """ % (func.__name__, name.lower()) for key in kwargs.keys(): commands += """%s=%r, """ % (key, kwargs[key]) commands += ')\n\n' return commands
def format_options_for_input(molecule=None, **kwargs): """Function to return a string of commands to replicate the current state of user-modified options. Used to capture C++ options information for distributed (sow/reap) input files. .. caution:: Some features are not yet implemented. Buy a developer a coffee. - Does not cover local (as opposed to global) options. """ if molecule is not None: symmetry = molecule.find_point_group(0.00001).symbol() commands = '' commands += """\ncore.set_memory_bytes(%s)\n\n""" % (core.get_memory()) for chgdopt in core.get_global_option_list(): if core.has_global_option_changed(chgdopt): chgdoptval = core.get_global_option(chgdopt) if molecule is not None: if chgdopt.lower() in kwargs: if symmetry in kwargs[chgdopt.lower()]: chgdoptval = kwargs[chgdopt.lower()][symmetry] if isinstance(chgdoptval, str): commands += """core.set_global_option('%s', '%s')\n""" % (chgdopt, chgdoptval) # Next four lines were conflict between master and roa branches (TDC, 10/29/2014) elif isinstance(chgdoptval, int) or isinstance(chgdoptval, float): commands += """core.set_global_option('%s', %s)\n""" % (chgdopt, chgdoptval) elif isinstance(chgdoptval, list): commands += """core.set_global_option('%s', %s)\n""" % (chgdopt, chgdoptval) else: commands += """core.set_global_option('%s', %s)\n""" % (chgdopt, chgdoptval) return commands
def format_currentstate_for_input(func, name, allButMol=False, **kwargs): """Function to return an input file in preprocessed psithon. Captures memory, molecule, options, function, method, and kwargs. Used to write distributed (sow/reap) input files. """ warnings.warn( "Using `psi4.driver.p4util.format_currentstate_for_input` is deprecated, and in 1.4 it will stop working\n", category=FutureWarning, stacklevel=2) commands = """\n# This is a psi4 input file auto-generated from the %s() wrapper.\n\n""" % (inspect.stack()[1][3]) commands += """memory %d mb\n\n""" % (int(0.000001 * core.get_memory())) if not allButMol: molecule = core.get_active_molecule() molecule.update_geometry() commands += format_molecule_for_input(molecule) commands += '\n' commands += prepare_options_for_modules(changedOnly=True, commandsInsteadDict=True) commands += """\n%s('%s', """ % (func.__name__, name.lower()) for key in kwargs.keys(): commands += """%s=%r, """ % (key, kwargs[key]) commands += ')\n\n' return commands
def _initialize_jk(self, basis, aux_basis, do_J=True, do_K=True): jk = core.JK.build(basis, aux_basis) jk.set_memory(int(float(core.get_global_option("SCF_MEM_SAFETY_FACTOR")) * core.get_memory() / 8)) jk.set_do_J(do_J) jk.set_do_K(do_K) jk.print_header() jk.initialize() return jk
def scf_initialize(self): """Specialized initialization, compute integrals and does everything to prepare for iterations""" # Figure out memory distributions # Get memory in terms of doubles total_memory = (core.get_memory() / 8) * core.get_global_option("SCF_MEM_SAFETY_FACTOR") # Figure out how large the DFT collocation matrices are vbase = self.V_potential() if vbase: collocation_size = vbase.grid().collocation_size() if vbase.functional().ansatz() == 1: collocation_size *= 4 # First derivs elif vbase.functional().ansatz() == 2: collocation_size *= 10 # Second derivs else: collocation_size = 0 # Change allocation for collocation matrices based on DFT type scf_type = core.get_global_option('SCF_TYPE').upper() nbf = self.get_basisset("ORBITAL").nbf() naux = self.get_basisset("DF_BASIS_SCF").nbf() if "DIRECT" == scf_type: jk_size = total_memory * 0.1 elif scf_type.endswith('DF'): jk_size = naux * nbf * nbf else: jk_size = nbf**4 # Give remaining to collocation if total_memory > jk_size: collocation_memory = total_memory - jk_size # Give up to 10% to collocation elif (total_memory * 0.1) > collocation_size: collocation_memory = collocation_size else: collocation_memory = total_memory * 0.1 if collocation_memory > collocation_size: collocation_memory = collocation_size # Set constants self.iteration_ = 0 self.memory_jk_ = int(total_memory - collocation_memory) self.memory_collocation_ = int(collocation_memory) # Print out initial docc/socc/etc data if core.get_option('SCF', "PRINT") > 0: core.print_out(" ==> Pre-Iterations <==\n\n") self.print_preiterations() # Initialize EFP efp_enabled = hasattr(self.molecule(), 'EFP') if efp_enabled: # EFP: Set QM system, options, and callback. Display efp geom in [A] efpobj = self.molecule().EFP core.print_out(efpobj.banner()) core.print_out( efpobj.geometry_summary(units_to_bohr=constants.bohr2angstroms)) efpptc, efpcoords, efpopts = get_qm_atoms_opts(self.molecule()) efpobj.set_point_charges(efpptc, efpcoords) efpobj.set_opts(efpopts, label='psi', append='psi') efpobj.set_electron_density_field_fn(field_fn) # Initilize all integratals and perform the first guess if self.attempt_number_ == 1: mints = core.MintsHelper(self.basisset()) if core.get_global_option('RELATIVISTIC') in ['X2C', 'DKH']: mints.set_rel_basisset(self.get_basisset('BASIS_RELATIVISTIC')) mints.one_electron_integrals() self.initialize_jk(self.memory_jk_) if self.V_potential(): self.V_potential().build_collocation_cache( self.memory_collocation_) core.timer_on("HF: Form core H") self.form_H() core.timer_off("HF: Form core H") if efp_enabled: # EFP: Add in permanent moment contribution and cache core.timer_on("HF: Form Vefp") verbose = core.get_option('SCF', "PRINT") Vefp = modify_Fock_permanent(self.molecule(), mints, verbose=verbose - 1) Vefp = core.Matrix.from_array(Vefp) self.H().add(Vefp) Horig = self.H().clone() self.Horig = Horig core.print_out( " QM/EFP: iterating Total Energy including QM/EFP Induction\n" ) core.timer_off("HF: Form Vefp") core.timer_on("HF: Form S/X") self.form_Shalf() core.timer_off("HF: Form S/X") core.timer_on("HF: Guess") self.guess() core.timer_off("HF: Guess") else: # We're reading the orbitals from the previous set of iterations. self.form_D() self.set_energies("Total Energy", self.compute_initial_E()) # turn off VV10 for iterations if core.get_option( 'SCF', "DFT_VV10_POSTSCF") and self.functional().vv10_b() > 0.0: core.print_out(" VV10: post-SCF option active \n \n") self.functional().set_lock(False) self.functional().set_do_vv10(False) self.functional().set_lock(True)
def scf_initialize(self): """Specialized initialization, compute integrals and does everything to prepare for iterations""" # Figure out memory distributions # Get memory in terms of doubles total_memory = (core.get_memory() / 8) * core.get_global_option("SCF_MEM_SAFETY_FACTOR") # Figure out how large the DFT collocation matrices are vbase = self.V_potential() if vbase: collocation_size = vbase.grid().collocation_size() if vbase.functional().ansatz() == 1: collocation_size *= 4 # First derivs elif vbase.functional().ansatz() == 2: collocation_size *= 10 # Second derivs else: collocation_size = 0 # Change allocation for collocation matrices based on DFT type jk = _build_jk(self, total_memory) jk_size = jk.memory_estimate() # Give remaining to collocation if total_memory > jk_size: collocation_memory = total_memory - jk_size # Give up to 10% to collocation elif (total_memory * 0.1) > collocation_size: collocation_memory = collocation_size else: collocation_memory = total_memory * 0.1 if collocation_memory > collocation_size: collocation_memory = collocation_size # Set constants self.iteration_ = 0 self.memory_jk_ = int(total_memory - collocation_memory) self.memory_collocation_ = int(collocation_memory) if self.get_print(): core.print_out(" ==> Integral Setup <==\n\n") # Initialize EFP efp_enabled = hasattr(self.molecule(), 'EFP') if efp_enabled: # EFP: Set QM system, options, and callback. Display efp geom in [A] efpobj = self.molecule().EFP core.print_out(efpobj.banner()) core.print_out( efpobj.geometry_summary(units_to_bohr=constants.bohr2angstroms)) efpptc, efpcoords, efpopts = get_qm_atoms_opts(self.molecule()) efpobj.set_point_charges(efpptc, efpcoords) efpobj.set_opts(efpopts, label='psi', append='psi') efpobj.set_electron_density_field_fn(efp_field_fn) # Initialize all integrals and perform the first guess if self.attempt_number_ == 1: mints = core.MintsHelper(self.basisset()) self.initialize_jk(self.memory_jk_, jk=jk) if self.V_potential(): self.V_potential().build_collocation_cache( self.memory_collocation_) core.timer_on("HF: Form core H") self.form_H() core.timer_off("HF: Form core H") if efp_enabled: # EFP: Add in permanent moment contribution and cache core.timer_on("HF: Form Vefp") verbose = core.get_option('SCF', "PRINT") Vefp = modify_Fock_permanent(self.molecule(), mints, verbose=verbose - 1) Vefp = core.Matrix.from_array(Vefp) self.H().add(Vefp) Horig = self.H().clone() self.Horig = Horig core.print_out( " QM/EFP: iterating Total Energy including QM/EFP Induction\n" ) core.timer_off("HF: Form Vefp") core.timer_on("HF: Form S/X") self.form_Shalf() core.timer_off("HF: Form S/X") core.print_out("\n ==> Pre-Iterations <==\n\n") core.timer_on("HF: Guess") self.guess() core.timer_off("HF: Guess") # Print out initial docc/socc/etc data if self.get_print(): lack_occupancy = core.get_local_option('SCF', 'GUESS') in ['SAD'] if core.get_global_option('GUESS') in ['SAD']: lack_occupancy = core.get_local_option('SCF', 'GUESS') in ['AUTO'] self.print_preiterations(small=lack_occupancy) else: self.print_preiterations(small=lack_occupancy) else: # We're reading the orbitals from the previous set of iterations. self.form_D() self.set_energies("Total Energy", self.compute_initial_E()) # turn off VV10 for iterations if core.get_option( 'SCF', "DFT_VV10_POSTSCF") and self.functional().vv10_b() > 0.0: core.print_out(" VV10: post-SCF option active \n \n") self.functional().set_lock(False) self.functional().set_do_vv10(False) self.functional().set_lock(True) # Print iteration header is_dfjk = core.get_global_option('SCF_TYPE').endswith('DF') diis_rms = core.get_option('SCF', 'DIIS_RMS_ERROR') core.print_out(" ==> Iterations <==\n\n") core.print_out( "%s Total Energy Delta E %s |[F,P]|\n\n" % (" " if is_dfjk else "", "RMS" if diis_rms else "MAX"))
def get_memory(): """Function to return the total memory allocation.""" return core.get_memory()
def compute_hessian(self, wfn, prog='psi4', geom=None, disp_points=3, disp_size=0.005, c4executable=None, c4kw={}): Natom = self.mol.natom() if prog.upper() == 'PSI4': self.pr("(ROA) Computing hessian with Psi4...\n") #Prepare geometry if geom is None: geom = self.analysis_geom_2D self.mol.set_geometry(core.Matrix.from_array(geom)) self.mol.fix_com(True) self.mol.fix_orientation(True) self.mol.reset_point_group('c1') # core.set_global_option('hessian_write', True) # compute the hessian, put in numpy format, then write out file15.dat file. psi4_hess = psi4.hessian(wfn, molecule=self.mol) npHess = psi4_hess.clone().np npHess = np.reshape(npHess, (3 * Natom * Natom, 3)) f = open('file15.dat', 'w') for i in range(npHess.shape[0]): f.write('{0:20.10f}{1:20.10f}{2:20.10f}\n'.format( npHess[i][0], npHess[i][1], npHess[i][2])) f.close() elif prog.upper() == 'CFOUR': self.pr("(ROA) Computing hessian with CFOUR...\n") kw = { 'CALC': wfn.upper(), # if basis not builtin C4, set BASIS=SPECIAL and SPECIAL_BASIS='name' 'BASIS': core.get_global_option('BASIS'), #'SPECIAL_BASIS' : '6-31G' 'VIB': 'EXACT', 'UNITS': 'BOHR', 'SCF_CONV': 9, 'MEM_UNIT': 'GB', 'MEMORY_SIZE': round(core.get_memory() // 1e9), 'SCF_DAMP': 600, # CFOUR's SCF is really poor at converging. 'SCF_EXPSTART': 300, 'SCF_MAXCYC': 600, } kw.update(c4kw) atom_symbols = [ self.mol.symbol(at) for at in range(self.mol.natom()) ] if c4executable is None: c4executable = 'run-cfour' c4 = CFOUR(self.analysis_geom_2D, atom_symbols, kw, title="hess-calc", executable=c4executable) c4.run() c4h = c4.parseHessian() # read the hessian output file (FCMFINAL) # Now rotate the Hessian into the original input orientation; fancy! c4coord = c4.parseGeometry() rmsd, mill = qcel.molutil.B787(c4coord, self.analysis_geom_2D, None, None, atoms_map=True, verbose=False) c4h[:] = mill.align_hessian(c4h) c4.writeFile15(c4h) else: raise Exception('Other hessian prog not yet implemented')
def compute_dipole_derivatives(self, wfn, prog='psi4', geom=None, disp_points=3, disp_size=0.001, c4kw={}): Natom = self.mol.natom() if prog.upper() == 'PSI4': # Lacking analytic derivatives, we will do fd of applied electric fields. We # alternately apply + and - electric fields in the x, y, and z directions, and # then take finite differences to get the dipole moment derivatives. self.pr( "(ROA) Computing dipole moment derivatives with Psi4 by f.d...\n" ) #Prepare geometry if geom is None: geom = self.analysis_geom_2D self.mol.set_geometry(core.Matrix.from_array(geom)) self.mol.fix_com(True) self.mol.fix_orientation(True) self.mol.reset_point_group('c1') N = self.mol.natom() if disp_points == 3: lambdas = [-1.0 * disp_size, 1.0 * disp_size] elif disp_points == 5: lambdas = [ -2.0 * disp_size, -1.0 * disp_size, 1.0 * disp_size, +2.0 * disp_size ] DmuxDx = psi4.core.Matrix("Dipole derivatives mu_x", N, 3) DmuyDx = psi4.core.Matrix("Dipole derivatives mu_y", N, 3) DmuzDx = psi4.core.Matrix("Dipole derivatives mu_z", N, 3) for dipole_xyz, dipole_vector in enumerate([[1, 0, 0], [0, 1, 0], [0, 0, 1]]): dx = [] for l in lambdas: core.set_global_option('perturb_h', True) core.set_global_option('perturb_with', 'dipole') scaled_dipole_vector = [] for x in dipole_vector: scaled_dipole_vector.append(x * l) core.set_global_option('perturb_dipole', scaled_dipole_vector) dx.append(psi4.gradient(wfn)) for A in range(N): for xyz in range(3): if disp_points == 3: val = (dx[1].get(A, xyz) - dx[0].get(A, xyz)) / (2.0 * disp_size) elif disp_points == 5: val = (dx[0].get(A,xyz) - 8.0*dx[1].get(A,xyz) \ + 8.0*dx[2].get(A,xyz) - dx[3].get(A,xyz)) / (12.0*disp_size) if dipole_xyz == 0: DmuxDx.set(A, xyz, val) elif dipole_xyz == 1: DmuyDx.set(A, xyz, val) elif dipole_xyz == 2: DmuzDx.set(A, xyz, val) core.set_global_option('PERTURB_H', 0) core.set_global_option('PERTURB_DIPOLE', '') # write out a file17 with the dipole moment derivatives f = open('file17.dat', 'w') for i in range(N): f.write('{0:20.10f}{1:20.10f}{2:20.10f}\n'.format( DmuxDx.get(i, 0), DmuxDx.get(i, 1), DmuxDx.get(i, 2))) for i in range(N): f.write('{0:20.10f}{1:20.10f}{2:20.10f}\n'.format( DmuyDx.get(i, 0), DmuyDx.get(i, 1), DmuyDx.get(i, 2))) for i in range(N): f.write('{0:20.10f}{1:20.10f}{2:20.10f}\n'.format( DmuzDx.get(i, 0), DmuzDx.get(i, 1), DmuzDx.get(i, 2))) f.close() elif prog.upper() == 'CFOUR': self.pr( "(ROA) Reading dipole moment derivatives from CFOUR's DIPDER.\n" ) kw = { 'CALC': wfn.upper(), 'BASIS': core.get_global_option('BASIS'), 'VIB': 'EXACT', 'UNITS': 'BOHR', 'VIB': 'EXACT', 'UNITS': 'BOHR', 'SCF_CONV': 9, 'MEM_UNIT': 'GB', 'MEMORY_SIZE': round(core.get_memory() // 1e9), 'SCF_DAMP': 600, # CFOUR's SCF is really poor at converging. 'SCF_EXPSTART': 300, 'SCF_MAXCYC': 600, } kw.update(c4kw) atom_symbols = [ self.mol.symbol(at) for at in range(self.mol.natom()) ] c4 = CFOUR(self.analysis_geom_2D, atom_symbols, kw, "input for DIPDIR read") (c4dipx, c4dipy, c4dipz) = c4.parseDIPDER() # Now rotate to input orientation c4coord = c4.parseGeometry() rmsd, mill = qcel.molutil.B787(c4coord, self.analysis_geom_2D, None, None, atoms_map=True, verbose=False) RotMat = mill.rotation # For each atom for field direction by nuclear direction 3x3 and transform it. for at in range(Natom): DIPDERatom = np.zeros((3, 3)) DIPDERatom[0, :] = c4dipx[at, :] DIPDERatom[1, :] = c4dipy[at, :] DIPDERatom[2, :] = c4dipz[at, :] DIPDERatom[:] = np.dot(RotMat.T, np.dot(DIPDERatom, RotMat)) c4dipx[at][:] = DIPDERatom[0, :] c4dipy[at][:] = DIPDERatom[1, :] c4dipz[at][:] = DIPDERatom[2, :] c4.writeFile17(c4dipx, c4dipy, c4dipz) else: raise Exception('Other muder prog not yet implemented') return
def compute(self, client: Optional["FractalClient"] = None): """Run quantum chemistry.""" from psi4.driver import pp if self.computed: return if client: self.computed = True from qcportal.models import KeywordSet, Molecule # Build the keywords keyword_id = client.add_keywords( [KeywordSet(values=self.keywords)])[0] # Build the molecule mol = Molecule(**self.molecule.to_schema(dtype=2)) r = client.add_compute("psi4", self.method, self.basis, self.driver, keyword_id, [mol]) self.result_id = r.ids[0] # NOTE: The following will re-run errored jobs by default if self.result_id in r.existing: ret = client.query_tasks(base_result=self.result_id) if ret: if ret[0].status == "ERROR": client.modify_tasks("restart", base_result=self.result_id) logger.info("Resubmitting Errored Job {}".format( self.result_id)) elif ret[0].status == "COMPLETE": logger.debug("Job already completed {}".format( self.result_id)) else: logger.debug("Job already completed {}".format( self.result_id)) else: logger.debug("Submitting AtomicResult {}".format( self.result_id)) return logger.info( f'<<< JSON launch ... {self.molecule.schoenflies_symbol()} {self.molecule.nuclear_repulsion_energy()}' ) gof = core.get_output_file() # EITHER ... # from psi4.driver import schema_wrapper # self.result = schema_wrapper.run_qcschema(self.plan()) # ... OR ... self.result = qcng.compute( self.plan(), "psi4", raise_error=True, # local_options below suitable for serial mode where each job takes all the resources of the parent Psi4 job. # distributed runs through QCFractal will likely need a different setup. local_options={ # B -> GiB "memory": core.get_memory() / (2**30), "ncores": core.get_num_threads(), }, ) # ... END #pp.pprint(self.result.dict()) #print("... JSON returns >>>") core.set_output_file(gof, True) core.reopen_outfile() logger.debug(pp.pformat(self.result.dict())) core.print_out(_drink_filter(self.result.dict()["stdout"])) self.computed = True
def write_zmat(name, dertype, molecule): """Returns string with contents of Cfour ZMAT file as gathered from active molecule, current keyword settings, and cfour {...} block. """ # Handle memory mem = int(0.000001 * core.get_memory()) if mem == 524: memcmd, memkw = '', {} else: memcmd, memkw = qcdb.cfour.muster_memory(mem) # Handle molecule and basis set if molecule.name() == 'blank_molecule_psi4_yo': molcmd, molkw = '', {} bascmd, baskw = '', {} core.set_local_option('CFOUR', 'TRANSLATE_PSI4', False) else: molecule.update_geometry() #print(molecule.create_psi4_string_from_molecule()) qcdbmolecule = qcdb.Molecule( molecule.create_psi4_string_from_molecule()) qcdbmolecule.tagline = molecule.name() molcmd, molkw = qcdbmolecule.format_molecule_for_cfour() if core.get_global_option('BASIS') in ["", "(AUTO)"]: bascmd, baskw = '', {} else: user_pg = molecule.schoenflies_symbol() molecule.reset_point_group( 'c1') # need basis printed for *every* atom qbs = core.BasisSet.build(molecule, "BASIS", core.get_global_option('BASIS')) if qbs.has_ECP(): raise ValidationError("""ECPs not hooked up for Cfour""") with open('GENBAS', 'w') as cfour_basfile: cfour_basfile.write(qbs.genbas()) core.print_out( ' GENBAS loaded from Psi4 LibMints for basis %s\n' % (core.get_global_option('BASIS'))) molecule.reset_point_group(user_pg) molecule.update_geometry() bascmd, baskw = qcdbmolecule.format_basis_for_cfour( qbs.has_puream()) # Handle psi4 keywords implying cfour keyword values if core.get_option('CFOUR', 'TRANSLATE_PSI4'): psicmd, psikw = qcdb.cfour.muster_psi4options( p4util.prepare_options_for_modules(changedOnly=True)) else: psicmd, psikw = '', {} # Handle calc type and quantum chemical method mdccmd, mdckw = qcdb.cfour.muster_modelchem(name, dertype) # Handle calc type and quantum chemical method mdccmd, mdckw = qcdb.cfour.muster_modelchem(name, dertype) # Handle driver vs input/default keyword reconciliation userkw = p4util.prepare_options_for_modules() userkw = qcdb.options.reconcile_options(userkw, memkw) userkw = qcdb.options.reconcile_options(userkw, molkw) userkw = qcdb.options.reconcile_options(userkw, baskw) userkw = qcdb.options.reconcile_options(userkw, psikw) userkw = qcdb.options.reconcile_options(userkw, mdckw) # Handle conversion of psi4 keyword structure into cfour format optcmd = qcdb.options.prepare_options_for_cfour(userkw) # Handle text to be passed untouched to cfour litcmd = core.get_global_option('LITERAL_CFOUR') # Assemble ZMAT pieces zmat = memcmd + molcmd + optcmd + mdccmd + psicmd + bascmd + litcmd if len(re.findall(r'^\*(ACES2|CFOUR|CRAPS)\(', zmat, re.MULTILINE)) != 1: core.print_out('\n Faulty ZMAT constructed:\n%s' % (zmat)) raise ValidationError(""" Multiple *CFOUR(...) blocks in input. This usually arises because molecule or options are specified both the psi4 way through molecule {...} and set ... and the cfour way through cfour {...}.""") return zmat
def scf_initialize(self): """Specialized initialization, compute integrals and does everything to prepare for iterations""" # Figure out memory distributions # Get memory in terms of doubles total_memory = (core.get_memory() / 8) * core.get_global_option("SCF_MEM_SAFETY_FACTOR") # Figure out how large the DFT collocation matrices are vbase = self.V_potential() if vbase: collocation_size = vbase.grid().collocation_size() if vbase.functional().ansatz() == 1: collocation_size *= 4 # First derivs elif vbase.functional().ansatz() == 2: collocation_size *= 10 # Second derivs else: collocation_size = 0 # Change allocation for collocation matrices based on DFT type jk = _build_jk(self, total_memory) jk_size = jk.memory_estimate() # Give remaining to collocation if total_memory > jk_size: collocation_memory = total_memory - jk_size # Give up to 10% to collocation elif (total_memory * 0.1) > collocation_size: collocation_memory = collocation_size else: collocation_memory = total_memory * 0.1 if collocation_memory > collocation_size: collocation_memory = collocation_size # Set constants self.iteration_ = 0 self.memory_jk_ = int(total_memory - collocation_memory) self.memory_collocation_ = int(collocation_memory) # Print out initial docc/socc/etc data if self.get_print(): core.print_out(" ==> Pre-Iterations <==\n\n") self.print_preiterations() if self.get_print(): core.print_out(" ==> Integral Setup <==\n\n") # Initialize EFP efp_enabled = hasattr(self.molecule(), 'EFP') if efp_enabled: # EFP: Set QM system, options, and callback. Display efp geom in [A] efpobj = self.molecule().EFP core.print_out(efpobj.banner()) core.print_out(efpobj.geometry_summary(units_to_bohr=constants.bohr2angstroms)) efpptc, efpcoords, efpopts = get_qm_atoms_opts(self.molecule()) efpobj.set_point_charges(efpptc, efpcoords) efpobj.set_opts(efpopts, label='psi', append='psi') efpobj.set_electron_density_field_fn(field_fn) # Initilize all integratals and perform the first guess if self.attempt_number_ == 1: mints = core.MintsHelper(self.basisset()) if core.get_global_option('RELATIVISTIC') in ['X2C', 'DKH']: mints.set_rel_basisset(self.get_basisset('BASIS_RELATIVISTIC')) mints.one_electron_integrals() self.initialize_jk(self.memory_jk_, jk=jk) if self.V_potential(): self.V_potential().build_collocation_cache(self.memory_collocation_) core.timer_on("HF: Form core H") self.form_H() core.timer_off("HF: Form core H") if efp_enabled: # EFP: Add in permanent moment contribution and cache core.timer_on("HF: Form Vefp") verbose = core.get_option('SCF', "PRINT") Vefp = modify_Fock_permanent(self.molecule(), mints, verbose=verbose-1) Vefp = core.Matrix.from_array(Vefp) self.H().add(Vefp) Horig = self.H().clone() self.Horig = Horig core.print_out(" QM/EFP: iterating Total Energy including QM/EFP Induction\n") core.timer_off("HF: Form Vefp") core.timer_on("HF: Form S/X") self.form_Shalf() core.timer_off("HF: Form S/X") core.timer_on("HF: Guess") self.guess() core.timer_off("HF: Guess") else: # We're reading the orbitals from the previous set of iterations. self.form_D() self.set_energies("Total Energy", self.compute_initial_E()) # turn off VV10 for iterations if core.get_option('SCF', "DFT_VV10_POSTSCF") and self.functional().vv10_b() > 0.0: core.print_out(" VV10: post-SCF option active \n \n") self.functional().set_lock(False) self.functional().set_do_vv10(False) self.functional().set_lock(True)
def get_memory() -> int: """Return the total memory allocation in bytes.""" return core.get_memory()