jaxvacua quickstart#
This notebook is the shortest end-to-end run through the
jaxvacua Type IIB
flux-vacuum engine. It
loads a small bundled \(h^{2,1}=2\) model (no CYTools, no network),
constructs the flux effective theory and evaluates \(W\), \(D_I W\), and the no-scale scalar potential at a sample point,
samples ISD-biased initial guesses,
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.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.0 + 2.0j, 0.0 + 2.5j]) # complex-structure moduli
tau = jnp.array(0.0 + 4.0j) # 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
jaxvacuacalls under the hood.