Skip to content

Mc26 cof26 cf22d#3251

Open
chen-yu-hao wants to merge 2 commits into
pyscf:masterfrom
chen-yu-hao:mc26-cof26-cf22d
Open

Mc26 cof26 cf22d#3251
chen-yu-hao wants to merge 2 commits into
pyscf:masterfrom
chen-yu-hao:mc26-cof26-cf22d

Conversation

@chen-yu-hao

Copy link
Copy Markdown

Add MC26/COF26 MC-PDFT on-top functionals; normalize CF22D xc code

Summary

This PR adds two new MC-PDFT on-top functionals (MC26 and COF26) and
normalizes the CF22D Kohn–Sham functional name.

Changes

1. MC26 and COF26 on-top functionals (pyscf/mcpdft/otfnal.py)

  • Register MC26 and COF26 in OT_PRESET / OT_ALIAS, usable as
    otxc="MC26" / "COF26" (and "tMC26" / "tCOF26").
  • MC26 uses the same ansatz as MC23/MC25
  • COF26 additionally includes reparametrized MN15-L exchange and
    correlation components (libxc MGGA_X_MN15_L 260 / MGGA_C_MN15_L 261)

2. Normalize CF22D (pyscf/dft/libxc.py)

  • Add 'CF22D': 'HYB_MGGA_X_CF22D,MGGA_C_CF22D' to XC_ALIAS, so the
    single name xc="CF22D" now resolves to the compound functional
    (previously it required xc="CF22D,CF22D").

3. Built-in dispersion for CF22D (pyscf/scf/dispersion.py)

  • Whitelist CF22D so it automatically applies its D3 zero-damping
    correction, consistent with how the functional was parameterized. The
    cf22d damping parameters (s6=1.0, rs6=1.53, s8=0.0) ship with
    simple-dftd3 (≥1.2.1) under zero damping.

References

  • MC26 / COF26: Y. Chen, D. Zhang, D. G. Truhlar, and X. He,
    Pushing the accuracy of on-top functionals with agent-driven supervised
    learning
    , arXiv:2605.06215 (2026). https://arxiv.org/abs/2605.06215
  • CF22D: Y. Liu, C. Zhang, Z. Liu, D. G. Truhlar, Y. Wang, and X. He,
    Supervised learning of a chemistry functional with damped dispersion,
    Nat. Comput. Sci. 3, 48–58 (2023).
    https://doi.org/10.1038/s43588-022-00371-5

cyhgithubcc and others added 2 commits June 12, 2026 01:10
MC26 shares the MC23/MC25 ansatz (reparametrized M06-L combined with a
CAS wave function contribution): E_ot = a0*E_CAS + E_xc[rep-M06L], with
a0 = 0.2781. COF26 extends this with reparametrized MN15-L exchange and
correlation components (libxc 260/261), a0 = 0.3096. The linear
parameters enter the LibXC components directly (facs = 1); a0 is the CAS
mixing coefficient supplied via hyb.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- libxc: register 'CF22D' in XC_ALIAS so xc='CF22D' resolves to
  HYB_MGGA_X_CF22D,MGGA_C_CF22D (previously required 'CF22D,CF22D').
- scf/dispersion: whitelist CF22D so it automatically applies its D3
  zero-damping correction. CF22D is parameterized under zero damping
  (s6=1.0, rs6=1.53, s8=0.0), shipped with simple-dftd3 as 'cf22d'.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@susilehtola

Copy link
Copy Markdown
Contributor

CF22D is already implemented in Libxc; a new release is imminent.

@chen-yu-hao

Copy link
Copy Markdown
Author

CF22D is already implemented in Libxc; a new release is imminent.

Thanks for the pointer! Just to clarify the scope of this PR — the libxc part is
actually not the issue. CF22D has been available in libxc since 7.0.0
(HYB_MGGA_X_CF22D / MGGA_C_CF22D), which PySCF already ships since v2.8.0.

What this PR addresses is two gaps that a libxc release cannot fix:

  1. Name resolution: xc = "CF22D" currently raises KeyError: name 'CF22D' not found — users must spell out 'HYB_MGGA_X_CF22D,MGGA_C_CF22D', unlike other functionals where the short alias resolves to the X/C pair.

  2. The dispersion term: CF22D as published (Nat. Comput. Sci. 3, 48 (2023)) is defined to include a damped dispersion term, and that term is intentionally non-standard: it is D3 zero-damping with only the r^-6 term retained (s6 = 1.0, s8 = 0.0, sr6 = 1.53). So without handling it on the PySCF side, a user requesting CF22D would silently compute only the semilocal+HF part and not reproduce the published functional.

