def get_source_terms(u, p, version="biot"): """ Function that computes the source terms f and g using sympy, returning FEniCS expressions in C-code. Find (f,g) given (u,p) s.t. f = - div(sigma(u)) + alpha*grad(p) g = c*p_t + alpha*div(u_t) - K*div(grad(p)) Args: u, p (str) : functions Returns: f, g (str) : FEniCS string expressions """ u = str2sympy(u); p = str2sympy(p) u_t = diff(u,t) div_u = div(u) p_t = diff(p,t) grad_p = grad(p) sigma_u = sigma(u) f = -div(sigma_u) + alpha*grad_p.T g = c*p_t + alpha*div(u_t) - K*div(grad_p) return sympy2expr(simplify(f)), sympy2expr(simplify(g))
def get_source_terms(u, p): """ Function that computes the source terms f and g=[g1,g2] using sympy, returning FEniCS expressions in C-code. Exact solutions u and p=[p1,p2] must be given. Find (f,g) given (u,p) s.t. -div(sigma(u)) + alpha1*grad(p1) +.. + alpha4*grad(p4) = f c1*p1_t + alpha1*div(u_t) - K1*div(grad(p1)) + S1 = g1 c2*p2_t + alpha2*div(u_t) - K2*div(grad(p2)) + S2 = g2 c3*p3_t + alpha3*div(u_t) - K3*div(grad(p3)) + S3 = g3 c4*p4_t + alpha4*div(u_t) - K4*div(grad(p4)) + S4 = g4 where, S1 = xi21*(p1-p2) + xi31*(p1-p3) + xi41*(p1-p4) S2 = xi12*(p2-p1) + xi32*(p2-p3) + xi42*(p2-p4) S3 = xi13*(p3-p1) + xi23*(p3-p2) + xi43*(p3-p4) S4 = xi14*(p4-p1) + xi24*(p4-p2) + xi34*(p4-p3) """ u = str2sympy(u) p = str2sympy(p) p1 = p[0] p2 = p[1] p3 = p[2] p4 = p[3] # Transfer parameters S1 = xi1 * (p1 - p2) + xi2 * (p1 - p3) + xi3 * (p1 - p4) S2 = xi1 * (p2 - p1) + xi4 * (p2 - p3) + xi5 * (p2 - p4) S3 = xi2 * (p3 - p1) + xi4 * (p3 - p2) + xi6 * (p3 - p4) S4 = xi3 * (p4 - p1) + xi5 * (p4 - p2) + xi6 * (p4 - p3) f = -div(sigma(u)) + alpha1 * grad(p1).T + alpha2 * grad( p2).T + alpha3 * grad(p3).T + alpha3 * grad(p3).T g1 = c1 * diff(p1, t) + alpha1 * div(diff(u, t)) - K1 * div(grad(p1)) + S1 g2 = c2 * diff(p2, t) + alpha2 * div(diff(u, t)) - K2 * div(grad(p2)) + S2 g3 = c3 * diff(p3, t) + alpha3 * div(diff(u, t)) - K3 * div(grad(p3)) + S3 g4 = c4 * diff(p4, t) + alpha4 * div(diff(u, t)) - K4 * div(grad(p4)) + S4 g = [ sympy2exp(simplify(g1)), sympy2exp(simplify(g2)), sympy2exp(simplify(g3)), sympy2exp(simplify(g4)) ] return sympy2exp(simplify(f)), g
def get_source_terms(u, p): """ Function that computes the source terms f and g=[g1,g2] using sympy, returning FEniCS expressions in C-code. Exact solutions u and p=[p1,p2] must be given. Find (f,g) given (u,p) s.t. -div(sigma(u)) + alpha1*grad(p1) + alpha2*grap(p2) = f c1*p1_t + alpha1*div(u_t) - K1*div(grad(p1)) + xi1*(p1-p2) = g1 c2*p2_t + alpha2*div(u_t) - K2*div(grad(p2)) + xi2*(p2-p1) = g2 """ u = str2sympy(u); p = str2sympy(p) p1 = p[0]; p2 = p[1] f = -div(sigma(u)) + alpha1*grad(p1).T + alpha2*grad(p2).T g1 = c1*diff(p1,t) + alpha1*div(diff(u,t)) - K1*div(grad(p1)) + xi1*(p1-p2) g2 = c2*diff(p2,t) + alpha2*div(diff(u,t)) - K2*div(grad(p2)) + xi2*(p2-p1) g = [sympy2exp(simplify(g1)),sympy2exp(simplify(g2))] return sympy2exp(simplify(f)), g
def sigma(u): """ Stress tensor """ # Infer dimension dim = len(u) # Handle zero-matrices for i in range(dim): if u[i] == 0: u = 0*eye(dim)*eye(dim) return u break return 2.0*mu*eps(u) + lamb*div(u)*eye(dim)
def sigma(u): """ Stress tensor """ return 2.0*mu*eps(u) + lamb*div(u)*eye(len(u))
def test(): """Test the convergence rate of S(REG)xCG for the biharmonic equation in 2D and 3D. Args: dim (int): Dimension, either 2 or 3. degree (int): SREG(degree) x CG(degree + 1) will be used. sizes (list): Mesh sizes to test. This should be given as [2,4,8]. """ # Parse input parser = argparse.ArgumentParser() parser.add_argument("dim", type=int) parser.add_argument("degree", type=int) parser.add_argument("mesh_sizes", type=ast.literal_eval) args = parser.parse_args() dim = args.dim degree = args.degree mesh_sizes = args.mesh_sizes # Exact solution ext_degree = 5 # Degree for the representation of the exact solution if dim == 2: sol = sf.str2sympy("sin(pi*x)*sin(pi*x)*sin(pi*y)*sin(pi*y)") else: sol = sf.str2sympy("sin(pi*x)*sin(pi*x)*sin(pi*y)*sin(pi*y)*sin(pi*z)" "*sin(pi*z)") u_ext = Expression(sf.sympy2exp(sol), degree=ext_degree) f_ext = Expression(sf.sympy2exp(sf.div(sf.grad(sf.div(sf.grad(sol))))), degree=ext_degree) sigma = sf.hess(sol) sigma_ext = Expression(sf.sympy2exp(sigma), degree=ext_degree) gradu_ext = Expression(sf.sympy2exp(sf.grad(sol)), degree=ext_degree) # Compute the convergence rates hs = [] eu_L2 = [] eu_H1 = [] esigma_L2 = [] for m in mesh_sizes: # Mesh if dim == 2: domain = Rectangle(Point(0, 0), Point(1, 1)) mesh = generate_mesh(domain, m) else: mesh = gaussian_mesh_randomizer(UnitCubeMesh(m, m, m), 0.1) hs.append((mesh.hmax() + mesh.hmin()) / 2.0) # Problem setup REG = FiniteElement('Regge', mesh.ufl_cell(), degree) CG = FiniteElement('CG', mesh.ufl_cell(), degree + 1) V = FunctionSpace(mesh, REG * CG) (gamma, u) = TrialFunctions(V) (mu, v) = TestFunctions(V) S = lambda mu: mu - Identity(dim) * tr(mu) def a(gamma, mu): return inner(S(gamma), S(mu)) * dx def b(mu, v): n = FacetNormal(mesh) return inner(S(mu), grad(grad(v))) * dx \ - dot(dot(S(mu('+')), n('+')), n('+')) * jump(grad(v), n) * dS \ - dot(dot(S(mu), n), n) * dot(grad(v), n) * ds B = a(gamma, mu) - b(mu, u) + b(gamma, v) L = f_ext * v * dx bc = DirichletBC(V.sub(1), Constant(0.0), lambda x, on_boundary: on_boundary) # Solve w_h = Function(V) print("Solve for m={}...".format(m), end="") solve(B == L, w_h, bc, solver_parameters={"linear_solver": "mumps"}) print("done.") (gamma_h, u_h) = w_h.split() # Error estimation ue = interpolate(u_ext, FunctionSpace(mesh, 'CG', degree + 2)) err = ue - u_h eu_L2.append(sqrt(assemble(err * err * dx))) gradue = interpolate(gradu_ext, VectorFunctionSpace(mesh, 'DG', degree + 1)) err = gradue - grad(u_h) eu_H1.append(sqrt(assemble(dot(err, err) * dx))) sigmae = interpolate(sigma_ext, TensorFunctionSpace(mesh, 'DG', degree + 1)) gamma_h = interpolate(gamma_h, TensorFunctionSpace(mesh, 'DG', degree + 1)) err = sigmae - S(gamma_h) esigma_L2.append(sqrt(assemble(inner(err, err) * dx))) # Compute convergence rates eu_L2r = calc_rate(hs, eu_L2) eu_H1r = calc_rate(hs, eu_H1) esigma_L2r = calc_rate(hs, esigma_L2) # Print table headers = ["Mesh size", "‖u‖", "Rate", "‖∇u‖", "Rate", "‖σ‖", "Rate"] table = zip( *[mesh_sizes, eu_L2, eu_L2r, eu_H1, eu_H1r, esigma_L2, esigma_L2r]) #format = "fancy_grid" # Pretty printing for the terminal format = "latex_booktabs" # Output LaTeX table print( tabulate(table, headers=headers, tablefmt=format, floatfmt=("d", ) + ("e", "0.2f") * 3))
def test(): """Test the convergence rate of S(REG)xNED for TDNNS elasticity 2D and 3D. Args: dim (int): Dimension, either 2 or 3. degree (int): SREG(degree) x NED(degree) will be used. sizes (list): Mesh sizes to test. This should be given as [2,4,8]. """ # Parse input parser = argparse.ArgumentParser() parser.add_argument("dim", type=int) parser.add_argument("degree", type=int) parser.add_argument("mesh_sizes", type=ast.literal_eval) args = parser.parse_args() dim = args.dim degree = args.degree mesh_sizes= args.mesh_sizes # Exact solution ext_degree = 3 # Degree for the representation of the exact solution if dim == 2: sol = sf.str2sympy('(sin(pi*x)*sin(pi*y), 15.0*x*(1.0-x)*y*(1.0-y))') else: sol = sf.str2sympy("""(sin(pi*x)*sin(pi*y)*sin(pi*z), 15.0*x*(1.0-x)*y*(1.0-y)*z*(1.0-z), 7.0*x*(1.0-x)*sin(pi*y)*sin(pi*z))""") u_ext = Expression(sf.sympy2exp(sol), degree=ext_degree) f_ext = Expression(sf.sympy2exp(sf.div(sf.epsilon(sol))), degree=ext_degree) sigma = sf.epsilon(sol) sigma_ext = Expression(sf.sympy2exp(sigma), degree=ext_degree) # Compute the convergence rates hs = [] eu_L2 = [] esigma_L2 = [] for m in mesh_sizes: # Mesh if dim == 2: mesh = gaussian_mesh_randomizer(UnitSquareMesh(m, m), 0.1) else: mesh = gaussian_mesh_randomizer(UnitCubeMesh(m, m, m), 0.1) hs.append((mesh.hmax() + mesh.hmin()) / 2.0) # Problem setup REG = FiniteElement('Regge', mesh.ufl_cell(), degree) NED = FiniteElement('N2curl', mesh.ufl_cell(), degree) V = FunctionSpace(mesh, REG * NED) print("space ok") (gamma, u) = TrialFunctions(V) (mu, v) = TestFunctions(V) S = lambda mu: mu - Identity(dim) * tr(mu) def a(gamma, mu): return inner(S(gamma), S(mu)) * dx def b(mu, v): n = FacetNormal(mesh) return - (inner(S(mu), sym(grad(v)))) * dx \ + dot(dot(S(mu('+')), n('+')), n('+')) * jump(v, n) * dS \ + dot(dot(S(mu), n), n) * dot(v, n) * ds B = a(gamma, mu) + b(mu, u) + b(gamma, v) L = dot(f_ext, v) * dx if dim == 2: homogenenous = Constant((0.0, 0.0)) else: homogenenous = Constant((0.0, 0.0, 0.0)) bc = DirichletBC(V.sub(1), homogenenous, lambda x, on_boundary: on_boundary) # Solve w_h = Function(V) print("Solve for m={}...".format(m), end="") solve(B == L, w_h, bc, solver_parameters={"linear_solver": "mumps"}) print("done.") (gamma_h, u_h) = w_h.split() # Error estimation ue = interpolate(u_ext, FunctionSpace(mesh, 'N2curl', degree + 1)) err = ue - u_h eu_L2.append(sqrt(assemble(dot(err, err) * dx))) sigmae = interpolate(sigma_ext, TensorFunctionSpace(mesh, 'DG', degree + 1)) gamma_h = interpolate(gamma_h, TensorFunctionSpace(mesh, 'DG', degree + 1)) err = sigmae - S(gamma_h) esigma_L2.append(sqrt(assemble(inner(err, err) * dx))) # Compute convergence rates eu_L2r = calc_rate(hs, eu_L2) esigma_L2r = calc_rate(hs, esigma_L2) # Print table headers = ["Mesh size", "‖u‖", "Rate", "‖σ‖", "Rate"] table = zip(*[mesh_sizes, eu_L2, eu_L2r, esigma_L2, esigma_L2r]) #format = "fancy_grid" # Pretty printing for the terminal format = "latex_booktabs" # Output LaTeX table print(tabulate(table, headers=headers, tablefmt=format, floatfmt=("d",) + ("e", "0.2f") * 2))