def test_doit(self): v1, v2, zero, one, nabla, C, vn1, vn2, x, y, z = self._get_vars() v = C.x * C.y * C.z assert gradient(v) == Grad(v).doit() expr = v * (VecDot(vn1, vn2)) assert isinstance(Grad(expr).doit(deep=False), Grad) assert isinstance(Grad(expr).doit(), Vector)
def test_expand(self): a, b, c, d, e, f, g, h = self.vector_symbols x, y, z = self.symbols nabla = Nabla() # expand divergence expr = nabla & (x * a + b) assert self._check_args(expr.expand(dot=False), expr) assert self._check_args(expr.expand(dot=True), (nabla & (x * a)) + (nabla & b)) expr = nabla & (x * a) assert self._check_args(expr.expand(dot=False), expr) assert self._check_args(expr.expand(dot=True), expr) assert self._check_args(expr.expand(dot=True, prod=True), x * (nabla & a) + (Grad(x) & a)) expr = nabla & (a / x) assert self._check_args(expr.expand(dot=False), expr) assert self._check_args(expr.expand(dot=True), expr) assert self._check_args(expr.expand(dot=True, quotient=True), (x * (nabla & a) - (Grad(x) & a)) / x**2) # expand additive terms in dot products expr = a & (b + c) assert self._check_args(expr.expand(dot=False), expr) assert self._check_args(expr.expand(dot=True), (a & b) + (a & c)) expr = (a + b) & c assert self._check_args(expr.expand(dot=False), expr) assert self._check_args(expr.expand(dot=True), (a & c) + (b & c)) expr = (a + b) & (c + d) assert self._check_args(expr.expand(dot=False), expr) assert self._check_args(expr.expand(dot=True), (a & c) + (b & c) + (b & d) + (a & d)) expr = a & (b + (c & (d + e) * f.mag) * g) assert self._check_args(expr.expand(dot=False), a & (b + (c & (d * f.mag + e * f.mag)) * g)) assert self._check_args(expr.expand(dot=True), (a & b) + f.mag * (a & g) * (c & d) + f.mag * (a & g) * (c & e))
def test_expand(self): a, b, c, d, e, f, g, h = self.vector_symbols x, y, z = self.symbols # Laplacian with scalar fields expr = Laplace(x * y) self._check_args(expr.expand(), expr) self._check_args(expr.expand(laplacian=True), expr) self._check_args( expr.expand(laplacian=True, prod=True), x * Laplace(y) + y * Laplace(x) + 2 * (Grad(x) & Grad(y))) self._check_args(expr.expand(prod=True), expr) expr = Laplace(x + y) self._check_args(expr.expand(), expr) self._check_args(expr.expand(laplacian=True), Laplace(x) + Laplace(y)) expr = Laplace(x + x * y) self._check_args(expr.expand(), expr) self._check_args(expr.expand(laplacian=True), Laplace(x) + Laplace(x * y)) self._check_args( expr.expand(laplacian=True, prod=True), Laplace(x) + x * Laplace(y) + y * Laplace(x) + 2 * (Grad(x) & Grad(y))) # Laplacian with vector fields expr = Laplace(a + b) self._check_args(expr.expand(), expr) self._check_args(expr.expand(laplacian=True), Laplace(a) + Laplace(b)) expr = Laplace(a.mag * b) self._check_args(expr.expand(), expr) self._check_args(expr.expand(laplacian=True), expr) self._check_args(expr.expand(laplacian=True, prod=True), expr) expr = Laplace(a.mag * b + c) self._check_args(expr.expand(), expr) self._check_args(expr.expand(laplacian=True), Laplace(a.mag * b) + Laplace(c)) self._check_args(expr.expand(laplacian=True, prod=True), Laplace(a.mag * b) + Laplace(c))
def test_creation(self): v1, v2, zero, one, nabla, C, vn1, vn2, x, y, z = self._get_vars() # gradient of scalar fields # TODO: separate scalar fields from constants symbols, numbers, ... assert isinstance(Grad(nabla, x), Grad) assert isinstance(Grad(x), Grad) assert isinstance(nabla.grad(x), Grad) # gradient of scalar field v = C.x * C.y * C.z assert isinstance(Grad(v), Grad) def func(*args): with self.assertRaises(TypeError) as context: Grad(*args) # gradient of vector fields func(nabla, v1) func(v1) # gradient of nabla with self.assertRaises(NotImplementedError) as context: Grad(nabla)
def test_identities(self): v1, v2, zero, one, nabla, C, vn1, vn2, x, y, z = self._get_vars() a, b, c, d, e, f, g, h = self.vector_symbols x, y, z = self.symbols # Identity C expr = (nabla & (x * a)) assert self._check_args( expr, identities(expr) ) assert self._check_args( identities(expr, prod_div=True), (Grad(x) & a) + (x * (nabla & a)) ) expr = (nabla & (x * a)) + 4 * (nabla & (y * a)) assert self._check_args( identities(expr, prod_div=True), # (Grad(x) & a) + (x * (nabla & a)) + 4 * (Grad(y) & a) + Mul(4, y) * (nabla & a) (Grad(x) & a) + (x * (nabla & a)) + 4 * (Grad(y) & a) + 4 * y * (nabla & a) ) # Identity D expr = (nabla ^ (x * a)) assert self._check_args( expr, identities(expr) ) assert self._check_args( identities(expr, prod_curl=True), (Grad(x) ^ a) + (x * (nabla ^ a)) ) expr = (nabla ^ (x * a)) + 4 * (nabla ^ (y * a)) assert self._check_args( identities(expr, prod_curl=True), (Grad(x) ^ a) + (x * (nabla ^ a)) + 4 * ((Grad(y) ^ a) + (y * (nabla ^ a))) ) # Identity E expr = (nabla & (a ^ b)) assert self._check_args( expr, identities(expr) ) assert self._check_args( identities(expr, div_of_cross=True), ((nabla ^ a) & b) - ((nabla ^ b) & a) ) expr = (nabla & (a ^ b)) + 4 * (nabla & (c ^ d)) assert self._check_args( identities(expr, div_of_cross=True), ((nabla ^ a) & b) - ((nabla ^ b) & a) + 4 * (((nabla ^ c) & d) - ((nabla ^ d) & c)) ) # Identity F expr = (nabla ^ (a ^ b)) assert self._check_args( expr, identities(expr) ) assert self._check_args( identities(expr, curl_of_cross=True), ((nabla & b) * a) + Advection(b, a) - ((nabla & a) * b) - Advection(a, b) ) expr = (nabla ^ (a ^ b)) + 4 * (nabla ^ (c ^ d)) assert self._check_args( identities(expr, curl_of_cross=True), (((nabla & b) * a) + Advection(b, a) - ((nabla & a) * b) - Advection(a, b) + 4 * (((nabla & d) * c) + Advection(d, c) - ((nabla & c) * d) - Advection(c, d))) ) # Identity G expr = Grad(a & b) assert self._check_args( expr, identities(expr) ) assert self._check_args( identities(expr, grad_of_dot=True), Advection(a, b) + Advection(b, a) + (a ^ (nabla ^ b)) + (b ^ (nabla ^ a)) ) expr = Grad(a & b) + 4 * Grad(c & d) assert self._check_args( identities(expr, grad_of_dot=True), (Advection(a, b) + Advection(b, a) + (a ^ (nabla ^ b)) + (b ^ (nabla ^ a)) + 4 * (Advection(c, d) + Advection(d, c) + (c ^ (nabla ^ d)) + (d ^ (nabla ^ c)))) ) # Identity H expr = nabla ^ Grad(x) assert self._check_args( expr, identities(expr) ) assert self._check_args( identities(expr, curl_of_grad=True), VectorZero() ) expr = (nabla ^ Grad(x)) + 4 * (nabla ^ Grad(y)) assert self._check_args( identities(expr, curl_of_grad=True), VectorZero() ) # Identity I expr = nabla & (nabla ^ a) assert self._check_args( expr, identities(expr) ) assert self._check_args( identities(expr, div_of_curl=True), S.Zero ) expr = (nabla & (nabla ^ a)) + 4 * (nabla & (nabla ^ b)) assert self._check_args( identities(expr, div_of_curl=True), S.Zero ) # Identity J expr = nabla ^ (nabla ^ a) assert self._check_args( expr, identities(expr) ) assert self._check_args( identities(expr, curl_of_curl=True), Grad(nabla & a) - Laplace(a) ) expr = (nabla ^ (nabla ^ a)) + 4 * (nabla ^ (nabla ^ b)) assert self._check_args( identities(expr, curl_of_curl=True), Grad(nabla & a) - Laplace(a) + 4 * (Grad(nabla & b) - Laplace(b)) )
def test_expand(self): a, b, c, d, e, f, g, h = self.vector_symbols x, y, z = self.symbols nabla = Nabla() # expand general expressions expr = self.one + 2 * (a ^ (b + c)) assert self._check_args( expr.expand(cross=False), expr ) assert self._check_args( expr.expand(cross=True), self.one + 2 * (a ^ b) + 2 * (a ^ c) ) expr = (x + y) * a + Grad(x + y * z) assert self._check_args( expr.expand(), x * a + y * a + Grad(x + y * z) ) assert self._check_args( expr.expand(gradient=True), x * a + y * a + Grad(x) + Grad(y * z) ) assert self._check_args( expr.expand(gradient=True, prod=True), x * a + y * a + Grad(x) + y * Grad(z) + z * Grad(y) ) expr = self.one + (c ^ ((d + e) ^ f)) assert self._check_args( expr.expand(cross=True), self.one + (c ^ (d ^ f)) + (c ^ (e ^ f)) ) expr = x * ((a & (b + (c & (d + e) * f.mag) * g)) + (((a + b) ^ c) & d)) assert self._check_args( expr.expand(dot=True, cross=True), (x * (a & b) + x * f.mag * (a & g) * (c & d) + x * f.mag * (a & g) * (c & e) + x * ((a ^ c) & d) + x * ((b ^ c) & d)) ) expr = Laplace(a + b) + ((c + d) ^ Grad(x * y)) assert self._check_args( expr.expand(cross=True), Laplace(a + b) + (c ^ Grad(x * y)) + (d ^ Grad(x * y)) ) assert self._check_args( expr.expand(cross=True, laplacian=True), Laplace(a) + Laplace(b) + (c ^ Grad(x * y)) + (d ^ Grad(x * y)) ) assert self._check_args( expr.expand(cross=True, laplacian=True, gradient=True, prod=True), Laplace(a) + Laplace(b) + (x * (c ^ Grad(y))) + (y * (c ^ Grad(x))) + (x * (d ^ Grad(y))) + (y * (d ^ Grad(x))) )
def test_find(self): v1, v2, zero, one, nabla, C, vn1, vn2, x, y, z = self._get_vars() a, b, c, d, e, f, g, h = self.vector_symbols w1, w2, w3, w4 = [ WildVectorSymbol(t) for t in ["w_1", "w_2", "w_3", "w_4"] ] w = Wild("w") expr = (a & b) + (c & d) assert len(expr.find(w1 & w2) - set([a & b, c & d])) == 0 expr = (a & b) + ((x * d) & (2 * (e & f) * g)) + a.mag assert len( expr.find(w1 & w2) - set([a & b, e & f, ((x * d) & (2 * (e & f) * g))])) == 0 expr = (a ^ (b ^ c)) + (d ^ e) * f.mag assert len(expr.find(w1 & w2) - set([a ^ (b ^ c), b ^ c, d ^ e])) == 0 expr = (nabla & ((a + b) ^ (c.mag * d))) + (e & f) assert len( expr.find(nabla & w1) - set([nabla & ((a + b) ^ (c.mag * d))])) == 0 assert len( expr.find(w1 & w2) - set([nabla & ((a + b) ^ (c.mag * d)), e & f])) == 0 expr = (nabla ^ ((a + b) ^ (c.mag * d))) + (e ^ f) assert len( expr.find(nabla ^ w1) - set([nabla ^ ((a + b) ^ (c.mag * d))])) == 0 assert len( expr.find(w1 ^ w2) - set([ nabla ^ ((a + b) ^ (c.mag * d)), e ^ f, (a + b) ^ (c.mag * d) ])) == 0 expr = Grad((a + b) & (c + d)) * e.mag + f assert len(expr.find(Grad(w1 & w2)) - set([Grad((a + b) & (c + d))])) == 0 expr = (a & a) + ((a + b) & (a + b)) + ( (a ^ b) & (a ^ b)) + (Grad(x) & Grad(x)) + (a & b) + ((a + b) & (c + d)) assert len( expr.find(w1 & w1) - set([(a & a), ((a + b) & (a + b)), ( (a ^ b) & (a ^ b)), (Grad(x) & Grad(x))])) == 0 expr = (nabla ^ (nabla ^ (a + b))) + (nabla ^ c) assert len( expr.find(nabla ^ (nabla ^ w1)) - set([nabla ^ (nabla ^ (a + b))])) == 0 expr = (nabla & (nabla ^ (a + b))) + (nabla & c) assert len( expr.find(nabla & (nabla ^ w1)) - set([nabla & (nabla ^ (a + b))])) == 0 expr = (nabla ^ Grad(x)) + (a + b + (nabla ^ Grad((a + b) & c))) * 3 assert len( expr.find(nabla ^ Grad(w)) - set([nabla ^ Grad(x), nabla ^ Grad((a + b) & c)])) == 0
def test_expand(self): x, y, z = self.symbols assert Grad(x).expand(gradient=True) == Grad(x) expr = Grad(x + y) assert self._check_args(expr.expand(gradient=False), expr) assert self._check_args(expr.expand(gradient=True), Grad(x) + Grad(y)) assert self._check_args(expr.expand(gradient=True, prod=True), Grad(x) + Grad(y)) expr = Grad(x * y) assert self._check_args(expr.expand(gradient=False), expr) assert self._check_args(expr.expand(gradient=True), expr) assert self._check_args(expr.expand(gradient=True, prod=True), y * Grad(x) + x * Grad(y)) expr = Grad(x * y * z) assert self._check_args(expr.expand(gradient=False), expr) assert self._check_args(expr.expand(gradient=True), expr) assert self._check_args( expr.expand(gradient=True, prod=True), z * y * Grad(x) + x * z * Grad(y) + y * x * Grad(z)) expr = Grad(x * y + z) assert self._check_args(expr.expand(gradient=False), expr) assert self._check_args(expr.expand(gradient=True), Grad(z) + Grad(x * y)) assert self._check_args(expr.expand(gradient=True, prod=True), Grad(z) + y * Grad(x) + x * Grad(y)) expr = Grad(x / y) assert self._check_args(expr.expand(gradient=False), expr) assert self._check_args(expr.expand(gradient=True), expr) assert self._check_args(expr.expand(gradient=True, quotient=True), (y * Grad(x) - x * Grad(y)) / y**2)
def func(*args): with self.assertRaises(TypeError) as context: Grad(*args)
def _curl_of_grad(expr): w = Wild("w") found = expr.find(Nabla() ^ Grad(w)) for f in found: expr = expr.subs(f, VectorZero()) return expr
w = Wild("w") wa = WVS("w_a") wb = WVS("w_b") wc = WVS("w_c") nabla = Nabla() _id = { # A x (B x C) = B (A . C) - C (A . B) "abc": [wa ^ (wb ^ wc), (wb * (wa & wc)) - (wc * (wa & wb))], # # B (A . C) - C (A . B) = A x (B x C) # "bac_cab": [ # (wb * (wa & wc)) - (wc * (wa & wb)), # wa ^ (wb ^ wc) # ], # Identity C "prod_div": [nabla & (w * wa), (Grad(w) & wa) + (w * (nabla & wa))], # Identity D "prod_curl": [nabla ^ (w * wa), (Grad(w) ^ wa) + (w * (nabla ^ wa))], # Identity E "div_of_cross": [nabla & (wa ^ wb), ((nabla ^ wa) & wb) - ((nabla ^ wb) & wa)], # Identity F "curl_of_cross": [ nabla ^ (wa ^ wb), ((nabla & wb) * wa) + Advection(wb, wa) - ((nabla & wa) * wb) - Advection(wa, wb) ], # Identity G "grad_of_dot": [ Grad(wa & wb), Advection(wa, wb) + Advection(wb, wa) + (wa ^ (nabla ^ wb)) + (wb ^ (nabla ^ wa))