def setup_mms(eps=None): '''Simple MMS problem for UnitSquareMesh''' from common import as_expression import sympy as sp x, y = sp.symbols('x[0] x[1]') sigma = sp.Matrix([ sp.sin(sp.pi * x * (1 - x) * y * (1 - y)), sp.sin(2 * sp.pi * x * (1 - x) * y * (1 - y)) ]) sp_div = lambda f: f[0].diff(x, 1) + f[1].diff(y, 1) sp_grad = lambda f: sp.Matrix([f.diff(x, 1), f.diff(y, 1)]) f = -sp_grad(sp_div(sigma)) + sigma g = sp.S(0) sigma_exact = as_expression(sigma) # It's quite interesting that you get surface divergence as the extra var p_exact = as_expression(sp_div(-sigma)) f_rhs, g_rhs = map(as_expression, (f, g)) return (sigma_exact, p_exact), (f_rhs, g_rhs)
def setup_mms(eps=None): '''Simple MMS problem for UnitSquareMesh''' from common import as_expression import sympy as sp x, y = sp.symbols('x[0] x[1]') sigma = sp.Matrix([sp.sin(sp.pi*x*(1-x)*y*(1-y)), sp.sin(2*sp.pi*x*(1-x)*y*(1-y))]) sp_grad = lambda f: sp.Matrix([f.diff(x, 1), f.diff(y, 1)]) sp_div = lambda f: f[0].diff(x, 1) + f[1].diff(y, 1) # This is a consistent with FEniCS definition ROT_MAT = sp.Matrix([[sp.S(0), sp.S(1)], [sp.S(-1), sp.S(0)]]) # Maps vector to scalar: sp_curl = lambda f: sp_div(ROT_MAT*f) # Maps scalar to vector sp_rot = lambda f: ROT_MAT*sp_grad(f) f = sp_rot(sp_curl(sigma)) + sigma g = sp.S(0) sigma_exact = as_expression(sigma) # It's quite nice that you get surface curl as the extra varp p_exact = as_expression(sp_curl(sigma)) f_rhs, g_rhs = map(as_expression, (f, g)) return (sigma_exact, p_exact), (f_rhs, g_rhs)
def setup_mms(eps): '''Simple MMS problem for UnitSquareMesh''' from common import as_expression import sympy as sp pi = sp.pi x, y, EPS = sp.symbols('x[0] x[1] EPS') sp_grad = lambda f: sp.Matrix([f.diff(x, 1), f.diff(y, 1)]) u1 = sp.sin(2*pi*x)*sp.sin(2*pi*y) # Zero at bdry, zero grad @ iface u2 = u1 + 1 # Zero grad @iface sigma1 = -sp_grad(u1) sigma2 = -sp_grad(u2) f1 = -u1.diff(x, 2) - u1.diff(y, 2) + u1 f2 = -u2.diff(x, 2) - u2.diff(y, 2) + u2 g = EPS*(u1 - u2) # + grad(u1).n1 # But the flux is 0 up = map(as_expression, (sigma1, sigma2, u1, u2, u1 - u2)) # The last gut is the u1 trace value but here is is 0 fg = map(as_expression, (f1, f2)) + [as_expression(g, EPS=eps)] return up, fg
def setup_mms(eps): '''Simple MMS problem for UnitSquareMesh''' from common import as_expression import sympy as sp pi = sp.pi x, y, EPS = sp.symbols('x[0] x[1] EPS') u1 = sp.cos(2 * pi * (x - 0.25) * (x - 0.75) * (y - 0.25) * (y - 0.75)) u2 = 2 * sp.cos(pi * (x - 0.25) * (x - 0.75) * (y - 0.25) * (y - 0.75)) # Note that u1 is such that grad(u1) is zero on the boudnary so # p = u1 only p = u1 f1 = EPS * (-u1.diff(x, 2) - u1.diff(y, 2)) + u1 f2 = -u2.diff(x, 2) - u2.diff(y, 2) sp_grad = lambda f: sp.Matrix([f.diff(x, 1), f.diff(y, 1)]) # The neumann term h2 = sp_grad(u2) # The 'Robin' boundary condition simplifies as grad(u1).n1 = grad(u2).n2 = 0 h = u1 + u2 g = u1 - u2 up = map(as_expression, (u1, u2, p)) fg = [as_expression(f1, EPS=eps[0])] + map(as_expression, (f2, h2, h, g)) return up, fg
def setup_mms(eps): '''Simple MMS problem for UnitSquareMesh''' from common import as_expression import sympy as sp pi = sp.pi x, y, EPS = sp.symbols('x[0] x[1] EPS') u1 = sp.cos(2*pi*(x-0.25)*(x-0.75)*(y-0.25)*(y-0.75)) u2 = 2*sp.cos(pi*(x-0.25)*(x-0.75)*(y-0.25)*(y-0.75)) # Note that u1 is such that grad(u1) is zero on the boudnary so # p = u1 only p = u1 f1 = EPS*(-u1.diff(x, 2) - u1.diff(y, 2)) + u1 f2 = -u2.diff(x, 2) - u2.diff(y, 2) sp_grad = lambda f: sp.Matrix([f.diff(x, 1), f.diff(y, 1)]) # The neumann term h2 = sp_grad(u2) # The 'Robin' boundary condition simplifies as grad(u1).n1 = grad(u2).n2 = 0 h = u1 + u2 g = u1 - u2 up = map(as_expression, (u1, u2, p)) fg = [as_expression(f1, EPS=eps)] + map(as_expression, (f2, h2, h, g)) return up, fg
def setup_mms(eps=None): '''Simple MMS problem for UnitSquareMesh''' from common import as_expression import sympy as sp x, y = sp.symbols('x[0], x[1]') u = sp.cos(sp.pi * x * (1 - x) * y * (1 - y)) f = -u.diff(x, 2) - u.diff(y, 2) + u x0 = (0.33, 0.66) # The desired point value is that of u in the point g = (float(u.subs({x: x0[0], y: x0[1]})), ) * 2 # This means that no stress is needed to enforce it :) p = np.array([0., 0.]) up = [as_expression((u, u)), p] fg = [x0, as_expression((f, f)), g] return up, fg
def setup_mms(eps=None): '''Simple MMS problem for UnitSquareMesh''' from common import as_expression import sympy as sp x, y = sp.symbols('x[0], x[1]') u = sp.cos(sp.pi*x*(1-x)*y*(1-y)) f = -u.diff(x, 2) - u.diff(y, 2) + u x0 = (0.33, 0.66) # The desired point value is that of u in the point g = (float(u.subs({x: x0[0], y: x0[1]})), )*2 # This means that no stress is needed to enforce it :) p = np.array([0., 0.]) up = [as_expression((u, u)), p] fg = [x0, as_expression((f, f)), g] return up, fg
def setup_mms(eps): '''Simple MMS...''' from common import as_expression import sympy as sp pi = sp.pi x, y, EPS = sp.symbols('x[0] x[1] EPS') sp_grad = lambda f: sp.Matrix([f.diff(x, 1), f.diff(y, 1)]) sp_Grad = lambda f: sp.Matrix([[f[0].diff(x, 1), f[0].diff(y, 1)], [f[1].diff(x, 1), f[1].diff(y, 1)]]) sp_div = lambda f: f[0].diff(x, 1) + f[1].diff(y, 1) sp_Div = lambda f: sp.Matrix([sp_div(f[0, :]), sp_div(f[1, :])]) u = sp.Matrix( [sp.sin(pi * y) * sp.cos(pi * x), -sp.cos(pi * y) * sp.sin(pi * x)]) X = -EPS * sp_Grad(u) # I think the multiplier is the tangential component of X.n # so now we circulate the boundaries 0 # 1 3 # 2 lambda_ = ((X.subs(y, 1) * sp.Matrix([0, 1]))[0], (X.subs(x, 0) * sp.Matrix([-1, 0]))[1], (X.subs(y, 0) * sp.Matrix([0, 1]))[0], -(X.subs(x, 1) * sp.Matrix([1, 0]))[1]) p = sp.sin(pi * ((x - 0.5)**2 + (y - 0.5)**2)) # EPS * 1./EPS f = -EPS * sp_Div(sp_Grad(u)) + u - sp_grad(p) p0 = p up = [as_expression(u, EPS=eps), as_expression(p, EPS=eps)] fg = [as_expression(f, EPS=eps), as_expression(p0)] return up + [[as_expression(l, EPS=eps) for l in lambda_]], fg
def setup_mms(eps): '''Simple MMS...''' from common import as_expression import sympy as sp pi = sp.pi x, y, EPS = sp.symbols('x[0] x[1] EPS') sp_grad = lambda f: sp.Matrix([f.diff(x, 1), f.diff(y, 1)]) sp_Grad = lambda f: sp.Matrix([[f[0].diff(x, 1), f[0].diff(y, 1)], [f[1].diff(x, 1), f[1].diff(y, 1)]]) sp_div = lambda f: f[0].diff(x, 1) + f[1].diff(y, 1) sp_Div = lambda f: sp.Matrix([sp_div(f[0, :]), sp_div(f[1, :])]) u = sp.Matrix([sp.sin(pi*y)*sp.cos(pi*x), -sp.cos(pi*y)*sp.sin(pi*x)]) X = -EPS*sp_Grad(u) # I think the multiplier is the tangential component of X.n # so now we circulate the boundaries 0 # 1 3 # 2 lambda_ = ((X.subs(y, 1)*sp.Matrix([0, 1]))[0], (X.subs(x, 0)*sp.Matrix([-1, 0]))[1], (X.subs(y, 0)*sp.Matrix([0, 1]))[0], -(X.subs(x, 1)*sp.Matrix([1, 0]))[1]) p = sp.sin(pi*((x-0.5)**2 + (y-0.5)**2)) # EPS * 1./EPS f = -EPS*sp_Div(sp_Grad(u)) + u - sp_grad(p) p0 = p up = [as_expression(u, EPS=eps), as_expression(p, EPS=eps)] fg = [as_expression(f, EPS=eps), as_expression(p0)] return up + [[as_expression(l, EPS=eps) for l in lambda_]], fg
def setup_mms(eps=None): '''Simple MMS problem for UnitSquareMesh''' from common import as_expression import sympy as sp x, y = sp.symbols('x[0] x[1]') sigma = sp.Matrix([sp.sin(sp.pi*x*(1-x)*y*(1-y)), sp.sin(2*sp.pi*x*(1-x)*y*(1-y))]) sp_div = lambda f: f[0].diff(x, 1) + f[1].diff(y, 1) sp_grad = lambda f: sp.Matrix([f.diff(x, 1), f.diff(y, 1)]) f = -sp_grad(sp_div(sigma)) + sigma g = sp.S(0) sigma_exact = as_expression(sigma) # It's quite interesting that you get surface divergence as the extra var p_exact = as_expression(sp_div(-sigma)) f_rhs, g_rhs = map(as_expression, (f, g)) return (sigma_exact, p_exact), (f_rhs, g_rhs)
def setup_mms(eps=None): '''Simple MMS problem for UnitSquareMesh''' from common import as_expression import sympy as sp x, y = sp.symbols('x[0], x[1]') u = sp.cos(sp.pi * x * (1 - x) * y * (1 - y)) p = sp.S(0) # Normal stress is the multiplier, here it is zero f = x + y g = u up = list(map(as_expression, (u, p))) f = as_expression(f) return up, f
def setup_mms(eps=None): '''Simple MMS problem for UnitSquareMesh''' from common import as_expression import sympy as sp x, y = sp.symbols('x[0], x[1]') u = sp.cos(sp.pi*x*(1-x)*y*(1-y)) p = sp.S(0) # Normal stress is the multiplier, here it is zero f = x + y g = u up = map(as_expression, (u, p)) f = as_expression(f) return up, f
def setup_mms(eps): '''Simple MMS problem for UnitSquareMesh''' from common import as_expression import sympy as sp pi = sp.pi x, y, EPS = sp.symbols('x[0] x[1] EPS') u1 = sp.cos(4 * pi * x) * sp.cos(4 * pi * y) u2 = 2 * u1 f1 = -u1.diff(x, 2) - u1.diff(y, 2) + u1 f2 = -u2.diff(x, 2) - u2.diff(y, 2) + u2 g = (u1 - u2) * EPS # NOTE: the multiplier is grad(u).n and with the chosen data this # means that it's zero on the interface up = map(as_expression, (u1, u2, sp.S(0))) # The flux f = map(as_expression, (f1, f2)) g = as_expression(g, EPS=eps) # Prevent recompilation return up, f + [g]
def setup_mms(eps): '''Simple MMS problem for UnitSquareMesh''' from common import as_expression import sympy as sp pi = sp.pi x, y, EPS = sp.symbols('x[0] x[1] EPS') u1 = sp.cos(4*pi*x)*sp.cos(4*pi*y) u2 = 2*u1 f1 = -u1.diff(x, 2) - u1.diff(y, 2) + u1 f2 = -u2.diff(x, 2) - u2.diff(y, 2) + u2 g = (u1 - u2)*EPS # NOTE: the multiplier is grad(u).n and with the chosen data this # means that it's zero on the interface up = map(as_expression, (u1, u2, sp.S(0))) # The flux f = map(as_expression, (f1, f2)) g = as_expression(g, EPS=eps) # Prevent recompilation return up, f+[g]