E8over27

In [61]:

    # This worksheet illustrates the use of Sage for the toric intersection calculations in the paper
    # "Modular Amplitudes and Flux-Superpotentials on elliptic Calabi-Yau fourfolds", https://arxiv.org/abs/1709.02820
    # As an example, we construct a 4-parameter elliptically fibered Calabi-Yau 4-fold with an E8 fiber and
    # polytope 27 as the base.
    # We choose polytope 27 because the corresponding variety is Fano and the intersection ring is relatively
    # non-trivial.
    # If you use this code or parts of it for a publication, please
    # cite the above paper.
    ReflexivePolytope(3, 27).points()

Out[61]:

    M( 1,  0,  0),
    M(-1,  0,  0),
    M( 0,  1,  0),
    M( 0,  0,  1),
    M( 1,  0, -1),
    M( 1, -1,  0),
    M( 0,  0,  0)
    in 3-d lattice M

In [1]:

    # Triangulate polytope and create toric variety
    vertices = \
    [[1, 0, 0, -2, -3], \
     [-1, 0, 0, -2, -3], \
     [0, 1, 0, -2, -3], \
     [0, 0, 1, -2, -3], \
     [1, 0, -1, -2, -3], \
     [1, -1, 0, -2, -3], \
     [0, 0, 0, -2, -3], \
     [0, 0, 0, 1, 0], \
     [0, 0, 0, 0, 1]]

    poly = LatticePolytope(vertices)

    irrelevantPoints = [b for a in map(lambda a: map(tuple, a.interior_points()), poly.faces_lp(codim=1)) for b in a]
    relevantPoints = list(set(map(tuple, poly.points())) - set(irrelevantPoints))

    pointTuples = relevantPoints

    pointConfiguration = PointConfiguration(pointTuples, fine=True, star=pointTuples.index((0, 0, 0, 0, 0)))
    triang = pointConfiguration.triangulate()
    fan = Fan([Cone([pointTuples[i] for i in indices]) for indices in triang])

    variety = ToricVariety(fan)

    HH = variety.cohomology_ring()
    D = [ HH(c) for c in variety.fan(dim=1) ]

    # Print Mori cone
    print variety.Mori_cone().rays()

    (0, 0, 0, -1, -1, 1, 0, 1, 0,  0),
    (0, 0, 0,  1,  0, 0, 3, 0, 2, -6),
    (0, 1, 0, -2,  1, 0, 0, 0, 0,  0),
    (1, 0, 1, -1, -1, 0, 0, 0, 0,  0)
    in Ambient free module of rank 10 over the principal ideal domain Integer Ring

In [3]:

    print variety.fan(dim = 1)[3].rays() # <-- this is (0,0,-2,-3)
    s = D[3] # <-- the corresponding toric divisor is the section

    # Using the Mori cone, we determine a basis for the Kähler cone
    d1 = D[5]
    d2 = D[1]
    d3 = D[0]
    d4 = D[3] + D[5] + 2*D[1] + D[0]

    tc1 = d4 - s

    kaehlerClasses = [d1,d2,d3,d4]

    cy = sum(D)

    cc=(reduce(operator.mul, [(1+d) for d in D], 1)/(1+sum(D)))
    c1=cc.part_of_degree(1)
    c2=cc.part_of_degree(2)
    c3=cc.part_of_degree(3)
    c4=cc.part_of_degree(4)
    todd=1+(1/12)*c2+(1/240)*c2*c2-(1/720)*c4

    intersections = {}

    import itertools
    import math

    print ""

    for comb in itertools.combinations_with_replacement(range(4), 4):

        intersection = variety.integrate(reduce(operator.mul, [[d1, d2,d3,d4][i] for i in comb], 1) * cy)
        intersections[tuple([a + 1 for a in comb])] = intersection
        print "C" + str([a + 1 for a in comb]) + ": " + str(intersection)

    N(0, 0, 0, -2, -3)
    in 5-d lattice N

    C[1, 1, 1, 1]: 0
    C[1, 1, 1, 2]: 0
    C[1, 1, 1, 3]: 0
    C[1, 1, 1, 4]: 0
    C[1, 1, 2, 2]: 0
    C[1, 1, 2, 3]: 0
    C[1, 1, 2, 4]: 0
    C[1, 1, 3, 3]: 0
    C[1, 1, 3, 4]: 0
    C[1, 1, 4, 4]: 0
    C[1, 2, 2, 2]: 0
    C[1, 2, 2, 3]: 0
    C[1, 2, 2, 4]: 1
    C[1, 2, 3, 3]: 0
    C[1, 2, 3, 4]: 1
    C[1, 2, 4, 4]: 3
    C[1, 3, 3, 3]: 0
    C[1, 3, 3, 4]: 0
    C[1, 3, 4, 4]: 2
    C[1, 4, 4, 4]: 8
    C[2, 2, 2, 2]: 0
    C[2, 2, 2, 3]: 0
    C[2, 2, 2, 4]: 2
    C[2, 2, 3, 3]: 0
    C[2, 2, 3, 4]: 1
    C[2, 2, 4, 4]: 6
    C[2, 3, 3, 3]: 0
    C[2, 3, 3, 4]: 0
    C[2, 3, 4, 4]: 3
    C[2, 4, 4, 4]: 18
    C[3, 3, 3, 3]: 0
    C[3, 3, 3, 4]: 0
    C[3, 3, 4, 4]: 0
    C[3, 4, 4, 4]: 8
    C[4, 4, 4, 4]: 52