The intent of this PR is therefore the same convenience/correctness layer PySCF
already provides for e.g. wB97X-D-type functionals: resolve the alias and wire
in the correct (non-default) dispersion parameters so that "CF22D" means the
functional as published. Happy to adjust the implementation if you'd prefer the
dispersion mapping to live elsewhere (e.g. in pyscf/dispersion).

@jeanwsr

jeanwsr commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Have you verified the CF22d result with any other program?

@susilehtola

susilehtola commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

CF22D is already implemented in Libxc; a new release is imminent.

Thanks for the pointer! Just to clarify the scope of this PR — the libxc part is actually not the issue. CF22D has been available in libxc since 7.0.0 (HYB_MGGA_X_CF22D / MGGA_C_CF22D), which PySCF already ships since v2.8.0.

OK, from the parameters it just seemed like you were reimplementing things already in Libxc, since you were overloading the parameters.

Comment thread pyscf/mcpdft/otfnal.py
Comment on lines +99 to +116
'ext_params': {
203: np.array([12.793598175048828, 1.0464407205581665, -1.1021970510482788,
-1.4680061340332031, 1.0868027210235596, 11.653898239135742,
-3.4057228565216064, -20.206926345825195, -1.7893168926239014,
14.40688705444336, 1.7784547805786133, -0.3958134949207306,
-12.139795303344727, -0.0605972521007061, 0.016891608014702797,
-7.153533806558698e-05, 0.0001199805992655456, 0.0]),
233: np.array([0.06, 0.0031, 0.00515088, 0.00304966,
-0.6178147196769714, 8.792010307312012, -8.655962944030762,
15.397195816040039, -9.685625076293945, 2.904688835144043,
-0.982710599899292, 1.7047909498214722, -1.9396733045578003,
-5.875694274902344, 1.1270228624343872, -0.29264968633651733,
0.10097602754831314, 0.002418402349576354,
-0.0004997584619559348, 0.0, -1.0493528842926025,
-0.03480437397956848, 0.01626494713127613,
7.84311632742174e-05, 0.000405816943384707, 0.0, 1e-10]),
},
'hyb': (0.278090700064691, 0.278090700064691, 0),

@susilehtola susilehtola Jun 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this is will be done in Libxc

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

these should be human readable, the integer ids might not be what you want them to be

Comment thread pyscf/mcpdft/otfnal.py
Comment on lines +125 to +165
'xc_base': 'MGGA_X_M06_L + MGGA_X_MN15_L, MGGA_C_M06_L + MGGA_C_MN15_L',
'ext_params': {
203: np.array([4.46751594543457, -0.620290219783783, -0.02489340677857399,
-1.9508483409881592, 3.8321266174316406, -4.5821146965026855,
-5.959300518035889, -0.26544812321662903, -1.444387435913086,
0.7572097778320312, 3.510108470916748, -1.1088151931762695,
-3.569631576538086, -0.06943392008543015, 0.042370155453681946,
7.512031879741699e-05, -0.000407030078349635, 0.0]),
233: np.array([0.06, 0.0031, 0.00515088, 0.00304966,
-4.060972213745117, 8.054978370666504, 0.16315306723117828,
0.20903074741363525, 1.67588472366333, 0.837023913860321,
-1.3942575454711914, -2.884153366088867, -0.7865201830863953,
5.253849029541016, -6.900444984436035, -0.07099238783121109,
-0.9084649085998535, -2.1175485017010942e-05,
0.011801144108176231, 0.0, 1.2753486633300781,
-0.022736486047506332, 0.09527082741260529,
0.000708779611159116, -0.0018802996492013335, 0.0, 1e-10]),
260: np.array([1.5309321880340576, -0.5386894345283508, 0.2505153715610504,
4.978420257568359, -5.5219902992248535, 6.497469425201416,
3.688972234725952, -0.6701527833938599, -0.7988651394844055,
-7.4512176513671875, 10.058389663696289, 2.617449998855591,
-4.1134748458862305, -4.58927059173584, 2.2586185932159424,
-8.232332229614258, 4.996926307678223, -4.7641282081604,
-2.3733041286468506, 4.265657424926758, -6.0180840492248535,
-6.202260494232178, 6.2710113525390625, 5.919536590576172,
-0.17825216054916382, -7.480823516845703, 6.210508823394775,
3.045118570327759, -1.476043462753296, -6.93911075592041,
1.2295597791671753, -5.026687145233154, 11.215118408203125,
2.8131494522094727, 5.998229503631592, -2.111699104309082,
-10.391032218933105, -0.4673156142234802, 3.2028167247772217,
-8.067900657653809]),
261: np.array([-0.642463207244873, -0.9184160828590393, 6.772172451019287,
-9.329075813293457, 0.7022364139556885, -1.3836524486541748,
11.549406051635742, -0.8307218551635742, 5.020711421966553,
-0.16478510200977325, 1.7352665662765503, -1.243597149848938,
4.824436187744141, -3.134183645248413, 0.6350889801979065,
-7.111184597015381, 3.5491936206817627, -2.827716112136841,
5.681900501251221, -4.908012866973877, 6.956517696380615,
-4.321927070617676, 4.578726768493652, -1.5277433395385742]),
},
'hyb': (0.30959611760805744, 0.30959611760805744, 0),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

