Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Electronic Structure Stack Refactoring - Part 2 #841

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions .pylintdict
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
aa
acknowledgment
adjoint
aer
Expand All @@ -22,8 +23,8 @@ antisymmetric
antisymmetrized
ao
april
arginine
arg
arginine
args
arrowheads
arrowstyle
Expand Down Expand Up @@ -145,6 +146,7 @@ eigenvector
eigenvectors
einact
einsum
electronicintegrals
endian
endif
enum
Expand Down Expand Up @@ -207,7 +209,7 @@ hijkls
hijs
hilbert
histidine
HJO
hjo
html
https
hubbard
Expand All @@ -217,7 +219,10 @@ ifdef
ifortvars
ij
ijkl
ijlk
ik
iklj
il
init
initializer
initio
Expand Down Expand Up @@ -248,6 +253,7 @@ jcf
jcp
jernigan
ji
jk
jl
jordan
jørgensen
Expand All @@ -266,12 +272,12 @@ kwargs
kwds
labelled
lda
leighton
lexicographically
ldots
leighton
len
leucine
levinthal
lexicographically
libifcoremd
libor
libxc
Expand All @@ -288,6 +294,7 @@ lysine
macos
majorana
makefile
matmul
matplotlib
maxdepth
maxiter
Expand Down Expand Up @@ -330,10 +337,10 @@ nbasis
nd
ndarray
nelec
neutron
neq
networkx
neuropeptide
neutron
nicholas
nielsen
nisq
Expand All @@ -357,8 +364,8 @@ ok
ollitrault
onee
oneeints
onwards
onsite
onwards
opflow
oppenheimer
optimizers
Expand All @@ -382,15 +389,16 @@ perturbative
pes
phenylalanine
phonons
physrevd
physik
physrevd
plesset
pmatrix
polynomialtensor
polypeptides
popovas
pos
posteriori
pqrs
pre
prebuilt
prepend
Expand All @@ -400,6 +408,7 @@ preprocesses
proline
protium
proton
prsq
ps
pseudorandom
pxd
Expand All @@ -410,17 +419,19 @@ qarg
qargs
qasm
qbit
qc
qcbase
qcmatrixio
qcschema
qeom
qfi
qiskit
qiskit's
qc
qj
qmolecule
qn
qregs
qs
quantization
quantized
quartic
Expand All @@ -446,6 +457,7 @@ rgb
rgba
rhf
rhs
rk
robert
rohf
rossmannek
Expand Down Expand Up @@ -475,8 +487,9 @@ setted
shende
siddhartha
sklearn
soham
sl
slater
soham
sparselabelop
spinop
springer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def grouped_property(self, grouped_property: BaseProblem) -> None:
)
return

self._reference_energy = electronic_energy.reference_energy if not None else 0.0
self._reference_energy = grouped_property.reference_energy if not None else 0.0
self._grouped_property = grouped_property

def to_numpy_array(self) -> np.ndarray:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@

from qiskit_nature.exceptions import QiskitNatureError
from qiskit_nature.second_q.circuit.library import UCC
from qiskit_nature.second_q.operators import ElectronicIntegrals
from qiskit_nature.second_q.operators.tensor_ordering import _phys_to_chem
from qiskit_nature.second_q.problems import BaseProblem, ElectronicStructureProblem
from qiskit_nature.second_q.properties.bases import ElectronicBasis
from qiskit_nature.second_q.properties.integrals import ElectronicIntegrals


from .initial_point import InitialPoint
Expand Down Expand Up @@ -158,29 +158,28 @@ def grouped_property(self, grouped_property: BaseProblem) -> None:
"The `ElectronicEnergy` cannot be obtained from the `grouped_property`."
)

two_body_mo_integral: ElectronicIntegrals | None = (
electronic_energy.get_electronic_integral(ElectronicBasis.MO, 2)
)
if two_body_mo_integral is None:
two_body_mo_integral: ElectronicIntegrals = electronic_energy.electronic_integrals.two_body
if two_body_mo_integral.alpha.is_empty():
raise QiskitNatureError(
"The two-body MO `electronic_integrals` cannot be obtained from the `grouped_property`."
"The alpha-alpha spin two-body MO `electronic_integrals` cannot be empty."
)

orbital_energies: np.ndarray | None = electronic_energy.orbital_energies
orbital_energies: np.ndarray | None = grouped_property.orbital_energies
if orbital_energies is None:
raise QiskitNatureError(
"The `orbital_energies` cannot be obtained from the `grouped_property`."
)

integral_matrix: np.ndarray = two_body_mo_integral.get_matrix()
if not np.allclose(integral_matrix, two_body_mo_integral.get_matrix(2)):
if two_body_mo_integral.beta.get("++--", None) is not None:
raise NotImplementedError(
"`MP2InitialPoint` only supports restricted-spin setups. "
"Alpha and beta spin orbitals must be identical. "
"See https://github.com/Qiskit/qiskit-nature/issues/645."
)

reference_energy = electronic_energy.reference_energy if not None else 0.0
integral_matrix = _phys_to_chem(two_body_mo_integral.alpha.get("++--"))

reference_energy = grouped_property.reference_energy if not None else 0.0