In [4]:

    # Intersection ring of the base:
    for comb in itertools.combinations_with_replacement(range(3), 3):

        intersection = variety.integrate(reduce(operator.mul, [[d1, d2, d3][i] for i in comb], 1) * s * cy)
        intersections[tuple([a + 1 for a in comb])] = intersection
        print "C" + str([a + 1 for a in comb]) + ": " + str(intersection)

    C[1, 1, 1]: 0
    C[1, 1, 2]: 0
    C[1, 1, 3]: 0
    C[1, 2, 2]: 1
    C[1, 2, 3]: 1
    C[1, 3, 3]: 0
    C[2, 2, 2]: 2
    C[2, 2, 3]: 1
    C[2, 3, 3]: 0
    C[3, 3, 3]: 0

In [5]:

    # Determine dual basis of the base:
    basecurves = [a * s for a in [d1*d1, d1*d2, d1*d3, d2*d2, d2*d3, d3*d3]]
    for c in basecurves:
        print [variety.integrate(c*a*cy) for a in [d1,d2,d3]]
        print ""
    basecurvebasis = [d2*d3 - d1*d3, d1*d3, d1*d2 - d1*d3]
    print matrix([[variety.integrate(c*a*s*cy) for a in [d1,d2,d3]] for c in basecurvebasis])

    [0, 0, 0]

    [0, 1, 1]

    [0, 1, 0]

    [1, 2, 1]

    [1, 1, 0]

    [0, 0, 0]

    [1 0 0]
    [0 1 0]
    [0 0 1]

In [6]:

    # We choose the following basis of H22 cycles:
    hilist=[s*d1,s*d2,s*d3] + basecurvebasis

    # Print the intersections
    print matrix([[variety.integrate(h*hp*cy) for hp in hilist] for h in hilist])

    [ 0 -3 -2  1  0  0]
    [-3 -6 -3  0  1  0]
    [-2 -3  0  0  0  1]
    [ 1  0  0  0  0  0]
    [ 0  1  0  0  0  0]
    [ 0  0  1  0  0  0]

In [7]:

    # Determine the fundamental class
    print variety.integrate(s*d1*d2*d3*cy)

    fundamentalClass = s*d1*d2*d3

    1

In [8]:

    # Express the basis of the Mori cone as intersections of toric divisors
    curves = [s * a for a in basecurvebasis] + [d1*d2*d3]
    print matrix([[variety.integrate(c*d*cy) for d in [d1,d2,d3,d4]] for c in curves])

    [1 0 0 0]
    [0 1 0 0]
    [0 0 1 0]
    [0 0 0 1]

