jaxvacua quickstart#

This notebook is the shortest end-to-end run through the jaxvacua Type IIB flux-vacuum engine. It

  1. loads a small bundled \(h^{2,1}=2\) model (no CYTools, no network),

  2. constructs the flux effective theory and evaluates \(W\), \(D_I W\), and the no-scale scalar potential at a sample point,

  3. samples ISD-biased initial guesses,

  4. runs a Newton refinement to a vacuum and reports \(|W_0|\), \(g_s\), and the residual.

For the full surface, see the JAXVacua tutorials index.

Setup#

import warnings; warnings.filterwarnings("ignore")

import numpy as np
import jax
import jax.numpy as jnp

import jaxvacua as jvc
jvc.set_precision("float64")     # 64-bit before any heavy compute

1. Build a flux effective theory#

The bundled model (h12=2, model_ID=1) is the degree-18 hypersurface in \(\mathbb{CP}^{1,1,1,6,9}\). Instanton corrections are truncated at maximum_degree=2 for speed.

model = jvc.FluxVacuaFinder(
    h12             = 2,
    model_ID        = 1,
    limit           = "LCS",
    maximum_degree  = 2,
)
print(f"h11 (mirror)        = {model.h12}")
print(f"intersection numbers = {np.asarray(model.lcs_tree.intnums).tolist()}")
print(f"Euler character chi = {model.lcs_tree.chi}")

2. Sample a flux + evaluate \(W\) and \(D_I W\)#

# A random integer flux vector inside the model's flux space
np.random.seed(42)
flux = np.random.randint(low=-3, high=4, size=2 * (model.h12 + 1) * 2).astype(np.int32)

# Initial moduli: large imaginary parts -> deep LCS regime
z   = jnp.array([0. + 2.j, 0. + 2.5j])     # complex-structure moduli
tau = jnp.array(0. + 4.j)                  # axio-dilaton

W   = model.superpotential(z, tau, flux)
DW  = model.DW(z, jnp.conj(z), tau, jnp.conj(tau), flux)
print(f"|W|        = {float(jnp.abs(W)):.4e}")
print(f"max |D_I W| = {float(jnp.max(jnp.abs(DW))):.4e}")

3. ISD-biased initial guesses#

The same flux is fed through the ISD-completion sampler to get initial guesses biased towards the imaginary-self-dual locus where \(F\)-term equations are easier to solve.

sampler = jvc.data_sampler(
    model,
    moduli_bounds  = (1.5, 3.0),
    axion_bounds   = (-0.3, 0.3),
    dilaton_bounds = (2.0, 5.0),
)
initial_guesses = sampler.initial_guesses(N=8)
print(f"initial-guess batch: {len(initial_guesses)} entries")

4. Newton refinement to a vacuum#

FluxVacuaFinder.newton_method_flux_vacua() runs scipy.optimize.root on the real-valued residual [Re D_I W, Im D_I W], starting from each initial guess.

# (For brevity we refine just the first guess; production runs
# vmap over the entire initial-guess batch.)
results = model.fterm_solver(initial_guesses[:1], flux, tol=1e-12, verbose=False)

if len(results):
    sol = results[0]
    print(f"|W_0|              = {float(jnp.abs(sol['W_0'])):.4e}")
    print(f"g_s                = {float(1.0 / sol['tau'].imag):.4f}")
    print(f"max |D_I W| residual = {float(jnp.max(jnp.abs(sol['DW_at_solution']))):.2e}")
else:
    print('Newton did not converge for this random flux -- rerun with a '
          'different seed or sampler config.  See the jaxvacua tutorials.')

What next#

  • See the full jaxvacua tutorials for the geometry-input pipeline (CYTools, the CY database, custom prepotentials), the flux-bounding enumerator, conifold and coni-LCS limits, the freezer EFT, and the vacuum-vault workflow.

  • Try the stringforge quickstart to see how to load larger models from the curated database.

  • Try the jaxpolylog quickstart to see the polylogarithm engine that jaxvacua calls under the hood.