same here

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thank you for your comments. The modification here is intended to include the new on-top functionals, MC26 and COF26, from:

MC26 / COF26: Y. Chen, D. Zhang, D. G. Truhlar, and X. He,
Pushing the accuracy of on-top functionals with agent-driven supervised learning, arXiv:2605.06215 (2026). https://arxiv.org/abs/2605.06215

rather than CF22D.

@jeanwsr

jeanwsr commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

CF22D is already implemented in Libxc; a new release is imminent.

Thanks for the pointer! Just to clarify the scope of this PR — the libxc part is actually not the issue. CF22D has been available in libxc since 7.0.0 (HYB_MGGA_X_CF22D / MGGA_C_CF22D), which PySCF already ships since v2.8.0.

No, the problem is that this PR is not scoped to interface Libxc's CF22D implementation; it is hardcoding all of the CF22D parameters. All that would be necessary is the mapping CF22D -> HYB_MGGA_X_CF22D,MGGA_C_CF22D.

The parameters are for MC26 and COF26, not CF22D.

@susilehtola

Copy link
Copy Markdown
Contributor

Your preprint says "The implementations of COF26 and MC26 are available in the add-cof26-mc26-mcpdft
branch of the PySCF repository at https://github.com/chen-yu-hao/pyscf.git"

I can't find such a branch

@chen-yu-hao

Copy link
Copy Markdown
Author

Your preprint says "The implementations of COF26 and MC26 are available in the add-cof26-mc26-mcpdft branch of the PySCF repository at https://github.com/chen-yu-hao/pyscf.git"

I can't find such a branch

We are currently reorganizing and replacing the branches. The updates on arXiv are not reflected promptly, and it will eventually point to the merged PySCF repository. Thank you for pointing out this issue.

@chen-yu-hao

Copy link
Copy Markdown
Author

Have you verified the CF22d result with any other program?

Thank you for your suggestion. This is our comparison between the PySCF implementation and the Gaussian 16 implementation, where Gaussian 16 has been internally modified to implement the parametrization and computation of CF22D.

Computational Setup

Item Description
Functional CF22D (hybrid meta-NGA + D3 zero-damping dispersion)
Basis set def2-QZVP
PySCF This branch: (xc="CF22D", automatic D3, s8 = 0; s6 = 1.0, sr6 = 1.53)
Gaussian 16 ; route: #p em=GD3 iop(3/174=1000000,3/175=-1,3/176=1530000) MN15/def2qzvp (in this build, the MN15 keyword corresponds to the CF22D coefficients)
Geometry Standard GMTKN55 structures: H₂O₂/H₂O₃/H₂O₄ from WATER27 and #2/#5/#3 from S66; identical geometries in both programs
Charge/Spin 0 / 1 (all closed-shell singlets)

Results