In [9]:

    import itertools

    def totalChern(te):

        totalChernClass = 0

        for h in te:

            if len(h[1]) == 0:

                chernClass = 1 + kaehlerClasses[0]
                chernClass = chernClass - kaehlerClasses[0] # Just a hack to lift the identity into the cohomology ring

            elif len(h[1]) == 1:

                d = h[1][0]

                chernClass = -d-(1/2)*d*d-(1/6)*d*d*d-(1/24)*d*d*d*d

            elif len(h[1]) == 2:

                da = h[1][0]
                db = h[1][1]

                chernClass = da*db+(1/2)*da*db*(da+db)+(1/12)*da*db*(2*da*da+3*da*db+2*db*db)

            elif len(h[1]) == 3:

                da = h[1][0]
                db = h[1][1]
                dc = h[1][2]

                chernClass = -da*db*dc-(1/2)*(da*da*db*dc+da*db*db*dc+da*db*dc*dc)

            elif len(h[1]) == 4:

                da = h[1][0]
                db = h[1][1]
                dc = h[1][2]
                dd = h[1][3]

                chernClass = da*db*dc*dd

            else:

                print "parameter error!"
                return

            totalChernClass = totalChernClass + h[0]*chernClass

        return totalChernClass

    def asymptotics(te):

        cy=sum(D)
        cc=(reduce(operator.mul, [(1+d) for d in D], 1)/(1+sum(D)))
        c2=cc.part_of_degree(2)
        c3=cc.part_of_degree(3)
        c4=cc.part_of_degree(4)

        totalChernClass = totalChern(te)

        curveC0 = totalChernClass.part_of_degree(0)
        curveC1 = totalChernClass.part_of_degree(1)
        curveC2 = totalChernClass.part_of_degree(2)
        curveC3 = totalChernClass.part_of_degree(3)
        curveC4 = totalChernClass.part_of_degree(4)

        kaehlerVariableString = ['t'+str(i) for i in range(1,len(kaehlerClasses)+1)]
        _ = var(kaehlerVariableString)
        kaehlerVariables = eval(",".join(kaehlerVariableString))

        gammaClass = [(1,1),(1/24,c2),(I*zeta(3)/(8*pi^3),c3),((1/5760),7*c2*c2-4*c4)]

        fourTuples = list(itertools.product(range(1,len(kaehlerClasses)+1), repeat=4))
        threeTuples = list(itertools.product(range(1,len(kaehlerClasses)+1), repeat=3))
        twoTuples = list(itertools.product(range(1,len(kaehlerClasses)+1), repeat=2))
        oneTuples = list(itertools.product(range(1,len(kaehlerClasses)+1), repeat=1))

        asymptotics = sum([g[0]*variety.integrate(g[1]*cy*totalChernClass) for g in gammaClass]) \
         + sum([(1/factorial(len(tup)))*sum([g[0]*variety.integrate(g[1]*cy*totalChernClass*reduce(operator.mul, [kaehlerClasses[i - 1] for i in tup])) \
            for g in gammaClass]) * reduce(operator.mul, [kaehlerVariables[i - 1] for i in tup]) for tup in oneTuples]) \
         + sum([(1/factorial(len(tup)))*sum([g[0]*variety.integrate(g[1]*cy*totalChernClass*reduce(operator.mul, [kaehlerClasses[i - 1] for i in tup])) \
            for g in gammaClass]) * reduce(operator.mul, [kaehlerVariables[i - 1] for i in tup]) for tup in twoTuples]) \
         + sum([(1/factorial(len(tup)))*sum([g[0]*variety.integrate(g[1]*cy*totalChernClass*reduce(operator.mul, [kaehlerClasses[i - 1] for i in tup])) \
            for g in gammaClass]) * reduce(operator.mul, [kaehlerVariables[i - 1] for i in tup]) for tup in threeTuples]) \
         + sum([(1/factorial(len(tup)))*sum([g[0]*variety.integrate(g[1]*cy*totalChernClass*reduce(operator.mul, [kaehlerClasses[i - 1] for i in tup])) \
            for g in gammaClass]) * reduce(operator.mul, [kaehlerVariables[i - 1] for i in tup]) for tup in fourTuples]) \

        return str(asymptotics).replace("zeta(3)","Zeta[3]").replace("pi","Pi")

    def dualClass(cl):

        return cl.part_of_degree(0) - cl.part_of_degree(1) + cl.part_of_degree(2) - cl.part_of_degree(3) + cl.part_of_degree(4)

