Exemple #1
0
    def setup(self):
        self.mesh = UnitCubeMesh(5, 5, 5)

        # Create time
        self.time = Constant(0.0)

        # Create stimulus
        self.stimulus = Expression("2.0*t", t=self.time, degree=1)

        # Create ac
        self.applied_current = Expression("sin(2*pi*x[0])*t",
                                          t=self.time,
                                          degree=3)

        # Create conductivity "tensors"
        self.M_i = 1.0
        self.M_e = 2.0

        self.cell_model = FitzHughNagumoManual()
        self.cardiac_model = CardiacModel(self.mesh, self.time, self.M_i,
                                          self.M_e, self.cell_model,
                                          self.stimulus, self.applied_current)

        dt = 0.1
        self.t0 = 0.0
        self.dt = [(0.0, dt), (dt * 2, dt / 2), (dt * 4, dt)]
        # Test using variable dt interval but using the same dt.

        self.T = self.t0 + 5 * dt
        self.ics = self.cell_model.initial_conditions()
Exemple #2
0
        def __init__(self):
            self.mesh = UnitCubeMesh(5, 5, 5)

            # Create time
            self.time = Constant(0.0)

            # Create stimulus
            self.stimulus = Expression("2.0*t", t=self.time, degree=1)

            # Create ac
            self.applied_current = Expression("sin(2*pi*x[0])*t",
                                              t=self.time,
                                              degree=3)

            # Create conductivity "tensors"
            self.M_i = 1.0
            self.M_e = 2.0

            self.cell_model = FitzHughNagumoManual()
            self.cardiac_model = CardiacModel(self.mesh, self.time, self.M_i,
                                              self.M_e, self.cell_model,
                                              self.stimulus,
                                              self.applied_current)

            dt = 0.1
            self.t0 = 0.0
            if Solver == SplittingSolver:
                # FIXME: Dolfin-adjoint fails with adaptive timestep and SplittingSolver
                self.dt = dt
            else:
                self.dt = [(0.0, dt), (dt * 2, dt / 2), (dt * 4, dt)]
            # Test using variable dt interval but using the same dt.

            self.T = self.t0 + 5 * dt

            # Create solver object
            params = Solver.default_parameters()

            if Solver == SplittingSolver:
                params.enable_adjoint = enable_adjoint
                params.BidomainSolver.linear_solver_type = solver_type
                params.BidomainSolver.petsc_krylov_solver.relative_tolerance = 1e-12
            else:
                params.BasicBidomainSolver.linear_variational_solver.linear_solver = \
                                "gmres" if solver_type == "iterative" else "lu"
                params.BasicBidomainSolver.linear_variational_solver.krylov_solver.relative_tolerance = 1e-12
                params.BasicBidomainSolver.linear_variational_solver.preconditioner = 'ilu'

            self.solver = Solver(self.cardiac_model, params=params)
            (vs_, vs, vur) = self.solver.solution_fields()

            if ics is None:
                self.ics = self.cell_model.initial_conditions()
                vs_.assign(self.ics)
            else:
                vs_.vector()[:] = ics.vector()
Exemple #3
0
    def _setup_solver(self, Model, Scheme, time=0.0, stim=None, params=None):
        ''' Generate a new solver object with the given start time, stimulus and parameters. '''
        # Create model instance
        if isinstance(Model, str):
            Model = eval(Model)
        model = Model(params=params)

        # Initialize time and stimulus (note t=time construction!)
        if stim is None:
            stim = Expression("1000*t", t=time, degree=1)

        # Initialize solver
        mesh = UnitIntervalMesh(5)
        params = CardiacODESolver.default_parameters()
        params["scheme"] = Scheme

        solver = CardiacODESolver(mesh, time, model, I_s=stim, params=params)

        # Create scheme
        info_green("\nTesting %s with %s scheme" % (model, Scheme))

        # Start with native initial conditions
        (vs_, vs) = solver.solution_fields()
        vs_.assign(model.initial_conditions())
        vs.assign(vs_)

        return solver
Exemple #4
0
    def test_default_basic_single_cell_solver(self, cell_model, theta):
        "Test basic single cell solver."
        time = Constant(0.0)
        model = cell_model
        Model = cell_model.__class__

        if Model == supported_cell_models[3] and theta > 0:
            pytest.xfail("failing configuration (but should work)")

        model.stimulus = Expression("1000*t", t=time, degree=1)

        info_green("\nTesting %s" % model)
        vec_solve = self._run_solve(model, time, theta)

        if Model == supported_cell_models[3] and theta == 0:
            pytest.xfail("failing configuration (but should work)")

        if Model in self.references and theta in self.references[Model]:
            ind, ref_value = self.references[Model][theta]
            print("vec_solve", vec_solve.get_local())
            print("ind", ind, "ref", ref_value)

            assert_almost_equal(vec_solve[ind], ref_value, 1e-10)
        else:
            info_red("Missing references for %r, %r" % (Model, theta))
