<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 The basic imports and the variables we'll be using
Step1:  Examples and tests
Step2:  Sympy can be a little tricky because it caches things, which means that the first implementation of this code silently changed tensors in place, without meaning to.  Let's just check that our variables haven't changed
<ASSISTANT_TASK:>
Python Code:
from __future__ import division
import sympy
from sympy import *
from sympy import Rational as frac
import simpletensors
from simpletensors import Vector, TensorProduct, SymmetricTensorProduct, Tensor
init_printing()
var('vartheta, varphi')
var('nu, m, delta, c, t')
# These are related scalar functions of time
var('r, v, Omega', cls=Function)
r = r(t)
v = v(t)
Omega = Omega(t)
# These get redefined momentarily, but have to exist first
var('nHat, lambdaHat, ellHat', cls=Function)
# And now we define them as vector functions of time
nHat = Vector('nHat', r'\hat{n}', [cos(Omega*t),sin(Omega*t),0,])(t)
lambdaHat = Vector('lambdaHat', r'\hat{\lambda}', [-sin(Omega*t),cos(Omega*t),0,])(t)
ellHat = Vector('ellHat', r'\hat{\ell}', [0,0,1,])(t)
# These are the spin functions -- first, the individual components as regular sympy.Function objects; then the vectors themselves
var('S_n, S_lambda, S_ell', cls=Function)
var('Sigma_n, Sigma_lambda, Sigma_ell', cls=Function)
SigmaVec = Vector('SigmaVec', r'\vec{\Sigma}', [Sigma_n(t), Sigma_lambda(t), Sigma_ell(t)])(t)
SVec = Vector('S', r'\vec{S}', [S_n(t), S_lambda(t), S_ell(t)])(t)
Explanation: The basic imports and the variables we'll be using:
End of explanation
nHat
diff(nHat, t)
diff(lambdaHat, t)
diff(lambdaHat, t).components
diff(lambdaHat, t).subs(t,0).components
diff(lambdaHat, t, 2).components
diff(lambdaHat, t, 2).subs(t,0).components
diff(ellHat, t)
diff(nHat, t, 2)
diff(nHat,t, 3)
diff(nHat,t, 4)
diff(SigmaVec,t, 0)
SigmaVec.fdiff()
diff(SigmaVec,t, 1)
diff(SigmaVec,t, 2)
diff(SigmaVec,t, 2) | nHat
T1 = TensorProduct(SigmaVec, SigmaVec, ellHat, coefficient=1)
T2 = TensorProduct(SigmaVec, nHat, lambdaHat, coefficient=1)
tmp = Tensor(T1,T2)
display(T1, T2, tmp)
diff(tmp, t, 1)
T1+T2
T2*ellHat
ellHat*T2
T1.trace(0,1)
T2*ellHat
for k in range(1,4):
    display((T2*ellHat).trace(0,k))
for k in range(1,4):
    display((T2*ellHat).trace(0,k).subs(t,0))
T1.trace(0,1) * T2
Explanation: Examples and tests
End of explanation
display(T1, T2)
T3 = SymmetricTensorProduct(SigmaVec, SigmaVec, ellHat, coefficient=1)
display(T3)
T3.trace(0,1)
diff(T3, t, 1)
T3.symmetric
T3*ellHat
ellHat*T3
T1+T3
T1 = SymmetricTensorProduct(SigmaVec, SigmaVec, ellHat, nHat, coefficient=1)
display(T1)
display(T1.trace())
T1*T2
type(_)
import simpletensors
isinstance(__, simpletensors.TensorProductFunction)
SymmetricTensorProduct(nHat, nHat, nHat).trace()
diff(T1.trace(), t, 1)
diff(T1.trace(), t, 2)
diff(T1.trace(), t, 2).subs(t,0)
Explanation: Sympy can be a little tricky because it caches things, which means that the first implementation of this code silently changed tensors in place, without meaning to.  Let's just check that our variables haven't changed:
End of explanation
<END_TASK>