Esempio n. 1
0
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)
Esempio n. 2
0
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)
Esempio n. 3
0
    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.)