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

How to store gradients and hessians? #85

Open
aizvorski opened this issue Jun 10, 2024 · 1 comment
Open

How to store gradients and hessians? #85

aizvorski opened this issue Jun 10, 2024 · 1 comment

Comments

@aizvorski
Copy link

aizvorski commented Jun 10, 2024

I'm wondering if it's possible to store gradients and hessians in a qcschema. The docs do mention this

Returned Result
The “primary” return of a given computation. For energy, gradient, and Hessian quantities these are either single numbers or a array representing the derivative quantity.

I couldn't find an example of a json file like that though. Would the array be flattened or nested? What is the order? eg for gradients [gx1, gy1, gz1, ... ] or [gx1, gx2, gx3, ...]

Also, it seems the gradient or hessian would be a "return_result", not a "property" - what happens if there's more than one, for example? It seems strange that energies are both properties and return results, but gradients are only return results.

Is there a way to store this type of values as properties, eg "scf_gradient" similar to "scf_total_energy"? What is the recommended best practice?

@aizvorski aizvorski changed the title Storing gradients and hessians Representing gradients and hessians Jun 10, 2024
@aizvorski aizvorski changed the title Representing gradients and hessians How to store gradients and hessians? Jun 10, 2024
@loriab
Copy link
Collaborator

loriab commented Jun 10, 2024

Here's an example of a gradient input and result. QCElemental has a working implementation of QCSchema with pydantic validation, so that's where all these are using.

I couldn't find an example of a json file like that though. Would the array be flattened or nested? What is the order? eg for gradients [gx1, gy1, gz1, ... ] or [gx1, gx2, gx3, ...]

So when it's in json, arrays should be flat (not nested) and amenable to reshaping as (natoms, 3). Here's the code: https://github.com/MolSSI/QCElemental/blob/master/qcelemental/models/results.py#L290-L296 . Below, you'll see the arrays while the schemas as pydantic model instances, so they're always in nested form.

Also, it seems the gradient or hessian would be a "return_result", not a "property" - what happens if there's more than one, for example? It seems strange that energies are both properties and return results, but gradients are only return results.

There's deliberate duplication. AtomicResult.return_result is always defined and depends on the AtomicInput.driver setting. AtomicResult.properties.return_energy|gradient|hessian are defined as available. And AtomicResult.properties.scf_total_energy|gradient|hessian https://github.com/MolSSI/QCElemental/blob/master/qcelemental/models/results.py#L102-L106 are defined as available and (if running through QCEngine) depending on how thorough the harness is at collecting properties.

Let me know if there's further questions.

AtomicInput

{'driver': <DriverEnum.gradient: 'gradient'>,
 'extras': {},
 'id': None,
 'keywords': {},
 'model': {'basis': 'cc-pvdz', 'method': 'hf'},
 'molecule': {'extras': {},
              'fix_com': True,
              'fix_orientation': True,
              'geometry': array([[0., 0., 0.],
       [0., 0., 6.]]),
              'molecular_charge': 0.0,
              'molecular_multiplicity': 1,
              'name': 'Ne2',
              'provenance': {'creator': 'QCElemental',
                             'routine': 'qcelemental.molparse.from_schema',
                             'version': '0.27.1'},
              'schema_name': 'qcschema_molecule',
              'schema_version': 2,
              'symbols': array(['Ne', 'Ne'], dtype='<U2'),
              'validated': True},
 'protocols': {'stdout': False},
 'provenance': {'creator': 'QCElemental',
                'routine': 'qcelemental.models.results',
                'version': '0.27.1'},
 'schema_name': 'qcschema_input',
 'schema_version': 1}

AtomicResult