System PySCF CF22D Energy (Ha) Gaussian 16 CF22D Energy (Ha) ΔE (Ha) Dispersion damping difference (Ha)
Water dimer (H₂O)₂ −152.8749460931 −152.874930581 −1.55×10⁻⁵ −9.5×10⁻¹²
Water trimer (H₂O)₃ −229.3266202149 −229.326601277 −1.89×10⁻⁵ +1.8×10⁻¹¹
Water tetramer (H₂O)₄ −305.7791983929 −305.779149378 −4.90×10⁻⁵ +1.6×10⁻¹¹
Water–methanol (S66#2) −192.1413453940 −192.141322872 −2.25×10⁻⁵ −4.4×10⁻¹¹
Methanol dimer (S66#5) −231.4073751458 −231.407347559 −2.76×10⁻⁵ +4.1×10⁻¹¹
Water–methylamine (S66#3) −172.2576624502 −172.257642980 −1.95×10⁻⁵ +1.4×10⁻¹¹
  • ΔE = E(PySCF) − E(G16).
  • Dispersion damping difference = E_disp(PySCF) − E_disp(G16).
  • The total energies from both programs include D3 dispersion.

Interpretation

  • ΔE (column 4): −1.5×10⁻⁵ to −4.9×10⁻⁵ Ha, with an average absolute deviation of |ΔE| = 2.6×10⁻⁵ Ha, corresponding to approximately 0.016 kcal/mol. The deviation increases slightly with system size. This is a normal residual difference for a meta-GGA functional implemented independently in two programs with different default integration grids, and it is far below chemical accuracy.

  • Dispersion damping difference (column 5): all values are approximately 10⁻¹¹ Ha, below the Gaussian dispersion-printing precision of about 10⁻¹⁰ Ha.

@susilehtola

Copy link
Copy Markdown
Contributor

Your energy differences look large. I think I checked CF22D without dispersion and got sub-uEh agreement. You need to use a much larger grid than the default in both codes to actually converge to a point where cross-code comparisons make sense; your message didn't say anything about the used grids.

@chen-yu-hao

chen-yu-hao commented Jun 12, 2026

Copy link
Copy Markdown
Author

Your energy differences look large. I think I checked CF22D without dispersion and got sub-uEh agreement. You need to use a much larger grid than the default in both codes to actually converge to a point where cross-code comparisons make sense; your message didn't say anything about the used grids.

Given that the implementation of the D3 term in the PySCF branch is fully consistent with the implementation in Gaussian, the differences in self‑consistent energies for CF22D can likely be attributed to basis set definitions and differences in SCF implementation between the two programs. Such discrepancies should originate from the upstream libxc library and the respective SCF algorithms, and are not issues that this PR needs to address.

In addition, when relative energies are used, the discrepancy between the two software packages becomes even smaller.

Comparison of Binding Energies: PySCF vs Gaussian 16

System PySCF Binding Energy (kcal/mol) G16 Binding Energy (kcal/mol) Difference (kcal/mol)
Water Dimer (H₂O)₂ −5.1577 −5.1574 −0.00028
Water Trimer (H₂O)₃ −16.6498 −16.6492 −0.00058
Water Tetramer (H₂O)₄ −28.6939 −28.6933 −0.00062
Water–Methanol (S66#2) −5.5697 −5.5696 −0.00012
Methanol Dimer (S66#5) −5.6709 −5.6708 −0.00010
Water–Methylamine (S66#3) −6.8713 −6.8711 −0.00013

@susilehtola

Copy link
Copy Markdown
Contributor

Given that the implementation of the D3 term in the PySCF branch is fully consistent with the implementation in Gaussian, the differences in self‑consistent energies for CF22D can likely be attributed to basis set definitions and differences in SCF implementation between the two programs. Such discrepancies should originate from the upstream libxc library and the respective SCF algorithms, and are not issues that this PR needs to address.

That's not what I said above. Please check your grid and converge your two calculations instead of spamming AI answers.

@chen-yu-hao

Copy link
Copy Markdown
Author

Given that the implementation of the D3 term in the PySCF branch is fully consistent with the implementation in Gaussian, the differences in self‑consistent energies for CF22D can likely be attributed to basis set definitions and differences in SCF implementation between the two programs. Such discrepancies should originate from the upstream libxc library and the respective SCF algorithms, and are not issues that this PR needs to address.

That's not what I said above. Please check your grid and converge your two calculations instead of spamming AI answers.

I have already listed the relative energy results for Gaussian SuperFineGrid and PySCF grid level 8 in detail in the previous comment. I have now updated it with a more detailed comparison using the H₂O molecule as the system.

Please note that my modifications to CF22D are limited to providing a more convenient calling interface and adding the D3 term by default. They do not involve any SCF-related changes. The implementation of CF22D and other functionals in PySCF and Libxc, as well as why the energies computed with Gaussian 16 differ from those computed with PySCF, are not issues that this PR is intended to resolve. If you are interested in these topics, you should perform your own calculations and submit an issue.

h2o_all_functionals_absolute_energy

@susilehtola

Copy link
Copy Markdown
Contributor

I just pointed out that energy comparisons don't make sense unless you actually converge them.

According to Gaussian documentation

SuperFineGrid is a more accurate grid than UltraFine; SuperFineGrid is a pruned 175,974 for first-row atoms and 250,974 for atoms in the second and later rows.

This may not be enough for Minnesota functionals, which are famously ill-behaved.

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.

4 participants