この日本語ページは準備中です。 技術的な詳細は英語版が最新かつ正確です。 → English version


GANSU2 Python API Usage Guide

Setup

Install

pip install gansu2

The wheel is small; the GPU shared library is fetched on first use and cached under ~/.cache/gansu2/<version>/, each file verified against its published SHA-256.

Import

import gansu2

To use a specific shared library instead (for example an offline copy), point GANSU2_LIB at it before importing:

export GANSU2_LIB=/path/to/libgansu2.so

Quick Start

import gansu2

gansu2.init()

# Create molecule and run RHF + MP2
mol = gansu2.Molecule("h2o.xyz", basis="cc-pvdz")
result = mol.run(method="RHF", post_hf="mp2")

print(f"HF energy:  {result.total_energy:.8f} Hartree")
print(f"MP2 corr:   {result.post_hf_energy:.8f} Hartree")
print(f"Total:      {result.total_energy + result.post_hf_energy:.8f} Hartree")

gansu2.finalize()

Preparing XYZ Files

XYZ files can be created inline in Python:

# H2O
with open("h2o.xyz", "w") as f:
    f.write("""3
Water
O   0.000   0.000   0.127
H   0.000   0.758  -0.509
H   0.000  -0.758  -0.509
""")

# H2 at a given bond length
def write_h2(path, R):
    with open(path, "w") as f:
        f.write(f"2\nH2 R={R}\nH 0 0 0\nH 0 0 {R}\n")

# Benzene
with open("benzene.xyz", "w") as f:
    f.write("""12
Benzene
C   0.000   1.387   0.000
C   1.201   0.693   0.000
C   1.201  -0.693   0.000
C   0.000  -1.387   0.000
C  -1.201  -0.693   0.000
C  -1.201   0.693   0.000
H   0.000   2.469   0.000
H   2.138   1.235   0.000
H   2.138  -1.235   0.000
H   0.000  -2.469   0.000
H  -2.138  -1.235   0.000
H  -2.138   1.235   0.000
""")

Periodic Systems (PBC)

Pass a lattice (a 3×3 matrix, rows a, b, c, in Angstrom) to Molecule to run a Gamma-point periodic Hartree–Fock calculation. GANSU2 attaches the lattice to the geometry as an extended XYZ internally and dispatches the PBC-RHF path:

import gansu2

with gansu2.session():
    mol = gansu2.Molecule("h2o.xyz", basis="sto-3g",
                          lattice=[[12, 0, 0], [0, 12, 0], [0, 0, 12]])
    r = mol.run()
    print(f"PBC-RHF energy: {r.total_energy:.8f} Hartree")

lattice also accepts a flat length-9 sequence; omit it for a molecular calculation. (k-point KS-DFT is provided by the gansu2_krks CLI.)

API Reference

Module Functions

gansu2.init(force_cpu=False)     # Initialize (call once)
gansu2.finalize()                # Cleanup (call at end)
gansu2.list_basis_sets()         # List available basis sets

gansu2.Molecule

mol = gansu2.Molecule(
    xyz_path,                   # Path to XYZ file
    basis="sto-3g",             # Basis set name or .gbs path
    **kwargs                    # Additional parameters
)

mol.run()

result = mol.run(
    method="RHF",               # "RHF", "UHF", "ROHF", or "RKS" (DFT)
    post_hf="none",             # Post-HF: "mp2", "ccsd", "fci", etc.
    quiet=True,                 # Suppress GANSU2 output (default True)
    **kwargs                    # Additional GANSU2 parameters
)

DFT(制限 Kohn-Sham)は method="RKS" で選択し、汎関数とグリッドは追加パラメータで渡します:

r = mol.run(method="RKS", functional="pbe", grid_level=3)   # functional: "svwn5" または "pbe"

gansu2.Result Properties

Property Type Description
total_energy float HF total energy (Hartree)
post_hf_energy float Post-HF correlation energy
correlation_energy float Alias for post_hf_energy
nuclear_repulsion_energy float Nuclear repulsion energy
num_basis int Number of basis functions
num_electrons int Number of electrons
num_atoms int Number of atoms
orbital_energies np.ndarray Orbital energies (nao,)
mo_coefficients np.ndarray MO coefficients (nao, nao)
ccsd_1rdm_mo np.ndarray CCSD 1-RDM in MO basis (nao, nao)
excited_state_report str Formatted excited state table
excited_states dict {'energies', 'oscillator_strengths'} arrays (after an excited-state run)
dipole np.ndarray Ground-state SCF dipole (3,), atomic units e·Bohr (RHF)
energy_gradient np.ndarray Analytic gradient / forces (natoms, 3), Hartree/Bohr — computed on demand
hessian np.ndarray Analytic Hessian (3N, 3N), Hartree/Bohr² — computed on demand
frequencies np.ndarray Harmonic vibrational frequencies (cm⁻¹), imaginary modes negative — computed on demand

