def test_getWithContraction(self): n = 3 m = Manifold('M', n) patch = PatchWithMetric('P', m) cart = CoordSystem('cart', patch) bc = VectorFieldBase("bc", cart) br = OneFormFieldBase(bc) #full trace x = TensorIndexSet("x", [bc, br]) x[0, 0] = 3 x[1, 1] = 4 i = Idx('i') self.assertEqual(x[i, i], 7) # partial trace x = TensorIndexSet("x", [bc, br, bc, br]) y = TensorIndexSet("y") x[0, 0, 0, 0] = 3 x[1, 1, 0, 0] = 4 i, j, k = map(Idx, ['i', 'j', 'k']) print("before test") y[j, k] = x[i, i, j, k] self.assertEqual(y.bases, [bc, br]) self.assertEqual(y[0, 0], 7) self.assertEqual(x[i, i, j, j], 7) x = TensorIndexSet("x", [bc, br, bc, br, bc]) y = TensorIndexSet("y") x[0, 0, 0, 0, 0] = 3 x[1, 1, 0, 0, 0] = 4 i, j, k, l = map(Idx, ['i', 'j', 'k', 'l']) z = x[i, i, j, j, 0] self.assertEqual(z, 7)
def test_curvature(): #For testing curvature conventions M = Manifold('Reisner-Nordstrom', 4) p = Patch('origin', M) cs = CoordSystem('spherical', p, ['t', 'r', 'theta', 'phi']) t, r, theta, phi = cs.coord_functions() dt, dr, dtheta, dphi = cs.base_oneforms() f = Function('f') metric = f(r)**2 * TP(dt, dt) - f(r)**(-2) * TP(dr, dr) - r**2 * TP( dtheta, dtheta) - r**2 * sin(theta)**2 * TP(dphi, dphi) ch_2nd = metric_to_Christoffel_2nd(metric) G = ToArray(metric) rm = TensorArray(components=metric_to_Riemann_components(metric), variance=[-1, 1, 1, 1], coordinate_system=cs) v = [Function(f) for f in ['v0', 'v1', 'v2', 'v3']] V = TensorArray(components=[f(t, r, theta, phi) for f in v], variance=[-1], coordinate_system=cs) dV = V.covD(ch_2nd) ddV = dV.covD(ch_2nd) #Commuted covariant derivative: D2V = ddV - ddV.braid(0, 1) rm = TensorArray(components=metric_to_Riemann_components(metric), variance=[-1, 1, 1, 1], coordinate_system=cs) rmv = rm.TensorProduct(V).contract(1, 4).braid(0, 1).braid(1, 2) rmvtensor = [(I, simplify(rmv.tensor[I])) for I in rmv.indices] rmvtensor = [(I, coeff) for (I, coeff) in rmvtensor if coeff != 0] rmvtensor.sort() D2Vtensor = [(I, simplify(D2V.tensor[I])) for I in D2V.indices] D2Vtensor = [(I, v) for (I, v) in D2Vtensor if v != 0] D2Vtensor.sort() for (a, b) in zip(rmvtensor, D2Vtensor): assert (a == b)
def _set_user_coordinates(self, sys_title, user_coord): from sympy.diffgeom import CoordSystem, Manifold, Patch manifold = Manifold("M", self.dim) patch = Patch("P", manifold) if self.dim == 4: system = CoordSystem(sys_title, patch, [str(user_coord[0]),str(user_coord[1]),\ str(user_coord[2]),str(user_coord[3])]) u, v, w, t = system.coord_functions() self.w = w self.t = t if self.dim == 3: system = CoordSystem( sys_title, patch, [str(user_coord[0]), str(user_coord[1]), str(user_coord[2])]) u, v, w = system.coord_functions() self.w = w if self.dim == 2: system = CoordSystem( sys_title, patch, [str(user_coord[0]), str(user_coord[1])]) u, v = system.coord_functions() self.u, self.v = u, v self.system = system
def test_from_sympy_coordsystem(self): """Test creating from sympy coord system""" manifold = Manifold('M', 4) origin_patch = Patch('o', manifold) sym_cs = _CoordSystem('cartesian', origin_patch, ['x', 'y', 'z']) cs = coords.CoordSystem.from_sympy_coordsystem(sym_cs) assert isinstance(cs, coords.CoordSystem)
def _set_flat_coordinates(self, sys_title, flat_diff): from sympy.diffgeom import CoordSystem, Manifold, Patch manifold = Manifold("M", self.dim) patch = Patch("P", manifold) flat_diff = sympy.Matrix(flat_diff) N = flat_diff.shape[0] coords = [] for i in range(0, N): n = str(flat_diff[i, i]).find('*') coord_i = str(flat_diff[i, i])[1:n] coords.append(coord_i) if self.dim == 4: system = CoordSystem(sys_title, patch, [str(coords[0]),str(coords[1]),\ str(coords[2]),str(coords[3])]) u, v, w, t = system.coord_functions() self.w = w self.t = t if self.dim == 3: system = CoordSystem(sys_title, patch, [str(coords[0]),str(coords[1]),\ str(coords[2])]) u, v, w = system.coord_functions() self.w = w if self.dim == 2: system = CoordSystem( sys_title, patch, [str(coords[0]), str(coords[1])]) u, v = system.coord_functions() self.u, self.v = u, v self.system = system
def test_free_symbols(self): n = 3 m = Manifold('M', n) patch = PatchWithMetric('P', m) cart = CoordSystem('cart', patch) # cellar base bc = VectorFieldBase("bc", cart) # roof base br = OneFormFieldBase(bc) g = TensorIndexSet("g", [bc, bc]) for i in range(n): g[i, i] = 1 patch.setMetric("cart", g) x = TensorIndexSet("x", [bc]) r, phi = symbols("r,phi") x[0] = r**2 x[1] = phi**2 i = Idx("i") res = x[i].free_symbols self.assertEqual(res, set({phi, r})) x = TensorIndexSet("x", [br]) r, phi = symbols("r,phi") x[0] = r**2 i = Idx("i") res = x[i].free_symbols self.assertEqual(res, set({r}))
def test_scalar(): M = Manifold('Reisner-Nordstrom', 4) p = Patch('origin', M) cs = CoordSystem('spherical', p, ['t', 'r', 'theta', 'phi']) t, r, theta, phi = cs.coord_functions() f = Function('f') assert (ToArray(1, coordinate_system=cs).to_tensor() == 1) assert (ToArray(f(r)).to_tensor() == f(r))
def test__coord_system_symbols(self): """Test coord symbol extraction""" manifold = Manifold('M', 4) origin_patch = Patch('o', manifold) x, y, z = symbols('x y z') sym_cs = _CoordSystem('cartesian', origin_patch, [x, y, z]) sym_cs_symbols = coords._coord_system_symbols(sym_cs) assert sym_cs_symbols == symbols('x y z')
def test_expand_tensor(): M = Manifold('Reisner-Nordstrom', 4) p = Patch('origin', M) cs = CoordSystem('spherical', p, ['t', 'r', 'theta', 'phi']) t, r, theta, phi = cs.coord_functions() dt, dr, dtheta, dphi = cs.base_oneforms() f = Function('f') metric = f(r)**2 * TP(dt, dt) - f(r)**(-2) * TP(dr, dr) - r**2 * TP( dtheta, dtheta) - r**2 * sin(theta)**2 * TP(dphi, dphi) assert (expand_tensor(metric) == metric)
def test_diffgeom(): from sympy.diffgeom import Manifold, Patch, CoordSystem, BaseScalarField m = Manifold('M', 2) assert str(m) == "M" p = Patch('P', m) assert str(p) == "P" rect = CoordSystem('rect', p) assert str(rect) == "rect" b = BaseScalarField(rect, 0) assert str(b) == "rect_0"
def test_diffgeom(): from sympy.diffgeom import Manifold, Patch, CoordSystem, BaseScalarField x,y = symbols('x y', real=True) m = Manifold('M', 2) assert str(m) == "M" p = Patch('P', m) assert str(p) == "P" rect = CoordSystem('rect', p, [x, y]) assert str(rect) == "rect" b = BaseScalarField(rect, 0) assert str(b) == "x"
def test_diffgeom(): from sympy.diffgeom import Manifold, Patch, CoordSystem, BaseScalarField m = Manifold('M', 2) p = Patch('P', m) rect = CoordSystem('rect', p) assert srepr( rect ) == "CoordSystem(Str('rect'), Patch(Str('P'), Manifold(Str('M'), Integer(2))), ('rect_0', 'rect_1'))" b = BaseScalarField(rect, 0) assert srepr( b ) == "BaseScalarField(CoordSystem(Str('rect'), Patch(Str('P'), Manifold(Str('M'), Integer(2))), ('rect_0', 'rect_1')), Integer(0))"
def test_getSetItems(self): n = 2 m = Manifold('M', n) patch = PatchWithMetric('P', m) cart = CoordSystem('cart', patch) bc = VectorFieldBase("cart_st", cart) br = OneFormFieldBase(bc) i, j, k, l = map(Idx, ['i', 'j', 'k', 'l']) x = TensorIndexSet("x", [br]) y = TensorIndexSet("y") x[0] = 10 x[1] = 20 y[i] = x[i] self.assertEqual(y[0], 10) self.assertEqual(y[1], 20) # actually the names of the free indices should not be important # as long as the indices have the same range y[j] = x[i] self.assertEqual(y[0], 10) self.assertEqual(y[1], 20) # two free indices on both sides x2 = TensorIndexSet("x2", [br, br]) y2 = TensorIndexSet("y2") x2[0, 0] = 10 x2[1, 1] = 20 y2[k, l] = x2[i, j] self.assertEqual(y2[0, 0], 10) self.assertEqual(y2[1, 1], 20) # now change the range of one index and get an Exception j = Idx("j", (0, 4)) with self.assertRaises(IndexRangeException): y[j] = x[i] # this should also happen when more than one Index is involved with self.assertRaises(IndexRangeException): y2[k, l] = x2[i, j] #1 common index the other one renamed j = Idx("j") x2[0, 0] = 0 x2[0, 1] = 1 x2[1, 0] = 10 x2[1, 1] = 11 y2[i, l] = x2[i, j] self.assertEqual(y2[0, 0], 0) self.assertEqual(y2[0, 1], 1) self.assertEqual(y2[1, 0], 10) self.assertEqual(y2[1, 1], 11) # with changed order y2[l, i] = x2[i, j] self.assertEqual(y2[0, 0], 0) self.assertEqual(y2[0, 1], 10) self.assertEqual(y2[1, 0], 1) self.assertEqual(y2[1, 1], 11)
def test_covD(): M = Manifold('Reisner-Nordstrom', 4) p = Patch('origin', M) cs = CoordSystem('spherical', p, ['t', 'r', 'theta', 'phi']) t, r, theta, phi = cs.coord_functions() dt, dr, dtheta, dphi = cs.base_oneforms() f = Function('f') metric = f(r)**2 * TP(dt, dt) - f(r)**(-2) * TP(dr, dr) - r**2 * TP( dtheta, dtheta) - r**2 * sin(theta)**2 * TP(dphi, dphi) ch_2nd = metric_to_Christoffel_2nd(metric) G = ToArray(metric) assert (G.covD(ch_2nd).to_tensor() == 0)
def test_mult(self): n = 2 m = Manifold('M', n) patch = PatchWithMetric('P', m) cart = CoordSystem('cart', patch) bc = VectorFieldBase("cart_st", cart) br = OneFormFieldBase(bc) ## cases with contraction res = TensorIndexSet("res") x = TensorIndexSet("x", [br]) A = TensorIndexSet("A", [bc, br]) i, j, k, l = map(Idx, ['i', 'j', 'k', 'l']) x[0] = 3 A[0, 0] = 2 print("befor mult") res[j] = A[i, j] * x[i] print("after mult") print("res.bases") print(res.bases) self.assertEqual(res[0], 6) self.assertEqual(res.bases, [br]) with self.assertRaises(ContractionIncompatibleBaseException): ## bases are not compatible res[j] = A[i, j] * x[j] x = TensorIndexSet("x", [br]) A = TensorIndexSet("A", [bc, br]) x[0] = 10 x[1] = 20 A[0, 0] = 1 A[1, 0] = 2 A[0, 1] = 3 A[1, 1] = 4 res[j] = A[i, j] * x[i] self.assertEqual(res[0], 50) self.assertEqual(res[1], 110) ## cases without contraction res = TensorIndexSet("res") res[i, j, k] = A[i, j] * x[k] self.assertEqual(res[0, 0, 0], 10) res = TensorIndexSet("res") with self.assertRaises(IncompatibleShapeException): res[j] = A[i, j] * x[k] res = TensorIndexSet("res") x = TensorIndexSet("x", [br]) A = TensorIndexSet("A", [bc, br, bc]) with self.assertRaises(IncompatibleShapeException): res[i, j, l] = A[i, j, k] * x[k]
def define_coord_sys(): global rect global polar """定义Manifold, Patch, CoordSystem""" r, theta = symbols('r, theta') x, y = symbols('x, y') m = Manifold('M', 2) # 定义一个patch patch = Patch('P', m) # 为这个patch建立坐标系,一个是笛卡尔,一个是极坐标 rect = CoordSystem('rect', patch) polar = CoordSystem('polar', patch) polar.connect_to(rect, [r, theta], [r * cos(theta), r * sin(theta)])
def test_partial_derivative_of_VI_wrt_a_coordinate(self): # note that we not only need the partial derivative of the components # but also the partial derivatives of the base vectors expressed as linear combinations # of those base vectors which are expressed by the cristoffel symbols which in turn can be computed from # known cristoffel symbols of a given coordinate system and the connection # between the coordinates # # A case of special interest is the cartesian coordinate system whose # coordinate functions are given as the partial derivatives of functions # on the manifold in the directions of the set of base vectors e_x,e_y,ez # We therefore start with the cartesian base or equivalently # with the cartesian coordinate system defined by this vectorfield #get the catesian cellar base vectors dim = 3 manyf = Manifold('M', dim) patch = PatchWithMetric('P', manyf) cart = CoordSystem('cart', patch) cc = VectorFieldBase("cc", cart) g = TensorIndexSet("g", [cc, cc]) for i in range(dim): g[i, i] = 1 i = Idx("i") j = Idx("j") patch.setMetric(cart, g) spherical = CoordSystem('spherical', patch) # now connect the two coordsystems by a transformation x, y, z = symbols("x,y,z") r = symbols("r", positive=True, real=True) phi, theta = symbols("phi,theta", real=True) spherical.connect_to(cart, [r, phi, theta], [ r * cos(phi) * sin(theta), r * sin(phi) * sin(theta), r * cos(theta) ], inverse=False) # cellar base bc = VectorFieldBase("bc", spherical) # roof base br = OneFormFieldBase(bc) x = TensorIndexSet("x", [bc]) r = Symbol("r") x[0] = r**2 i = Idx("i") print(type(x[i])) #res=Derivative(x[i],r,evaluate=True) raise (Exception( "The following line hangs we have to check the creation of the ingredients in new tests: metrics in the new coordinate system simple derivative without coord transformation" )) res = diff(x[i], r) print((res))
def test_deprecations(): m = Manifold('M', 2) p = Patch('P', m) with warns_deprecated_sympy(): CoordSystem('Car2d', p, names=['x', 'y']) with warns_deprecated_sympy(): c = CoordSystem('Car2d', p, ['x', 'y']) with warns_deprecated_sympy(): list(m.patches) with warns_deprecated_sympy(): list(c.transforms)
def test_derivedMetricInNewCoordSystem3d(self): # A metric is a property of a patch so # it is shared by all coordinate systems # on this patch # We define the typical euklidian metric # by the metric tensor w.r.t the cartesian # base vectors # system and then derive the form of # the metric tensors w.r.t to the new base #get the catesian cellar base vectors dim = 3 manyf = Manifold('M', dim) patch = PatchWithMetric('P', manyf) cart = CoordSystem('unitbase', patch) cc = VectorFieldBase("cc", cart) g = TensorIndexSet("g", [cc, cc]) for i in range(dim): g[i, i] = 1 i = Idx("i") j = Idx("j") patch.setMetric(cart, g) longVecs = CoordSystem('longCellarBaseVectors', patch) # now connect the two coordsystems by a transformation x, y, z = symbols("x,y,z") u, v, w = symbols("u v w", real=True) lu, lv, lw = symbols("lu lv lw", real=True) longVecs.connect_to(cart, [u, v, w], [lu * u, lv * v, lw * w], inverse=False) #another coordsystem metric = patch.getMetricRepresentation('longCellarBaseVectors') print(metric.bases) #pprint(metric[0,0]) self.assertEqual(metric[0, 0], lu**(-2)) self.assertEqual(metric[1, 1], lv**(-2)) self.assertEqual(metric[2, 2], lw**(-2)) spherical = CoordSystem('spherical', patch) # now connect the two coordsystems by a transformation r = symbols("r", positive=True, real=True) phi, theta = symbols("phi,theta", real=True) spherical.connect_to(cart, [r, phi, theta], [ r * cos(phi) * sin(theta), r * sin(phi) * sin(theta), r * cos(theta) ], inverse=False) metric = patch.getMetricRepresentation('spherical') print(metric.bases) print(metric.data) raise (Exception("There must be a fixture for this"))
def test_setWithWrongShape(self): x = TensorIndexSet("x") x[1] = 1 with self.assertRaises(IncompatibleShapeException): x[1, 1] = 1 n = 3 m = Manifold('M', n) patch = PatchWithMetric('P', m) cart = CoordSystem('cart', patch) bc = VectorFieldBase("bc", cart) br = OneFormFieldBase(bc) x = TensorIndexSet("x", [bc, br, bc, br]) with self.assertRaises(IncompatibleShapeException): x[0, 0] = 3
def mobius_strip(): import find_metric as fm import tensor as t g, diff = fm.mobius_strip() R = t.Riemann(g, dim=2, sys_title='mobius_strip', flat_diff=diff) #metric=R.metric from sympy.diffgeom import TensorProduct, Manifold, Patch, CoordSystem manifold = Manifold("M", 2) patch = Patch("P", manifold) system = CoordSystem('mobius_strip', patch, ["u", "v"]) u, v = system.coord_functions() du, dv = system.base_oneforms() from sympy import cos metric = (cos(u / 2)**2 * v**2 / 4 + cos(u / 2) * v + v**2 / 16 + 1) * TensorProduct(du, du) + 0.25 * TensorProduct(dv, dv) C = Christoffel_2nd(metric=metric) return C
def toroidal_coords(manifold: Manifold = None, dim: int = 4): """Create a Toroidal Coordinate system (t ~ R and (x,y,z) ~ S^3) with maximal dimension 4 (can create subspaces too) Args: manifold: Manifold, default None. If specified use this Manifold to take a coordinate patch dim: int, the dimension of the resulting coordinate system. Must be less than or equal to 4, and must match the dimension of the given Manifold if specified. Returns: CoordSystem, the coordinate system """ if manifold is None: manifold = Manifold('M', dim) origin_patch = Patch('o', manifold) return CoordSystem('toroidal', origin_patch, SPHERICAL_SYMBOLS[:dim])
def flat_kerr(a=0, G=1, M=0.5): import find_metric as fm from sympy.diffgeom import CoordSystem, Manifold, Patch, TensorProduct manifold = Manifold("M", 3) patch = Patch("P", manifold) kerr = CoordSystem("kerr", patch, ["u", "v", "w"]) u, v, w = kerr.coord_functions() du, dv, dw = kerr.base_oneforms() g11 = (a**2 * sym.cos(v) + u**2) / (-2 * G * M * u + a**2 + u**2) g22 = a**2 * sym.cos(v) + u**2 g33 = -(1 - 2 * G * M * u / (u**2 + a**2 * sym.cos(v))) # time independent : unphysical ? #g33 = 2*G*M*a**2*sym.sin(v)**4*u/(a**2*sym.cos(v) + u**2)**2 + a**2*sym.sin(v)**2 + sym.sin(v)**2*u**2 metric = g11 * TensorProduct(du, du) + g22 * TensorProduct( dv, dv) + g33 * TensorProduct(dw, dw) C = Christoffel_2nd(metric=metric) return C
def setUp(s): # we assume that we know the matrix connecting # the new cellar base vectors to the old cellar base vectors n = 2 m = Manifold('M', n) P = PatchWithMetric('P', m) cart = CoordSystem('cart', P) # oldcellar base s.bc = VectorFieldBase("bc", cart) # old roof base s.br = OneFormFieldBase(s.bc) # new cellar base s.Bc = VectorFieldBase("Bc") # new roof base s.Br = OneFormFieldBase(s.Bc) a, b = symbols("a,b") s.symbols = [a, b] M = Matrix([[a, 0], [0, b]]) #columns contain representation of new # base vectors w.r.t. old s.Bc.connect(s.bc, M)
def _set_coordinates(self, sys_title): from sympy.diffgeom import CoordSystem, Manifold, Patch manifold = Manifold("M", self.dim) patch = Patch("P", manifold) if self.dim == 4: system = CoordSystem(sys_title, patch, ["u", "v", "w", "t"]) u, v, w, t = system.coord_functions() self.w = w self.t = t if self.dim == 3: system = CoordSystem(sys_title, patch, ["u", "v", "w"]) u, v, w = system.coord_functions() self.w = w if self.dim == 2: system = CoordSystem(sys_title, patch, ["u", "v"]) u, v = system.coord_functions() self.u, self.v = u, v self.system = system
import numpy as np import matplotlib.pyplot as plt # from IPython.display import display, Math # Basic imports and functions from sympy import latex, symbols, sin, cos, pi, simplify from scipy.integrate import solve_ivp from sympy.diffgeom import (Manifold, Patch, CoordSystem, metric_to_Christoffel_2nd, TensorProduct as TP) # def lprint(v): # display(Math(latex(v))) # Create a manifold. M = Manifold('M', 4) # Create a patch. patch = Patch('P', M) # Basic symbols c, r_s = symbols('c r_s') # Coordinate system schwarzchild_coord = CoordSystem('schwarzchild', patch, ['t', 'r', 'theta', 'phi']) # Get the coordinate functions t, r, theta, phi = schwarzchild_coord.coord_functions() # Get the base one forms.
from sympy.diffgeom import Manifold, Patch, CoordSystem, Point from sympy import symbols, Function m = Manifold('m', 2) p = Patch('p', m) cs = CoordSystem('cs', p, ['a', 'b']) cs_noname = CoordSystem('cs', p) x, y = symbols('x y') f = Function('f') s1, s2 = cs.coord_functions() v1, v2 = cs.base_vectors() f1, f2 = cs.base_oneforms() def test_point(): point = Point(cs, [x, y]) assert point == point.func(*point.args) assert point != Point(cs, [2, y]) #TODO assert point.subs(x, 2) == Point(cs, [2, y]) #TODO assert point.free_symbols == set([x, y]) def test_rebuild(): assert m == m.func(*m.args) assert p == p.func(*p.args) assert cs == cs.func(*cs.args) assert cs_noname == cs_noname.func(*cs_noname.args) assert s1 == s1.func(*s1.args) assert v1 == v1.func(*v1.args) assert f1 == f1.func(*f1.args)
# http://docs.sympy.org/latest/modules/diffgeom.html from sympy import symbols, sin, cos, pi from sympy.diffgeom import Manifold, Patch, CoordSystem from sympy.simplify import simplify r, theta = symbols('r, theta') m = Manifold('M', 2) patch = Patch('P', m) rect = CoordSystem('rect', patch) polar = CoordSystem('polar', patch) print(rect in patch.coord_systems) polar.connect_to(rect, [r, theta], [r*cos(theta), r*sin(theta)]) print(polar.coord_tuple_transform_to(rect, [0, 2])) print(polar.coord_tuple_transform_to(rect, [2, pi/2])) print(rect.coord_tuple_transform_to(polar, [1, 1]).applyfunc(simplify)) print(polar.jacobian(rect, [r, theta])) p = polar.point([1, 3*pi/4]) print(rect.point_to_coords(p)) print(rect.coord_function(0)(p)) print(rect.coord_function(1)(p)) v_x = rect.base_vector(0) x = rect.coord_function(0)
# http://docs.sympy.org/latest/modules/diffgeom.html from sympy import cos, pi, sin, symbols from sympy.diffgeom import CoordSystem, Manifold, Patch from sympy.simplify import simplify r, theta = symbols("r, theta") m = Manifold("M", 2) patch = Patch("P", m) rect = CoordSystem("rect", patch) polar = CoordSystem("polar", patch) print(rect in patch.coord_systems) polar.connect_to(rect, [r, theta], [r * cos(theta), r * sin(theta)]) print(polar.coord_tuple_transform_to(rect, [0, 2])) print(polar.coord_tuple_transform_to(rect, [2, pi / 2])) print(rect.coord_tuple_transform_to(polar, [1, 1]).applyfunc(simplify)) print(polar.jacobian(rect, [r, theta])) p = polar.point([1, 3 * pi / 4]) print(rect.point_to_coords(p)) print(rect.coord_function(0)(p)) print(rect.coord_function(1)(p)) v_x = rect.base_vector(0) x = rect.coord_function(0)
from sympy.diffgeom import Manifold, Patch m = Manifold('M', 3) p = Patch('P', m) p in m.patches