Example #1
0
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       
Example #2
0
    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
Example #3
0
    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
Example #4
0
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
Example #5
0
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)
Example #6
0
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)
Example #8
0
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) 
Example #9
0
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
Example #10
0
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
Example #11
0
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())