Exemple #1
0
def Test_Reciprocal_Frame():
    Print_Function()
    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)
    return
Exemple #2
0
def Test_Reciprocal_Frame():
    Print_Function()
    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)
    return
Exemple #3
0
    def setup(base, n=None, metric=None, coords=None, curv=(None, None), debug=False):
        """
        Generate basis of vector space as tuple of vectors and
        associated metric tensor as Matrix.  See str_array(base,n) for
        usage of base and n and str_array(metric) for usage of metric.

        To overide elements in the default metric use the character '#'
        in the metric string.  For example if one wishes the diagonal
        elements of the metric tensor to be zero enter metric = '0 #,# 0'.

        If the basis vectors are e1 and e2 then the default metric -

            Vector.metric = ((dot(e1,e1),dot(e1,e2)),dot(e2,e1),dot(e2,e2))

        becomes -

            Vector.metric = ((0,dot(e1,e2)),(dot(e2,e1),0)).

        The function dot returns a Symbol and is symmetric.

        The functions 'Bases' calculates the global quantities: -

            Vector.basis
                tuple of basis vectors
            Vector.base_to_index
                dictionary to convert base to base inded
            Vector.metric
                metric tensor represented as a matrix of symbols and numbers

        """
        Vector.is_orthogonal = False
        Vector.coords = coords
        Vector.subscripts = []
        base_name_lst = base.split(' ')

        # Define basis vectors

        if '*' in base:
            base_lst = base.split('*')
            base = base_lst[0]
            Vector.subscripts = base_lst[1].split('|')
            base_name_lst = []
            for subscript in Vector.subscripts:
                base_name_lst.append(base + '_' + subscript)
        else:
            if len(base_name_lst) > 1:
                Vector.subscripts = []
                for base_name in base_name_lst:
                    tmp = base_name.split('_')
                    Vector.subscripts.append(tmp[-1])
            elif len(base_name_lst) == 1 and Vector.coords is not None:
                base_name_lst = []
                for coord in Vector.coords:
                    Vector.subscripts.append(str(coord))
                    base_name_lst.append(base + '_' + str(coord))
            else:
                raise TypeError("'%s' does not define basis vectors" % base)

        basis = []
        base_to_index = {}
        index = 0
        for base_name in base_name_lst:
            basis_vec = Vector(base_name)
            basis.append(basis_vec)
            base_to_index[basis_vec.obj] = index
            index += 1

        Vector.base_to_index = base_to_index
        Vector.basis = tuple(basis)

        # define metric tensor

        default_metric = []
        for bv1 in Vector.basis:
            row = []
            for bv2 in Vector.basis:
                row.append(Vector.basic_dot(bv1, bv2))
            default_metric.append(row)
        Vector.metric = Matrix(default_metric)
        if metric is not None:
            if metric[0] == '[' and metric[-1] == ']':
                Vector.is_orthogonal = True
                metric_str_lst = metric[1:-1].split(',')
                Vector.metric = []
                for g_ii in metric_str_lst:
                    Vector.metric.append(S(g_ii))
                Vector.metric = Matrix(Vector.metric)
            else:
                metric_str_lst = flatten(str_array(metric))
                for index in range(len(metric_str_lst)):
                    if metric_str_lst[index] != '#':
                        Vector.metric[index] = S(metric_str_lst[index])

        Vector.metric_dict = {}  # Used to calculate dot product
        N = range(len(Vector.basis))
        if Vector.is_orthogonal:
            for ii in N:
                    Vector.metric_dict[Vector.basis[ii].obj] = Vector.metric[ii]
        else:
            for irow in N:
                for icol in N:
                    Vector.metric_dict[(Vector.basis[irow].obj, Vector.basis[icol].obj)] = Vector.metric[irow, icol]

        # calculate tangent vectors and metric for curvilinear basis

        if curv != (None, None):
            X = S.Zero
            for (coef, base) in zip(curv[0], Vector.basis):
                X += coef * base.obj
            Vector.tangents = []
            for (coord, norm) in zip(Vector.coords, curv[1]):
                tau = diff(X, coord)
                tau = trigsimp(tau)
                tau /= norm
                tau = expand(tau)
                Vtau = Vector()
                Vtau.obj = tau
                Vector.tangents.append(Vtau)
            metric = []
            for tv1 in Vector.tangents:
                row = []
                for tv2 in Vector.tangents:
                    row.append(tv1 * tv2)
                metric.append(row)
            metric = Matrix(metric)
            metric = metric.applyfunc(TrigSimp)
            Vector.metric_dict = {}
            if metric.is_diagonal:
                Vector.is_orthogonal = True
                tmp_metric = []
                for ii in N:
                    tmp_metric.append(metric[ii, ii])
                    Vector.metric_dict[Vector.basis[ii].obj] = metric[ii, ii]
                Vector.metric = Matrix(tmp_metric)
            else:
                Vector.is_orthogonal = False
                Vector.metric = metric
                for irow in N:
                    for icol in N:
                        Vector.metric_dict[(Vector.basis[irow].obj, Vector.basis[icol].obj)] = Vector.metric[irow, icol]
            Vector.norm = curv[1]

            if debug:
                oprint('Tangent Vectors', Vector.tangents,
                       'Metric', Vector.metric,
                       'Metric Dictionary', Vector.metric_dict,
                       'Normalization', Vector.norm, dict_mode=True)

            # calculate derivatives of tangent vectors

            Vector.dtau_dict = None
            dtau_dict = {}

            for x in Vector.coords:
                for (tau, base) in zip(Vector.tangents, Vector.basis):
                    dtau = tau.diff(x).applyfunc(TrigSimp)
                    result = S.Zero
                    for (t, b) in zip(Vector.tangents, Vector.basis):
                        t_dtau = TrigSimp(t * dtau)
                        result += t_dtau * b.obj
                    dtau_dict[(base.obj, x)] = result

            Vector.dtau_dict = dtau_dict

            if debug:
                oprint('Basis Derivatives', Vector.dtau_dict, dict_mode=True)

        return tuple(Vector.basis)
    def __init__(self, x, coords, debug=False, I=None):
        """
        coords: list of coordinate variables
        x: vector fuction of coordinate variables (parametric surface)
        """
        self.I = I
        self.x = x
        self.coords = coords

        self.basis = []
        self.basis_str = []
        self.embedded_basis = []
        for u in coords:
            tv = x.diff(u)
            self.basis.append(tv)
            (coefs, bases) = linear_expand(tv.obj)
            tc = {}
            for (coef, base) in zip(coefs, bases):
                str_base = str(base)
                tc[str_base] = coef
                if str_base not in self.embedded_basis:
                    self.embedded_basis.append(str_base)
            self.basis_str.append(tc)

        self.gij = []

        for base1 in self.basis:
            tmp = []
            for base2 in self.basis:
                tmp.append(simplify(trigsimp((base1 | base2).scalar())))
            self.gij.append(tmp)

        for tv in self.basis_str:
            for base in self.embedded_basis:
                if base not in tv:
                    tv[base] = 0

        self.dim = len(self.basis)

        indexes = tuple(range(self.dim))
        self.index = [()]
        for i in indexes:
            self.index.append(tuple(combinations(indexes, i + 1)))
        self.index = tuple(self.index)

        self.MFbasis = [[MV.ONE], self.basis]

        for igrade in self.index[2:]:
            grade = []
            for iblade in igrade:
                blade = MV(1, 'scalar')
                for ibasis in iblade:
                    blade ^= self.basis[ibasis]
                blade = blade.trigsimp(deep=True, recursive=True)
                grade.append(blade)
            self.MFbasis.append(grade)
        self.E = self.MFbasis[-1][0]
        self.E_sq = trigsimp((self.E * self.E).scalar(),
                             deep=True,
                             recursive=True)

        duals = copy.copy(self.MFbasis[-2])

        duals.reverse()
        sgn = 1
        self.rbasis = []
        for dual in duals:
            recpv = (sgn * dual * self.E).trigsimp(deep=True, recursive=True)
            self.rbasis.append(recpv)
            sgn = -sgn

        self.dbasis = []

        for base in self.basis:
            dbase = []
            for coord in self.coords:
                d = base.diff(coord).trigsimp(deep=True, recursive=True)
                dbase.append(d)
            self.dbasis.append(dbase)

        self.surface = {}
        (coefs, bases) = linear_expand(self.x.obj)

        for (coef, base) in zip(coefs, bases):
            self.surface[str(base)] = coef

        self.grad = MV()
        self.grad.is_grad = True
        self.grad.blade_rep = True
        self.grad.igrade = 1
        self.grad.rcpr_bases_MV = []
        for rbase in self.rbasis:
            self.grad.rcpr_bases_MV.append(rbase / self.E_sq)
        self.grad.rcpr_bases_MV = tuple(self.grad.rcpr_bases_MV)
        self.grad.coords = self.coords
        self.grad.norm = self.E_sq
        self.grad.connection = {}

        if debug:
            oprint('x', self.x, 'coords', self.coords, 'basis vectors',
                   self.basis, 'index', self.index, 'basis blades',
                   self.MFbasis, 'E', self.E, 'E**2', self.E_sq, '*basis',
                   duals, 'rbasis', self.rbasis, 'basis derivatives',
                   self.dbasis, 'surface', self.surface, 'basis strings',
                   self.basis_str, 'embedding basis', self.embedded_basis,
                   'metric tensor', self.gij)
