Skip to main content
Docs

Search guides and API endpoints, for example “Idempotency-Key” or “submit job”.

    Tools · Quantum Chemistry

    QC Thermochemistry

    Ideal-gas zero-point energy, enthalpy, entropy, Gibbs energy, and heat capacity from quantum chemical frequencies, with quasi-RRHO corrections and NASA-7 polynomials for Cantera.

    Updated October 18, 2026

    On this page

    Prices, workflows, and method papersOpen in the app

    QC Thermochemistry turns optimized geometries and their harmonic frequencies into thermodynamic functions over temperature. For every structure it computes the zero-point energy, enthalpy, entropy, Gibbs energy, and heat capacity of the ideal gas, optionally with quasi-RRHO corrections that keep soft torsions from dominating the entropy. Species with a known standard enthalpy of formation also get two-range NASA-7 polynomials, written as a Cantera species entry. It is the step between a frequency calculation and kinetics or reactor modeling, and runs on CPU.

    How a run works

    1. Each SDF record (or mol block) is one optimized structure. Its molecule_index and structure_index tags join it to its rows in the uploaded vibrations.csv, the frequency table from the same calculation.
    2. Isotope masses and the moments of inertia come from the geometry, so the rotor type is detected automatically: atoms, linear molecules, and nonlinear molecules are each treated correctly.
    3. On every temperature of the grid (298.15 K is always included), the worker adds the translational (Sackur–Tetrode at the chosen pressure), rotational, vibrational, and electronic-spin contributions. Enthalpy includes the zero-point energy and RT; heat capacity is the temperature derivative of that enthalpy.
    4. A structure that fails gets a row with its error in the summary, and the rest of the run continues.

    Choosing the low-frequency treatment

    • Quasi-RRHO (S + H), the default: below the damping frequency ω₀ (100 cm⁻¹ by default), each mode's entropy blends toward a free rotor (Grimme, 2012) and its energy toward RT/2 (Li and Head-Gordon, 2015). This is the treatment GoodVibes popularized, and it avoids the very large entropies harmonic oscillators give to soft modes.
    • Quasi-RRHO (S only) applies the entropy correction and keeps the harmonic enthalpy.
    • Harmonic (RRHO) treats every mode as a harmonic oscillator.

    A frequency scale multiplies every wavenumber before the thermochemistry, for example a method-specific zero-point scale factor. Imaginary modes are negative wavenumbers in the table; by default they are dropped and counted for each structure, which is the usual convention for a transition state's reaction coordinate. You can make them fail the structure instead.

    Getting the frequencies

    • From xTB / CREST: run its frequencies mode and use structures.sdf with vibrations.csv. By default xtb optimizes first. To keep a transition state, run the Hessian at the input geometry instead.
    • From PySCF Electronic Structure: its frequency mode writes geometries.sdf and vibrations.csv. It computes the Hessian at the geometry it is given, so optimize first (or chain an optimization into it) unless the structure is already a stationary point.

    In a workflow, connect those outputs straight to this tool's molecules and vibrations inputs.

    Symmetry number and multiplicity

    Each molecule has a row for its rotational symmetry number σ (for example 2 for water, 3 for ammonia, 12 for methane) and its spin multiplicity, which sets the electronic entropy R ln(multiplicity). Blank cells use σ = 1 and the multiplicity implied by the structure's unpaired-electron tag. Symmetry numbers are not detected from the geometry, so set them for symmetric molecules: a wrong σ shifts the entropy by R ln σ.

    NASA-7 polynomials for Cantera

    Absolute quantum chemical energies are not enthalpies of formation, so polynomials are only fitted for molecules where you enter ΔHf(298). For each, the lowest-G conformer is fitted with two NASA-7 ranges that meet at a common temperature with continuous Cp and slope, anchored so that H equals ΔHf and S equals the computed entropy at 298.15 K. The species go into mechanism/primary.yaml, a Cantera YAML file you can merge into a mechanism or pass to Cantera. The fit's largest errors in Cp, H, and S against the statistical-mechanics values are in nasa_fit.csv.

    Reading the results

    • thermo.csv: one row per species and temperature, with h, g (kJ/mol, the electronic energy plus the thermal correction, when the structure carries its energy), s and cp (J/mol/K), and the corrections h_corr, g_corr, and zpe. The columns and units are what Transition-State-Theory Rate Calculator reads as species thermochemistry.
    • summary.csv: one row per structure, with its rotor type, σ, multiplicity, mode counts, imaginary modes, lowest frequency, and the values at 298.15 K.
    • mechanism/primary.yaml and nasa_fit.csv: the NASA-7 species and their fit errors.
    • metadata.json: the settings and units of the run.

    Limits and not covered

    The model is the ideal gas with rigid rotors and (quasi-)harmonic oscillators. Hindered-rotor treatments, anharmonic or VPT2 corrections, conformer mixing into one species, and automatic symmetry detection are not part of this tool, and enthalpies of formation are not estimated: for estimated thermochemistry from structure use Group-Contribution Properties and NASA / Cantera Species Builder.

    Compute frequencies with xTB / CREST or PySCF Electronic Structure, turn reactant and transition-state thermochemistry into rate constants with Transition-State-Theory Rate Calculator, and run reactors with the polynomials in Cantera.

    Run it from the API

    Submit with Submit a job and the job_type below. Price it first with Estimate job reservation cost: submitting reserves that amount from your wallet, and the charge settles at the actual runtime.

    QC Thermochemistry qc-thermo

    Job type
    qc-thermo
    Hardware
    cpu (default)
    Typical runtime
    1 min on CPU

    Payload

    Payload fields
    FieldTypeDescription
    input_data[]required(string | object)[]

    Limits: min items 1, max items 200

    input_formatrequiredstring

    One of: "molblock", "sdf"

    vibrationsrequiredfile_object
    temperatures_k[]number[]

    Limits: min items 1, max items 500

    t_min_knumber

    Default: 200Limits: ≥ 10, ≤ 5000

    t_max_knumber

    Default: 2000Limits: ≥ 10, ≤ 5000

    t_step_knumber

    Default: 100Limits: > 0, ≤ 5000

    pressure_atmnumber

    Default: 1Limits: > 0, ≤ 1000

    qrrhostring

    Default: "grimme_head_gordon"One of: "grimme_head_gordon", "grimme_entropy", "rrho"

    cutoff_cm1number

    Default: 100Limits: > 0, ≤ 1000

    frequency_scalenumber

    Default: 1Limits: ≥ 0.5, ≤ 1.5

    imaginary_modestring

    Default: "ignore"One of: "ignore", "reject"

    species[]object[]

    Limits: max items 200

    species.molecule_indexrequiredinteger

    Limits: ≥ 0, ≤ 199

    species.namestring

    Limits: min length 1, max length 64

    species.symmetry_numberinteger

    Default: 1Limits: ≥ 1, ≤ 60

    species.multiplicityinteger

    Limits: ≥ 1, ≤ 11

    species.hf_298_kj_molnumber

    Limits: ≥ -100000, ≤ 100000

    nasaobject
    nasa.enabledboolean

    Default: true

    nasa.t_min_knumber

    Default: 200Limits: ≥ 10, ≤ 6000

    nasa.t_mid_knumber

    Default: 1000Limits: ≥ 10, ≤ 6000

    nasa.t_max_knumber

    Default: 3000Limits: ≥ 10, ≤ 6000

    File fields take {"name": "x.pdb", "content_b64": "…"} or a stored artifact, {"$artifact": {"id": "art-…", "port": "…"}}. Files are up to 25 MiB each.

    Example

    from cognichem_client import CogniChem
    
    client = CogniChem.from_env()  # reads COGNICHEM_API_KEY
    payload = {
        "input_data": [
            "water_0\n     RDKit          3D\n\n  3  2  0  0  0  0  0  0  0 … (1,065 characters)",
        ],
        "input_format": "sdf",
        "vibrations": {
            "name": "vibrations.csv",
            "content_b64": "<file contents, base64>",
        },
        "t_min_k": 300,
        "t_max_k": 1500,
        "t_step_k": 100,
        "pressure_atm": 1,
        "qrrho": "grimme_head_gordon",
        "cutoff_cm1": 100,
        "species": [
            {
                "molecule_index": 0,
                "name": "H2O",
                "symmetry_number": 2,
                "hf_298_kj_mol": -241.826,
            },
            {"molecule_index": 1, "name": "CO2", "symmetry_number": 2},
        ],
        "nasa": {
            "enabled": True,
            "t_min_k": 200,
            "t_mid_k": 1000,
            "t_max_k": 3000,
        },
    }
    
    estimate = client.jobs.estimate(job_type="qc-thermo", payload=payload, resource="cpu")
    print(f"Reserves ${estimate.cost:.2f}")
    
    job = client.jobs.submit(
        job_name="my-qc-thermo-run",
        job_type="qc-thermo",
        payload=payload,
        resource="cpu",
    )
    status = client.jobs.wait(job.process_id)
    if status.status == "completed":
        client.jobs.result(job.process_id, save_path=".")

    Sample data from the job catalog; long values are shortened here. Each job_name must be unique among your jobs.

    Workflow inputs

    • Molecules (list)SDF, MOLBLOCK
    • TableCSV

    Workflow outputs

    • ArchiveZIP
    • Kinetic mechanismYAML
    • TableCSV
    • TableCSV