def test_only_first_order(V): u = Coefficient(V) v = TestFunction(V) c = Coefficient(V) F = (inner(c, c) * inner(Dt(Dt(u)), v) + inner(grad(u), grad(v)) + inner(c, v) + inner(Dt(u), v)) * dx with pytest.raises(ValueError): check_integrals(F.integrals(), expect_time_derivative=True)
def wave(n, deg, butcher_tableau, splitting=AI): N = 2**n msh = UnitIntervalMesh(N) params = { "snes_type": "ksponly", "ksp_type": "preonly", "mat_type": "aij", "pc_type": "lu" } V = FunctionSpace(msh, "CG", deg) W = FunctionSpace(msh, "DG", deg - 1) Z = V * W x, = SpatialCoordinate(msh) t = Constant(0.0) dt = Constant(2.0 / N) up = project(as_vector([0, sin(pi * x)]), Z) u, p = split(up) v, w = TestFunctions(Z) F = (inner(Dt(u), v) * dx + inner(u.dx(0), w) * dx + inner(Dt(p), w) * dx - inner(p, v.dx(0)) * dx) E = 0.5 * (inner(u, u) * dx + inner(p, p) * dx) stepper = TimeStepper(F, butcher_tableau, t, dt, up, solver_parameters=params, splitting=splitting) energies = [] while (float(t) < 1.0): if (float(t) + float(dt) > 1.0): dt.assign(1.0 - float(t)) stepper.advance() t.assign(float(t) + float(dt)) energies.append(assemble(E)) return np.array(energies)
def heat_subdomainbc(N, deg, butcher_tableau, splitting=AI): dt = Constant(1.0 / N) t = Constant(0.0) msh = UnitSquareMesh(N, N) V = FunctionSpace(msh, "CG", 2) x, y = SpatialCoordinate(msh) uexact = t*(x+y) rhs = expand_derivatives(diff(uexact, t)) - div(grad(uexact)) u = interpolate(uexact, V) v = TestFunction(V) n = FacetNormal(msh) F = inner(Dt(u), v)*dx + inner(grad(u), grad(v))*dx - inner(rhs, v)*dx - inner(dot(grad(uexact), n), v)*ds bc = DirichletBC(V, uexact, [1, 2]) luparams = {"mat_type": "aij", "snes_type": "ksponly", "ksp_type": "preonly", "pc_type": "lu"} stepper = TimeStepper(F, butcher_tableau, t, dt, u, bcs=bc, solver_parameters=luparams) while (float(t) < 1.0): if (float(t) + float(dt) > 1.0): dt.assign(1.0 - float(t)) stepper.advance() t.assign(float(t) + float(dt)) return norm(u-uexact)
def StokesTest(N, butcher_tableau, stage_type="deriv", splitting=AI): mesh = UnitSquareMesh(N, N) Ve = VectorElement("CG", mesh.ufl_cell(), 2) Pe = FiniteElement("CG", mesh.ufl_cell(), 1) Ze = MixedElement([Ve, Pe]) Z = FunctionSpace(mesh, Ze) t = Constant(0.0) dt = Constant(1.0/N) (x, y) = SpatialCoordinate(mesh) uexact = as_vector([x*t + y**2, -y*t+t*(x**2)]) pexact = Constant(0, domain=mesh) u_rhs = expand_derivatives(diff(uexact, t)) - div(grad(uexact)) + grad(pexact) p_rhs = -div(uexact) z = Function(Z) test_z = TestFunction(Z) (u, p) = split(z) (v, q) = split(test_z) F = (inner(Dt(u), v)*dx + inner(grad(u), grad(v))*dx - inner(p, div(v))*dx - inner(q, div(u))*dx - inner(u_rhs, v)*dx - inner(p_rhs, q)*dx) bcs = [DirichletBC(Z.sub(0), uexact, "on_boundary")] nsp = [(1, VectorSpaceBasis(constant=True))] u, p = z.split() u.interpolate(uexact) lu = {"mat_type": "aij", "snes_type": "newtonls", "snes_linesearch_type": "l2", "snes_linesearch_monitor": None, "snes_monitor": None, "snes_rtol": 1e-8, "snes_atol": 1e-8, "snes_force_iteration": 1, "ksp_type": "preonly", "pc_type": "lu", "pc_factor_mat_solver_type": "mumps"} stepper = TimeStepper(F, butcher_tableau, t, dt, z, stage_type=stage_type, bcs=bcs, solver_parameters=lu, nullspace=nsp) while (float(t) < 1.0): if (float(t) + float(dt) > 1.0): dt.assign(1.0 - float(t)) stepper.advance() t.assign(float(t) + float(dt)) (u, p) = z.split() return errornorm(uexact, u) + errornorm(pexact, p)
def test_can_split_mixed(W): u = Coefficient(W) v = TestFunction(W) c = Coefficient(W) F = (inner(c, c) * inner(Dt(u), v) + inner(grad(u), grad(v)) + inner(c, v) + inner(Dt(u), v)) * dx split = extract_terms(F) expect_t = (inner(c, c) * inner(Dt(u), v) + inner(Dt(u), v)) * dx expect_no_t = inner(grad(u), grad(v)) * dx + inner(c, v) * dx assert sig(expect_t) == sig(split.time) assert sig(expect_no_t) == sig(split.remainder)
def Fubc(V, uexact, rhs): u = interpolate(uexact, V) v = TestFunction(V) F = inner(Dt(u), v) * dx + inner(grad(u), grad(v)) * dx - inner(rhs, v) * dx bc = DirichletBC(V, uexact, "on_boundary") return (F, u, bc)
def NSETest(butch, stage_type, splitting): N = 16 M = UnitSquareMesh(N, N) V = VectorFunctionSpace(M, "CG", 2) W = FunctionSpace(M, "CG", 1) Z = V * W up = Function(Z) u, p = split(up) v, q = TestFunctions(Z) Re = Constant(100.0) F = (inner(Dt(u), v) * dx + 1.0 / Re * inner(grad(u), grad(v)) * dx + inner(dot(grad(u), u), v) * dx - p * div(v) * dx + div(u) * q * dx ) bcs = [DirichletBC(Z.sub(0), Constant((1, 0)), (4,)), DirichletBC(Z.sub(0), Constant((0, 0)), (1, 2, 3))] nullspace = [(1, VectorSpaceBasis(constant=True))] solver_parameters = {"mat_type": "aij", "snes_type": "newtonls", "snes_linesearch_type": "bt", "snes_linesearch_monitor": None, "snes_monitor": None, "snes_rtol": 1e-10, "snes_atol": 1e-10, "snes_force_iteration": 1, "ksp_type": "preonly", "pc_type": "lu", "pc_factor_mat_solver_type": "mumps"} t = Constant(0.0) dt = Constant(0.3/N) stepper = TimeStepper(F, butch, t, dt, up, bcs=bcs, stage_type="value", solver_parameters=solver_parameters, nullspace=nullspace) tfinal = 1.0 while (float(t) < tfinal): if (float(t) + float(dt) > tfinal): dt.assign(1.0 - float(t)) stepper.advance() t.assign(float(t) + float(dt)) u, p = up.split() return norm(u)
def test_can_split_mixed_split(W): u = Coefficient(W) from ufl import split as splt u0, u1 = splt(u) v = TestFunction(W) v0, v1 = splt(v) c = Coefficient(W) F = (inner(c, c) * inner(Dt(u0), v0) + inner(grad(u), grad(v)) + inner(c, v) + inner(Dt(u), v)) * dx split = extract_terms(F) expect_t = (inner(c, c) * inner(Dt(u0), v0) + inner(Dt(u), v)) * dx expect_no_t = inner(grad(u), grad(v)) * dx + inner(c, v) * dx assert sig(expect_t) == sig(split.time) assert sig(expect_no_t) == sig(split.remainder)
def test_1d_heat_dirichletbc(butcher_tableau): # Boundary values u_0 = Constant(2.0) u_1 = Constant(3.0) N = 100 x0 = 0.0 x1 = 10.0 msh = IntervalMesh(N, x1) V = FunctionSpace(msh, "CG", 1) dt = Constant(10.0 / N) t = Constant(0.0) (x,) = SpatialCoordinate(msh) # Method of manufactured solutions copied from Heat equation demo. S = Constant(2.0) C = Constant(1000.0) B = (x - Constant(x0)) * (x - Constant(x1)) / C R = (x * x) ** 0.5 # Note end linear contribution uexact = ( B * atan(t) * (pi / 2.0 - atan(S * (R - t))) + u_0 + ((x - x0) / x1) * (u_1 - u_0) ) rhs = expand_derivatives(diff(uexact, t)) - div(grad(uexact)) u = interpolate(uexact, V) v = TestFunction(V) F = ( inner(Dt(u), v) * dx + inner(grad(u), grad(v)) * dx - inner(rhs, v) * dx ) bc = [ DirichletBC(V, u_1, 2), DirichletBC(V, u_0, 1), ] luparams = {"mat_type": "aij", "ksp_type": "preonly", "pc_type": "lu"} stepper = TimeStepper( F, butcher_tableau, t, dt, u, bcs=bc, solver_parameters=luparams ) t_end = 2.0 while float(t) < t_end: if float(t) + float(dt) > t_end: dt.assign(t_end - float(t)) stepper.advance() t.assign(float(t) + float(dt)) # Check solution and boundary values assert norm(u - uexact) / norm(uexact) < 10.0 ** -5 assert isclose(u.at(x0), u_0) assert isclose(u.at(x1), u_1)
def test_appctx(): msh = UnitIntervalMesh(2) V = FunctionSpace(msh, "CG", 1) u = Function(V) v = TestFunction(V) F = inner(Dt(u) + u, v) * dx bt = GaussLegendre(1) t = Constant(0.0) dt = Constant(0.1) stepper = TimeStepper(F, bt, t, dt, u, appctx={"hello": "world"}) assert "hello" in stepper.solver._ctx.appctx
def heat(n, deg, time_stages, stage_type="deriv", splitting=IA): N = 2**n msh = UnitIntervalMesh(N) params = { "snes_type": "ksponly", "ksp_type": "preonly", "mat_type": "aij", "pc_type": "lu" } V = FunctionSpace(msh, "CG", deg) x, = SpatialCoordinate(msh) t = Constant(0.0) dt = Constant(2.0 / N) uexact = exp(-t) * sin(pi * x) rhs = expand_derivatives(diff(uexact, t)) - div(grad(uexact)) butcher_tableau = GaussLegendre(time_stages) u = project(uexact, V) v = TestFunction(V) F = (inner(Dt(u), v) * dx + inner(grad(u), grad(v)) * dx - inner(rhs, v) * dx) bc = DirichletBC(V, Constant(0), "on_boundary") stepper = TimeStepper(F, butcher_tableau, t, dt, u, bcs=bc, solver_parameters=params, stage_type=stage_type, splitting=splitting) while (float(t) < 1.0): if (float(t) + float(dt) > 1.0): dt.assign(1.0 - float(t)) stepper.advance() t.assign(float(t) + float(dt)) return errornorm(uexact, u) / norm(uexact)
def test_expecting_time_derivative(V): u = Coefficient(V) v = TestFunction(V) c = Coefficient(V) F = (inner(grad(u), grad(v)) + inner(c, v)) * dx with pytest.raises(ValueError): check_integrals(F.integrals(), expect_time_derivative=True) check_integrals(F.integrals(), expect_time_derivative=False) F += inner(Dt(u), v) * dx with pytest.raises(ValueError): check_integrals(F.integrals(), expect_time_derivative=False)
def RTCFtest(N, deg, butcher_tableau, splitting=AI): msh = UnitSquareMesh(N, N, quadrilateral=True) Ve = FiniteElement("RTCF", msh.ufl_cell(), 2) V = FunctionSpace(msh, Ve) dt = Constant(0.1 / N) t = Constant(0.0) x, y = SpatialCoordinate(msh) uexact = as_vector( [t + 2 * t * x + 4 * t * y, 7 * t + 5 * t * x + 6 * t * y]) rhs = expand_derivatives(diff(uexact, t)) + grad(div(uexact)) u = project(uexact, V) v = TestFunction(V) F = inner(Dt(u), v) * dx + inner(div(u), div(v)) * dx - inner(rhs, v) * dx bc = DirichletBC(V, uexact, "on_boundary") luparams = {"mat_type": "aij", "ksp_type": "preonly", "pc_type": "lu"} stepper = TimeStepper(F, butcher_tableau, t, dt, u, bcs=bc, solver_parameters=luparams, splitting=splitting) while (float(t) < 0.1): if (float(t) + float(dt) > 0.1): dt.assign(0.1 - float(t)) stepper.advance() print(float(t)) t.assign(float(t) + float(dt)) return norm(u - uexact)
def curltest(N, deg, butcher_tableau, splitting): msh = UnitSquareMesh(N, N) Ve = FiniteElement("N1curl", msh.ufl_cell(), 2, variant="integral") V = FunctionSpace(msh, Ve) dt = Constant(0.1 / N) t = Constant(0.0) x, y = SpatialCoordinate(msh) uexact = as_vector([t + 2*t*x + 4*t*y + 3*t*(y**2) + 2*t*x*y, 7*t + 5*t*x + 6*t*y - 3*t*x*y - 2*t*(x**2)]) rhs = expand_derivatives(diff(uexact, t)) + curl(curl(uexact)) u = interpolate(uexact, V) v = TestFunction(V) n = FacetNormal(msh) F = inner(Dt(u), v)*dx + inner(curl(u), curl(v))*dx - inner(curlcross(uexact, n), v)*ds - inner(rhs, v)*dx bc = DirichletBC(V, uexact, [1, 2]) luparams = {"mat_type": "aij", "ksp_type": "preonly", "pc_type": "lu"} stepper = TimeStepper(F, butcher_tableau, t, dt, u, bcs=bc, solver_parameters=luparams, splitting=splitting) while (float(t) < 0.1): if (float(t) + float(dt) > 0.1): dt.assign(0.1 - float(t)) stepper.advance() print(float(t)) t.assign(float(t) + float(dt)) return norm(u-uexact)
def test_Dt_linear(V, typ): u = Coefficient(V) v = TestFunction(V) c = Coefficient(V) F = (inner(grad(u), grad(v)) + inner(c, v) + inner(Dt(u), v)) * dx if typ == "mul": F += inner(Dt(u), c) * inner(Dt(u), v) * dx elif typ == "div": F += inner(Dt(u), v) / Dt(u)[0] * dx elif typ == "sin": F += inner(sin(Dt(u)[0]), v[0]) * dx with pytest.raises(ValueError): check_integrals(F.integrals(), expect_time_derivative=True)
u, p = split(up) n = FacetNormal(msh) dt = Constant(1.0 / 1600) t = Constant(0.0) nu = Constant(0.001) rho = 1.0 r = 0.05 Umean = 1.0 L = 0.1 # define the variational form once outside the loop gamma = Constant(1.e2) F = ( inner(Dt(u), v) * dx + inner(dot(grad(u), u), v) * dx #+ gamma * inner(cell_avg(div(u)), cell_avg(div(v))) * dx + nu * inner(grad(u), grad(v)) * dx - inner(p, div(v)) * dx + inner(div(u), w) * dx) # boundary conditions are specified for each subspace UU = 1.5 * sin(pi * t / 8) bcs = [ DirichletBC(Z.sub(0), as_vector([4 * UU * y * (y1 - y) / (y1**2), 0]), (4, )), DirichletBC(Z.sub(0), Constant((0, 0)), (1, 3, 5)) ] #nullspace = MixedVectorSpaceBasis( # Z, [Z.sub(0), VectorSpaceBasis(constant=True)])
def elastodynamics(N, deg, butcher_tableau, splitting=AI): dt = Constant(1.0 / N) t = Constant(0.0) msh = UnitSquareMesh(N, N) x, y = SpatialCoordinate(msh) V = VectorFunctionSpace(msh, "CG", 1) VV = V * V uu1 = Function(VV) u1, udot1 = uu1.split() u1.interpolate( as_vector([sin(pi * x) * sin(pi * y), sin(pi * x) * sin(pi * y)])) uu2 = Function(VV) u2, udot2 = uu2.split() u2.interpolate( as_vector([sin(pi * x) * sin(pi * y), sin(pi * x) * sin(pi * y)])) u1, udot1 = split(uu1) u2, udot2 = split(uu2) v, w = TestFunctions(VV) F1 = (inner(Dt(u1) - udot1, v) * dx + inner(Dt(udot1), w) * dx + inner(grad(u1), grad(w)) * dx) F2 = (inner(Dt(u2) - udot2, v) * dx + inner(Dt(udot2), w) * dx + inner(grad(u2), grad(w)) * dx) bc1 = DirichletBC(VV.sub(0), Function(VV.sub(0)), "on_boundary") bc2 = [ DirichletBC( VV.sub(0).sub(i), Function(VV.sub(0).sub(i)), "on_boundary") for i in (0, 1) ] luparams = { "mat_type": "aij", "snes_type": "ksponly", "ksp_type": "preonly", "pc_type": "lu" } stepper1 = TimeStepper(F1, butcher_tableau, t, dt, uu1, bcs=bc1, solver_parameters=luparams, splitting=splitting) stepper2 = TimeStepper(F2, butcher_tableau, t, dt, uu2, bcs=bc2, solver_parameters=luparams, splitting=splitting) stepper1.advance() stepper2.advance() return norm(uu1 - uu2)
# This will give the exact solution at any time t. We just have # to t.assign(time_we_want) uexact = exp(-t) * cos(pi * x) * sin(pi * y) # MMS works on symbolic differentiation of true solution, not weak form rhs = expand_derivatives(diff(uexact, t)) - div(grad(uexact)) u = interpolate(uexact, V) # define the variational form once outside the loop h = CellSize(msh) n = FacetNormal(msh) beta = Constant(100.0) v = TestFunction(V) F = (inner(Dt(u), v) * dx + inner(grad(u), grad(v)) * dx - inner(rhs, v) * dx - inner(dot(grad(u), n), v) * ds - inner(dot(grad(v), n), u - uexact) * ds + beta / h * inner(u - uexact, v) * ds) params = { "mat_type": "aij", "snes_type": "ksponly", "ksp_type": "preonly", "pc_type": "lu" } stepper = TimeStepper(F, ButcherTableau, t, dt, u, solver_parameters=params) while (float(t) < 1.0): if (float(t) + float(dt) > 1.0): dt.assign(1.0 - float(t))