In [59]:

    # The syntax of asymptotics(...) (and totalChern) is such that you pass a list of tuples
    # (a_i, [D_{i,1},...,D_{i,n}]) and get the asymptotic period (or the chern class)
    # of a brane corresponding to \sum_i a_i D_{i,1}*...*D_{i,n}
    print "d8asy="+asymptotics([(1,[])])+";"

    print "d6asy1="+asymptotics([(1,[s])])+";"
    print "d6asy2="+asymptotics([(1,[d1])])+";"
    print "d6asy3="+asymptotics([(1,[d2])])+";"
    print "d6asy4="+asymptotics([(1,[d3])])+";"

    print "d4asy1="+asymptotics([(1,[s,d1])])+";"
    print "d4asy2="+asymptotics([(1,[s,d2])])+";"
    print "d4asy3="+asymptotics([(1,[s,d3])])+";"
    print "d4asy4="+asymptotics([(1,[d2,d3]),(-1,[d1,d3])])+";"
    print "d4asy5="+asymptotics([(1,[d1,d3])])+";"
    print "d4asy6="+asymptotics([(1,[d1,d2]),(-1,[d1,d3])])+";"

    print "d2asy1="+asymptotics([(1,[s,d2,d3]),(-1,[s,d1,d3])])+";"
    print "d2asy2="+asymptotics([(1,[s,d1,d3]),(-1,[s,d1,d2,d3])])+";" # <-- choosen such that d2asy2 == -t2
    print "d2asy3="+asymptotics([(1,[s,d1,d2]),(-1,[s,d1,d3])])+";"
    print "d2asy4="+asymptotics([(1,[d1,d2,d3])])+";"

    print "d0asy="+asymptotics([(1,[s,d1,d2,d3])])+";"

    d8asy=1/2*t1*t2^2*t4 + 1/3*t2^3*t4 + t1*t2*t3*t4 + 1/2*t2^2*t3*t4 + 3/2*t1*t2*t4^2 + 3/2*t2^2*t4^2 + t1*t3*t4^2 + 3/2*t2*t3*t4^2 + 4/3*t1*t4^3 + 3*t2*t4^3 + 4/3*t3*t4^3 + 13/6*t4^4 + 3/2*t1*t2 + 3/2*t2^2 + t1*t3 + 3/2*t2*t3 + 23/6*t1*t4 + 103/12*t2*t4 + 23/6*t3*t4 + 149/12*t4^2 - 60*I*t1*Zeta[3]/Pi^3 - 135*I*t2*Zeta[3]/Pi^3 - 60*I*t3*Zeta[3]/Pi^3 - 392*I*t4*Zeta[3]/Pi^3 - 59/12;
    d6asy1=-1/2*t1*t2^2 - 1/3*t2^3 - t1*t2*t3 - 1/2*t2^2*t3 + 3/2*t1*t2 + 3/2*t2^2 + t1*t3 + 3/2*t2*t3 - 7/6*t1 - 31/12*t2 - 7/6*t3 + 2*I*Zeta[3]/Pi^3 + 19/12;
    d6asy2=-1/2*t2^2*t4 - t2*t3*t4 - 3/2*t2*t4^2 - t3*t4^2 - 4/3*t4^3 - 3/2*t2 - t3 - 23/6*t4 + 60*I*Zeta[3]/Pi^3;
    d6asy3=-t1*t2*t4 - t2^2*t4 - t1*t3*t4 - t2*t3*t4 - 3/2*t1*t4^2 - 3*t2*t4^2 - 3/2*t3*t4^2 - 3*t4^3 - 1/2*t1*t4 - t2*t4 - 1/2*t3*t4 - 3/2*t4^2 - 3/2*t1 - 3*t2 - 3/2*t3 - 107/12*t4 + 135*I*Zeta[3]/Pi^3 - 3/2;
    d6asy4=-t1*t2*t4 - 1/2*t2^2*t4 - t1*t4^2 - 3/2*t2*t4^2 - 4/3*t4^3 - t1 - 3/2*t2 - 23/6*t4 + 60*I*Zeta[3]/Pi^3;
    d4asy1=1/2*t2^2 + t2*t3 - 3/2*t2 - t3 + 7/6;
    d4asy2=t1*t2 + t2^2 + t1*t3 + t2*t3 - t1 - 2*t2 - t3 + 17/12;
    d4asy3=t1*t2 + 1/2*t2^2 - t1 - 3/2*t2 + 7/6;
    d4asy4=t1*t4 + 1/2*t4^2 + 1/2*t4 + 1/2;
    d4asy5=t2*t4 + t4^2 + 1;
    d4asy6=t3*t4 + 1/2*t4^2 + 1/2*t4 + 1/2;
    d2asy1=-t1;
    d2asy2=-t2;
    d2asy3=-t3;
    d2asy4=-t4;
    d0asy=1;

