Problemas de Estructura Vibracional con v0.5#

Más recursos#

Asegúrate de consultar el tutorial de estructura vibracional para obtener más detalles sobre cómo usar el nuevo código.

TL;DR#

Esta sección te brinda una celda con un código v0.4 seguida de una celda con un código v0.5 que hace lo mismo. Esperemos que esto ya te brinde toda la información que estabas buscando.

Previamente#

from qiskit_nature.drivers.second_quantization import GaussianForcesDriver
from qiskit_nature.problems.second_quantization import VibrationalStructureProblem
from qiskit_nature.settings import settings

settings.dict_aux_operators = True

driver = GaussianForcesDriver(logfile="aux_files/CO2_freq_B3LYP_631g.log")

problem = VibrationalStructureProblem(driver, num_modals=[2, 2, 3, 4], truncation_order=2)

# Note: at this point, `driver.run()` has NOT been called yet. We can trigger this indirectly like so:
second_q_ops = problem.second_q_ops()

hamiltonian = second_q_ops["VibrationalEnergy"]
print("\n".join(str(hamiltonian).splitlines()[:10] + ["..."]))
  NIIIIIIIIII * (1268.0676746875001+0j)
+ INIIIIIIIII * (3813.8767834375008+0j)
+ IINIIIIIIII * (705.8633818750001+0j)
+ II+-IIIIIII * (-46.025705898886045+0j)
+ II-+IIIIIII * (-46.025705898886045+0j)
+ IIINIIIIIII * (2120.1145593750007+0j)
+ IIIINIIIIII * (238.31540750000005+0j)
+ IIII+I-IIII * (19.820422279761104+0j)
+ IIIIINIIIII * (728.9613775000003+0j)
+ IIII-I+IIII * (19.820422279761104+0j)
...

Nuevo#

from qiskit_nature.second_q.drivers import GaussianForcesDriver
from qiskit_nature.second_q.problems import HarmonicBasis

driver = GaussianForcesDriver(logfile="aux_files/CO2_freq_B3LYP_631g.log")
basis = HarmonicBasis(num_modals=[2, 2, 3, 4])

# this is now done explicitly and already requires the basis
problem = driver.run(basis=basis)
problem.hamiltonian.truncation_order = 2

hamiltonian = problem.hamiltonian.second_q_op()
print("\n".join(str(hamiltonian).splitlines()[:10] + ["..."]))
Vibrational Operator
number modes=4, number modals=[2, 2, 3, 4], number terms=177
  (1268.0676746875001+0j) * ( +_0_0 -_0_0 )
+ (3813.8767834375008+0j) * ( +_0_1 -_0_1 )
+ (705.8633818750002+0j) * ( +_1_0 -_1_0 )
+ (-46.025705898886045+0j) * ( +_1_0 -_1_1 )
+ (-46.025705898886045+0j) * ( +_1_1 -_1_0 )
+ (2120.1145593750007+0j) * ( +_1_1 -_1_1 )
+ (238.31540750000005+0j) * ( +_2_0 -_2_0 )
+ (19.82042227976109+0j) * ( +_2_0 -_2_2 )
...

qiskit_nature.drivers#

Esta sección trata exclusivamente de la migración de los manejadores (drivers) relacionados con la estructura vibracional.

La siguiente tabla resume dónde ha terminado cada uno de los componentes de la estructura vibracional de qiskit_nature.drivers.second_quantization.

Componente antiguo

Ubicación nueva

BaseDriver

qiskit_nature.second_q.drivers.BaseDriver

VibrationalStructureDriver

qiskit_nature.second_q.drivers.VibrationalStructureDriver

VibrationalStructureDriverType

eliminado

VibrationalStructureMoleculeDriver

eliminado

GaussianForcesDriver

qiskit_nature.second_q.drivers.GaussianForcesDriver

GaussianLogDriver

qiskit_nature.second_q.drivers.GaussiaLogDriver

GaussianLogResult

qiskit_nature.second_q.drivers.GaussianLogResult

Además, los dos componentes de qiskit_nature.drivers se movieron así:

Componente antiguo

Ubicación nueva

Molécula

qiskit_nature.second_q.formats.molecule_info.MoleculeInfo

UnitsType

qiskit_nature.units.DistanceUnit