Note: energy_gradient, hessian, and frequencies are computed lazily when the property is accessed, so no special run_type is required — a plain run() is enough.


Examples

1. HF Energy with Different Basis Sets

import gansu2

gansu2.init()

with open("h2o.xyz", "w") as f:
    f.write("3\nWater\nO 0 0 0.127\nH 0 0.758 -0.509\nH 0 -0.758 -0.509\n")

for basis in ["sto-3g", "cc-pvdz", "cc-pvtz"]:
    r = gansu2.Molecule("h2o.xyz", basis=basis).run()
    print(f"{basis:10s}  E = {r.total_energy:.8f}  nao = {r.num_basis}")

gansu2.finalize()

2. Post-HF Method Comparison

import gansu2

gansu2.init()

with open("h2o.xyz", "w") as f:
    f.write("3\nWater\nO 0 0 0.127\nH 0 0.758 -0.509\nH 0 -0.758 -0.509\n")

for method in ["none", "mp2", "mp3", "ccsd", "ccsd_t", "fci"]:
    mol = gansu2.Molecule("h2o.xyz", basis="sto-3g")
    r = mol.run(post_hf=method)
    E = r.total_energy + r.post_hf_energy
    label = method.upper() if method != "none" else "HF"
    print(f"{label:10s}  E = {E:.8f}")

gansu2.finalize()

3. H2 Dissociation Curve

import gansu2
import numpy as np

gansu2.init()

print(f"{'R (A)':>8s}  {'RHF':>14s}  {'CCSD':>14s}  {'FCI':>14s}")
print("-" * 56)

for R in np.linspace(0.4, 5.0, 24):
    with open("h2.xyz", "w") as f:
        f.write(f"2\nH2\nH 0 0 0\nH 0 0 {R}\n")

    r_hf   = gansu2.Molecule("h2.xyz", basis="cc-pvdz").run()
    r_ccsd = gansu2.Molecule("h2.xyz", basis="cc-pvdz").run(post_hf="ccsd")
    r_fci  = gansu2.Molecule("h2.xyz", basis="cc-pvdz").run(post_hf="fci")

    e_hf   = r_hf.total_energy
    e_ccsd = r_ccsd.total_energy + r_ccsd.post_hf_energy
    e_fci  = r_fci.total_energy + r_fci.post_hf_energy

    print(f"{R:8.3f}  {e_hf:14.8f}  {e_ccsd:14.8f}  {e_fci:14.8f}")

gansu2.finalize()

4. Excited States

import gansu2

gansu2.init()

with open("h2o.xyz", "w") as f:
    f.write("3\nWater\nO 0 0 0.127\nH 0 0.758 -0.509\nH 0 -0.758 -0.509\n")

mol = gansu2.Molecule("h2o.xyz", basis="cc-pvdz")
r = mol.run(post_hf="eom_ccsd", n_excited_states="5")
print(r.excited_state_report)

gansu2.finalize()

Available excited-state / spectroscopy post_hf methods (all accept n_excited_states):

post_hf= Method
"cis" Configuration Interaction Singles
"adc2", "sos_adc2", "lt_sos_adc2", "adc2x" ADC(2) family
"thc_sos_adc2" Tensor Hypercontraction SOS-ADC(2) (--eri_method ri recommended)
"eom_mp2", "eom_cc2", "eom_ccsd" Equation-of-Motion methods
"ip_eom_ccsd", "ea_eom_ccsd" IP / EA-EOM-CCSD — (N∓1)-electron states (RHF)
"steom_ccsd" Similarity-Transformed EOM-CCSD (auto-runs CIS-NTO + IP/EA-EOM; RHF)
"dlpno_steom_ccsd" Local STEOM-CCSD (RHF, requires RI)
# STEOM-CCSD (RI recommended); reads the auxiliary basis via the `ag` kwarg.
r = gansu2.Molecule("h2o.xyz", basis="cc-pvdz").run(
        post_hf="steom_ccsd",
        eri_method="ri",
        ag="cc-pvdz-rifit",       # auxiliary basis (name or path)
        n_excited_states="5")
print(r.excited_state_report)

5. Orbital Energies and MO Coefficients

import gansu2
import numpy as np

gansu2.init()

with open("h2o.xyz", "w") as f:
    f.write("3\nWater\nO 0 0 0.127\nH 0 0.758 -0.509\nH 0 -0.758 -0.509\n")

r = gansu2.Molecule("h2o.xyz", basis="cc-pvdz").run()

print("Orbital energies (Hartree):")
eps = r.orbital_energies
nocc = r.num_electrons // 2
for i, e in enumerate(eps):
    label = "occ" if i < nocc else "vir"
    print(f"  MO {i+1:3d} ({label})  {e:12.6f}")

