| """SI Figure S2: literature Diels-Alder barriers for ethylene + butadiene. |
| |
| Published quantum-chemistry predictions span ~15-45 kcal/mol (experiment ~23.3). The barriers are a |
| literature compilation (paper reference 26); the table below is the data (no dataset/reader). This |
| file holds the table and its method-family grouping; the bar chart is drawn inline in the notebook. |
| """ |
| |
| EXPERIMENTAL_BARRIER = 23.3 |
|
|
| |
| |
| DATA = [ |
| ("HF/3-21G//HF/3-21G", 35.9), |
| ("HF/6-31G*//HF/6-31G*", 45.0), |
| ("HF/6-31G**//HF/6-31G**", 45.9), |
| ("CASSCF(6,6)/3-21G// CASSCF(6,6)/3-21G", 37.3), |
| ("CASSCF(6,6)/6-31G*//B3LYP/6-31G*", 43.8), |
| ("MRMP2-CAS(6,6)/6-31G*//B3LYP/6-31G*", 28.6), |
| ("CASSCF(6,6)/6-31G*// CASSCF(6,6)/6-31G*", 43.8), |
| ("CASSCF(6,6)/6-31G(d,p)//CASSCF(6,6)/6-31(d,p)", 44.5), |
| ("CASSCF(6,6)-MP2/6-31G(d,p)//CASSCF(6,6)/6-31(d,p)", 39.4), |
| ("CASSCF(6,6)/6-311+G(d,p)//CASSCF(6,6)/6-31(d,p)", 37.0), |
| ("CASSCF(6,6)-MP2/6-311+G(d,p)//CASSCF(6,6)/6-31(d,p)", 40.9), |
| ("CASSCF(6,6)/6-31G*//CASSCF(6,6)/6-31G*", 25.0), |
| ("CASSCF(6,6)/6-31G*//CASSCF(6,6)/6-31G*", 43.6), |
| ("MR-AQCC/6-31G*//MR-AQCC/6-31G*", 25.7), |
| ("MR-AQCC/6-31G**//MR-AQCC/6-31G**", 25.3), |
| ("MR-AQCC/6-31G**//MR-AQCC/6-31G**", 24.2), |
| ("MR-AQCC/6-311G(2d,p)//MR-AQCC/6-311G(2d,p)", 23.7), |
| ("MP2/6-31G*//HF/6-31G*", 16.6), |
| ("MP2/6-31G*//MP2/6-31G*", 18.5), |
| ("MP2/6-31G*//B3LYP/6-31G*", 20.4), |
| ("MP2/6-31G**//MP2/6-31G**", 15.9), |
| ("MP2/6-311G(d,p)//B3LYP/6-31G", 17.5), |
| ("MP3/6-31G*//HF/6-31G*", 26.9), |
| ("MP3/6-311G(d,p)//B3LYP/6-31G", 28.2), |
| ("MP4(SDQ)/6-31G*//HF/6-31G*", 29.0), |
| ("MP4(SDTQ)/6-31G*//HF/6-31G*", 21.9), |
| ("MP4(SDTQ)/6-31G*//MP2/6-31G*", 22.4), |
| ("MP4(SDTQ)/6-311G(d,p)//B3LYP/6-31G", 22.8), |
| ("B3LYP/6-31G*//B3LYP/6-31G*", 23.1), |
| ("B3LYP/6-31G*//B3LYP/6-31G*", 24.9), |
| ("B3LYP/6-31G**//B3LYP/6-31G**", 22.4), |
| ("B3LYP/6-311+G(2d,p)//B3LYP/6-311+G(2d,p)", 27.2), |
| ("BPW91/6-31G*//BPW91/6-31G*", 26.2), |
| ("MPW1K/6-31+G**//MPW1K/6-31+G*", 24.4), |
| ("KMLYP/6-31G*//KMLYP/6-31G*", 21.1), |
| ("KMLYP/6-311G//KMLYP/6-31G", 22.4), |
| ("OLYP/6-31G(d)//OLYP/6-31G(d)", 26.7), |
| ("OLYP/6-311+G(2d,p)//OLYP/6-311+G(2d,p)", 30.1), |
| ("OLYP/6-311G(2df,2pd)// OLYP/6-311G(2df,2pd)", 29.2), |
| ("O3LYP/6-31G(d)//OLYP/6-31G(d)", 26.8), |
| ("O3LYP/6-311+G(2d,p)//OLYP/6-311+G(2d,p)", 30.1), |
| ("O3LYP/6-311G(2df,2pd)// OLYP/6-311G(2df,2pd)", 29.3), |
| ("M06-2x/6-31G(d)", 20.4), |
| ("M06-2x/cc-pVTZ", 23.2), |
| ("ωB97X-D/6-31G(d)", 21.7), |
| ("ωB97X-D/cc-pVTZ", 25.1), |
| ("B2PLYP/cc-pVDZ", 24.0), |
| ("QCISD(T)/6-31G*//CASSCF(6,6)/6-31G*", 25.5), |
| ("QCISD(T)/6-31G*//B3LYP/6-31G*", 25.0), |
| ("CCSD/6-311G(d,p)//B3LYP/6-31G", 30.8), |
| ("CCSD(T)/6-311G(d,p)//B3LYP/6-31G", 25.7), |
| ("CCSD(T)/6-31G**//B3LYP/6-31G**", 27.6), |
| ("G2MP2/6-311+G(3df,2p)", 24.6), |
| ("G2MS/6-311+G(2df,2p)", 23.9), |
| ("CBS-QB3", 22.9), |
| ] |
|
|
| |
| CATEGORY_ORDER = ["HF", "MP2", "MP3", "MP4", "DFT", "CASSCF", |
| "Multireference", "Coupled Cluster", "Composite"] |
|
|
|
|
| def energy_method(method_string): |
| """The energy method (the part before '//') of a 'method//geometry' string. This is what the |
| bar is labeled with and categorized by; a string with no '//' is returned unchanged.""" |
| return method_string.split("//")[0].strip() if "//" in method_string else method_string |
|
|
|
|
| def categorize_method(method): |
| """The method family ('HF', 'MP2', 'DFT', 'CASSCF', ...) of an energy method, by the same rules |
| as the original figure. Used to group the bars.""" |
| m = method.upper() |
| if m.startswith("HF"): |
| return "HF" |
| if m.startswith("MP2"): |
| return "MP2" |
| if m.startswith("MP3"): |
| return "MP3" |
| if m.startswith("MP4"): |
| return "MP4" |
| if any(k in m for k in ("B3LYP", "BPW91", "MPW1K", "KMLYP", "OLYP", "O3LYP", "M06", |
| "ωB97X", "B2PLYP")): |
| return "DFT" |
| if "CASSCF" in m: |
| return "CASSCF" |
| if "CCSD" in m or "QCISD" in m: |
| return "Coupled Cluster" |
| if m.startswith("G2") or "CBS" in m: |
| return "Composite" |
| if "MR-AQCC" in m or "MRMP2" in m: |
| return "Multireference" |
| return "Other" |
|
|
|
|
| def ordered_layout(data=DATA, group_spacing=2): |
| """Lay the bars out grouped by method family and sorted by barrier within each group, with a gap |
| of group_spacing between groups. Returns a dict with parallel lists methods (the energy-method |
| labels), energies, positions (x of each bar), and group_labels / group_boundaries (the |
| (start, end) bar position of each group), in CATEGORY_ORDER. |
| """ |
| grouped = {} |
| for method_string, energy in data: |
| method = energy_method(method_string) |
| grouped.setdefault(categorize_method(method), []).append((method, energy)) |
| for entries in grouped.values(): |
| entries.sort(key=lambda me: me[1]) |
|
|
| methods, energies, positions = [], [], [] |
| group_labels, group_boundaries = [], [] |
| pos = 0 |
| for i, category in enumerate(CATEGORY_ORDER): |
| if category not in grouped: |
| continue |
| if i > 0 and methods: |
| pos += group_spacing |
| start = pos |
| for method, energy in grouped[category]: |
| methods.append(method) |
| energies.append(energy) |
| positions.append(pos) |
| pos += 1 |
| group_labels.append(category) |
| group_boundaries.append((start, pos - 1)) |
| return {"methods": methods, "energies": energies, "positions": positions, |
| "group_labels": group_labels, "group_boundaries": group_boundaries} |
|
|