Tartalomjegyzék

Script anal3_diffgeom_tenzor_spherical_1

Teljes Matlab script (és live script) kiegészítő függvényekkel.
Tekintsd meg LiveEditor nézetben is!

File: anal3_diffgeom_tenzor_spherical_1.m

Author: Peter Polcz ppolcz@gmail.com

Created on 2017.08.08. Tuesday, 14:34:51

Reviewed on 2017. November 08.

Index notation during the script

The name of a symbolic object $T^{i}_{j}$ is chosen to be Ti_j

Ti_j = sym('T%d_%d',[2 2])
Output:
Ti_j =
[ T1_1, T1_2]
[ T2_1, T2_2]

The name of a symbolic object $T^{ij}$ is chosen to be Tij

Tij = sym('T%d%d',[2 2])
Output:
Tij =
[ T11, T12]
[ T21, T22]

The name of a symbolic object $T^k_{ij}$ is chosen to be Tk_ij

Tk_ij = sym('T%d_%d%d',[2 2 2])
Output:
Tk_ij(:,:,1) =
[ T1_11, T1_21]
[ T2_11, T2_21]
Tk_ij(:,:,2) =
[ T1_12, T1_22]
[ T2_12, T2_22]

Variables of spherical coordinate system

Dimension of the vector space

n = 3;

Coordinates $Z^i$. During the script the name of variable representing coordinates $Z^i$ will be denoted by lower case letter 'z'. Coordinates: $Z^1 = r$, $Z^2 = 'theta$, $Z^3 = \phi$.

syms r theta phi real
t = theta;
p = phi;
zi = [ r ; t ; p ];
% zi = sym('z%d',[n 1])

Mapping from Cartesian coordinate system to spherical.

R = [
    r*cos(t)*sin(p)
    r*sin(t)*sin(p)
    r*cos(p)
    ]
Output:
R =
 r*cos(theta)*sin(phi)
 r*sin(phi)*sin(theta)
            r*cos(phi)

Covariant basis vectors $\vec Z_i$.

Zr = diff(R,r)
Zt = diff(R,t)
Zp = diff(R,p)
Output:
Zr =
 cos(theta)*sin(phi)
 sin(phi)*sin(theta)
            cos(phi)
Zt =
 -r*sin(phi)*sin(theta)
  r*cos(theta)*sin(phi)
                      0
Zp =
 r*cos(phi)*cos(theta)
 r*cos(phi)*sin(theta)
           -r*sin(phi)

Covariant basis vectors in a single operation.

Z_i = jacobian(R,zi)
Output:
Z_i =
[ cos(theta)*sin(phi), -r*sin(phi)*sin(theta), r*cos(phi)*cos(theta)]
[ sin(phi)*sin(theta),  r*cos(theta)*sin(phi), r*cos(phi)*sin(theta)]
[            cos(phi),                      0,           -r*sin(phi)]

Covariant metric tensor $Z_{ij}$.