In [10]:

    charges = [[(1,[d2,d3]),(-1,[d1,d3])], \
              [(1,[d1,d3])], \
              [(1,[d1,d2]),(-1,[d1,d3])]]
    hv = [variety.integrate(s*totalChern((c)).part_of_degree(3)*cy) for c in charges]
    avo = [variety.integrate(s*c*tc1*cy) for c in [d2*d3-d1*d3,d1*d3,d1*d2-d1*d3]]

    print "The vector h^i is"
    print hv

    The vector h^i is
    [1/2, 0, 1/2]

In [11]:

    def cal_cijk(i,j,k):
        di = [d1,d2,d3][i]
        dj = [d1,d2,d3][j]
        dk = [d1,d2,d3][k]
        return variety.integrate(di*dj*dk*s*cy)
    def cal_aij(i,j):
        di = [d1,d2,d3][i]
        dj = [d1,d2,d3][j]
        return variety.integrate(di*dj*tc1*s*cy)
    def cal_aiu(i):
        di = [d1,d2,d3][i]
        return variety.integrate(di*tc1*tc1*s*cy)
    def cal_aio(i):
        c = basecurvebasis[i]
        return variety.integrate(tc1*c*s*cy)
    def cal_a():
        return variety.integrate(tc1*tc1*tc1*s*cy)