particle_number = grouped_property.properties.particle_number
if particle_number is None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
QCWavefunction,
)
from qiskit_nature.second_q.problems import ElectronicStructureProblem
from qiskit_nature.second_q.properties.bases import ElectronicBasis

from .base_driver import BaseDriver

Expand Down Expand Up @@ -112,12 +113,14 @@ def to_qcschema(self) -> QCSchema:
def to_problem(
self,
*,
basis: ElectronicBasis = ElectronicBasis.MO,
include_dipole: bool = True,
) -> ElectronicStructureProblem:
"""Extends the :meth:`to_qcschema` method and translates the :class:`.QCSchema` object to an
:class:`.ElectronicStructureProblem`.

Args:
basis: the :class:`.ElectronicBasis` in which to construct the problem.
include_dipole: whether or not to include an :class:`.ElectronicDipoleMoment` property
in the generated problem (if the data is available).

Expand Down
52 changes: 29 additions & 23 deletions qiskit_nature/second_q/drivers/gaussiand/gaussiandriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,14 @@
from qiskit_nature.settings import settings
from qiskit_nature.second_q.formats.molecule_info import MoleculeInfo
from qiskit_nature.second_q.formats.qcschema import QCSchema
from qiskit_nature.second_q.formats.qcschema_translator import qcschema_to_problem
from qiskit_nature.second_q.formats.qcschema_translator import (
qcschema_to_problem,
get_ao_to_mo_from_qcschema,
)
from qiskit_nature.second_q.operators import ElectronicIntegrals
from qiskit_nature.second_q.problems import ElectronicStructureProblem
from qiskit_nature.second_q.properties import DipoleMoment, ElectronicDipoleMoment
from qiskit_nature.second_q.properties import ElectronicDipoleMoment
from qiskit_nature.second_q.properties.bases import ElectronicBasis
from qiskit_nature.second_q.properties.integrals import OneBodyElectronicIntegrals

from .gaussian_utils import run_g16
from ..electronic_structure_driver import ElectronicStructureDriver, MethodType, _QCSchemaData
Expand Down Expand Up @@ -409,46 +412,49 @@ def _qcschema_from_matrix_file(mel: MatEl) -> QCSchema:
def to_problem(
self,
*,
basis: ElectronicBasis = ElectronicBasis.MO,
include_dipole: bool = True,
) -> ElectronicStructureProblem:
return GaussianDriver._problem_from_matrix_file(self._mel, include_dipole=include_dipole)
return GaussianDriver._problem_from_matrix_file(
self._mel, basis=basis, include_dipole=include_dipole
)

@staticmethod
def _problem_from_matrix_file(
mel: MatEl, *, include_dipole: bool = True
mel: MatEl,
*,
basis: ElectronicBasis = ElectronicBasis.MO,
include_dipole: bool = True,
) -> ElectronicStructureProblem:
qcschema = GaussianDriver._qcschema_from_matrix_file(mel)

problem = qcschema_to_problem(qcschema)
problem = qcschema_to_problem(qcschema, basis=basis)

if include_dipole:
# dipole moment
dipints = GaussianDriver._get_matrix(mel, "DIPOLE INTEGRALS")
dipints = np.einsum("ijk->kji", dipints)

x_dip_ints = OneBodyElectronicIntegrals(ElectronicBasis.AO, (dipints[0], None))
y_dip_ints = OneBodyElectronicIntegrals(ElectronicBasis.AO, (dipints[1], None))
z_dip_ints = OneBodyElectronicIntegrals(ElectronicBasis.AO, (dipints[2], None))
x_dip = ElectronicIntegrals.from_raw_integrals(dipints[0])
y_dip = ElectronicIntegrals.from_raw_integrals(dipints[1])
z_dip = ElectronicIntegrals.from_raw_integrals(dipints[2])

x_dipole = DipoleMoment(
"x", [x_dip_ints, x_dip_ints.transform_basis(problem.basis_transform)]
)
y_dipole = DipoleMoment(
"y", [y_dip_ints, y_dip_ints.transform_basis(problem.basis_transform)]
)
z_dipole = DipoleMoment(
"z", [z_dip_ints, z_dip_ints.transform_basis(problem.basis_transform)]
)
if basis == ElectronicBasis.MO:
basis_transform = get_ao_to_mo_from_qcschema(qcschema)

x_dip = basis_transform.transform_electronic_integrals(x_dip)
y_dip = basis_transform.transform_electronic_integrals(y_dip)
z_dip = basis_transform.transform_electronic_integrals(z_dip)

coords = np.reshape(mel.c, (len(mel.ian), 3))
nucl_dip = np.einsum("i,ix->x", mel.ian, coords)
nucl_dip = np.round(nucl_dip, decimals=8)

problem.properties.electronic_dipole_moment = ElectronicDipoleMoment(
[x_dipole, y_dipole, z_dipole],
nuclear_dipole_moment=nucl_dip,
reverse_dipole_sign=True,
)
dipole_moment = ElectronicDipoleMoment(x_dip, y_dip, z_dip)
dipole_moment.nuclear_dipole_moment = nucl_dip
dipole_moment.reverse_dipole_sign = True

problem.properties.electronic_dipole_moment = dipole_moment

return problem

Expand Down
Loading