Exemple #5
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)
    def setup(self):
        self.mesh = UnitCubeMesh(5, 5, 5)
        self.time = Constant(0.0)

        # Create stimulus
        self.stimulus = Expression("2.0", degree=1)

        # Create applied current
        self.applied_current = Expression("sin(2*pi*x[0])*t", t=self.time,
                                          degree=3)

        # Create conductivity "tensors"
        self.M_i = 1.0
        self.M_e = 2.0

        self.t0 = 0.0
        self.dt = 0.1
        self.T = 5*self.dt
    def _setup_solver(self, model, Scheme, mesh):

        # Initialize time and stimulus (note t=time construction!)
        time = Constant(0.0)
        stim = Expression("(time >= stim_start) && (time < stim_start + stim_duration)"
                          " ? stim_amplitude : 0.0 ", time=time, stim_amplitude=52.0,
                          stim_start=0.0, stim_duration=1.0, name="stim", degree=1)

        # Initialize solver
        params = CardiacODESolver.default_parameters()
        params["scheme"] = Scheme
        solver = CardiacODESolver(mesh, time, model, I_s=stim, params=params)

        return solver
def test_solver_with_domains():

    mesh = UnitCubeMesh(5, 5, 5)
    time = Constant(0.0)

    stimulus = Expression("2.0*t", t=time, degree=1)

    # Create ac
    applied_current = Expression("sin(2*pi*x[0])*t", t=time, degree=3)

    # Create conductivity "tensors"
    M_i = 1.0
    M_e = 2.0

    cell_model = FitzHughNagumoManual()
    cardiac_model = CardiacModel(mesh, time, M_i, M_e, cell_model,
                                 stimulus, applied_current)

    dt = 0.1
    t0 = 0.0
    dt = dt
    T = t0 + 5*dt

    ics = cell_model.initial_conditions()

    # Create basic solver
    params = SplittingSolver.default_parameters()
    params["ode_solver_choice"] = "BasicCardiacODESolver"
    solver = SplittingSolver(cardiac_model, params=params)

    (vs_, vs, vur) = solver.solution_fields()
    vs_.assign(ics)

    # Solve
    solutions = solver.solve((t0, T), dt)
    for (interval, fields) in solutions:
        (vs_, vs, vur) = fields
    def _setup_solver(self, Model, Scheme, mesh, time, stim=None, params=None):
        # Create model instance
        model = Model(params=params)

        # Initialize time and stimulus (note t=time construction!)
        if stim is None:
            stim = Expression("1000*t", t=time, degree=1)

        # Initialize solver
        params = CardiacODESolver.default_parameters()
        params["scheme"] = Scheme
        solver = CardiacODESolver(mesh, time, model, I_s=stim, params=params)

        # Create scheme
        info_green("\nTesting %s with %s scheme" % (model, Scheme))

        # Start with native initial conditions
        (vs_, vs) = solver.solution_fields()
        vs_.assign(model.initial_conditions())
        vs.assign(vs_)

        return solver
    def long_run_compare(self):
        mesh = UnitIntervalMesh(5)

        # FIXME: We need to make this run in paralell.
        if MPI.size(mesh.mpi_comm()) > 1:
            return

        Model = Tentusscher_2004_mcell
        tstop = 10
        ind_V = 0
        dt_ref = 0.1
        time_ref = np.linspace(0, tstop, int(tstop/dt_ref)+1)
        dir_path = os.path.dirname(__file__)
        Vm_reference = np.fromfile(os.path.join(dir_path, "Vm_reference.npy"))
        params = Model.default_parameters()

        time = Constant(0.0)
        stim = Expression("(time >= stim_start) && (time < stim_start + stim_duration)"\
                             " ? stim_amplitude : 0.0 ", time=time, stim_amplitude=52.0, \
                             stim_start=1.0, stim_duration=1.0, degree=1)

        # Initiate solver, with model and Scheme
        if dolfin_adjoint:
            adj_reset()

        solver = self._setup_solver(Model, Scheme, mesh, time, stim, params)
        solver._pi_solver.parameters["newton_solver"]["relative_tolerance"] = 1e-8
        solver._pi_solver.parameters["newton_solver"]["maximum_iterations"] = 30
        solver._pi_solver.parameters["newton_solver"]["report"] = False

        scheme = solver._scheme
        (vs_, vs) = solver.solution_fields()

        vs.assign(vs_)

        dof_to_vertex_map_values = dof_to_vertex_map(vs.function_space())
        scheme.t().assign(0.0)

        vs_array = np.zeros(mesh.num_vertices()*\
                            vs.function_space().dofmap().num_entity_dofs(0))
        vs_array[dof_to_vertex_map_values] = vs.vector().array()
        output = [vs_array[ind_V]]
        time_output = [0.0]
        dt = dt_org

        # Time step
        next_dt = max(min(tstop-float(scheme.t()), dt), 0.0)
        t0 = 0.0

        while next_dt > 0.0:

            # Step solver
            solver.step((t0, t0 + next_dt))
            vs_.assign(vs)

            # Collect plt output data
            vs_array[dof_to_vertex_map_values] = vs.vector().array()
            output.append(vs_array[ind_V])
            time_output.append(float(scheme.t()))

            # Next time step
            t0 += next_dt
            next_dt = max(min(tstop-float(scheme.t()), dt), 0.0)

        # Compare solution from CellML run using opencell
        assert_almost_equal(output[-1], Vm_reference[-1], abs_tol)

        output = np.array(output)
        time_output = np.array(time_output)

        output = np.interp(time_ref, time_output, output)

        value = np.sqrt(np.sum(((Vm_reference-output)/Vm_reference)**2))/len(Vm_reference)
        assert_almost_equal(value, 0.0, rel_tol)