Exemple #5
0
    def setup(base,
              n=None,
              metric=None,
              coords=None,
              curv=(None, None),
              debug=False):
        """
        Generate basis of vector space as tuple of vectors and
        associated metric tensor as Matrix.  See str_array(base,n) for
        usage of base and n and str_array(metric) for usage of metric.

        To overide elements in the default metric use the character '#'
        in the metric string.  For example if one wishes the diagonal
        elements of the metric tensor to be zero enter metric = '0 #,# 0'.

        If the basis vectors are e1 and e2 then the default metric -

            Vector.metric = ((dot(e1,e1),dot(e1,e2)),dot(e2,e1),dot(e2,e2))

        becomes -

            Vector.metric = ((0,dot(e1,e2)),(dot(e2,e1),0)).

        The function dot returns a Symbol and is symmetric.

        The functions 'Bases' calculates the global quantities: -

            Vector.basis
                tuple of basis vectors
            Vector.base_to_index
                dictionary to convert base to base inded
            Vector.metric
                metric tensor represented as a matrix of symbols and numbers

        """
        Vector.is_orthogonal = False
        Vector.coords = coords
        Vector.subscripts = []
        base_name_lst = base.split(' ')

        # Define basis vectors

        if '*' in base:
            base_lst = base.split('*')
            base = base_lst[0]
            Vector.subscripts = base_lst[1].split('|')
            base_name_lst = []
            for subscript in Vector.subscripts:
                base_name_lst.append(base + '_' + subscript)
        else:
            if len(base_name_lst) > 1:
                Vector.subscripts = []
                for base_name in base_name_lst:
                    tmp = base_name.split('_')
                    Vector.subscripts.append(tmp[-1])
            elif len(base_name_lst) == 1 and Vector.coords is not None:
                base_name_lst = []
                for coord in Vector.coords:
                    Vector.subscripts.append(str(coord))
                    base_name_lst.append(base + '_' + str(coord))
            else:
                raise TypeError("'%s' does not define basis vectors" % base)

        basis = []
        base_to_index = {}
        index = 0
        for base_name in base_name_lst:
            basis_vec = Vector(base_name)
            basis.append(basis_vec)
            base_to_index[basis_vec.obj] = index
            index += 1

        Vector.base_to_index = base_to_index
        Vector.basis = tuple(basis)

        # define metric tensor

        default_metric = []
        for bv1 in Vector.basis:
            row = []
            for bv2 in Vector.basis:
                row.append(Vector.basic_dot(bv1, bv2))
            default_metric.append(row)
        Vector.metric = Matrix(default_metric)
        if metric is not None:
            if metric[0] == '[' and metric[-1] == ']':
                Vector.is_orthogonal = True
                metric_str_lst = metric[1:-1].split(',')
                Vector.metric = []
                for g_ii in metric_str_lst:
                    Vector.metric.append(S(g_ii))
                Vector.metric = Matrix(Vector.metric)
            else:
                metric_str_lst = flatten(str_array(metric))
                for index in range(len(metric_str_lst)):
                    if metric_str_lst[index] != '#':
                        Vector.metric[index] = S(metric_str_lst[index])

        Vector.metric_dict = {}  # Used to calculate dot product
        N = range(len(Vector.basis))
        if Vector.is_orthogonal:
            for ii in N:
                Vector.metric_dict[Vector.basis[ii].obj] = Vector.metric[ii]
        else:
            for irow in N:
                for icol in N:
                    Vector.metric_dict[(
                        Vector.basis[irow].obj,
                        Vector.basis[icol].obj)] = Vector.metric[irow, icol]

        # calculate tangent vectors and metric for curvilinear basis

        if curv != (None, None):
            X = S.Zero
            for (coef, base) in zip(curv[0], Vector.basis):
                X += coef * base.obj
            Vector.tangents = []
            for (coord, norm) in zip(Vector.coords, curv[1]):
                tau = diff(X, coord)
                tau = trigsimp(tau)
                tau /= norm
                tau = expand(tau)
                Vtau = Vector()
                Vtau.obj = tau
                Vector.tangents.append(Vtau)
            metric = []
            for tv1 in Vector.tangents:
                row = []
                for tv2 in Vector.tangents:
                    row.append(tv1 * tv2)
                metric.append(row)
            metric = Matrix(metric)
            metric = metric.applyfunc(TrigSimp)
            Vector.metric_dict = {}
            if metric.is_diagonal:
                Vector.is_orthogonal = True
                tmp_metric = []
                for ii in N:
                    tmp_metric.append(metric[ii, ii])
                    Vector.metric_dict[Vector.basis[ii].obj] = metric[ii, ii]
                Vector.metric = Matrix(tmp_metric)
            else:
                Vector.is_orthogonal = False
                Vector.metric = metric
                for irow in N:
                    for icol in N:
                        Vector.metric_dict[(
                            Vector.basis[irow].obj,
                            Vector.basis[icol].obj)] = Vector.metric[irow,
                                                                     icol]
            Vector.norm = curv[1]

            if debug:
                oprint('Tangent Vectors',
                       Vector.tangents,
                       'Metric',
                       Vector.metric,
                       'Metric Dictionary',
                       Vector.metric_dict,
                       'Normalization',
                       Vector.norm,
                       dict_mode=True)

            # calculate derivatives of tangent vectors

            Vector.dtau_dict = None
            dtau_dict = {}

            for x in Vector.coords:
                for (tau, base) in zip(Vector.tangents, Vector.basis):
                    dtau = tau.diff(x).applyfunc(TrigSimp)
                    result = S.Zero
                    for (t, b) in zip(Vector.tangents, Vector.basis):
                        t_dtau = TrigSimp(t * dtau)
                        result += t_dtau * b.obj
                    dtau_dict[(base.obj, x)] = result

            Vector.dtau_dict = dtau_dict

            if debug:
                oprint('Basis Derivatives', Vector.dtau_dict, dict_mode=True)

        return tuple(Vector.basis)
