def planar_wave(ode, domain, D, S1, threshold, d=5): ''' Finds the conduction velocity of a planar wave. First paces the 0D ode model for 50 cycles at a BCL of 1000, then initiates a single planar wave, measuring the conduction velocity half-way in the domain. ''' # Load the cell model from file cellmodel = load_ode(ode) cellmodel = dolfin_jit(cellmodel, field_states, field_parameters) # Create the CardiacModel for the given domain and cell model heart = CardiacModel(domain, Constant(0.0), D, None, cellmodel) # Create the solver solver = GOSSplittingSolver(heart, GOSSparams()) dolfin_solver = solver.ode_solver ode_solver = dolfin_solver._ode_system_solvers[0] BCL = 1000 try: sspath = "../data/steadystates/" steadystate = np.load(sspath+"steadystate_%s_BCL%d.npy" % (ode, BCL)) except: print "Did not find steadystate for %s at BCL: %g, pacing 0D model" % (ode, BCL) steadystate = find_steadystate(ODE, BCL, 0.01) # Load steadystate into 2D model (u, um) = solver.solution_fields() for node in range(domain.coordinates().shape[0]): ode_solver.states(node)[:] = steadystate u.vector()[node] = steadystate[0] # Define the planar wave stimulus V = VectorFunctionSpace(domain, 'CG', 1) S1 = interpolate(S1, V).vector().array() # Apply the stimulus ode_solver.set_field_parameters(S1) xp = 0; yp = 0; t0 = 0; t1 = 0; for timestep, (u, vm) in solver.solve((0, tstop), dt): #plot(u, **plot_args) x = u.vector()[N/2-d] y = u.vector()[N/2+d] print u.vector().max(), x, y if x > threshold and (x-threshold)*(xp-threshold) < 0: # X cell has activated t0 = timestep[0] if y > threshold and (y-threshold)*(yp-threshold) < 0 and t0 != 0: # Y cell has activated t1 = timestep[0] # Calculate conduction velocity print "CV: ", 2*d*h/(t1-t0)*1e3 break xp = x yp = y
def __init__(self, ode): # Create the domain domain = RectangleMesh(0, 0, L, L, N, N) # Load the cell model from file cellmodel = load_ode(ode) cellmodel = dolfin_jit(cellmodel, field_states, field_parameters) # Create the CardiacModel for the given domain and cell model heart = CardiacModel(domain, Constant(0.0), D, None, cellmodel) # Create the solver solver = GOSSplittingSolver(heart, self.GOSSparams()) # Get the solution fields and subsolvers dolfin_solver = solver.ode_solver ode_solver = dolfin_solver._ode_system_solvers[0] self.solver = solver self.ode = ode self.dolfin_solver = dolfin_solver self.ode_solver = ode_solver self.domain = domain
def pacing_cv(ode, BCL_range, D, L, h, dt): """ Pace a 0D cell model for 50 cycles at given BCL, then simulate a wave in a 1D strand. 5 beats are initiated at the left hand side of the strand, after the fifth beat, the conduction velocity is measured. """ # Create domain N = int(L/h) # number of nodes - 1 domain = IntervalMesh(N, 0, L) # Define functions V = FunctionSpace(domain, 'Lagrange', 1) u = TrialFunction(V) up = Function(V) v = TestFunction(V) # Assemble the mass matrix and the stiffness matrix M = assemble(u*v*dx) K = assemble(Constant(dt)*inner(D*grad(u), grad(v))*dx) A = M + K pde_solver = LUSolver(A) pde_solver.parameters["reuse_factorization"] = True # Set up ODESolver ode = load_ode(ode) compiled_ode = dolfin_jit(ode, field_states=["V"], field_parameters = [ "stim_period"]) params = DOLFINODESystemSolver.default_parameters() params["scheme"] = "RL1" stim_field = interpolate(Expression("near(x[0],0)*sd", sd=1.), V) #compiled_ode.set_parameter("stim_duration", stim_field) BCL = 1000 #compiled_ode.set_parameter("stim_period", BCL) ode_solver = DOLFINODESystemSolver(domain, compiled_ode, params=params) solver = ode_solver._ode_system_solvers[0] try: states = np.load("../data/steadystate_%s_BCL%d.npy" % (ode, BCL)) except: states = find_steadystate(BCL, 50, dt, ode, plot_results=False) for i in range(N+1): solver.states(i)[:] = states up.vector()[i] = solver.states(i)[0] #params = np.zeros((N+1)*2) solver.set_field_parameters(np.array([BCL]+[0]*N, dtype=np.float_)) #stim_field = interpolate(Expression("0"), V) #compiled_ode.set_parameter("stim_duration", stim_field) t = 0. tstop = 1e6 while t < tstop: # Step ODE solver ode_solver.step((t, t+dt), up) # Assemble RHS and solve pde b = M*up.vector() pde_solver.solve(up.vector(), b) # Plot solution plot(up, range_min=-80.0, range_max=40.0) t += dt
def pacing_cv(ode, BCL_range, D, dt, threshold=0, stim_amp=0, plot_args=None): D = Constant(D) # Must be adjusted with temporal and spatial resolution L = 20 h = 0.5 dt_low = 0.1 # Create dolfin mesh N = int(L / h) domain = IntervalMesh(N, 0, L) # Load the cell model from file ode = load_ode(ode) cellmodel = dolfin_jit(ode, field_states=["V"], field_parameters=["stim_period", "stim_amplitude"]) # Create the CardiacModel for the given mesh and cell model heart = CardiacModel(domain, Constant(0.0), D, None, cellmodel) # Create the solver solver = GOSSplittingSolver(heart, GOSSparams()) # Get the solution fields and subsolvers dolfin_solver = solver.ode_solver ode_solver = dolfin_solver._ode_system_solvers[0] results = np.zeros((4, len(BCL_range))) for i, BCL in enumerate(BCL_range): # Set the stimulus parameter field stim_field = np.zeros(2 * (N + 1), dtype=np.float_) stim_field[0] = BCL stim_field[1] = stim_amp ode_solver.set_field_parameters(stim_field) # Pace 0D cell model and find quasi steady state sspath = "../data/steadystates/" try: states = np.load(sspath + "steadystate_%s_BCL%d.npy" % (ode, BCL)) except: print "Did not find steadystate for %s at BCL: %g, pacing 0D model" % ( ode, BCL) find_steadystate(ODE, BCL, 0.01) # Load quasi steady state into 1D model (u, um) = solver.solution_fields() for node in range(N + 1): ode_solver.states(node)[:] = states u.vector()[node] = states[0] # Used for measuring cell activation xp = 0 yp = 0 results[0][i] = BCL print "BCL: %g" % BCL # Do 3 pulses for pulsenr in range(1, 4): # Solve the pulse in higher temporal resolution for timestep, (u, vm) in solver.solve((i * BCL, i * BCL + 50), dt): if plot_args: plot(u, **plot_args) x = u.vector()[20] y = u.vector()[35] if x > threshold and (x - threshold) * (xp - threshold) < 0: t0 = (threshold - xp) / (x - xp) * dt + tp if y > threshold and (y - threshold) * (yp - threshold) < 0: t1 = (threshold - yp) / (y - yp) * dt + tp # Calculate conduction velocity Cv = 15 * h / (t1 - t0) * 1e3 print "\tCv: %g" % Cv results[pulsenr][i] = Cv t0 = 0 t1 = 0 xp = x yp = y tp = timestep[0] # Wait for next pulse for timestep, (u, vm) in solver.solve( (i * BCL + 50, (i + 1) * BCL), dt_low): if plot_args: plot(u, **plot_args) np.save("../data/results/cv_%s" % ode, results)
def spiral(ode, domain, D, S1, S2, plot_args={}, save_fig=False, threshold=0, BCL=500): # Load the cell model from file cellmodel = load_ode(ode) cellmodel = dolfin_jit(cellmodel, field_states, field_parameters) # Create the CardiacModel for the given domain and cell model heart = CardiacModel(domain, Constant(0.0), D, None, cellmodel) # Create the solver solver = GOSSplittingSolver(heart, GOSSparams()) dolfin_solver = solver.ode_solver ode_solver = dolfin_solver._ode_system_solvers[0] # Calculate parameter fields V = VectorFunctionSpace(domain, 'CG', 1) S1 = interpolate(S1, V).vector().array() S2 = interpolate(S2, V).vector().array() nostim = np.zeros(S1.shape, dtype=np.float_) # Read in steady state from file try: sspath = "../data/steadystates/" steadystate = np.load(sspath + "steadystate_%s_BCL%d.npy" % (ode, BCL)) except: print "Did not find steadystate for %s at BCL: %g, pacing 0D model" % ( ode, BCL) steadystate = find_steadystate(ODE, BCL, 0.01) # Load steadystate into 2D model (u, um) = solver.solution_fields() for node in range(domain.coordinates().shape[0]): ode_solver.states(node)[:] = steadystate u.vector()[node] = steadystate[0] cnt = 0 # Stimulate S1 pulse plot(u, interactive=True, **plot_args) ode_solver.set_field_parameters(S1) for timestep, (u, vm) in solver.solve((0, S2_time), dt): fig = plot(u, interactive=False, **plot_args) if save_fig and cnt % 5 == 0: padded_index = '%08d' % cnt fig.write_png('../tmp/randfib2_spiral_%s' % ode + padded_index) cnt += 1 ode_solver.set_field_parameters(S2) # Stimulate S2 pulse for timestep, (u, vm) in solver.solve((S2_time, S2_time + 100), dt): fig = plot(u, interactive=False, **plot_args) if save_fig and cnt % 5 == 0: padded_index = '%08d' % cnt fig.write_png('../tmp/randfib2_spiral_%s' % ode + padded_index) cnt += 1 # Turn of all stimulus and iterate until simulation stop # We monitor the top right corner to find the randfib_spiral period ode_solver.set_field_parameters(nostim) trig_time = [] xp = 0 for timestep, (u, vm) in solver.solve((S2_time + 100, tstop), dt): fig = plot(u, interactive=False, **plot_args) x = u.vector()[-1] if x > threshold and (x - threshold) * (xp - threshold) < 0: trig_time.append(timestep[0]) print "Trigger: %g" % timestep[0] xp = x if save_fig and cnt % 5 == 0: padded_index = '%08d' % cnt fig.write_png('../tmp/randfib2_spiral_%s' % ode + padded_index) cnt += 1
save_fig = True plot_args = { 'range_min': 0., 'range_max': 1., 'mode': 'color', #'window_width': 1366, #'window_height': 744 } ode = 'FK_cAF' domain = Mesh('atrial_mesh.xml') # Load the cell model from file cellmodel = load_ode(ode) cellmodel = dolfin_jit(cellmodel, field_states, field_parameters) def GOSSparams(): params = GOSSplittingSolver.default_parameters() params["pde_solver"] = "monodomain" params["MonodomainSolver"]["linear_solver_type"] = "iterative" params["MonodomainSolver"]["theta"] = 1.0 params["ode_solver"]["scheme"] = "RL1" params["apply_stimulus_current_to_pde"] = False return params # Create the CardiacModel for the given domain and cell model heart = CardiacModel(domain, Constant(0.0), D, None, cellmodel)
def pacing_cv(ode, BCL_range, D, dt, threshold=0, stim_amp=0, plot_args=None): D = Constant(D) # Must be adjusted with temporal and spatial resolution L = 20 h = 0.5 dt_low = 0.1 # Create dolfin mesh N = int(L/h) domain = IntervalMesh(N, 0, L) # Load the cell model from file ode = load_ode(ode) cellmodel = dolfin_jit(ode, field_states=["V"], field_parameters=["stim_period", "stim_amplitude"]) # Create the CardiacModel for the given mesh and cell model heart = CardiacModel(domain, Constant(0.0), D, None, cellmodel) # Create the solver solver = GOSSplittingSolver(heart, GOSSparams()) # Get the solution fields and subsolvers dolfin_solver = solver.ode_solver ode_solver = dolfin_solver._ode_system_solvers[0] results = np.zeros((4, len(BCL_range))) for i, BCL in enumerate(BCL_range): # Set the stimulus parameter field stim_field = np.zeros(2*(N+1), dtype=np.float_) stim_field[0] = BCL stim_field[1] = stim_amp ode_solver.set_field_parameters(stim_field) # Pace 0D cell model and find quasi steady state sspath = "../data/steadystates/" try: states = np.load(sspath+"steadystate_%s_BCL%d.npy" % (ode, BCL)) except: print "Did not find steadystate for %s at BCL: %g, pacing 0D model" % (ode, BCL) find_steadystate(ODE, BCL, 0.01) # Load quasi steady state into 1D model (u, um) = solver.solution_fields() for node in range(N+1): ode_solver.states(node)[:] = states u.vector()[node] = states[0] # Used for measuring cell activation xp = 0; yp=0 results[0][i] = BCL print "BCL: %g" % BCL # Do 3 pulses for pulsenr in range(1,4): # Solve the pulse in higher temporal resolution for timestep, (u, vm) in solver.solve((i*BCL, i*BCL+50), dt): if plot_args: plot(u, **plot_args) x = u.vector()[20] y = u.vector()[35] if x > threshold and (x-threshold)*(xp-threshold) < 0: t0 = (threshold - xp)/(x - xp)*dt + tp if y > threshold and (y-threshold)*(yp-threshold) < 0: t1 = (threshold - yp)/(y - yp)*dt + tp # Calculate conduction velocity Cv = 15*h/(t1-t0)*1e3 print "\tCv: %g" % Cv results[pulsenr][i] = Cv t0 = 0; t1 = 0 xp = x yp = y tp = timestep[0] # Wait for next pulse for timestep, (u, vm) in solver.solve((i*BCL+50, (i+1)*BCL), dt_low): if plot_args: plot(u, **plot_args) np.save("../data/results/cv_%s"%ode, results)
def spiral(ode, domain, D, S1, S2, plot_args={}, save_fig=False, threshold=0, BCL=500): # Load the cell model from file cellmodel = load_ode(ode) cellmodel = dolfin_jit(cellmodel, field_states, field_parameters) # Create the CardiacModel for the given domain and cell model heart = CardiacModel(domain, Constant(0.0), D, None, cellmodel) # Create the solver solver = GOSSplittingSolver(heart, GOSSparams()) dolfin_solver = solver.ode_solver ode_solver = dolfin_solver._ode_system_solvers[0] # Calculate parameter fields V = VectorFunctionSpace(domain, 'CG', 1) S1 = interpolate(S1, V).vector().array() S2 = interpolate(S2, V).vector().array() nostim = np.zeros(S1.shape, dtype=np.float_) # Read in steady state from file try: sspath = "../data/steadystates/" steadystate = np.load(sspath+"steadystate_%s_BCL%d.npy" % (ode, BCL)) except: print "Did not find steadystate for %s at BCL: %g, pacing 0D model" % (ode, BCL) steadystate = find_steadystate(ODE, BCL, 0.01) # Load steadystate into 2D model (u, um) = solver.solution_fields() for node in range(domain.coordinates().shape[0]): ode_solver.states(node)[:] = steadystate u.vector()[node] = steadystate[0] cnt = 0 # Stimulate S1 pulse plot(u, interactive=True, **plot_args) ode_solver.set_field_parameters(S1) for timestep, (u, vm) in solver.solve((0, S2_time), dt): fig = plot(u, interactive=False, **plot_args) if save_fig and cnt % 5 == 0: padded_index = '%08d' % cnt fig.write_png('../tmp/spiral_%s' % ode + padded_index) cnt += 1 ode_solver.set_field_parameters(S2) # Stimulate S2 pulse for timestep, (u, vm) in solver.solve((S2_time, S2_time+100), dt): fig = plot(u, interactive=False, **plot_args) if save_fig and cnt % 5 == 0: padded_index = '%08d' % cnt fig.write_png('../tmp/spiral_%s' % ode + padded_index) cnt += 1 # Turn of all stimulus and iterate until simulation stop # We monitor the top right corner to find the spiral period ode_solver.set_field_parameters(nostim) trig_time = [] xp = 0; for timestep, (u, vm) in solver.solve((S2_time+100, tstop), dt): fig = plot(u, interactive=False, **plot_args) x = u.vector()[-1] if x > threshold and (x-threshold)*(xp-threshold) < 0: trig_time.append(timestep[0]) print "Trigger: %g" % timestep[0] xp = x if save_fig and cnt % 5 == 0: padded_index = '%08d' % cnt fig.write_png('../tmp/spiral_%s' % ode + padded_index) cnt += 1
def pacing_cv(ode, BCL_range, D, L, h, dt): """ Pace a 0D cell model for 50 cycles at given BCL, then simulate a wave in a 1D strand. 5 beats are initiated at the left hand side of the strand, after the fifth beat, the conduction velocity is measured. """ # Create domain N = int(L / h) # number of nodes - 1 domain = IntervalMesh(N, 0, L) # Define functions V = FunctionSpace(domain, 'Lagrange', 1) u = TrialFunction(V) up = Function(V) v = TestFunction(V) # Assemble the mass matrix and the stiffness matrix M = assemble(u * v * dx) K = assemble(Constant(dt) * inner(D * grad(u), grad(v)) * dx) A = M + K pde_solver = LUSolver(A) pde_solver.parameters["reuse_factorization"] = True # Set up ODESolver ode = load_ode(ode) compiled_ode = dolfin_jit(ode, field_states=["V"], field_parameters=["stim_period"]) params = DOLFINODESystemSolver.default_parameters() params["scheme"] = "RL1" stim_field = interpolate(Expression("near(x[0],0)*sd", sd=1.), V) #compiled_ode.set_parameter("stim_duration", stim_field) BCL = 1000 #compiled_ode.set_parameter("stim_period", BCL) ode_solver = DOLFINODESystemSolver(domain, compiled_ode, params=params) solver = ode_solver._ode_system_solvers[0] try: states = np.load("../data/steadystate_%s_BCL%d.npy" % (ode, BCL)) except: states = find_steadystate(BCL, 50, dt, ode, plot_results=False) for i in range(N + 1): solver.states(i)[:] = states up.vector()[i] = solver.states(i)[0] #params = np.zeros((N+1)*2) solver.set_field_parameters(np.array([BCL] + [0] * N, dtype=np.float_)) #stim_field = interpolate(Expression("0"), V) #compiled_ode.set_parameter("stim_duration", stim_field) t = 0. tstop = 1e6 while t < tstop: # Step ODE solver ode_solver.step((t, t + dt), up) # Assemble RHS and solve pde b = M * up.vector() pde_solver.solve(up.vector(), b) # Plot solution plot(up, range_min=-80.0, range_max=40.0) t += dt
D = as_tensor([[Dx, 0.], [0, Dy]]) dt = 0.125 tstop = 25.0 a = Constant(1.) V_init = -85. V_amp = 85. t = Constant(0.) # Domain and solution space do_plot = False L = 100. N = 1024 #N = 128 domain = RectangleMesh(-L, -L, L, L, N, N) cellmodel = dolfin_jit(load_ode("tentusscher_panfilov_2006_M_cell.ode"), field_states=["V"]) heart = CardiacModel(domain, t, D, None, cellmodel) ps = GOSSplittingSolver.default_parameters() ps["pde_solver"] = "monodomain" ps["MonodomainSolver"]["linear_solver_type"] = "iterative" ps["MonodomainSolver"]["theta"] = 1.0 ps["ode_solver"]["solver"] = "RL1" ps["ode_solver"]["num_threads"] = 8 / MPI.size(domain.mpi_comm()) # If cuda ps["ode_solver"]["use_cuda"] = True ps["ode_solver"]["cuda_params"]["float_precision"] = "double" ps["ode_solver"]["cuda_params"]["solver"] = "rush_larsen" ps["apply_stimulus_current_to_pde"] = True
axis = [-80., 40.] save_fig = True plot_args = {'range_min': 0., 'range_max': 1., 'mode': 'color', #'window_width': 1366, #'window_height': 744 } ode = 'FK_cAF' domain = Mesh('atrial_mesh.xml') # Load the cell model from file cellmodel = load_ode(ode) cellmodel = dolfin_jit(cellmodel, field_states, field_parameters) def GOSSparams(): params = GOSSplittingSolver.default_parameters() params["pde_solver"] = "monodomain" params["MonodomainSolver"]["linear_solver_type"] = "iterative" params["MonodomainSolver"]["theta"] = 1.0 params["ode_solver"]["scheme"] = "RL1" params["apply_stimulus_current_to_pde"] = False return params # Create the CardiacModel for the given domain and cell model heart = CardiacModel(domain, Constant(0.0), D, None, cellmodel) # Create the solver solver = GOSSplittingSolver(heart, GOSSparams())