Vale la pena agregar algunas notas:

  • El VibrationalStructureMoleculeDriver se eliminó porque nos dirigimos hacia un futuro con una integración más estrecha, similar a un complemento, con códigos clásicos, lo que hace que el concepto de controladores (drivers) donde Qiskit inicia una simulación clásica quede obsoleto. Todavía puedes usar los métodos .from_molecule(...) de los controladores restantes en combinación con la clase MoleculeInfo.

  • MoleculeInfo se ha convertido en un contenedor de datos puro y ya no admite grados de libertad.

Controladores de Estructura Vibracional#

Los controladores (drivers) de estructura vibracional funcionan de forma ligeramente diferente a sus contrapartes de estructura electrónica, porque debe proporcionar una base al ejecutar el controlador, que mapea el espacio real del Hamiltoniano de Watson en un segundo espacio cuantizado. Esto se trató de manera inconsistente en Qiskit Nature v0.4 como se explica a continuación.

Previamente#

En Qiskit Nature v0.4, la implementación de la pila era en realidad inconsistente porque los VibrationalIntegrals (que formaban parte de la pila de second_quantization) en realidad estaban almacenando los coeficientes del Hamiltoniano de Watson en el espacio real. Solo más tarde estos se asignarían a una base específica:

from qiskit_nature.drivers.second_quantization import GaussianLogResult
from qiskit_nature.properties.second_quantization.vibrational.bases import HarmonicBasis
from qiskit_nature.settings import settings

settings.dict_aux_operators = True

log_result = GaussianLogResult("aux_files/CO2_freq_B3LYP_631g.log")

hamiltonian = log_result.get_vibrational_energy()
print(hamiltonian)

hamiltonian.basis = HarmonicBasis([2, 2, 3, 4])
op = hamiltonian.second_q_ops()["VibrationalEnergy"]
print("\n".join(str(op).splitlines()[:10] + ["..."]))
VibrationalEnergy:
    None
    1-Body Terms:
            <sparse integral list with 13 entries>
            (2, 2) = 352.3005875
            (-2, -2) = -352.3005875
            (1, 1) = 631.6153975
            (-1, -1) = -631.6153975
            (4, 4) = 115.653915
            ... skipping 8 entries
    2-Body Terms:
            <sparse integral list with 11 entries>
            (1, 1, 2) = -88.2017421687633
            (4, 4, 2) = 42.675273102831454
            (3, 3, 2) = 42.675273102831454
            (1, 1, 2, 2) = 4.9425425
            (4, 4, 2, 2) = -4.194299375
            ... skipping 6 entries
    3-Body Terms:
            <sparse integral list with 0 entries>
  NIIIIIIIIII * (1268.0676746875001+0j)
+ INIIIIIIIII * (3813.8767834375008+0j)
+ IINIIIIIIII * (705.8633818750001+0j)
+ II+-IIIIIII * (-46.025705898886045+0j)
+ II-+IIIIIII * (-46.025705898886045+0j)
+ IIINIIIIIII * (2120.1145593750007+0j)
+ IIIINIIIIII * (238.31540750000005+0j)
+ IIII+I-IIII * (19.820422279761104+0j)
+ IIIIINIIIII * (728.9613775000003+0j)
+ IIII-I+IIII * (19.820422279761104+0j)
...

Nuevo#

A partir de Qiskit Nature v0.5, el diseño separa constantemente el tratamiento del Hamiltoniano de Watson en el espacio real de los coeficientes de segunda cuantización. Esto se logra introduciendo una clase de datos dedicada que almacena un WatsonHamiltonian:

from qiskit_nature.second_q.drivers import GaussianLogResult
from qiskit_nature.second_q.formats import watson_to_problem
from qiskit_nature.second_q.problems import HarmonicBasis

log_result = GaussianLogResult("aux_files/CO2_freq_B3LYP_631g.log")

watson = log_result.get_watson_hamiltonian()
print(watson)

basis = HarmonicBasis(num_modals=[2, 2, 3, 4])

problem = watson_to_problem(watson, basis)

hamiltonian = problem.hamiltonian.second_q_op()
print("\n".join(str(hamiltonian).splitlines()[:10] + ["..."]))
WatsonHamiltonian(quadratic_force_constants=<COO: shape=(4, 4), dtype=float64, nnz=4, fill_value=0.0>, cubic_force_constants=<COO: shape=(4, 4, 4), dtype=float64, nnz=4, fill_value=0.0>, quartic_force_constants=<COO: shape=(4, 4, 4, 4), dtype=float64, nnz=12, fill_value=0.0>, kinetic_coefficients=<COO: shape=(4, 4), dtype=float64, nnz=4, fill_value=-0.0>)
Vibrational Operator
number modes=4, number modals=[2, 2, 3, 4], number terms=177
  (1268.0676746875001+0j) * ( +_0_0 -_0_0 )