In [16]:

    d8cc=totalChern([(1,[])])

    d6cc1=totalChern([(1,[s])])
    d6cc2=totalChern([(1,[d1])])
    d6cc3=totalChern([(1,[d2])])
    d6cc4=totalChern([(1,[d3])])

    d4cc1=totalChern([(1,[s,d1])])
    d4cc2=totalChern([(1,[s,d2])])
    d4cc3=totalChern([(1,[s,d3])])
    d4cc4=totalChern([(1,[d2,d3]),(-1,[d1,d3])])
    d4cc5=totalChern([(1,[d1,d3])])
    d4cc6=totalChern([(1,[d1,d2]),(-1,[d1,d3])])

    d2cc1=totalChern([(1,[s,d2,d3]),(-1,[s,d1,d3])])
    d2cc2=totalChern([(1,[s,d1,d3])])
    d2cc3=totalChern([(1,[s,d1,d2]),(-1,[s,d1,d3])])
    d2cc4=totalChern([(1,[d1,d2,d3])])

    d0cc=totalChern([(1,[s,d1,d2,d3])])

    chargeList = [d8cc,d6cc1,d6cc2,d6cc3,d6cc4,d4cc1,d4cc2,d4cc3,d4cc4,d4cc5,d4cc6,d2cc1,d2cc2,d2cc3,d2cc4,d0cc]

    intersection = matrix([[variety.integrate(dualClass(f1)*f2*todd*cy) for f1 in chargeList] for f2 in chargeList])
    print "The mirror dual 4-cycles intersect as"
    print intersection

    print ""
    print "int="+("["+(str(intersection).replace("\n",",").replace(" ",",").replace(" ","").replace(" ","").replace(" ","").replace(" ","").replace(",,",",").replace(",,",",").replace(",,",",").replace("[,","["))+"]").replace("[","{").replace("]","}")+";"

    The mirror dual 4-cycles intersect as
    [ 2  1  0 -3  0  1  1  1  1  2  1  0  1  0  0  1]
    [ 1  2 -1 -4 -1  0 -3  0  1  1  1  1  2  1 -1  0]
    [ 0 -1  0 -3 -2  0 -1 -1  0  0  0 -1  0  0  0  0]
    [-3 -4 -3 -6 -3 -2 -3 -2  0  0  0  0 -1  0  0  0]
    [ 0 -1 -2 -3  0 -1 -1  0  0  0  0  0  0 -1  0  0]
    [ 1  0  0 -2 -1  0 -3 -2  1  0  0  0  0  0  0  0]
    [ 1 -3 -1 -3 -1 -3 -6 -3  0  1  0  0  0  0  0  0]
    [ 1  0 -1 -2  0 -2 -3  0  0  0  1  0  0  0  0  0]
    [ 1  1  0  0  0  1  0  0  0  0  0  0  0  0  0  0]
    [ 2  1  0  0  0  0  1  0  0  0  0  0  0  0  0  0]
    [ 1  1  0  0  0  0  0  1  0  0  0  0  0  0  0  0]
    [ 0  1 -1  0  0  0  0  0  0  0  0  0  0  0  0  0]
    [ 1  2  0 -1  0  0  0  0  0  0  0  0  0  0  0  0]
    [ 0  1  0  0 -1  0  0  0  0  0  0  0  0  0  0  0]
    [ 0 -1  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
    [ 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]

    int={{2,1,0,-3,0,1,1,1,1,2,1,0,1,0,0,1},{1,2,-1,-4,-1,0,-3,0,1,1,1,1,2,1,-1,0},{0,-1,0,-3,-2,0,-1,-1,0,0,0,-1,0,0,0,0},{-3,-4,-3,-6,-3,-2,-3,-2,0,0,0,0,-1,0,0,0},{0,-1,-2,-3,0,-1,-1,0,0,0,0,0,0,-1,0,0},{1,0,0,-2,-1,0,-3,-2,1,0,0,0,0,0,0,0},{1,-3,-1,-3,-1,-3,-6,-3,0,1,0,0,0,0,0,0},{1,0,-1,-2,0,-2,-3,0,0,0,1,0,0,0,0,0},{1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0},{2,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0},{1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0},{0,1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0},{1,2,0,-1,0,0,0,0,0,0,0,0,0,0,0,0},{0,1,0,0,-1,0,0,0,0,0,0,0,0,0,0,0},{0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};

In [12]:

    tp_a = variety.integrate(tc1*tc1*tc1*d4*cy)
    tp_ai = [variety.integrate(tc1*tc1*i*d4*cy) for i in [d1,d2,d3]]
    tp_aij = [[variety.integrate(tc1*i*j*d4*cy) for i in [d1,d2,d3]] for j in [d1,d2,d3]]
    tp_cijk = [[[variety.integrate(i*j*k*d4*cy) for i in [d1,d2,d3]] for j in [d1,d2,d3]] for k in [d1,d2,d3]]
    tp_aio = [cal_aio(i) for i in range(3)]

In [13]:

    print "a: " + str(tp_a) + "\n"
    print "a_i: " + str(tp_ai) + "\n"
    print "a_ij:\n" + str(matrix(tp_aij)) + "\n"
    print "c_ijk: " + str(tp_cijk) + "\n"
    print "a^i: " + str(tp_aio) + "\n"
    print "h^i: " + str(hv)

    a: 52

    a_i: [8, 18, 8]

    a_ij:
    [0 3 2]
    [3 6 3]
    [2 3 0]

    c_ijk: [[[0, 0, 0], [0, 1, 1], [0, 1, 0]], [[0, 1, 1], [1, 2, 1], [1, 1, 0]], [[0, 1, 0], [1, 1, 0], [0, 0, 0]]]

    a^i: [1, 2, 1]

    h^i: [1/2, 0, 1/2]

In [ ]: