Exemplo n.º 1
0
    def normalize_metric(self):

        if self.de is None:
            return

        renorm = []
        #  Generate mapping for renormalizing reciprocal basis vectors
        for ib in self.n_range:  # e^{ib} --> e^{ib}/|e_{ib}|
            renorm.append((self.r_symbols[ib], self.r_symbols[ib] / self.e_norm[ib]))

        # Normalize derivatives of basis vectors

        for x_i in self.n_range:
            for jb in self.n_range:
                self.de[x_i][jb] = Simp.apply((((self.de[x_i][jb].subs(renorm)
                                              - diff(self.e_norm[jb], self.coords[x_i]) *
                                              self.basis[jb]) / self.e_norm[jb])))
        if self.debug:
            for x_i in self.n_range:
                for jb in self.n_range:
                    print '\partial_{' + str(self.coords[x_i]) + '}\hat{e}_{' + str(self.coords[jb]) + '} =', self.de[x_i][jb]

        # Normalize metric tensor

        for ib in self.n_range:
            for jb in self.n_range:
                self.g[ib, jb] = Simp.apply(self.g[ib, jb] / (self.e_norm[ib] * self.e_norm[jb]))

        if self.debug:
            printer.oprint('e^{i}->e^{i}/|e_{i}|', renorm)
            printer.oprint('renorm(g)', self.g)

        return
Exemplo n.º 2
0
    def normalize_metric(self):

        if self.de is None:
            return

        renorm = []
        #  Generate mapping for renormalizing reciprocal basis vectors
        for ib in self.n_range:  # e^{ib} --> e^{ib}/|e_{ib}|
            renorm.append((self.r_symbols[ib], self.r_symbols[ib] / self.e_norm[ib]))

        # Normalize derivatives of basis vectors

        for x_i in self.n_range:
            for jb in self.n_range:
                self.de[x_i][jb] = Simp.apply((((self.de[x_i][jb].subs(renorm)
                                              - diff(self.e_norm[jb], self.coords[x_i]) *
                                              self.basis[jb]) / self.e_norm[jb])))
        if self.debug:
            for x_i in self.n_range:
                for jb in self.n_range:
                    print '\partial_{' + str(self.coords[x_i]) + '}\hat{e}_{' + str(self.coords[jb]) + '} =', self.de[x_i][jb]

        # Normalize metric tensor

        for ib in self.n_range:
            for jb in self.n_range:
                self.g[ib, jb] = Simp.apply(self.g[ib, jb] / (self.e_norm[ib] * self.e_norm[jb]))

        if self.debug:
            printer.oprint('e^{i}->e^{i}/|e_{i}|', renorm)
            printer.oprint('renorm(g)', self.g)

        return
Exemplo n.º 3
0
    def derivatives_of_basis(
            self):  # Derivatives of basis vectors from Christ-Awful symbols

        dg = []  # dg[i][j][k] = \partial_{x_{k}}g_{ij}

        for i in self.n_range:
            dg_row = []
            for j in self.n_range:
                dg_row.append(
                    [diff(self.g[i, j], coord) for coord in self.coords])
            dg.append(dg_row)

        # See if metric is flat

        self.connect_flg = False

        for i in self.n_range:
            for j in self.n_range:
                for k in self.n_range:
                    if dg[i][j][k] != 0:
                        self.connect_flg = True
                        break

        if not self.connect_flg:
            self.de = None
            return

        n_range = range(len(self.basis))

        de = []  # de[i][j] = \partial_{x_{i}}e^{x_{j}}

        # Christoffel symbols of the first kind, \Gamma_{ijk}

        for i in n_range:
            de_row = []
            for j in n_range:
                Gamma = []
                for k in n_range:
                    gamma = half * (dg[j][k][i] + dg[i][k][j] - dg[i][j][k])
                    Gamma.append(Simp.apply(gamma))
                de_row.append(
                    sum([
                        gamma * base
                        for (gamma, base) in zip(Gamma, self.r_symbols)
                    ]))
            de.append(de_row)
        if self.debug:
            printer.oprint('D_{i}e^{j}', de)
        self.de = de
        return
Exemplo n.º 4
0
    def derivatives_of_basis(self):  # Derivatives of basis vectors from Christ-Awful symbols

        dg = []  # dg[i][j][k] = \partial_{x_{k}}g_{ij}

        for i in self.n_range:
            dg_row = []
            for j in self.n_range:
                dg_row.append([diff(self.g[i, j], coord) for coord in self.coords])
            dg.append(dg_row)

        # See if metric is flat

        self.connect_flg = False

        for i in self.n_range:
            for j in self.n_range:
                for k in self.n_range:
                    if dg[i][j][k] != 0:
                        self.connect_flg = True
                        break

        if not self.connect_flg:
            self.de = None
            return

        n_range = range(len(self.basis))

        de = []  # de[i][j] = \partial_{x_{i}}e^{x_{j}}

        # Christoffel symbols of the first kind, \Gamma_{ijk}

        for i in n_range:
            de_row = []
            for j in n_range:
                Gamma = []
                for k in n_range:
                    gamma = half * (dg[j][k][i] + dg[i][k][j] - dg[i][j][k])
                    Gamma.append(Simp.apply(gamma))
                de_row.append(sum([gamma * base for (gamma, base) in zip(Gamma, self.r_symbols)]))
            de.append(de_row)
        if self.debug:
            printer.oprint('D_{i}e^{j}', de)
        self.de = de
        return
Exemplo n.º 5
0
def main():
    enhance_print()

    coords = symbols('x y z')
    (ex,ey,ez,grad) = MV.setup('ex ey ez',metric='[1,1,1]',coords=coords)

    mfvar = (u,v) = symbols('u v')

    eu = ex+ey
    ev = ex-ey

    (eu_r,ev_r) = ReciprocalFrame([eu,ev])

    oprint('Frame',(eu,ev),'Reciprocal Frame',(eu_r,ev_r))

    print 'eu.eu_r =',eu|eu_r
    print 'eu.ev_r =',eu|ev_r
    print 'ev.eu_r =',ev|eu_r
    print 'ev.ev_r =',ev|ev_r

    eu = ex+ey+ez
    ev = ex-ey

    (eu_r,ev_r) = ReciprocalFrame([eu,ev])

    oprint('Frame',(eu,ev),'Reciprocal Frame',(eu_r,ev_r))

    print 'eu.eu_r =',eu|eu_r
    print 'eu.ev_r =',eu|ev_r
    print 'ev.eu_r =',ev|eu_r
    print 'ev.ev_r =',ev|ev_r

    print 'eu =',eu
    print 'ev =',ev

    def_prec(locals())

    print GAeval('eu^ev|ex',True)
    print GAeval('eu^ev|ex*eu',True)
    return
Exemplo n.º 6
0
def main():
    enhance_print()

    coords = symbols('x y z')
    (ex, ey, ez, grad) = MV.setup('ex ey ez', metric='[1,1,1]', coords=coords)

    mfvar = (u, v) = symbols('u v')

    eu = ex + ey
    ev = ex - ey

    (eu_r, ev_r) = ReciprocalFrame([eu, ev])

    oprint('Frame', (eu, ev), 'Reciprocal Frame', (eu_r, ev_r))

    print('eu.eu_r =', eu | eu_r)
    print('eu.ev_r =', eu | ev_r)
    print('ev.eu_r =', ev | eu_r)
    print('ev.ev_r =', ev | ev_r)

    eu = ex + ey + ez
    ev = ex - ey

    (eu_r, ev_r) = ReciprocalFrame([eu, ev])

    oprint('Frame', (eu, ev), 'Reciprocal Frame', (eu_r, ev_r))

    print('eu.eu_r =', eu | eu_r)
    print('eu.ev_r =', eu | ev_r)
    print('ev.eu_r =', ev | eu_r)
    print('ev.ev_r =', ev | ev_r)

    print('eu =', eu)
    print('ev =', ev)

    def_prec(locals())

    print(GAeval('eu^ev|ex', True))
    print(GAeval('eu^ev|ex*eu', True))
    return
Exemplo n.º 7
0
def main():
    Eprint()

    coords = symbols('x y z')
    (o3d,ex,ey,ez) = Ga.build('ex ey ez',g=[1,1,1],coords=coords)

    mfvar = (u,v) = symbols('u v')

    eu = ex+ey
    ev = ex-ey

    (eu_r,ev_r) = o3d.ReciprocalFrame([eu,ev])

    oprint('Frame',(eu,ev),'Reciprocal Frame',(eu_r,ev_r))

    print 'eu.eu_r =',eu|eu_r
    print 'eu.ev_r =',eu|ev_r
    print 'ev.eu_r =',ev|eu_r
    print 'ev.ev_r =',ev|ev_r

    eu = ex+ey+ez
    ev = ex-ey

    (eu_r,ev_r) = o3d.ReciprocalFrame([eu,ev])

    oprint('Frame',(eu,ev),'Reciprocal Frame',(eu_r,ev_r))

    print 'eu.eu_r =',eu|eu_r
    print 'eu.ev_r =',eu|ev_r
    print 'ev.eu_r =',ev|eu_r
    print 'ev.ev_r =',ev|ev_r

    print 'eu =',eu
    print 'ev =',ev

    def_prec(locals())

    print GAeval('eu^ev|ex',True)
    print GAeval('eu^ev|ex*eu',True)
    return
Exemplo n.º 8
0
    def __init__(self, basis, **kwargs):

        kwargs = test_init_slots(Metric.init_slots, **kwargs)

        self.name = 'GA' + str(Metric.count)
        Metric.count += 1

        if not isinstance(basis, basestring):
            raise TypeError('"' + str(basis) + '" must be string')

        X = kwargs['X']  # Vector manifold
        g = kwargs['g']  # Explicit metric or base metric for vector manifold
        debug = kwargs['debug']
        coords = kwargs['coords']  # Manifold coordinates (sympy symbols)
        norm = kwargs['norm']  # Normalize basis vectors
        self.sig = kwargs['sig']  # Hint for metric signature
        """
        String for symbolic metric determinant.  If self.gsym = 'g'
        then det(g) is sympy scalar function of coordinates with
        name 'det(g)'.  Useful for complex non-orthogonal coordinate
        systems or for calculations with general metric.
        """
        self.gsym = kwargs['gsym']

        self.debug = debug
        self.is_ortho = False  # Is basis othogonal
        self.coords = coords  # Manifold coordinates
        if self.coords is None:
            self.connect_flg = False
        else:
            self.connect_flg = True  # Connection needed for postion dependent metric
        self.norm = norm  # True to normalize basis vectors
        self.detg = None  # Determinant of g
        self.g_adj = None  # Adjugate of g
        self.g_inv = None  # Inverse of g
        # Generate list of basis vectors and reciprocal basis vectors
        # as non-commutative symbols

        if ' ' in basis or ',' in basis or '*' in basis:  # bases defined by substrings separated by spaces or commas
            self.basis = symbols_list(basis)
            self.r_symbols = symbols_list(basis, sub=False)
        else:
            if coords is not None:  # basis defined by root string with symbol list as indices
                self.basis = symbols_list(basis, coords)
                self.r_symbols = symbols_list(basis, coords, sub=False)
                self.coords = coords
                if self.debug:
                    printer.oprint('x^{i}', self.coords)
            else:
                raise ValueError('for basis "' + basis + '" coords must be entered')

        if self.debug:
            printer.oprint('e_{i}', self.basis, 'e^{i}', self.r_symbols)
        self.n = len(self.basis)
        self.n_range = range(self.n)

        # Generate metric as list of lists of symbols, rationals, or functions of coordinates

        if g is None:
            if X is None:  # default metric from dot product of basis as symbols
                self.g = self.metric_symbols_list()
            else:  # Vector manifold
                if coords is None:
                    raise ValueError('For metric derived from vector field ' +
                                     ' coordinates must be defined.')
                else:  # Vector manifold defined by vector field
                    dX = []
                    for coord in coords:  # Get basis vectors by differentiating vector field
                        dX.append([diff(x, coord) for x in X])
                    g_tmp = []
                    for dx1 in dX:
                        g_row = []
                        for dx2 in dX:
                            dx1_dot_dx2 = trigsimp(Metric.dot_orthogonal(dx1, dx2, g))
                            g_row.append(dx1_dot_dx2)
                        g_tmp.append(g_row)
                    self.g = Matrix(g_tmp)
                    if self.debug:
                        printer.oprint('X_{i}', X, 'D_{i}X_{j}', dX)

        else:  # metric is symbolic or list of lists of functions of coordinates
            if isinstance(g, basestring):  # metric elements are symbols or constants
                if g == 'g':  # general symbolic metric tensor (g_ij functions of position)
                    g_lst = []
                    g_inv_lst = []
                    for coord1 in self.coords:
                        i1 = str(coord2)
                        tmp = []
                        tmp_inv = []
                        for coord2 in self.coords:
                            i2 = str(coord2)
                            tmp.append(Function('g_'+i1+'_'+i2)(*self.coords))
                            tmp_inv.append(Function('g__'+i1+'__'+i2)(*self.coords))
                        g_lst.append(tmp)
                        g_inv_lst.append(tmp_inv)
                    self.g = Matrix(g_lst)
                    self.g_inv = Matrix(g_inv_lst)
                else:  # specific symbolic metric tensor (g_ij are symbolic or numerical constants)
                    self.g = self.metric_symbols_list(g)  # construct symbolic metric from string and basis
            else:  # metric is given as list of function or list of lists of function or matrix of functions
                if isinstance(g, Matrix):
                    self.g = g
                else:
                    if isinstance(g[0], list):
                        self.g = Matrix(g)
                    else:
                        m = eye(len(g))
                        for i in range(len(g)):
                            m[i, i] = g[i]
                        self.g = m

        self.g_raw = copy.deepcopy(self.g)  # save original metric tensor for use with submanifolds

        if self.debug:
            printer.oprint('g', self.g)

        # Determine if metric is orthogonal

        self.is_ortho = True

        for i in self.n_range:
            for j in self.n_range:
                if i < j:
                    if self.g[i, j] != 0:
                        self.is_ortho = False
                        break

        self.g_is_numeric = True

        for i in self.n_range:
            for j in self.n_range:
                if i < j:
                    if not self.g[i, j].is_number:
                        self.g_is_numeric = False
                        break

        if self.coords is not None:
            self.derivatives_of_basis()  # calculate derivatives of basis
            if self.norm:  # normalize basis, metric, and derivatives of normalized basis
                self.e_norm = []
                for i in self.n_range:
                    self.e_norm.append(square_root_of_expr(self.g[i, i]))
                if debug:
                    printer.oprint('|e_{i}|', self.e_norm)
            else:
                self.e_norm = None

        if self.norm:
            if self.is_ortho:
                self.normalize_metric()
            else:
                raise ValueError('!!!!Basis normalization only implemented for orthogonal basis!!!!')

        if not self.g_is_numeric:
            self.signature()
            # Sign of square of pseudo scalar
            self.e_sq_sgn = '+'
            if ((self.n*(self.n-1))/2+self.sig[1])%2 == 1:
                self.e_sq_sgn = '-'

        if self.debug:
            print 'signature =', self.sig
Exemplo n.º 9
0
    def Christoffel_symbols(self,mode=1):
        """
        mode = 1  Christoffel symbols of the first kind
        mode = 2  Christoffel symbols of the second kind
        """

        if mode == 1:
            dg = []  # dg[i][j][k] = \partial_{x_{k}}g_{ij}

            for i in self.n_range:
                dg_row = []
                for j in self.n_range:
                    dg_row.append([diff(self.g[i, j], coord) for coord in self.coords])
                dg.append(dg_row)

            # See if connection is zero

            self.connect_flg = False

            for i in self.n_range:
                for j in self.n_range:
                    for k in self.n_range:
                        if dg[i][j][k] != 0:
                            self.connect_flg = True
                            break

            if not self.connect_flg:
                self.de = None
                return

            n_range = range(len(self.basis))

            dG = []  # dG[i][j][k] = half * (dg[j][k][i] + dg[i][k][j] - dg[i][j][k])

            # Christoffel symbols of the first kind, \Gamma_{ijk}
            # \partial_{x^{i}}e_{j} = \Gamma_{ijk}e^{k}

            for i in n_range:
                dG_j = []
                for j in n_range:
                    dG_k = []
                    for k in n_range:
                        gamma = half * (dg[j][k][i] + dg[i][k][j] - dg[i][j][k])
                        dG_k.append(Simp.apply(gamma))
                    dG_j.append(dG_k)
                dG.append(dG_j)
            if self.debug:
                printer.oprint('Gamma_{ijk}', dG)
            return dG

        elif mode == 2:
            Gamma1 = self.Christoffel_symbols(mode=1)
            if self.connect_flg:  # Connection is not zero
                self.inverse_metric()

                # Christoffel symbols of the second kind, \Gamma_{ij}^{k} = \Gamma_{ijl}g^{lk}
                # \partial_{x^{i}}e_{j} = \Gamma_{ij}^{k}e_{k}

                Gamma = []
                for Gi in Gamma1:
                    Gamma_i = []
                    for Gij in Gi:
                        Gamma_ij = []
                        Gamma_ijk = S(0)
                        l = 0
                        for Gijl in Gij:
                            Gamma_ijk += Gijl * g(l,)

            else:
                return

        else:
            raise ValueError('In Christoffle_symobols mode = ' +str(mode) +' is not allowed\n')
Exemplo n.º 10
0
    def __init__(self, basis, **kwargs):

        kwargs = test_init_slots(Metric.init_slots, **kwargs)

        self.name = 'GA' + str(Metric.count)
        Metric.count += 1

        if not isinstance(basis, basestring):
            raise TypeError('"' + str(basis) + '" must be string')

        X = kwargs['X']  # Vector manifold
        g = kwargs['g']  # Explicit metric or base metric for vector manifold
        debug = kwargs['debug']
        coords = kwargs['coords']  # Manifold coordinates (sympy symbols)
        norm = kwargs['norm']  # Normalize basis vectors
        self.sig = kwargs['sig']  # Hint for metric signature
        """
        String for symbolic metric determinant.  If self.gsym = 'g'
        then det(g) is sympy scalar function of coordinates with
        name 'det(g)'.  Useful for complex non-orthogonal coordinate
        systems or for calculations with general metric.
        """
        self.gsym = kwargs['gsym']

        self.debug = debug
        self.is_ortho = False  # Is basis othogonal
        self.coords = coords  # Manifold coordinates
        if self.coords is None:
            self.connect_flg = False
        else:
            self.connect_flg = True  # Connection needed for postion dependent metric
        self.norm = norm  # True to normalize basis vectors
        self.detg = None  # Determinant of g
        self.g_adj = None  # Adjugate of g
        self.g_inv = None  # Inverse of g
        # Generate list of basis vectors and reciprocal basis vectors
        # as non-commutative symbols

        if ' ' in basis or ',' in basis or '*' in basis:  # bases defined by substrings separated by spaces or commas
            self.basis = symbols_list(basis)
            self.r_symbols = symbols_list(basis, sub=False)
        else:
            if coords is not None:  # basis defined by root string with symbol list as indices
                self.basis = symbols_list(basis, coords)
                self.r_symbols = symbols_list(basis, coords, sub=False)
                self.coords = coords
                if self.debug:
                    printer.oprint('x^{i}', self.coords)
            else:
                raise ValueError('for basis "' + basis + '" coords must be entered')

        if self.debug:
            printer.oprint('e_{i}', self.basis, 'e^{i}', self.r_symbols)
        self.n = len(self.basis)
        self.n_range = range(self.n)

        # Generate metric as list of lists of symbols, rationals, or functions of coordinates

        if g is None:
            if X is None:  # default metric from dot product of basis as symbols
                self.g = self.metric_symbols_list()
            else:  # Vector manifold
                if coords is None:
                    raise ValueError('For metric derived from vector field ' +
                                     ' coordinates must be defined.')
                else:  # Vector manifold defined by vector field
                    dX = []
                    for coord in coords:  # Get basis vectors by differentiating vector field
                        dX.append([diff(x, coord) for x in X])
                    g_tmp = []
                    for dx1 in dX:
                        g_row = []
                        for dx2 in dX:
                            dx1_dot_dx2 = trigsimp(Metric.dot_orthogonal(dx1, dx2, g))
                            g_row.append(dx1_dot_dx2)
                        g_tmp.append(g_row)
                    self.g = Matrix(g_tmp)
                    if self.debug:
                        printer.oprint('X_{i}', X, 'D_{i}X_{j}', dX)

        else:  # metric is symbolic or list of lists of functions of coordinates
            if isinstance(g, basestring):  # metric elements are symbols or constants
                if g == 'g':  # general symbolic metric tensor (g_ij functions of position)
                    g_lst = []
                    g_inv_lst = []
                    for coord1 in self.coords:
                        i1 = str(coord2)
                        tmp = []
                        tmp_inv = []
                        for coord2 in self.coords:
                            i2 = str(coord2)
                            tmp.append(Function('g_'+i1+'_'+i2)(*self.coords))
                            tmp_inv.append(Function('g__'+i1+'__'+i2)(*self.coords))
                        g_lst.append(tmp)
                        g_inv_lst.append(tmp_inv)
                    self.g = Matrix(g_lst)
                    self.g_inv = Matrix(g_inv_lst)
                else:  # specific symbolic metric tensor (g_ij are symbolic or numerical constants)
                    self.g = self.metric_symbols_list(g)  # construct symbolic metric from string and basis
            else:  # metric is given as list of function or list of lists of function or matrix of functions
                if isinstance(g, Matrix):
                    self.g = g
                else:
                    if isinstance(g[0], list):
                        self.g = Matrix(g)
                    else:
                        m = eye(len(g))
                        for i in range(len(g)):
                            m[i, i] = g[i]
                        self.g = m

        self.g_raw = copy.deepcopy(self.g)  # save original metric tensor for use with submanifolds

        if self.debug:
            printer.oprint('g', self.g)

        # Determine if metric is orthogonal

        self.is_ortho = True

        for i in self.n_range:
            for j in self.n_range:
                if i < j:
                    if self.g[i, j] != 0:
                        self.is_ortho = False
                        break

        if self.coords is not None:
            self.derivatives_of_basis()  # calculate derivatives of basis
            if self.norm:  # normalize basis, metric, and derivatives of normalized basis
                self.e_norm = []
                for i in self.n_range:
                    self.e_norm.append(square_root_of_expr(self.g[i, i]))
                if debug:
                    printer.oprint('|e_{i}|', self.e_norm)
            else:
                self.e_norm = None

        if self.norm:
            if self.is_ortho:
                self.normalize_metric()
            else:
                raise ValueError('!!!!Basis normalization only implemented for orthogonal basis!!!!')

        self.signature()
        # Sign of square of pseudo scalar
        self.e_sq_sgn = '+'
        if ((self.n*(self.n-1))/2+self.sig[1])%2 == 1:
            self.e_sq_sgn = '-'

        if self.debug:
            print 'signature =', self.sig