print(f"\nHOMO-LUMO gap: {(eps[nocc] - eps[nocc-1]) * 27.2114:.2f} eV")

gansu2.finalize()

5b. Forces, Hessian, Frequencies, and Dipole

import gansu2
import numpy as np

gansu2.init()

with open("h2o.xyz", "w") as f:
    f.write("3\nWater\nO 0 0 0.127\nH 0 0.758 -0.509\nH 0 -0.758 -0.509\n")

r = gansu2.Molecule("h2o.xyz", basis="cc-pvdz").run()   # plain energy run is enough

# Dipole moment (atomic units e·Bohr; ×2.5417464157 → Debye)
mu = r.dipole
print(f"Dipole |mu| = {np.linalg.norm(mu) * 2.5417464157:.4f} Debye")

# Nuclear forces (analytic gradient), (natoms, 3) in Hartree/Bohr
g = r.energy_gradient
print("Max |grad| =", np.abs(g).max())

# Harmonic vibrational frequencies (cm^-1); Hessian built on demand
freqs = r.frequencies
print("Frequencies (cm^-1):", np.round(freqs, 1))

gansu2.finalize()

6. CCSD 1-RDM (Correlation Density)

import gansu2
import numpy as np

gansu2.init()

with open("h2o.xyz", "w") as f:
    f.write("3\nWater\nO 0 0 0.127\nH 0 0.758 -0.509\nH 0 -0.758 -0.509\n")

r = gansu2.Molecule("h2o.xyz", basis="sto-3g").run(post_hf="ccsd_density")

D = r.ccsd_1rdm_mo
print(f"1-RDM shape: {D.shape}")
print(f"Trace(D) = {np.trace(D):.6f}  (should be {r.num_electrons})")
print(f"Natural occupations: {np.sort(np.linalg.eigvalsh(D))[::-1]}")

gansu2.finalize()

6b. DMET-CCSD (Fragment-Based Correlation)

import gansu2

gansu2.init()

# Benzene with auto-detected fragments (each heavy atom + nearest H)
# 6 CH fragments, 2 unique by para-symmetry
r = gansu2.Molecule("../xyz/Benzene.xyz", basis="sto-3g").run(
    post_hf="dmet",
    eri_method="ri",
    auxiliary_gbsfilename="../auxiliary_basis/cc-pvdz-rifit.gbs",
    num_gpus=4,
)
print(f"HF:           {r.total_energy:.6f} Ha")
print(f"DMET-CCSD:    {r.total_energy + r.post_hf_energy:.6f} Ha")
print(f"E_corr:       {r.post_hf_energy:.6f} Ha")

# Manual fragment specification
r2 = gansu2.Molecule("../xyz/Benzene.xyz", basis="sto-3g").run(
    post_hf="dmet",
    dmet_fragments="{0,6} {1,7} {2,8} {3,9} {4,10} {5,11}",
)

# Vayesta-compatible loose tolerance
r3 = gansu2.Molecule("../xyz/Benzene.xyz", basis="sto-3g").run(
    post_hf="dmet",
    dmet_n_tol=4.2e-3,
)

gansu2.finalize()

6c. DLPNO-CCSD / DLPNO-CCSD(T) (Local Correlation)

DLPNO methods scale near-linearly with system size by combining occupied LMO localization, PAO + per-LMO atom domains, per-pair PNO truncation, and strong/weak-pair partitioning. Closed-shell RHF only; requires the RI back-end.

import gansu2

gansu2.init()

# Water hexamer DLPNO-CCSD(T) with the default "normal" preset
r = gansu2.Molecule(
    "../xyz/large_molecular/water_hexamer.xyz",
    basis="cc-pvdz",
).run(
    post_hf="dlpno_ccsd_t",
    eri_method="ri",
    auxiliary_gbsfilename="../auxiliary_basis/cc-pvdz-rifit.gbs",
    dlpno_preset="normal",          # loose / normal / tight / very_tight
    num_gpus=8,
)
print(f"HF:                 {r.total_energy:.6f} Ha")
print(f"DLPNO-CCSD(T) corr: {r.post_hf_energy:.6f} Ha")
print(f"Total:              {r.total_energy + r.post_hf_energy:.6f} Ha")

# Tighter accuracy
r2 = gansu2.Molecule("...").run(
    post_hf="dlpno_ccsd_t",
    eri_method="ri",
    auxiliary_gbsfilename="...",
    dlpno_preset="tight",
)

gansu2.finalize()

6d. Exporting Localized Orbitals

import gansu2

gansu2.init()

