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 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
print "done." # Get the solution fields (u, um) = solver.solution_fields() # Load steadystate into 2D model for i in range(domain.coordinates().shape[0]): ode_solver.states(i)[:] = steadystate u.vector()[i] = 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, 10), dt): fig = plot(u, interactive=False, **plot_args) if save_fig and cnt % 10 == 0: padded_index = '%08d' % cnt fig.write_png('../tmp/atrial_spiral_%s' % ode + padded_index) cnt += 1 ode_solver.set_field_parameters(S2) # Stimulate S2 pulse for timestep, (u, vm) in solver.solve((10, S2_time + 5 * stim_period), dt): fig = plot(u, interactive=False, **plot_args) if save_fig and cnt % 10 == 0: padded_index = '%08d' % cnt
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
"V_amp/2.*(1+tanh(-sqrt(a/(8*D))*2*sqrt(x[0]*x[0]+x[1]*x[1])/r))+V_init", r=20., a=a, D=Dx, V_init=V_init, V_amp=V_amp) u.interpolate(init_expr) # Plot solution if do_plot: plot(u, scale=1., range_min=-90., range_max=40.) # Iterate t = 0. for timestep, (u, vm) in solver.solve((0, tstop), dt): # plot solution if do_plot: plot(u, scale=1., range_min=-90., range_max=40.) if MPI.rank(domain.mpi_comm()) == 0: print timestep[0], "Min:", u.vector().min(), "Max:", u.vector().max() else: u.vector().min() u.vector().max() if MPI.rank(domain.mpi_comm()) == 0: list_timings() interactive()
print "done." # Get the solution fields (u, um) = solver.solution_fields() # Load steadystate into 2D model for i in range(domain.coordinates().shape[0]): ode_solver.states(i)[:] = steadystate u.vector()[i] = 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, 10), dt): fig = plot(u, interactive=False, **plot_args) if save_fig and cnt % 10 == 0: padded_index = '%08d' % cnt fig.write_png('../tmp/atrial_spiral_%s' % ode + padded_index) cnt += 1 ode_solver.set_field_parameters(S2) # Stimulate S2 pulse for timestep, (u, vm) in solver.solve((10, S2_time+5*stim_period), dt): fig = plot(u, interactive=False, **plot_args) if save_fig and cnt % 10 == 0: padded_index = '%08d' % cnt