{'driver': <DriverEnum.gradient: 'gradient'>,
 'error': None,
 'extras': {'qcvars': {'CURRENT DIPOLE': array([0.00000000e+00, 0.00000000e+00, 4.97379915e-14]),
                       'CURRENT ENERGY': -256.977621071098,
                       'CURRENT GRADIENT': array([[ 4.81482486e-35,  0.00000000e+00, -6.54470201e-05],
       [-4.81482486e-35,  0.00000000e+00,  6.54470212e-05]]),
                       'CURRENT REFERENCE ENERGY': -256.977621071098,
                       'DD SOLVATION ENERGY': 0.0,
                       'HF KINETIC ENERGY': 256.97713564856093,
                       'HF POTENTIAL ENERGY': -513.9547567196589,
                       'HF TOTAL ENERGY': -256.977621071098,
                       'HF TOTAL GRADIENT': array([[ 4.81482486e-35,  0.00000000e+00, -6.54470201e-05],
       [-4.81482486e-35,  0.00000000e+00,  6.54470212e-05]]),
                       'HF VIRIAL RATIO': 2.000001888971701,
                       'NUCLEAR REPULSION ENERGY': 16.666666666666668,
                       'ONE-ELECTRON ENERGY': -398.5650589792168,
                       'PCM POLARIZATION ENERGY': 0.0,
                       'PE ENERGY': 0.0,
                       'SCF DIPOLE': array([0.00000000e+00, 0.00000000e+00, 4.97379915e-14]),
                       'SCF ITERATION ENERGY': -256.977621071098,
                       'SCF ITERATIONS': 5.0,
                       'SCF TOTAL ENERGIES': array([-256.97759612, -256.97762005, -256.9776209 , -256.97762107,
       -256.97762107, -256.97762107]),
                       'SCF TOTAL ENERGY': -256.977621071098,
                       'SCF TOTAL GRADIENT': array([[ 4.81482486e-35,  0.00000000e+00, -6.54470201e-05],
       [-4.81482486e-35,  0.00000000e+00,  6.54470212e-05]]),
                       'TWO-ELECTRON ENERGY': 124.92077124145213}},
 'id': None,
 'keywords': {},
 'model': {'basis': 'cc-pvdz', 'method': 'hf'},
 'molecule': {'extras': {},
              'fix_com': True,
              'fix_orientation': True,
              'geometry': array([[0., 0., 0.],
       [0., 0., 6.]]),
              'molecular_charge': 0.0,
              'molecular_multiplicity': 1,
              'name': 'Ne2',
              'provenance': {'creator': 'QCElemental',
                             'routine': 'qcelemental.molparse.from_schema',
                             'version': '0.27.1'},
              'schema_name': 'qcschema_molecule',
              'schema_version': 2,
              'symbols': array(['Ne', 'Ne'], dtype='<U2'),
              'validated': True},
 'native_files': {},
 'properties': {'calcinfo_nalpha': 10,
                'calcinfo_natom': 2,
                'calcinfo_nbasis': 28,
                'calcinfo_nbeta': 10,
                'calcinfo_nmo': 28,
                'nuclear_repulsion_energy': 16.666666666666668,
                'return_energy': -256.977621071098,
                'return_gradient': array([[ 4.81482486e-35,  0.00000000e+00, -6.54470201e-05],
       [-4.81482486e-35,  0.00000000e+00,  6.54470212e-05]]),
                'return_hessian': None,
                'scf_dipole_moment': array([0.00000000e+00, 0.00000000e+00, 4.97379915e-14]),
                'scf_iterations': 5,
                'scf_one_electron_energy': -398.5650589792168,
                'scf_total_energy': -256.977621071098,
                'scf_total_gradient': array([[ 4.81482486e-35,  0.00000000e+00, -6.54470201e-05],
       [-4.81482486e-35,  0.00000000e+00,  6.54470212e-05]]),
                'scf_total_hessian': None,
                'scf_two_electron_energy': 124.92077124145213},
 'protocols': {'stdout': False},
 'provenance': {'creator': 'Psi4',
                'module': 'scf',
                'routine': 'psi4.schema_runner.run_qcschema',
                'version': '1.9.1'},
 'return_result': array([[ 4.81482486e-35,  0.00000000e+00, -6.54470201e-05],
       [-4.81482486e-35,  0.00000000e+00,  6.54470212e-05]]),
 'schema_name': 'qcschema_output',
 'schema_version': 1,
 'stderr': None,
 'stdout': None,
 'success': True,
 'wavefunction': None}

generating script

import pprint
from qcelemental.models import Molecule, AtomicInput, AtomicResult
import psi4

nene = Molecule(geometry= [0, 0, 0, 0, 0, 6], symbols=["Ne", "Ne"], fix_com=True, fix_orientation=True)

atin = {
    "molecule": nene,
    "driver": "gradient",
    "model": {
        "method": "hf",
        "basis": "cc-pvdz",
    },
    "protocols": {
        "stdout": False,
    },
}

atin = AtomicInput(**atin)
print("\n<<< AtomicInput\n")
pprint.pprint(atin.dict(), width=100)

atres = psi4.schema_wrapper.run_qcschema(atin)
print("\n<<< AtomicResult\n")
pprint.pprint(atres.dict(), width=100)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants