def test_fitzhugh(): parameters["reorder_dofs_serial"] = False parameters["form_compiler"]["cpp_optimize"] = True parameters["form_compiler"]["optimize"] = True # Set-up cardiac model heart = setup_model() # Set-up solver ps = BasicSplittingSolver.default_parameters() ps["BasicBidomainSolver"]["linear_variational_solver"][ "linear_solver"] = "direct" ps["BasicBidomainSolver"]["theta"] = 1.0 ps["theta"] = 1.0 ps["BasicCardiacODESolver"]["S_polynomial_family"] = "CG" ps["BasicCardiacODESolver"]["S_polynomial_degree"] = 1 ps["BasicCardiacODESolver"]["V_polynomial_family"] = "CG" ps["BasicCardiacODESolver"]["V_polynomial_degree"] = 1 solver = BasicSplittingSolver(heart, ps) # Define end-time and (constant) timesteps dt = 0.25 # mS T = 1.0 # + 1.e-6 # mS # Define initial condition(s) ic = InitialCondition(degree=1) # Should use degree=0 here for # correctness, but to match # reference, using 1 vs0 = project(ic, solver.VS) (vs_, vs, u) = solver.solution_fields() vs_.assign(vs0) # Solve solutions = solver.solve((0, T), dt) for (timestep, (vs_, vs, vur)) in solutions: continue u = project(vur[1], vur.function_space().sub(1).collapse()) norm_u = norm(u) reference = 10.3756526773 print(("norm_u = ", norm_u)) print(("reference = ", reference)) assert_almost_equal(reference, norm_u, 1.e-4)
def main(N, dt, T, theta): if dolfin_adjoint: adj_reset() # Create cardiac model mesh = UnitSquareMesh(N, N) time = Constant(0.0) cell_model = NoCellModel() ac_str = "cos(t)*cos(2*pi*x[0])*cos(2*pi*x[1]) + 4*pow(pi, 2)*cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)" stimulus = Expression(ac_str, t=time, degree=3) heart = CardiacModel(mesh, time, 1.0, 1.0, cell_model, stimulus=stimulus) # Set-up solver ps = BasicSplittingSolver.default_parameters() ps["theta"] = theta ps["BasicBidomainSolver"]["linear_variational_solver"][ "linear_solver"] = "direct" solver = BasicSplittingSolver(heart, params=ps) # Define exact solution (Note: v is returned at end of time # interval(s), u is computed at somewhere in the time interval # depending on theta) v_exact = Expression("cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)", t=T, degree=3) u_exact = Expression("-cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)/2.0", t=T - (1 - theta) * dt, degree=3) # Define initial condition(s) vs0 = Function(solver.VS) (vs_, vs, vur) = solver.solution_fields() vs_.assign(vs0) # Solve solutions = solver.solve((0, T), dt) for (timestep, (vs_, vs, vur)) in solutions: continue # Compute errors (v, s) = vs.split(deepcopy=True) v_error = errornorm(v_exact, v, "L2", degree_rise=2) (v, u, r) = vur.split(deepcopy=True) u_error = errornorm(u_exact, u, "L2", degree_rise=2) return (v_error, u_error, mesh.hmin(), dt, T)
def test_basic_and_optimised_splitting_solver_exact(self, solver_type): """Test that basic and optimised splitting solvers yield very comparative results when configured identically.""" # Create basic solver params = BasicSplittingSolver.default_parameters() params["BasicCardiacODESolver"]["S_polynomial_family"] = "CG" params["BasicCardiacODESolver"]["S_polynomial_degree"] = 1 solver = BasicSplittingSolver(self.cardiac_model, params=params) (vs_, vs, vur) = solver.solution_fields() vs_.assign(self.ics) # Solve solutions = solver.solve((self.t0, self.T), self.dt) for (interval, fields) in solutions: (vs_, vs, vur) = fields a = vs.vector().norm("l2") c = vur.vector().norm("l2") assert_almost_equal(interval[1], self.T, 1e-10) if dolfin_adjoint: adj_reset() # Create optimised solver with direct solution algorithm params = SplittingSolver.default_parameters() params["BidomainSolver"]["linear_solver_type"] = solver_type params["enable_adjoint"] = False if solver_type == "direct": params["BidomainSolver"]["use_avg_u_constraint"] = True solver = SplittingSolver(self.cardiac_model, params=params) (vs_, vs, vur) = solver.solution_fields() vs_.assign(self.ics) # Solve again solutions = solver.solve((self.t0, self.T), self.dt) for (interval, fields) in solutions: (vs_, vs, vur) = fields assert_almost_equal(interval[1], self.T, 1e-10) b = vs.vector().norm("l2") d = vur.vector().norm("l2") print "a, b = ", a, b print "c, d = ", c, d print "a - b = ", (a - b) print "c - d = ", (c - d) # Compare results, discrepancy is in difference in ODE # solves. assert_almost_equal(a, b, tolerance=1.) assert_almost_equal(c, d, tolerance=1.)