Skip to content

Add method=xtb: OpenQP-XTB (LC-GFN1-xTB + MRSF) backend adapter#269

Open
karmachoi wants to merge 2 commits into
mainfrom
feat/openqp-xtb-adapter
Open

Add method=xtb: OpenQP-XTB (LC-GFN1-xTB + MRSF) backend adapter#269
karmachoi wants to merge 2 commits into
mainfrom
feat/openqp-xtb-adapter

Conversation

@karmachoi

Copy link
Copy Markdown
Contributor

Summary

Adds method=xtb — the PyOQP side of the new openqp-xtb external library (Open-Quantum-Platform/openqp-xtb), a native LC-GFN1-xTB reference carrying the full MRSF excited-state stack (CSF construction, analytic Z-vector gradients, cross-geometry state overlaps, one-center SOC). It mirrors the merged method=dftb integration (#266): a decoupled ctypes adapter loading libopenqp_xtb_c, routed through the shared drivers so energy/grad/optimize/meci/mep/nac/nacme/namd/soc all work.

This is the decoupled Python/ctypes half. The Fortran library lives in its own repo and is loaded at runtime (pip openqp-xtb wheel, OPENQP_XTB_LIBRARY, or staged next to liboqp). No OpenQP build coupling.

What's here

  • oqp/utils/tb_backends.pyTB_METHODS = {"dftb", "xtb"}, is_tb_method / tb_section_name / tb_config / make_tb_adapter. Both TB backends intentionally share the OQP:: wavefunction tag names (VEC_MO_A, td_bvec_mo, dftb_wf_dims, …) and the mol.dftb_external_potential QM/MM handoff, so BasisOverlap / NACME / the NAMD back_door carry work for both unchanged.
  • oqp/library/openqp_dftb.py — refactored to expose the backend as class attributes (SECTION / SYMBOL_PREFIX / LIB_BASENAMES / env vars) + _lc_gamma_code() / _model_args() hooks. DFTB behavior is byte-identical: the ctypes argument order is unchanged (dftb splices no model scalars), and the input-checker diagnostics were diffed across 31 scenario configs against main with 0 mismatches.
  • oqp/library/openqp_xtb.pyOpenQPXTBAdapter(OpenQPDFTBAdapter) for libopenqp_xtb_c. Implements the C ABI v3 delta: lc_gamma_kind (yukawa/erf/ok) replacing the DFTB lc_gamma_erf flag, plus 5 model scalars (model, dispersion, halogen_bond, third_order, spin_scale). GFN1 defaults ω=0.3, cam_β=1, lc_gamma=ok. xtb_soc driver included.
  • Dispatch generalization — single_point / namd / qmmm_driver / runfunc / openqp route through the tb_backends helpers (function names kept to minimize the diff).
  • [xtb] schema + input_checkermethod=xtb, model∈{gfn1}, dispersion / halogen_bond / third_order booleans, spin_scale>0, lc_gamma∈{yukawa,erf,ok}; namd/nacme/nac/soc allowed for the MRSF type exactly as dftb, md blocked identically.
  • Examplesexamples/XTB/ GFN1 H2O MRSF energy + C2H4 MRSF gradient.
  • Tests — schema hooks (15) + a ctypes ABI recorder (4) that pins the v3 argument layout position-for-position.

Verification

  • method=dftb suites re-run green; the only failures are pre-existing/environmental (no locally built liboqp matching this tree's oqp.h), identical on a clean main.
  • End-to-end: this exact adapter was driven against a freshly built libopenqp_xtb_c.dylib for an H2O GFN1-MRSF job — PyOQP vs the Fortran probe agree to reference 4.4e-15, S1 1.3e-12 Eh, gradient 1.5e-11 Ha/bohr; the ABI recorder test confirms the Fortran shim's argument list matches this adapter position-for-position (no reconciliation needed).

Notes

Requires the openqp-xtb library at runtime (private repo, same access pattern as openqp-dftb). The first MRSF-xTB excitations from the paired library: H2O 6.66/8.68/9.19 eV, C2H4 1.80/3.75/4.03 eV (LC-GFN1, ω=0.3).

🤖 Generated with Claude Code

…n, [xtb] schema

- oqp/utils/tb_backends.py: TB_METHODS={dftb,xtb}, is_tb_method/tb_section_name/
  tb_config/make_tb_adapter; both TB backends share the OQP:: wavefunction tag
  names and mol.dftb_external_potential (QM/MM contract unchanged)
- openqp_dftb.py: extract SECTION/SYMBOL_PREFIX/LIB_BASENAMES/env-var class
  attributes + _lc_gamma_code/_model_args hooks; dftb ctypes argument order and
  checker diagnostics byte-identical (31-scenario diff vs upstream/main: 0)
- openqp_xtb.py: OpenQPXTBAdapter for libopenqp_xtb_c (C ABI v3: +model/
  dispersion/halogen_bond/third_order/spin_scale scalars, lc_gamma ok|erf|yukawa,
  defaults omega=0.3 cam_beta=1 lc_gamma=ok), xtb_soc driver; probe backend
  rejected with a clear error
- dispatch arms generalized: single_point 19, namd 22, qmmm_driver 3, runfunc 3,
  openqp 2 references through the tb_backends helpers (function names kept)
- input_checker/oqpdata: method xtb + [xtb] section (model=gfn1, dispersion,
  halogen_bond, third_order, spin_scale, lc_gamma incl. ok); namd/nacme/nac/soc
  allowed for MRSF like dftb, md blocked identically
- examples/XTB: gfn1 h2o mrsf energy + c2h4 mrsf grad inputs
- tests: xtb schema hooks (15) + ctypes ABI recorder (4) proving the v3 splice
  position; dftb suites re-run green (env-only failures identical on clean tree)

Co-Authored-By: Claude Fable 5 <[email protected]>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1e36572ef2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

# adapter base class) minus the DFTB-only probe executable, plus the GFN1
# model options of the C ABI v3 (model/dispersion/halogen_bond/third_order/
# spin_scale) and the 'ok' lc_gamma kind (the xtb default).
'xtb': {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add compact API helper for xtb

Adding this schema section exposes job.xtb only as the generic section proxy from OpenQP.__getattr__; unlike job.dftb(...) it does not set input.method=xtb or wire the TDHF response, and _TheoryProxy/OpenQP._theory still have no xtb/openqp-xtb branch. Compact API users calling job.theory('xtb', ...) or job.xtb(parameter_path=...) therefore fail or create a non-xTB job; add an xTB helper/proxy plus tests/test_openqp_api.py coverage.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in a221464: added the compact xtb API mirroring dftb — job.xtb(...) ([xtb] section property + _XTBSectionProxy), OpenQP._xtb(...) (sets input.method=xtb, wires the TDHF response), _TheoryProxy.xtb, and _theory branches for xtb/openqp-xtb (ground), tdxtb/td-xtb, sf-xtb/sfxtb, mrsf-xtb/mrsfxtb. The _dftb helper is byte-identical. Tests: 4 new cases in tests/test_openqp_api.py + tests/test_openqp_xtb_api.py mirroring the dftb API suite — 67 passed, 19 skipped (native-runtime-dependent skips identical for dftb/xtb).

# adapter base class) minus the DFTB-only probe executable, plus the GFN1
# model options of the C ABI v3 (model/dispersion/halogen_bond/third_order/
# spin_scale) and the 'ok' lc_gamma kind (the xtb default).
'xtb': {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Link documentation for xtb keywords

This introduces user-facing [xtb] keywords, but the reviewable description for this change links only the openqp-xtb implementation repo and does not link a companion openqp-docs PR as required by AGENTS.md rule 4. Without that linked docs update, users cannot find the new section/keywords in the manual and the documented release gate cannot be verified.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Companion docs PR opened: Open-Quantum-Platform/openqp-docs#11 — adds docs/keywords/xtb.md documenting the [xtb] section (backend/type/parameter_path/library_path, GFN1 model options model/dispersion/halogen_bond/third_order/spin_scale, LC controls lc_gamma=ok|erf|yukawa/omega/cam_alpha/cam_beta/lc_ground_state, zvector, and the shared SCC/response/MRSF-shift families), wired into the keywords index and mkdocs nav.

'cam_alpha': {'type': float, 'default': '0.0'},
'cam_beta': {'type': float, 'default': '1.0'},
'lc_gamma': {'type': string, 'default': 'ok'},
'lc_ground_state': {'type': bool, 'default': 'False'},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exercise xtb lc_ground_state flag

This adds a new default-false opt-in flag for the xTB backend, but the new examples/XTB inputs never set lc_ground_state=true. AGENTS.md rule 2 requires new opt-in boolean flags to be exercised by an example or explicitly classified with a reason; the existing DFTB example covers the DFTB code path, not the newly added xTB model block and defaults.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in a221464: examples/XTB/xtb_gfn1_h2o_mrsf_energy.inp now sets lc_ground_state=true (the production LC-GFN1 MRSF configuration — the response-consistent reference that MRSF reference recovery requires) with a header note. Verified the edited input parses (lc_ground_state=True) and passes check_input_values.

Resolve the Codex review of PR #269 (method=xtb adapter):

- Add the xtb compact-API surface mirroring the dftb helper: the
  job.xtb(...) callable [xtb] section proxy, OpenQP._xtb (method=xtb,
  [xtb] section, TDHF response wiring), the _theory('xtb'/'tdxtb'/
  'sf-xtb'/'mrsf-xtb', ...) branches, and _TheoryProxy.xtb, so
  job.theory('xtb', ...) / job.xtb(...) build a real xtb job. The dftb
  helper (_dftb) is left byte-identical.
- Cover the new API in tests/test_openqp_api.py (mirroring the dftb
  helper tests) and add tests/test_openqp_xtb_api.py mirroring
  tests/test_openqp_dftb_api.py.
- Exercise the opt-in [xtb] lc_ground_state flag in the MRSF energy
  example (the production LC-GFN1 configuration); the input still passes
  check_input_values.

[xtb] keywords are documented in the companion openqp-docs PR
(Open-Quantum-Platform/openqp-docs#11).

Co-Authored-By: Claude Fable 5 <[email protected]>
@karmachoi

Copy link
Copy Markdown
Contributor Author

@codex review

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

Successfully merging this pull request may close these issues.

1 participant