im_id = sim.add_internal_model(IM)

# set all cells to have the same internal model
sim.set_internal_model(range(NCells),im_id)

# set boundary conditions before setting intercellular interactions
sim.set_boundary_conditions([0],'ref_on')

# cells adjacent to one another are connected
# for diffusion we include main diagonal
# equivalent to 3 wide diagonal
diff_connections = (np.eye(NCells,k=-1) + np.eye(NCells,k=0) + np.eye(NCells,k=1)) > 0

# add diffusion to h and u
sim.add_interaction('h','h','diffusion',diff_connections,params=[Dh/Th])
sim.add_interaction('u','u','diffusion',diff_connections,params=[Du/Tu])

# spi diffusion
sim.add_interaction('sp','sp','diffusion',diff_connections,params=[5.0/Tsp])

'''
# no just lateral connections
# cells adjacent to one another are connected
# for activation, don't inlude main diagonal
hill_connections = (np.eye(NCells,k=-1) + np.eye(NCells,k=1)) > 0

# a -> pnt
sim.add_interaction('a','pnt','hill_activ',hill_connections,params=[1.0,1.5,4])
# a -> notch
sim.add_interaction('a','notch','hill_activ',hill_connections,params=[1.5,0.5,2])
IM2 = InternalModel()
IM2.add_node('a','linear',params=[0.5])
IM2.add_node('b','linear',params=[1])
eid = IM2.add_edge('b','b','hill_activ',params=[1,1,2])
IM2.add_edge('a',eid,'lin_activ',is_mod=True,mod_type='mult',params=[5])

cell1 = Cell([0])
cell2 = Cell([1])
cell3 = Cell([3])

sim = Simulation()
sim.add_cell(cell1)
sim.add_cell(cell2)
sim.add_cell(cell3)

im_id = sim.add_internal_model(IM)
im_id2 = sim.add_internal_model(IM2)

connections = np.array([[True,True,False],[True,True,True],[False,True,True]])

sim.set_internal_model([0,1],im_id)
sim.set_internal_model([2],im_id2)
sim.add_interaction('a','a','diffusion',connections,params=[1])

sim.set_initial_conditions([0],{'a':0})
sim.set_initial_conditions([1],{'a':6})
sim.set_initial_conditions([2],{'a':0,'b':1})

t = np.linspace(0,10,100)
cdata = sim.simulate(t)
# calculate custom square distance matrix for periodic boundary conditions on diffusion
Dmat = np.zeros((NCells,NCells))
for i in xrange(NCells):
    for j in xrange(NCells):
        dx,dy = abs(centers[i,:] - centers[j,:]) # take absolute value to order h to l
        # check if connecting outer boundaries
        lr_connect =  (i % ncolumns == 0 and j % ncolumns == ncolumns - 1)
        rl_connect = (i % ncolumns == ncolumns - 1 and j % ncolumns == 0)
        if lr_connect or rl_connect:
            # we're connecting boundaries
            dx = dx - ncolumns
        Dmat[i,j] = dx ** 2 + dy ** 2

# add diffusion to h and u
# try using custom square distance matrix for period BC
sim.add_interaction('h','h','diffusion',connections,params=([Dh/Th],Dmat))
sim.add_interaction('u','u','diffusion',connections,params=([Du/Tu],Dmat))

# start with only first cell up
low_dict = {'a':0.0,'s':0.0,'h':0.0,'u':0.0}
med_dict = {'a':0.0,'s':0.0,'h':0.015,'u':4e-6} # start with some h and u in template
high_dict = {'a':1.0+F,'s':1.0,'h':0.015,'u':4e-6} # start with some h and u (0.015 ss)
sim.set_initial_conditions(range(0,NCells),low_dict)
# templating different numbers of rows of R8s
ntemplate = 8
sim.set_initial_conditions(range(0,ncolumns*(4*(ntemplate-1)+1)),med_dict)
high_cells = []
for i in xrange(ntemplate):
    if i % 2 == 0:
        high_cells += [ncolumns*4*i+4,ncolumns*4*i+12]
    else:
    sim.add_cell(cells[i])

im_id = sim.add_internal_model(IM)

# set all cells to have the same internal model
sim.set_internal_model(range(NCells),im_id)

# set boundary condition
sim.set_boundary_conditions([0],'ref_on')

# cells adjacent to one another are connected
# equivalent to 3 wide diagonal
connections = (np.eye(NCells,k=-1) + np.eye(NCells,k=0) + np.eye(NCells,k=1)) > 0

# add diffusion to h and u
sim.add_interaction('h','h','diffusion',connections,params=[Dh/Th])
sim.add_interaction('u','u','diffusion',connections,params=[Du/Tu])

# start with only first cell up
low_dict = {'a':0.0,'s':0.0,'h':0.0,'u':0.0}
high_dict = {'a':1.0+F,'s':1.0,'h':0.0,'u':0.0}
sim.set_initial_conditions(range(1,NCells),low_dict)
sim.set_initial_conditions([0],high_dict)

print 'starting simulation'
t = np.linspace(0,300,200)
cdata = sim.simulate(t)
print 'simulation done'


import matplotlib.pyplot as plt