Exemplo n.º 11
0
    def Christoffel_symbols(self,mode=1):
        """
        mode = 1  Christoffel symbols of the first kind
        mode = 2  Christoffel symbols of the second kind
        """

        if mode == 1:
            dg = []  # dg[i][j][k] = \partial_{x_{k}}g_{ij}

            for i in self.n_range:
                dg_row = []
                for j in self.n_range:
                    dg_row.append([diff(self.g[i, j], coord) for coord in self.coords])
                dg.append(dg_row)

            # See if connection is zero

            self.connect_flg = False

            for i in self.n_range:
                for j in self.n_range:
                    for k in self.n_range:
                        if dg[i][j][k] != 0:
                            self.connect_flg = True
                            break

            if not self.connect_flg:
                self.de = None
                return

            n_range = range(len(self.basis))

            dG = []  # dG[i][j][k] = half * (dg[j][k][i] + dg[i][k][j] - dg[i][j][k])

            # Christoffel symbols of the first kind, \Gamma_{ijk}
            # \partial_{x^{i}}e_{j} = \Gamma_{ijk}e^{k}

            for i in n_range:
                dG_j = []
                for j in n_range:
                    dG_k = []
                    for k in n_range:
                        gamma = half * (dg[j][k][i] + dg[i][k][j] - dg[i][j][k])
                        dG_k.append(Simp.apply(gamma))
                    dG_j.append(dG_k)
                dG.append(dG_j)
            if self.debug:
                printer.oprint('Gamma_{ijk}', dG)
            return dG

        elif mode == 2:
            Gamma1 = self.Christoffel_symbols(mode=1)
            if self.connect_flg:  # Connection is not zero
                self.inverse_metric()

                # Christoffel symbols of the second kind, \Gamma_{ij}^{k} = \Gamma_{ijl}g^{lk}
                # \partial_{x^{i}}e_{j} = \Gamma_{ij}^{k}e_{k}

                Gamma = []
                for Gi in Gamma1:
                    Gamma_i = []
                    for Gij in Gi:
                        Gamma_ij = []
                        Gamma_ijk = S(0)
                        l = 0
                        for Gijl in Gij:
                            Gamma_ijk += Gijl * g(l,)

            else:
                return

        else:
            raise ValueError('In Christoffle_symobols mode = ' +str(mode) +' is not allowed\n')