# Write Pipek-Mezey occupied LMOs to output_lmo.molden (alongside the SCF).
# Works for RHF / UHF / ROHF; the canonical virtual orbitals are retained.
gansu2.Molecule("../xyz/Benzene.xyz", basis="cc-pvdz").run(
    export_lmo_molden=True,
)
# Open output_lmo.molden in Avogadro / Jmol / VMD / MOrbVis to visualize
# the bond-localized σ orbitals and lone pairs.

gansu2.finalize()

7. Potential Energy Scan (Bond Stretching)

import gansu2
import numpy as np

gansu2.init()

# OH stretch in water: fix one H, move the other
distances = np.linspace(0.8, 2.5, 20)
energies = []

for d in distances:
    with open("h2o_scan.xyz", "w") as f:
        f.write(f"3\nH2O OH scan\nO 0 0 0\nH 0 0.758 -0.509\nH 0 {-0.758*d/0.958:.6f} {-0.509*d/0.958:.6f}\n")
    r = gansu2.Molecule("h2o_scan.xyz", basis="cc-pvdz").run(post_hf="mp2")
    E = r.total_energy + r.post_hf_energy
    energies.append(E)
    print(f"d={d:.3f} A  E={E:.8f}")

gansu2.finalize()

8. Basis Set Convergence Study

import gansu2

gansu2.init()

with open("h2o.xyz", "w") as f:
    f.write("3\nWater\nO 0 0 0.127\nH 0 0.758 -0.509\nH 0 -0.758 -0.509\n")

print(f"{'Basis':>12s}  {'nao':>5s}  {'HF':>14s}  {'CCSD':>14s}  {'Corr':>12s}")
print("-" * 65)

for basis in ["sto-3g", "3-21g", "6-31g", "6-31g_st", "cc-pvdz", "cc-pvtz"]:
    try:
        r = gansu2.Molecule("h2o.xyz", basis=basis).run(post_hf="ccsd")
        e_hf = r.total_energy
        e_corr = r.post_hf_energy
        print(f"{basis:>12s}  {r.num_basis:5d}  {e_hf:14.8f}  {e_hf+e_corr:14.8f}  {e_corr:12.8f}")
    except Exception as e:
        print(f"{basis:>12s}  FAILED: {e}")

gansu2.finalize()

9. Context Manager

import gansu2

with gansu2.session():  # init + finalize automatically
    r = gansu2.Molecule("h2o.xyz", basis="cc-pvdz").run(post_hf="mp2")
    print(f"E = {r.total_energy + r.post_hf_energy:.8f}")

10. CPU-Only Mode

import gansu2

gansu2.init(force_cpu=True)  # No GPU used

r = gansu2.Molecule("h2o.xyz", basis="sto-3g").run(post_hf="ccsd")
print(f"E = {r.total_energy + r.post_hf_energy:.8f}")

gansu2.finalize()

Full Parameter Reference

All parameters accepted by mol.run(**kwargs) and gansu2.Molecule(..., **kwargs) are the same as the CLI parameters. See parameters.md for the complete list.

# Example: passing arbitrary parameters
r = mol.run(
    method="RHF",
    post_hf="adc2",
    n_excited_states="10",
    adc2_solver="schur_omega",
    initial_guess="sad",
)

Available Basis Sets

No gansu2.init() required — works immediately:

import gansu2
print(gansu2.list_basis_sets())
# ['3-21g', '4-31g', '6-311g_st_st', '6-31g', '6-31g_st',
#  'ano-rcc-mb', 'cc-pvdz', 'cc-pvqz', 'cc-pvtz', 'sto-3g']

From CLI:

gansu2 --list-basis

Plotting Example (matplotlib)

import gansu2
import numpy as np
import matplotlib.pyplot as plt

gansu2.init()

Rs = np.linspace(0.4, 5.0, 30)
methods = {"RHF": "none", "MP2": "mp2", "CCSD": "ccsd", "FCI": "fci"}
results = {m: [] for m in methods}

for R in Rs:
    with open("h2.xyz", "w") as f:
        f.write(f"2\nH2\nH 0 0 0\nH 0 0 {R}\n")
    for label, post_hf in methods.items():
        r = gansu2.Molecule("h2.xyz", basis="cc-pvdz").run(post_hf=post_hf)
        results[label].append(r.total_energy + r.post_hf_energy)

gansu2.finalize()

plt.figure(figsize=(8, 6))
for label, Es in results.items():
    plt.plot(Rs, Es, "o-", label=label)
plt.xlabel("H-H distance (A)")
plt.ylabel("Total energy (Hartree)")
plt.title("H2 dissociation curve")
plt.legend()
plt.grid(alpha=0.3)
plt.tight_layout()
plt.savefig("h2_dissociation.png", dpi=150)
plt.show()

This site uses Just the Docs, a documentation theme for Jekyll.