+ (3813.8767834375008+0j) * ( +_0_1 -_0_1 )
+ (705.8633818750002+0j) * ( +_1_0 -_1_0 )
+ (-46.025705898886045+0j) * ( +_1_0 -_1_1 )
+ (-46.025705898886045+0j) * ( +_1_1 -_1_0 )
+ (2120.1145593750007+0j) * ( +_1_1 -_1_1 )
+ (238.31540750000005+0j) * ( +_2_0 -_2_0 )
+ (19.82042227976109+0j) * ( +_2_0 -_2_2 )
...

El VibrationalStructureProblem (qiskit_nature.problems)#

Esta sección detalla todos los cambios en torno al VibrationalStructureProblem.

La siguiente tabla resume los componentes vibracionales del nuevo módulo qiskit_nature.second_q.problems y muestra de dónde se originaron estas partes en el código antiguo:

Nuevo componente

Ubicación antigua

BaseProblem

qiskit_nature.problems.second_quantization.BaseProblem

EigenstateResult

qiskit_nature.results.EigenstateResult

PropertiesContainer

similar a qiskit_nature.properties.GroupedProperty

VibrationalBasis

qiskit_nature.properties.second_quantization.vibrational.bases.VibrationalBasis

HarmonicBasis

qiskit_nature.properties.second_quantization.vibrational.bases.HarmonicBasis

VibrationalStructureProblem

qiskit_nature.problems.second_quantization.vibrational.VibrationalStructureProblem

VibrationalPropertiesContainer

aun no existia

VibrationalStructureResult

qiskit_nature.results.VibrationalStructureResult

Previamente#

from qiskit_nature.drivers.second_quantization import GaussianForcesDriver
from qiskit_nature.problems.second_quantization import VibrationalStructureProblem

driver = GaussianForcesDriver(logfile="aux_files/CO2_freq_B3LYP_631g.log")

problem = VibrationalStructureProblem(driver, num_modals=[2, 2, 3, 4], truncation_order=2)

# we trigger driver.run() implicitly like so:
second_q_ops = problem.second_q_ops()

hamiltonian_op = second_q_ops.pop("VibrationalEnergy")
aux_ops = second_q_ops

Nuevo#

from qiskit_nature.second_q.drivers import GaussianForcesDriver
from qiskit_nature.second_q.problems import HarmonicBasis

driver = GaussianForcesDriver(logfile="aux_files/CO2_freq_B3LYP_631g.log")
basis = HarmonicBasis(num_modals=[2, 2, 3, 4])

problem = driver.run(basis=basis)
problem.hamiltonian.truncation_order = 2

hamiltonian_op, aux_ops = problem.second_q_ops()

Para obtener más información sobre el nuevo y mejorado VibrationalStructureProblem, consulta el tutorial de estructura vibracional.

qiskit_nature.properties#

El módulo de propiedades se ha refactorizado y dividido en varias ubicaciones. En esta sección, solo nos centraremos en sus componentes vibracionales.

La siguiente tabla enlista dónde se ha movido cada componente de qiskit_nature.properties.

Componente antiguo

Ubicación nueva

Property

qiskit_nature.second_q.properties.SparseLabelOpsFactory

GroupedProperty

reemplazado por qiskit_nature.second_q.problems.PropertiesContainer

second_quantization.DriverMetadata

eliminado

second_quantization.vibrational.VibrationalEnergy

qiskit_nature.second_q.hamiltonians.VibrationalEnergy

second_quantization.vibrational.OccupiedModals

qiskit_nature.second_q.properties.OccupiedModals

second_quantization.vibrational.bases.VibrationalBasis

qiskit_nature.second_q.problems.VibrationalBasis

second_quantization.vibrational.bases.HarmonicBasis

qiskit_nature.second_q.problems.HarmonicBasis

second_quantization.vibrational.integrals.VibrationalIntegrals

reemplazado por qiskit_nature.second_q.operators.VibrationalIntegrals

Te sugerimos que consultes el tutorial de estructura vibracional para obtener explicaciones más detalladas, pero dejaremos algunos comentarios aquí:

  • la VibrationalBasis ahora solo se rastrea en el VibrationalStructureProblem y no para cada operador individualmente

  • la VibrationalEnergy (que siempre ha sido una Property _especial_) está en el nuevo módulo second_q.hamiltonians para resaltar este rol especial