Exemple #6
0
    def __init__(self, x, coords, debug=False, I=None):
        """
        coords: list of coordinate variables
        x: vector fuction of coordinate variables (parametric surface)
        """
        self.I = I
        self.x = x
        self.coords = coords

        self.basis = []
        self.basis_str = []
        self.embedded_basis = []
        for u in coords:
            tv = x.diff(u)
            self.basis.append(tv)
            (coefs, bases) = linear_expand(tv.obj)
            tc = {}
            for (coef, base) in zip(coefs, bases):
                str_base = str(base)
                tc[str_base] = coef
                if str_base not in self.embedded_basis:
                    self.embedded_basis.append(str_base)
            self.basis_str.append(tc)

        self.gij = []

        for base1 in self.basis:
            tmp = []
            for base2 in self.basis:
                tmp.append(simplify(trigsimp((base1 | base2).scalar())))
            self.gij.append(tmp)

        for tv in self.basis_str:
            for base in self.embedded_basis:
                if base not in tv:
                    tv[base] = 0

        self.dim = len(self.basis)

        indexes = tuple(range(self.dim))
        self.index = [()]
        for i in indexes:
            self.index.append(tuple(combinations(indexes, i + 1)))
        self.index = tuple(self.index)

        self.MFbasis = [[MV.ONE], self.basis]

        for igrade in self.index[2:]:
            grade = []
            for iblade in igrade:
                blade = MV(1, 'scalar')
                for ibasis in iblade:
                    blade ^= self.basis[ibasis]
                blade = blade.trigsimp(deep=True, recursive=True)
                grade.append(blade)
            self.MFbasis.append(grade)
        self.E = self.MFbasis[-1][0]
        self.E_sq = trigsimp((self.E * self.E).scalar(), deep=True, recursive=True)

        duals = copy.copy(self.MFbasis[-2])

        duals.reverse()
        sgn = 1
        self.rbasis = []
        for dual in duals:
            recpv = (sgn * dual * self.E).trigsimp(deep=True, recursive=True)
            self.rbasis.append(recpv)
            sgn = -sgn

        self.dbasis = []

        for base in self.basis:
            dbase = []
            for coord in self.coords:
                d = base.diff(coord).trigsimp(deep=True, recursive=True)
                dbase.append(d)
            self.dbasis.append(dbase)

        self.surface = {}
        (coefs, bases) = linear_expand(self.x.obj)

        for (coef, base) in zip(coefs, bases):
            self.surface[str(base)] = coef

        self.grad = MV()
        self.grad.is_grad = True
        self.grad.blade_rep = True
        self.grad.igrade = 1
        self.grad.rcpr_bases_MV = []
        for rbase in self.rbasis:
            self.grad.rcpr_bases_MV.append(rbase / self.E_sq)
        self.grad.rcpr_bases_MV = tuple(self.grad.rcpr_bases_MV)
        self.grad.coords = self.coords
        self.grad.norm = self.E_sq
        self.grad.connection = {}

        if debug:
            oprint('x', self.x,
                   'coords', self.coords,
                   'basis vectors', self.basis,
                   'index', self.index,
                   'basis blades', self.MFbasis,
                   'E', self.E,
                   'E**2', self.E_sq,
                   '*basis', duals,
                   'rbasis', self.rbasis,
                   'basis derivatives', self.dbasis,
                   'surface', self.surface,
                   'basis strings', self.basis_str,
                   'embedding basis', self.embedded_basis,
                   'metric tensor', self.gij)