EKC Construction: h11=2 Example#

This notebook demonstrates constructing the extended Kahler cone (EKC) of a Calabi-Yau threefold with \(h^{1,1} = 2\), using the GV-based method of arXiv:2212.10573 and arXiv:2303.00757.

The cybir package implements this pipeline and integrates with CYTools.

import cybir
from cybir import CYBirationalClass, patch_cytools
import cytools
import numpy as np

# Activate CYTools integration
patch_cytools()
Warning: cache /Users/elijahsheridan/Library/Caches/CYTools/twoface_ineqs.pkl.gz is broken (Ran out of input), removing it...

Load a Calabi-Yau threefold#

We fetch an \(h^{1,1} = 2\) polytope from the CYTools database, triangulate it, and extract a Calabi-Yau hypersurface.

# Load an h11=2 polytope from CYTools database
p = cytools.fetch_polytopes(h11=2, limit=1)[0]
cy = p.triangulate().get_cy()
print(f"h11 = {cy.h11()}, h21 = {cy.h21()}")
h11 = 2, h21 = 29

Construct the Extended Kahler Cone#

The CYBirationalClass.from_gv classmethod runs the full pipeline:

  1. Compute GV invariants up to max_deg

  2. Set up the root phase from the CYTools geometry

  3. BFS over Mori cone walls, classifying and flopping

ekc = CYBirationalClass.from_gv(cy, max_deg=10, verbose=True)
print(ekc)
CYBirationalClass(constructed, phases=1, contractions=2)

Inspect Phases#

Each phase is a CalabiYauLite object with intersection numbers, second Chern class, Mori cone generators, and Kahler cone generators.

for phase in ekc.phases:
    print(f"{phase.label}: int_nums shape = {phase.int_nums.shape}")
print(f"\nTotal phases: {len(ekc.phases)}")
CY_0: int_nums shape = (2, 2, 2)

Total phases: 1

Inspect Contractions#

Each wall between phases is an ExtremalContraction with a classified type (flop, symmetric flop, asymptotic, CFT, or su(2)) and the contraction curve.

for c in ekc.contractions:
    print(f"  {c.contraction_type.display_name()}: curve = {c.contraction_curve}")
  asymptotic: curve = [1 0]
  asymptotic: curve = [0 1]

Phase Graph Structure#

The CYGraph encodes which phases are connected by contractions. Self-loops represent terminal walls (asymptotic, CFT, su(2)).

print(ekc.graph)
for phase in ekc.phases:
    neighbors = ekc.graph.neighbors(phase.label)
    print(f"{phase.label} -> {[n.label for n in neighbors]}")
CYGraph(phases=1, contractions=2)
CY_0 -> ['CY_0']

Coxeter Data#

If any symmetric-flop walls are found, their reflection matrices form a Coxeter group. The Coxeter matrix encodes the orders of pairwise products.

if ekc.coxeter_matrix is not None:
    print("Coxeter matrix:")
    print(ekc.coxeter_matrix)
else:
    print("No Coxeter reflections found (all walls are terminal or generic flops)")
No Coxeter reflections found (all walls are terminal or generic flops)

Coxeter Orbit Expansion (optional)#

If the Coxeter group from symmetric-flop reflections is non-trivial and finite, apply_coxeter_orbit enumerates the full group and applies every element to each fundamental-domain phase, producing the complete birational geometry.

ekc.apply_coxeter_orbit()
print(f"After orbit expansion: {len(ekc.phases)} phases")
if ekc.coxeter_type:
    print(f"Coxeter type: {ekc.coxeter_type}")
    print(f"Group order: {ekc.coxeter_order}")
After orbit expansion: 1 phases