Z_ij = simplify(Z_i'*Z_i)
Output:
Z_ij =
[ 1,              0,   0]
[ 0, r^2*sin(phi)^2,   0]
[ 0,              0, r^2]

Contravariant metric tensor $Z^{ij}$.

Zij = inv(Z_ij)
Output:
Zij =
[ 1,                  0,     0]
[ 0, 1/(r^2*sin(phi)^2),     0]
[ 0,                  0, 1/r^2]

Contravariant components $V^i$ of vector field $\vec V = V^i \vec Z_i$.

Vi = sym('V%d',[n 1])
syms V1(r,theta,phi) V2(r,theta,phi) V3(r,theta,phi)
fVi = [ V1 ; V2 ; V3 ];
fVi = fVi(r,t,p)
assume(in(fVi, 'real'))
Output:
Vi =
 V1
 V2
 V3
fVi =
 V1(r, theta, phi)
 V2(r, theta, phi)
 V3(r, theta, phi)

Convariant components $V_i$ of vector field $\vec V = V_i \vec {Z^i}$.

V_i = sym('V_%d',[n 1])
syms V_1(r,theta,phi) V_2(r,theta,phi) V_3(r,theta,phi)
fV_i = [ V_1 ; V_2 ; V_3 ];
fV_i = fV_i(r,t,p)
assume(in(fV_i, 'real') & in(fVi, 'real'))
Output:
V_i =
 V_1
 V_2
 V_3
fV_i =
 V_1(r, theta, phi)
 V_2(r, theta, phi)
 V_3(r, theta, phi)

Christoffel symbol $\Gamma_{ij}^k$

Denoted by 3-dimensional symbolic array Gamma(i,j,k).

Gamma = sym(zeros(n,n,n));
for i = 1:n
    for j = 1:n
        for k = 1:n
            for m = 1:n
                Gamma(i,j,k) = Gamma(i,j,k) + 0.5 * Zij(k,m) * ( ...
                    diff(Z_ij(m,i), zi(j)) + diff(Z_ij(m,j), zi(i)) - diff(Z_ij(i,j), zi(m)) ...
                    );
            end
        end
    end
end
Gamma
Output:
Gamma(:,:,1) =
[ 0,             0,  0]
[ 0, -r*sin(phi)^2,  0]
[ 0,             0, -r]
Gamma(:,:,2) =
[   0,               1/r,                 0]
[ 1/r,                 0, cos(phi)/sin(phi)]
[   0, cos(phi)/sin(phi),                 0]
Gamma(:,:,3) =
[   0,                  0, 1/r]
[   0, -cos(phi)*sin(phi),   0]
[ 1/r,                  0,   0]

Covariant derivative $\nabla_j V^i$

Using for loops

Covariant derivative of covariant tensor field $V_i$.

$$\nabla_j V_i = \frac{\partial V_i}{\partial Z^j} - \Gamma^k_{ij} V_k$$

Using for loops (more transparent, clear-cut)

D_jfV_i = sym(zeros(n,n));

tic
for i = 1:n
    for j = 1:n
        D_jfV_i(i,j) = diff(fV_i(i),zi(j));
        for k = 1:n
            D_jfV_i(i,j) = D_jfV_i(i,j) + Gamma(i,j,k) * fV_i(k);
        end
    end
end
toc
Output:
Elapsed time is 0.375051 seconds.

Using matrix operations

With matrix operations the code is less transparent, but 10x faster.

Christoffel symbol demo for reshape operations

comb = allcomb(1:n,1:n,1:n);
comb = comb(:,[3 2 1]);

T = reshape(cellfun(@(a) {sprintf('(%d,%d,%d)', a)}, num2cell(comb,2)),[n,n,n])
Output:
  3×3×3 cell array
T(:,:,1) = 
    {'(1,1,1)'}    {'(1,2,1)'}    {'(1,3,1)'}
    {'(2,1,1)'}    {'(2,2,1)'}    {'(2,3,1)'}
    {'(3,1,1)'}    {'(3,2,1)'}    {'(3,3,1)'}
T(:,:,2) = 
    {'(1,1,2)'}    {'(1,2,2)'}    {'(1,3,2)'}
    {'(2,1,2)'}    {'(2,2,2)'}    {'(2,3,2)'}
    {'(3,1,2)'}    {'(3,2,2)'}    {'(3,3,2)'}
T(:,:,3) = 
    {'(1,1,3)'}    {'(1,2,3)'}    {'(1,3,3)'}
    {'(2,1,3)'}    {'(2,2,3)'}    {'(2,3,3)'}
    {'(3,1,3)'}    {'(3,2,3)'}    {'(3,3,3)'}

Reshaped Christoffel symbol $\Gamma_{ij}^k$ for multiplication along index $k$.

  • First dimension: $(i,j)$
  • Second simension: $k$
T2D_ij_k = reshape(T,[n^2 n])
Output:
T2D_ij_k =
  9×3 cell array
    {'(1,1,1)'}    {'(1,1,2)'}    {'(1,1,3)'}
    {'(2,1,1)'}    {'(2,1,2)'}    {'(2,1,3)'}
    {'(3,1,1)'}    {'(3,1,2)'}    {'(3,1,3)'}
    {'(1,2,1)'}    {'(1,2,2)'}    {'(1,2,3)'}
    {'(2,2,1)'}    {'(2,2,2)'}    {'(2,2,3)'}
    {'(3,2,1)'}    {'(3,2,2)'}    {'(3,2,3)'}
    {'(1,3,1)'}    {'(1,3,2)'}    {'(1,3,3)'}
    {'(2,3,1)'}    {'(2,3,2)'}    {'(2,3,3)'}
    {'(3,3,1)'}    {'(3,3,2)'}    {'(3,3,3)'}

Restore after multiplication along index $k$.

Restored_2tenzor = reshape(T2D_ij_k(:,1),[n n])
Output:
Restored_2tenzor =
  3×3 cell array
    {'(1,1,1)'}    {'(1,2,1)'}    {'(1,3,1)'}
    {'(2,1,1)'}    {'(2,2,1)'}    {'(2,3,1)'}
    {'(3,1,1)'}    {'(3,2,1)'}    {'(3,3,1)'}
Gamma2D_ij_k = reshape(Gamma,[n^2 n])
Output:
Gamma2D_ij_k =
[             0,                 0,                  0]
[             0,               1/r,                  0]
[             0,                 0,                1/r]
[             0,               1/r,                  0]
[ -r*sin(phi)^2,                 0, -cos(phi)*sin(phi)]
[             0, cos(phi)/sin(phi),                  0]
[             0,                 0,                1/r]
[             0, cos(phi)/sin(phi),                  0]
[            -r,                 0,                  0]

Using reshape and matrix multiplication ()

tic
D_jfV_i_fast = reshape(Gamma2D_ij_k * fV_i, [n n]) + jacobian(fV_i,zi);
toc

pcz_info(pcz_symzero(D_jfV_i - D_jfV_i_fast), 'The two operations gave the same result')
Output:
Elapsed time is 0.008739 seconds.
│   [  OK  ] The two operations gave the same result

Permutation symbol

e_ijk = reshape(levicivita(comb,2), ones(1,n)*n)
Output:
e_ijk(:,:,1) =
     0     0     0
     0     0     1
     0    -1     0
e_ijk(:,:,2) =
     0     0    -1
     0     0     0
     1     0     0
e_ijk(:,:,3) =
     0     1     0
    -1     0     0
     0     0     0