def mr_dsrg_pt2(job_type, forte_objects, ints, options): """ Driver to perform a MCSRGPT2_MO computation. :return: the computed energy """ final_energy = 0.0 ref_wfn, state_weights_map, mo_space_info, scf_info, fcidump = forte_objects state = forte.make_state_info_from_psi(options) # generate a list of states with their own weights state_map = forte.to_state_nroots_map(state_weights_map) cas_type = options.get_str("ACTIVE_SPACE_SOLVER") actv_type = options.get_str("FCIMO_ACTV_TYPE") if actv_type == "CIS" or actv_type == "CISD": raise Exception('Forte: VCIS/VCISD is not supported for MR-DSRG-PT2') max_rdm_level = 2 if options.get_str("THREEPDC") == "ZERO" else 3 as_ints = forte.make_active_space_ints(mo_space_info, ints, "ACTIVE", ["RESTRICTED_DOCC"]) ci = forte.make_active_space_solver(cas_type, state_map, scf_info, mo_space_info, as_ints, options) ci.compute_energy() rdms = ci.compute_average_rdms(state_weights_map, max_rdm_level, forte.RDMsType.spin_dependent) semi = forte.SemiCanonical(mo_space_info, ints, options) semi.semicanonicalize(rdms) mcsrgpt2_mo = forte.MCSRGPT2_MO(rdms, options, ints, mo_space_info) energy = mcsrgpt2_mo.compute_energy() return energy
def prepare_ints_rdms(wfn, mo_spaces, rdm_level=3, rdm_type=forte.RDMsType.spin_dependent): """ Preparation step for DSRG: compute a CAS and its RDMs. :param wfn: reference wave function from psi4 :param mo_spaces: a dictionary {mo_space: occupation}, e.g., {'ACTIVE': [0,0,0,0]} :param rdm_level: max RDM to be computed :param rdm_type: RDMs type: spin_dependent or spin_free :return: a tuple of (reference energy, MOSpaceInfo, ForteIntegrals, RDMs) """ forte_objects = prepare_forte_objects(wfn, mo_spaces) ints = forte_objects['ints'] as_ints = forte_objects['as_ints'] scf_info = forte_objects['scf_info'] mo_space_info = forte_objects['mo_space_info'] state_weights_map = forte_objects['state_weights_map'] # build a map {StateInfo: a list of weights} for multi-state computations state_weights_map = forte.make_state_weights_map(forte.forte_options, mo_space_info) # converts {StateInfo: weights} to {StateInfo: nroots} state_map = forte.to_state_nroots_map(state_weights_map) # create an active space solver object and compute the energy as_solver_type = 'FCI' as_solver = forte.make_active_space_solver(as_solver_type, state_map, scf_info, mo_space_info, as_ints, forte.forte_options) state_energies_list = as_solver.compute_energy( ) # a map {StateInfo: a list of energies} # compute averaged energy --- reference energy for DSRG Eref = forte.compute_average_state_energy(state_energies_list, state_weights_map) # compute RDMs rdms = as_solver.compute_average_rdms(state_weights_map, rdm_level, rdm_type) # semicanonicalize orbitals semi = forte.SemiCanonical(mo_space_info, ints, forte.forte_options) semi.semicanonicalize(rdms, rdm_level) return { 'reference_energy': Eref, 'mo_space_info': mo_space_info, 'ints': ints, 'rdms': rdms }
def _run(self): """Run an active space solver computation""" # compute the guess orbitals if not self.input_nodes[0].executed: flog('info', 'ActiveSpaceSolver: MOs not available in mo_solver. Calling mo_solver run()') self.input_nodes[0].run() else: flog('info', 'ActiveSpaceSolver: MOs read from mo_solver object') # make the state_map state_map = to_state_nroots_map(self._states) # make the mo_space_info object self.make_mo_space_info(self._mo_space_info_map) # prepare the options options = {'E_CONVERGENCE': self.e_convergence, 'R_CONVERGENCE': self.r_convergence} # values from self._options (user specified) replace those from options full_options = {**options, **self._options} flog('info', 'ActiveSpaceSolver: adding options') local_options = ForteOptions(forte_options) local_options.set_from_dict(full_options) flog('info', 'ActiveSpaceSolver: getting integral from the model object') self.ints = self.model.ints(self.data, local_options) # Make an active space integral object flog('info', 'ActiveSpaceSolver: making active space integrals') self.as_ints = make_active_space_ints(self.mo_space_info, self.ints, "ACTIVE", ["RESTRICTED_DOCC"]) # create an active space solver object and compute the energy flog('info', 'ActiveSpaceSolver: creating active space solver object') self._active_space_solver = make_active_space_solver( self._type, state_map, self.scf_info, self.mo_space_info, self.as_ints, local_options ) flog('info', 'ActiveSpaceSolver: calling compute_energy() on active space solver object') state_energies_list = self._active_space_solver.compute_energy() flog('info', 'ActiveSpaceSolver: compute_energy() done') flog('info', f'ActiveSpaceSolver: active space energy = {state_energies_list}') self._results.add('active space energy', state_energies_list, 'Active space energy', 'Eh') return self
def forte_driver(state_weights_map, scf_info, options, ints, mo_space_info): """ Driver to perform a Forte calculation using new solvers. :param state_weights_map: dictionary of {state: weights} :param scf_info: a SCFInfo object of Forte :param options: a ForteOptions object of Forte :param ints: a ForteIntegrals object of Forte :param mo_space_info: a MOSpaceInfo object of Forte :return: the computed energy """ # map state to number of roots state_map = forte.to_state_nroots_map(state_weights_map) # create an active space solver object and compute the energy active_space_solver_type = options.get_str('ACTIVE_SPACE_SOLVER') as_ints = forte.make_active_space_ints(mo_space_info, ints, "ACTIVE", ["RESTRICTED_DOCC"]) active_space_solver = forte.make_active_space_solver( active_space_solver_type, state_map, scf_info, mo_space_info, as_ints, options) state_energies_list = active_space_solver.compute_energy() if options.get_bool('SPIN_ANALYSIS'): rdms = active_space_solver.compute_average_rdms( state_weights_map, 2, forte.RDMsType.spin_dependent) forte.perform_spin_analysis(rdms, options, mo_space_info, as_ints) # solver for dynamical correlation from DSRG correlation_solver_type = options.get_str('CORRELATION_SOLVER') if correlation_solver_type != 'NONE': dsrg_proc = ProcedureDSRG(active_space_solver, state_weights_map, mo_space_info, ints, options, scf_info) return_en = dsrg_proc.compute_energy() dsrg_proc.print_summary() dsrg_proc.push_to_psi4_environment() else: average_energy = forte.compute_average_state_energy( state_energies_list, state_weights_map) return_en = average_energy return return_en
def forte_driver(state_weights_map, scf_info, options, ints, mo_space_info): max_rdm_level = 3 # TODO: set this (Francesco) return_en = 0.0 state_map = forte.to_state_nroots_map(state_weights_map) # Create an active space solver object and compute the energy active_space_solver_type = options.get_str('ACTIVE_SPACE_SOLVER') as_ints = forte.make_active_space_ints(mo_space_info, ints, "ACTIVE", ["RESTRICTED_DOCC"]) active_space_solver = forte.make_active_space_solver( active_space_solver_type, state_map, scf_info, mo_space_info, as_ints, options) active_space_solver.set_max_rdm_level(max_rdm_level) state_energies_list = active_space_solver.compute_energy() # Notes (York): # cases to run active space solver: reference relaxation, state-average dsrg # cases to run contracted ci solver (will be put in ActiveSpaceSolver): contracted state-average dsrg Etemp1, Etemp2 = 0.0, 0.0 # Create a dynamical correlation solver object correlation_solver_type = options.get_str('CORRELATION_SOLVER') if correlation_solver_type != 'NONE': # Grab the reference reference = active_space_solver.compute_average_reference( state_weights_map) # TODO: this should be chosen in a smart way # Compute unitary matrices Ua and Ub that rotate the orbitals to the semicanonical basis semi = forte.SemiCanonical(mo_space_info, ints, options) if options.get_bool("SEMI_CANONICAL"): semi.semicanonicalize(reference, max_rdm_level) Ua = semi.Ua_t() Ub = semi.Ub_t() dsrg = forte.make_dsrg_method(correlation_solver_type, reference, scf_info, options, ints, mo_space_info) dsrg.set_Uactv(Ua, Ub) Edsrg = dsrg.compute_energy() psi4.core.set_scalar_variable('UNRELAXED ENERGY', Edsrg) # dipole moment related do_dipole = options.get_bool("DSRG_DIPOLE") if do_dipole: if correlation_solver_type == 'MRDSRG' or correlation_solver_type == 'THREE-DSRG-MRPT2': do_dipole = False psi4.core.print_out( "\n !Dipole moment is not implemented for {}.".format( correlation_solver_type)) warnings.warn("Dipole moment is not implemented for MRDSRG.", UserWarning) udm_x = psi4.core.variable('UNRELAXED DIPOLE X') udm_y = psi4.core.variable('UNRELAXED DIPOLE Y') udm_z = psi4.core.variable('UNRELAXED DIPOLE Z') udm_t = psi4.core.variable('UNRELAXED DIPOLE') def dipole_routine(dsrg_method, reference): dipole_moments = dsrg_method.nuclear_dipole() dipole_dressed = dsrg_method.deGNO_DMbar_actv() for i in range(3): dipole_moments[i] += dipole_dressed[i].contract_with_densities( reference) dm_total = math.sqrt(sum([i * i for i in dipole_moments])) dipole_moments.append(dm_total) return dipole_moments # determine the relaxation procedure relax_mode = options.get_str("RELAX_REF") is_multi_state = True if options.get_str( "CALC_TYPE") != "SS" else False if relax_mode == 'NONE' and is_multi_state: relax_mode = 'ONCE' if relax_mode == 'NONE': return Edsrg elif relax_mode == 'ONCE': maxiter = 1 elif relax_mode == 'TWICE': maxiter = 2 else: maxiter = options.get_int('MAXITER_RELAX_REF') # filter out some ms-dsrg algorithms ms_dsrg_algorithm = options.get_str("DSRG_MULTI_STATE") if is_multi_state and ("SA" not in ms_dsrg_algorithm): raise NotImplementedError( "MS or XMS is disabled due to the reconstruction.") if ms_dsrg_algorithm == "SA_SUB" and relax_mode != 'ONCE': raise NotImplementedError( "Need to figure out how to compute relaxed SA density.") # prepare for reference relaxation iteration relax_conv = options.get_double("RELAX_E_CONVERGENCE") e_conv = options.get_double("E_CONVERGENCE") converged = False if relax_mode != 'ONCE' and relax_mode != 'TWICE' else True # store (unrelaxed, relaxed) quantities dsrg_energies = [] dsrg_dipoles = [] for N in range(maxiter): # Grab the effective Hamiltonian in the actice space ints_dressed = dsrg.compute_Heff_actv() # Compute the energy if is_multi_state and ms_dsrg_algorithm == "SA_SUB": state_energies_list = active_space_solver.compute_contracted_energy( ints_dressed) Erelax = forte.compute_average_state_energy( state_energies_list, state_weights_map) return Erelax else: # Make a new ActiveSpaceSolver with the new ints as_solver_relaxed = forte.make_active_space_solver( active_space_solver_type, state_map, scf_info, mo_space_info, ints_dressed, options) as_solver_relaxed.set_max_rdm_level(max_rdm_level) state_energies_list = as_solver_relaxed.compute_energy() Erelax = forte.compute_average_state_energy( state_energies_list, state_weights_map) dsrg_energies.append((Edsrg, Erelax)) if do_dipole: if is_multi_state: psi4.core.print_out( "\n !DSRG transition dipoles are disabled temporarily." ) warnings.warn( "DSRG transition dipoles are disabled temporarily.", UserWarning) else: reference = as_solver_relaxed.compute_average_reference( state_weights_map) x, y, z, t = dipole_routine(dsrg, reference) dsrg_dipoles.append( ((udm_x, udm_y, udm_z, udm_t), (x, y, z, t))) psi4.core.print_out( "\n\n {} partially relaxed dipole moment:".format( correlation_solver_type)) psi4.core.print_out( "\n X: {:10.6f} Y: {:10.6f}" " Z: {:10.6f} Total: {:10.6f}\n".format(x, y, z, t)) # test convergence and break loop if abs(Edsrg - Etemp1) < relax_conv and abs(Erelax - Etemp2) < relax_conv \ and abs(Edsrg - Erelax) < e_conv: converged = True break Etemp1, Etemp2 = Edsrg, Erelax # continue iterations if N + 1 != maxiter: # Compute the reference in the original basis # reference available if done relaxed dipole if do_dipole and (not is_multi_state): reference = semi.transform_reference( Ua, Ub, reference, max_rdm_level) else: reference = semi.transform_reference( Ua, Ub, as_solver_relaxed.compute_average_reference( state_weights_map), max_rdm_level) # Now semicanonicalize the reference and orbitals semi.semicanonicalize(reference, max_rdm_level) Ua = semi.Ua_t() Ub = semi.Ub_t() # Compute DSRG in the semicanonical basis dsrg = forte.make_dsrg_method(correlation_solver_type, reference, scf_info, options, ints, mo_space_info) dsrg.set_Uactv(Ua, Ub) Edsrg = dsrg.compute_energy() if do_dipole: udm_x = psi4.core.variable('UNRELAXED DIPOLE X') udm_y = psi4.core.variable('UNRELAXED DIPOLE Y') udm_z = psi4.core.variable('UNRELAXED DIPOLE Z') udm_t = psi4.core.variable('UNRELAXED DIPOLE') # printing if (not is_multi_state) or maxiter > 1: psi4.core.print_out( "\n\n => {} Reference Relaxation Energy Summary <=\n".format( correlation_solver_type)) indent = ' ' * 4 dash = '-' * 71 title = indent + "{:5} {:>31} {:>31}\n".format( ' ', "Fixed Ref. (a.u.)", "Relaxed Ref. (a.u.)") title += indent + "{} {} {}\n".format(' ' * 5, '-' * 31, '-' * 31) title += indent + "{:5} {:>20} {:>10} {:>20} {:>10}\n".format( "Iter.", "Total Energy", "Delta", "Total Energy", "Delta") psi4.core.print_out("\n{}".format(title + indent + dash)) E0_old, E1_old = 0.0, 0.0 for n, pair in enumerate(dsrg_energies): E0, E1 = pair psi4.core.print_out("\n{}{:>5} {:>20.12f} {:>10.3e}" " {:>20.12f} {:>10.3e}".format( indent, n + 1, E0, E0 - E0_old, E1, E1 - E1_old)) E0_old, E1_old = E0, E1 psi4.core.print_out("\n{}{}".format(indent, dash)) if do_dipole and (not is_multi_state): psi4.core.print_out( "\n\n => {} Reference Relaxation Dipole Summary <=\n".format( correlation_solver_type)) psi4.core.print_out("\n {} unrelaxed dipole moment:".format( correlation_solver_type)) psi4.core.print_out( "\n X: {:10.6f} Y: {:10.6f} " "Z: {:10.6f} Total: {:10.6f}\n".format(*dsrg_dipoles[0][0])) psi4.core.set_scalar_variable('UNRELAXED DIPOLE', dsrg_dipoles[0][0][-1]) psi4.core.print_out( "\n {} partially relaxed dipole moment:".format( correlation_solver_type)) psi4.core.print_out( "\n X: {:10.6f} Y: {:10.6f} " "Z: {:10.6f} Total: {:10.6f}\n".format(*dsrg_dipoles[0][1])) psi4.core.set_scalar_variable('PARTIALLY RELAXED DIPOLE', dsrg_dipoles[0][1][-1]) if maxiter > 1: psi4.core.print_out("\n {} relaxed dipole moment:".format( correlation_solver_type)) psi4.core.print_out("\n X: {:10.6f} Y: {:10.6f} " "Z: {:10.6f} Total: {:10.6f}\n".format( *dsrg_dipoles[1][0])) psi4.core.set_scalar_variable('RELAXED DIPOLE', dsrg_dipoles[1][0][-1]) # set energies to environment psi4.core.set_scalar_variable('PARTIALLY RELAXED ENERGY', dsrg_energies[0][1]) if maxiter > 1: psi4.core.set_scalar_variable('RELAXED ENERGY', dsrg_energies[1][0]) # throw not converging error if relaxation not converged if not converged: psi4.core.set_scalar_variable('CURRENT UNRELAXED ENERGY', dsrg_energies[-1][0]) psi4.core.set_scalar_variable('CURRENT RELAXED ENERGY', dsrg_energies[-1][1]) psi4.core.set_scalar_variable('CURRENT ENERGY', dsrg_energies[-1][1]) raise psi4.core.ConvergenceError( "DSRG relaxation does not converge in {} cycles".format( maxiter)) else: if relax_mode != 'ONCE' and relax_mode != 'TWICE': psi4.core.set_scalar_variable('FULLY RELAXED ENERGY', dsrg_energies[-1][1]) psi4.core.set_scalar_variable('CURRENT ENERGY', dsrg_energies[-1][1]) if do_dipole and (not is_multi_state): psi4.core.print_out( "\n {} fully relaxed dipole moment:".format( correlation_solver_type)) psi4.core.print_out( "\n X: {:10.6f} Y: {:10.6f} " "Z: {:10.6f} Total: {:10.6f}\n".format( *dsrg_dipoles[-1][1])) psi4.core.set_scalar_variable('FULLY RELAXED DIPOLE', dsrg_dipoles[-1][1][-1]) return Erelax else: average_energy = forte.compute_average_state_energy( state_energies_list, state_weights_map) return_en = average_energy return return_en
def forte_driver(state_weights_map, scf_info, options, ints, mo_space_info): max_rdm_level = 3 # TODO: set this (Francesco) return_en = 0.0 state_map = forte.to_state_nroots_map(state_weights_map) # Create an active space solver object and compute the energy active_space_solver_type = options.get_str('ACTIVE_SPACE_SOLVER') as_ints = forte.make_active_space_ints(mo_space_info, ints, "ACTIVE", ["RESTRICTED_DOCC"]); active_space_solver = forte.make_active_space_solver(active_space_solver_type,state_map,scf_info,mo_space_info,as_ints,options) state_energies_list = active_space_solver.compute_energy() # Notes (York): # cases to run active space solver: reference relaxation, state-average dsrg # cases to run contracted ci solver (will be put in ActiveSpaceSolver): contracted state-average dsrg Etemp1, Etemp2 = 0.0, 0.0 # Create a dynamical correlation solver object correlation_solver_type = options.get_str('CORRELATION_SOLVER') if correlation_solver_type != 'NONE': # Grab the reference rdms = active_space_solver.compute_average_rdms(state_weights_map, 3) # TODO: max_rdm_level should be chosen in a smart way # Compute unitary matrices Ua and Ub that rotate the orbitals to the semicanonical basis semi = forte.SemiCanonical(mo_space_info, ints, options) if options.get_bool("SEMI_CANONICAL"): semi.semicanonicalize(rdms, max_rdm_level) Ua = semi.Ua_t() Ub = semi.Ub_t() dsrg = forte.make_dsrg_method(correlation_solver_type, rdms, scf_info, options, ints, mo_space_info) dsrg.set_Uactv(Ua, Ub) Edsrg = dsrg.compute_energy() psi4.core.set_scalar_variable('UNRELAXED ENERGY', Edsrg) # dipole moment related do_dipole = options.get_bool("DSRG_DIPOLE") if do_dipole: if correlation_solver_type == 'MRDSRG' or correlation_solver_type == 'THREE-DSRG-MRPT2': do_dipole = False psi4.core.print_out("\n !Dipole moment is not implemented for {}.".format(correlation_solver_type)) warnings.warn("Dipole moment is not implemented for MRDSRG.", UserWarning) udm_x = psi4.core.variable('UNRELAXED DIPOLE X') udm_y = psi4.core.variable('UNRELAXED DIPOLE Y') udm_z = psi4.core.variable('UNRELAXED DIPOLE Z') udm_t = psi4.core.variable('UNRELAXED DIPOLE') def dipole_routine(dsrg_method, rdms): dipole_moments = dsrg_method.nuclear_dipole() dipole_dressed = dsrg_method.deGNO_DMbar_actv() for i in range(3): dipole_moments[i] += dipole_dressed[i].contract_with_rdms(rdms) dm_total = math.sqrt(sum([i * i for i in dipole_moments])) dipole_moments.append(dm_total) return dipole_moments # determine the relaxation procedure relax_mode = options.get_str("RELAX_REF") is_multi_state = True if options.get_str("CALC_TYPE") != "SS" else False if relax_mode == 'NONE' and is_multi_state: relax_mode = 'ONCE' if relax_mode == 'NONE': return Edsrg elif relax_mode == 'ONCE': maxiter = 1 elif relax_mode == 'TWICE': maxiter = 2 else: maxiter = options.get_int('MAXITER_RELAX_REF') # filter out some ms-dsrg algorithms ms_dsrg_algorithm = options.get_str("DSRG_MULTI_STATE") if is_multi_state and ("SA" not in ms_dsrg_algorithm): raise NotImplementedError("MS or XMS is disabled due to the reconstruction.") if ms_dsrg_algorithm == "SA_SUB" and relax_mode != 'ONCE': raise NotImplementedError("Need to figure out how to compute relaxed SA density.") # prepare for reference relaxation iteration relax_conv = options.get_double("RELAX_E_CONVERGENCE") e_conv = options.get_double("E_CONVERGENCE") converged = False if relax_mode != 'ONCE' and relax_mode != 'TWICE' else True # store (unrelaxed, relaxed) quantities dsrg_energies = [] dsrg_dipoles = [] for N in range(maxiter): # Grab the effective Hamiltonian in the actice space ints_dressed = dsrg.compute_Heff_actv() # Compute the energy if is_multi_state and ms_dsrg_algorithm == "SA_SUB": sa_sub_max_rdm = 2 # TODO: This should be 3 if do_hbar3 is true state_energies_list = active_space_solver.compute_contracted_energy(ints_dressed, sa_sub_max_rdm) Erelax = forte.compute_average_state_energy(state_energies_list,state_weights_map) return Erelax else: # Make a new ActiveSpaceSolver with the new ints as_solver_relaxed = forte.make_active_space_solver(active_space_solver_type, state_map,scf_info, mo_space_info,ints_dressed, options) state_energies_list = as_solver_relaxed.compute_energy() Erelax = forte.compute_average_state_energy(state_energies_list,state_weights_map) dsrg_energies.append((Edsrg, Erelax)) if do_dipole: if is_multi_state: psi4.core.print_out("\n !DSRG transition dipoles are disabled temporarily.") warnings.warn("DSRG transition dipoles are disabled temporarily.", UserWarning) else: rdms = as_solver_relaxed.compute_average_rdms(state_weights_map, 3) x, y, z, t = dipole_routine(dsrg, rdms) dsrg_dipoles.append(((udm_x, udm_y, udm_z, udm_t), (x, y, z, t))) psi4.core.print_out("\n\n {} partially relaxed dipole moment:".format(correlation_solver_type)) psi4.core.print_out("\n X: {:10.6f} Y: {:10.6f}" " Z: {:10.6f} Total: {:10.6f}\n".format(x, y, z, t)) # test convergence and break loop if abs(Edsrg - Etemp1) < relax_conv and abs(Erelax - Etemp2) < relax_conv \ and abs(Edsrg - Erelax) < e_conv: converged = True break Etemp1, Etemp2 = Edsrg, Erelax # continue iterations if N + 1 != maxiter: # Compute the rdms in the original basis # rdms available if done relaxed dipole if do_dipole and (not is_multi_state): rdms = semi.transform_rdms(Ua, Ub, rdms, max_rdm_level) else: rdms = semi.transform_rdms(Ua, Ub, as_solver_relaxed.compute_average_rdms(state_weights_map, 3), max_rdm_level) # Now semicanonicalize the reference and orbitals semi.semicanonicalize(rdms, max_rdm_level) Ua = semi.Ua_t() Ub = semi.Ub_t() # Compute DSRG in the semicanonical basis dsrg = forte.make_dsrg_method(correlation_solver_type, rdms, scf_info, options, ints, mo_space_info) dsrg.set_Uactv(Ua, Ub) Edsrg = dsrg.compute_energy() if do_dipole: udm_x = psi4.core.variable('UNRELAXED DIPOLE X') udm_y = psi4.core.variable('UNRELAXED DIPOLE Y') udm_z = psi4.core.variable('UNRELAXED DIPOLE Z') udm_t = psi4.core.variable('UNRELAXED DIPOLE') # printing if (not is_multi_state) or maxiter > 1: psi4.core.print_out("\n\n => {} Reference Relaxation Energy Summary <=\n".format(correlation_solver_type)) indent = ' ' * 4 dash = '-' * 71 title = indent + "{:5} {:>31} {:>31}\n".format(' ', "Fixed Ref. (a.u.)", "Relaxed Ref. (a.u.)") title += indent + "{} {} {}\n".format(' ' * 5, '-' * 31, '-' * 31) title += indent + "{:5} {:>20} {:>10} {:>20} {:>10}\n".format("Iter.", "Total Energy", "Delta", "Total Energy", "Delta") psi4.core.print_out("\n{}".format(title + indent + dash)) E0_old, E1_old = 0.0, 0.0 for n, pair in enumerate(dsrg_energies): E0, E1 = pair psi4.core.print_out("\n{}{:>5} {:>20.12f} {:>10.3e}" " {:>20.12f} {:>10.3e}".format(indent, n + 1, E0, E0 - E0_old, E1, E1 - E1_old)) E0_old, E1_old = E0, E1 psi4.core.print_out("\n{}{}".format(indent, dash)) if do_dipole and (not is_multi_state): psi4.core.print_out("\n\n => {} Reference Relaxation Dipole Summary <=\n".format(correlation_solver_type)) psi4.core.print_out("\n {} unrelaxed dipole moment:".format(correlation_solver_type)) psi4.core.print_out("\n X: {:10.6f} Y: {:10.6f} " "Z: {:10.6f} Total: {:10.6f}\n".format(*dsrg_dipoles[0][0])) psi4.core.set_scalar_variable('UNRELAXED DIPOLE', dsrg_dipoles[0][0][-1]) psi4.core.print_out("\n {} partially relaxed dipole moment:".format(correlation_solver_type)) psi4.core.print_out("\n X: {:10.6f} Y: {:10.6f} " "Z: {:10.6f} Total: {:10.6f}\n".format(*dsrg_dipoles[0][1])) psi4.core.set_scalar_variable('PARTIALLY RELAXED DIPOLE', dsrg_dipoles[0][1][-1]) if maxiter > 1: psi4.core.print_out("\n {} relaxed dipole moment:".format(correlation_solver_type)) psi4.core.print_out("\n X: {:10.6f} Y: {:10.6f} " "Z: {:10.6f} Total: {:10.6f}\n".format(*dsrg_dipoles[1][0])) psi4.core.set_scalar_variable('RELAXED DIPOLE', dsrg_dipoles[1][0][-1]) # set energies to environment psi4.core.set_scalar_variable('PARTIALLY RELAXED ENERGY', dsrg_energies[0][1]) if maxiter > 1: psi4.core.set_scalar_variable('RELAXED ENERGY', dsrg_energies[1][0]) # throw not converging error if relaxation not converged if not converged: psi4.core.set_scalar_variable('CURRENT UNRELAXED ENERGY', dsrg_energies[-1][0]) psi4.core.set_scalar_variable('CURRENT RELAXED ENERGY', dsrg_energies[-1][1]) psi4.core.set_scalar_variable('CURRENT ENERGY', dsrg_energies[-1][1]) raise psi4.core.ConvergenceError("DSRG relaxation does not converge in {} cycles".format(maxiter)) else: if relax_mode != 'ONCE' and relax_mode != 'TWICE': psi4.core.set_scalar_variable('FULLY RELAXED ENERGY', dsrg_energies[-1][1]) psi4.core.set_scalar_variable('CURRENT ENERGY', dsrg_energies[-1][1]) if do_dipole and (not is_multi_state): psi4.core.print_out("\n {} fully relaxed dipole moment:".format(correlation_solver_type)) psi4.core.print_out("\n X: {:10.6f} Y: {:10.6f} " "Z: {:10.6f} Total: {:10.6f}\n".format(*dsrg_dipoles[-1][1])) psi4.core.set_scalar_variable('FULLY RELAXED DIPOLE', dsrg_dipoles[-1][1][-1]) return Erelax else : average_energy = forte.compute_average_state_energy(state_energies_list,state_weights_map) return_en = average_energy return return_en