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()
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()
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
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))
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)