def setUp(self): mdl = smodel.Model() S1 = smodel.Spec('S1', mdl) ssys = smodel.Surfsys('ssys', mdl) smodel.SReac('SR01', ssys, slhs=[S1], srhs=[S1], kcst=1) if __name__ == "__main__": mesh = meshio.importAbaqus('meshes/test.inp', 1e-7)[0] else: mesh = meshio.importAbaqus( 'tetODE_setPatchSReacK_bugfix_test/meshes/test.inp', 1e-7)[0] comp1 = sgeom.TmComp('comp1', mesh, range(mesh.countTets())) patch1 = sgeom.TmPatch('patch1', mesh, mesh.getSurfTris(), comp1) patch1.addSurfsys('ssys') rng = srng.create('mt19937', 512) rng.initialize(1234) self.sim = ssolver.TetODE(mdl, mesh, rng) self.sim.setTolerances(1.0e-3, 1.0e-3)
def init_sim(model, mesh, seed, param): # previous setup # rng = srng.create('r123', 512) # rng.initialize(seed) # sim = ssolver.Tetexact(model, mesh, rng, True) # Create the solver objects if param['SSA_solver'] == 'TetODE': sim = ssolver.TetODE(model, mesh, calcMembPot=sim_parameters['EF_solver']) sim.setTolerances(1.0e-6, 1e-6) elif param['SSA_solver'] == 'Tetexact': rng = srng.create('mt19937', 512) rng.initialize(seed) sim = ssolver.Tetexact(model, mesh, rng, calcMembPot=sim_parameters['EF_solver']) sim.reset() sim.setEfieldDT(param['EF_dt']) else: raise ValueError('SSA solver ' + param['SSA_solver'] + 'not available') print('Running Rallpack1 test with ' + param['SSA_solver']) # Correction factor for deviation between mesh and model cylinder: area_cylinder = np.pi * param['diameter'] * param['length'] area_mesh_factor = sim.getPatchArea('memb') / area_cylinder # Set initial conditions memb = sgeom.castToTmPatch(mesh.getPatch('memb')) for t in memb.tris: sim.setTriCount(t, 'Leak', 1) sim.setMembPotential('membrane', param['E_M']) sim.setMembVolRes('membrane', param['R_A']) sim.setMembCapac('membrane', param['C_M'] / area_mesh_factor) v_zmin = mesh.getROIData('v_zmin') I = param['Iinj'] / len(v_zmin) for v in v_zmin: sim.setVertIClamp(v, I) return sim
def run_sim(): # Set up and run the simulations once, before the tests # analyze the results. ##################### First order irreversible ######################### global KCST_foi, N_foi, tolerance_foi KCST_foi = 5 # The reaction constant N_foi = 50 # Can set count or conc NITER_foi = 1 # The number of iterations # Tolerance for the comparison: tolerance_foi = 1.0e-4 / 100 ####################### First order reversible ######################### global KCST_f_for, KCST_b_for, COUNT_for, tolerance_for KCST_f_for = 20.0 # The reaction constant KCST_b_for = 5.0 COUNT_for = 100000 # Can set count or conc NITER_for = 1 # The number of iterations tolerance_for = 1.0e-4 / 100 ####################### Second order irreversible A2 ################### global KCST_soA2, CONCA_soA2, tolerance_soA2 KCST_soA2 = 10.0e6 # The reaction constant CONCA_soA2 = 10.0e-6 NITER_soA2 = 1 # The number of iterations tolerance_soA2 = 1.0e-4 / 100 ####################### Second order irreversible AA ################### global KCST_soAA, CONCA_soAA, CONCB_soAA, tolerance_soAA KCST_soAA = 5.0e6 # The reaction constant CONCA_soAA = 20.0e-6 CONCB_soAA = CONCA_soAA NITER_soAA = 1 # The number of iterations tolerance_soAA = 1.0e-4 / 100 ####################### Second order irreversible AB ################### global KCST_soAB, CONCA_soAB, CONCB_soAB, tolerance_soAB KCST_soAB = 5.0e6 # The reaction constant CONCA_soAB = 1.0e-6 n_soAB = 2 CONCB_soAB = CONCA_soAB / n_soAB NITER_soAB = 1 # The number of iterations tolerance_soAB = 1.0e-4 / 100 ####################### Third order irreversible A3 ################### global KCST_toA3, CONCA_toA3, tolerance_toA3 KCST_toA3 = 1.0e12 # The reaction constant CONCA_toA3 = 10.0e-6 NITER_toA3 = 1 # The number of iterations tolerance_toA3 = 1.0e-4 / 100 ####################### Third order irreversible A2B ################### global KCST_toA2B, CONCA_toA2B, CONCB_toA2B, tolerance_toA2B KCST_toA2B = 0.1e12 # The reaction constant CONCA_toA2B = 30.0e-6 CONCB_toA2B = 20.0e-6 NITER_toA2B = 1 # The number of iterations tolerance_toA2B = 1.0e-4 / 100 ####################### Second order irreversible 2D ################### global COUNTA_so2d, COUNTB_so2d, CCST_so2d, tolerance_so2d COUNTA_so2d = 100.0 n_so2d = 2.0 COUNTB_so2d = COUNTA_so2d / n_so2d KCST_so2d = 10.0e10 # The reaction constant AREA_so2d = 10.0e-12 NITER_so2d = 1 # The number of iterations tolerance_so2d = 1.0e-4 / 100 ############################ Common parameters ######################## global VOL DT = 0.1 # Sampling time-step INT = 1.1 # Sim endtime NITER_max = 1 ######################################################################## mdl = smod.Model() volsys = smod.Volsys('vsys', mdl) surfsys = smod.Surfsys('ssys', mdl) # First order irreversible A_foi = smod.Spec('A_foi', mdl) A_foi_diff = smod.Diff('A_foi_diff', volsys, A_foi, 0.01e-12) R1_foi = smod.Reac('R1_foi', volsys, lhs=[A_foi], rhs=[], kcst=KCST_foi) # First order reversible A_for = smod.Spec('A_for', mdl) B_for = smod.Spec('B_for', mdl) A_for_diff = smod.Diff('A_for_diff', volsys, A_for, 0.01e-12) B_for_diff = smod.Diff('B_for_diff', volsys, B_for, 0.01e-12) R1_for = smod.Reac('R1_for', volsys, lhs=[A_for], rhs=[B_for], kcst=KCST_f_for) R2_for = smod.Reac('R2_for', volsys, lhs=[B_for], rhs=[A_for], kcst=KCST_b_for) # Second order irreversible A2 A_soA2 = smod.Spec('A_soA2', mdl) C_soA2 = smod.Spec('C_soA2', mdl) A_soA2_diff = smod.Diff('A_soA2_diff', volsys, A_soA2, 1e-12) R1_soA2 = smod.Reac('R1_soA2', volsys, lhs=[A_soA2, A_soA2], rhs=[C_soA2], kcst=KCST_soA2) # Second order irreversible AA A_soAA = smod.Spec('A_soAA', mdl) B_soAA = smod.Spec('B_soAA', mdl) C_soAA = smod.Spec('C_soAA', mdl) A_soAA_diff = smod.Diff('A_soAA_diff', volsys, A_soAA, 0.2e-12) B_soAA_diff = smod.Diff('B_soAA_diff', volsys, B_soAA, 0.2e-12) R1_soAA = smod.Reac('R1_soAA', volsys, lhs=[A_soAA, B_soAA], rhs=[C_soAA], kcst=KCST_soAA) # Second order irreversible AB A_soAB = smod.Spec('A_soAB', mdl) B_soAB = smod.Spec('B_soAB', mdl) C_soAB = smod.Spec('C_soAB', mdl) A_soAB_diff = smod.Diff('A_soAB_diff', volsys, A_soAB, 0.1e-12) B_soAB_diff = smod.Diff('B_soAB_diff', volsys, B_soAB, 0.1e-12) R1_soAB = smod.Reac('R1_soAB', volsys, lhs=[A_soAB, B_soAB], rhs=[C_soAB], kcst=KCST_soAB) # Third order irreversible A3 A_toA3 = smod.Spec('A_toA3', mdl) C_toA3 = smod.Spec('C_toA3', mdl) A_soA3_diff = smod.Diff('A_soA3_diff', volsys, A_toA3, 0.2e-12) R1_toA3 = smod.Reac('R1_toA3', volsys, lhs=[A_toA3, A_toA3, A_toA3], rhs=[C_toA3], kcst=KCST_toA3) # Third order irreversible A2B A_toA2B = smod.Spec('A_toA2B', mdl) B_toA2B = smod.Spec('B_toA2B', mdl) C_toA2B = smod.Spec('C_toA2B', mdl) A_soA2B_diff = smod.Diff('A_soA2B_diff', volsys, A_toA2B, 0.1e-12) B_soA2B_diff = smod.Diff('B_soA2B_diff', volsys, B_toA2B, 0.1e-12) R1_toA3 = smod.Reac('R1_toA2B', volsys, lhs=[A_toA2B, A_toA2B, B_toA2B], rhs=[C_toA2B], kcst=KCST_toA2B) # Second order irreversible 2D A_so2d = smod.Spec('A_so2d', mdl) B_so2d = smod.Spec('B_so2d', mdl) C_so2d = smod.Spec('C_so2d', mdl) A_so2d_diff = smod.Diff('A_so2d_diff', surfsys, A_so2d, 1.0e-12) B_so2d_diff = smod.Diff('B_so2d_diff', surfsys, B_so2d, 1.0e-12) SR1_so2d = smod.SReac('SR1_so2d', surfsys, slhs=[A_so2d, B_so2d], srhs=[C_so2d], kcst=KCST_so2d) mesh = smeshio.importAbaqus('validation_rd/meshes/sphere_rad1_37tets.inp', 1e-6)[0] VOL = mesh.getMeshVolume() comp1 = sgeom.TmComp('comp1', mesh, range(mesh.ntets)) comp1.addVolsys('vsys') patch1 = sgeom.TmPatch('patch1', mesh, mesh.getSurfTris(), comp1) patch1.addSurfsys('ssys') CCST_so2d = KCST_so2d / (6.02214179e23 * patch1.getArea()) rng = srng.create('r123', 512) rng.initialize(1000) sim = ssolv.TetODE(mdl, mesh, rng) sim.setTolerances(1e-9, 1e-7) global tpnts, ntpnts tpnts = numpy.arange(0.0, INT, DT) ntpnts = tpnts.shape[0] res_m_foi = numpy.zeros([NITER_foi, ntpnts, 1]) res_m_for = numpy.zeros([NITER_for, ntpnts, 2]) res_m_soA2 = numpy.zeros([NITER_soA2, ntpnts, 2]) res_m_soAA = numpy.zeros([NITER_soAA, ntpnts, 3]) res_m_soAB = numpy.zeros([NITER_soAB, ntpnts, 3]) res_m_toA3 = numpy.zeros([NITER_toA3, ntpnts, 2]) res_m_toA2B = numpy.zeros([NITER_toA2B, ntpnts, 3]) res_m_so2d = numpy.zeros([NITER_so2d, ntpnts, 3]) for i in range(0, NITER_max): if i < NITER_foi: sim.setCompCount('comp1', 'A_foi', N_foi) if i < NITER_for: sim.setCompCount('comp1', 'A_for', COUNT_for) sim.setCompCount('comp1', 'B_for', 0.0) if i < NITER_soA2: sim.setCompConc('comp1', 'A_soA2', CONCA_soA2) if i < NITER_soAA: sim.setCompConc('comp1', 'A_soAA', CONCA_soAA) sim.setCompConc('comp1', 'B_soAA', CONCB_soAA) if i < NITER_soAB: sim.setCompConc('comp1', 'A_soAB', CONCA_soAB) sim.setCompConc('comp1', 'B_soAB', CONCB_soAB) if i < NITER_toA3: sim.setCompConc('comp1', 'A_toA3', CONCA_toA3) if i < NITER_toA2B: sim.setCompConc('comp1', 'A_toA2B', CONCA_toA2B) sim.setCompConc('comp1', 'B_toA2B', CONCB_toA2B) if i < NITER_so2d: sim.setPatchCount('patch1', 'A_so2d', COUNTA_so2d) sim.setPatchCount('patch1', 'B_so2d', COUNTB_so2d) for t in range(0, ntpnts): sim.run(tpnts[t]) if i < NITER_foi: res_m_foi[i, t, 0] = sim.getCompCount('comp1', 'A_foi') if i < NITER_for: res_m_for[i, t, 0] = sim.getCompConc('comp1', 'A_for') * 1e6 res_m_for[i, t, 1] = sim.getCompConc('comp1', 'B_for') * 1e6 if i < NITER_soA2: res_m_soA2[i, t, 0] = sim.getCompConc('comp1', 'A_soA2') if i < NITER_soAA: res_m_soAA[i, t, 0] = sim.getCompConc('comp1', 'A_soAA') res_m_soAA[i, t, 1] = sim.getCompConc('comp1', 'B_soAA') if i < NITER_soAB: res_m_soAB[i, t, 0] = sim.getCompConc('comp1', 'A_soAB') res_m_soAB[i, t, 1] = sim.getCompConc('comp1', 'B_soAB') if i < NITER_toA3: res_m_toA3[i, t, 0] = sim.getCompConc('comp1', 'A_toA3') if i < NITER_toA2B: res_m_toA2B[i, t, 0] = sim.getCompConc('comp1', 'A_toA2B') res_m_toA2B[i, t, 1] = sim.getCompConc('comp1', 'B_toA2B') res_m_toA2B[i, t, 2] = sim.getCompConc('comp1', 'C_toA2B') if i < NITER_so2d: res_m_so2d[i, t, 0] = sim.getPatchCount('patch1', 'A_so2d') res_m_so2d[i, t, 1] = sim.getPatchCount('patch1', 'B_so2d') global mean_res_foi mean_res_foi = numpy.mean(res_m_foi, 0) global mean_res_for mean_res_for = numpy.mean(res_m_for, 0) global mean_res_soA2 mean_res_soA2 = numpy.mean(res_m_soA2, 0) global mean_res_soAA mean_res_soAA = numpy.mean(res_m_soAA, 0) global mean_res_soAB mean_res_soAB = numpy.mean(res_m_soAB, 0) global mean_res_toA3 mean_res_toA3 = numpy.mean(res_m_toA3, 0) global mean_res_toA2B mean_res_toA2B = numpy.mean(res_m_toA2B, 0) global mean_res_so2d mean_res_so2d = numpy.mean(res_m_so2d, 0) global ran_sim ran_sim = True
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # SIMULATION # # # # # # # # # # # # # # # # # # # # # # r = srng.create_mt19937(512) r.initialize(7) r_dummy = srng.create_mt19937(512) r_dummy.initialize(7) print "Creating Tet exact solver" #Creating two solvers sim_stoch = ssolver.Tetexact(mdl_stoch, mesh_stoch, r, True) print "Creating Tet ODE solver" sim_det = ssolver.TetODE(mdl_det, mesh_det, r_dummy) sim_det.setTolerances(1.0e-3, 1.0e-3) print "Resetting simulation objects.." sim_stoch.reset() print "Injecting molecules.." sim_stoch.setTemp(TEMPERATURE + 273.15) sim_stoch.setCompConc('cyto_stoch', 'Ca_stoch', Ca_iconc) print "Calcium concentration in stochastic simulation is: ", sim_stoch.getCompConc( 'cyto_stoch', 'Ca_stoch') print "No. of Ca molecules in stochastic simulation is: ", sim_stoch.getCompCount(
def test_unbdiff2D_ode(): "Surface Diffusion - Unbounded, point source (TetODE)" m = gen_model() g, patch_tris, patch_tris_n, ctri_idx, trirads, triareas = gen_geom() sim = solvmod.TetODE(m, g) sim.setTolerances(1.0e-7, 1.0e-7) tpnts = numpy.arange(0.0, INT, DT) ntpnts = tpnts.shape[0] res_count = numpy.zeros((ntpnts, patch_tris_n)) sim.setTriCount(ctri_idx, 'X', NINJECT) for i in range(ntpnts): sim.run(tpnts[i]) for k in range(patch_tris_n): res_count[i, k] = sim.getTriCount(patch_tris[k], 'X') ######################################################################## tpnt_compare = [50, 100, 150] passed = True max_err = 0.0 for t in tpnt_compare: bin_n = 20 r_max = 0.0 for i in trirads: if (i > r_max): r_max = i r_min = 0.0 r_seg = (r_max - r_min) / bin_n bin_mins = numpy.zeros(bin_n + 1) r_tris_binned = numpy.zeros(bin_n) bin_areas = numpy.zeros(bin_n) r = r_min for b in range(bin_n + 1): bin_mins[b] = r if (b != bin_n): r_tris_binned[b] = r + r_seg / 2.0 r += r_seg bin_counts = [None] * bin_n for i in range(bin_n): bin_counts[i] = [] for i in range((res_count[t].size)): i_r = trirads[i] for b in range(bin_n): if (i_r >= bin_mins[b] and i_r < bin_mins[b + 1]): bin_counts[b].append(res_count[t][i]) bin_areas[b] += sim.getTriArea(int(patch_tris[i])) break bin_concs = numpy.zeros(bin_n) for c in range(bin_n): for d in range(bin_counts[c].__len__()): bin_concs[c] += bin_counts[c][d] bin_concs[c] /= (bin_areas[c] * 1.0e12) for i in range(bin_n): if (r_tris_binned[i] > 1.0 and r_tris_binned[i] < 5.0): rad = r_tris_binned[i] * 1.0e-6 det_conc = 1.0e-12 * ( NINJECT / (4 * math.pi * DCST * tpnts[t])) * (math.exp( (-1.0 * (rad * rad)) / (4 * DCST * tpnts[t]))) steps_conc = bin_concs[i] assert tol_funcs.tolerable(det_conc, steps_conc, tolerance)
membrane = sgeom.Memb('membrane', mesh, [memb], opt_method=2, search_percent=100.0) # Set the single-channel conductance: g_leak_sc = L_G_tot / len(memb_tris) OC_L = smodel.OhmicCurr('OC_L', ssys, chanstate=Leak, erev=leak_rev, g=g_leak_sc) # Create the solver objects sim = ssolver.TetODE(mdl, mesh, calcMembPot=True) sim.setTolerances(1.0e-6, 1e-6) surfarea_mesh = sim.getPatchArea('memb') surfarea_cyl = 1.0 * math.pi * 1000 * 1e-12 corr_fac_area = surfarea_mesh / surfarea_cyl vol_cyl = math.pi * 0.5 * 0.5 * 1000 * 1e-18 vol_mesh = sim.getCompVol('cyto') corr_fac_vol = vol_mesh / vol_cyl RES_POT = zeros((SIM_NTPNTS, POT_N)) print "\nRunning simulation" for t in memb_tris:
def test_unbdiff2D_linesource_ring_ode(): "Surface Diffusion - Unbounded, line source (TetODE)" m = gen_model() g, patch_tris, patch_tris_n, inject_tris, tridists, triareas = gen_geom() sim = solvmod.TetODE(m, g, rng) sim.setTolerances(1e-7, 1e-7) tpnts = np.arange(0.0, INT, DT) ntpnts = tpnts.shape[0] res_count = np.zeros((ntpnts, patch_tris_n)) for t in inject_tris: sim.setTriCount(t, 'X', float(NINJECT) / len(inject_tris)) for i in range(ntpnts): sim.run(tpnts[i]) for k in range(patch_tris_n): res_count[i, k] = sim.getTriCount(patch_tris[k], 'X') tpnt_compare = [75, 100, 150] passed = True max_err = 0.0 for t in tpnt_compare: bin_n = 50 r_min = 0 r_max = 0 for i in tridists: if (i > r_max): r_max = i if (i < r_min): r_min = i r_seg = (r_max - r_min) / bin_n bin_mins = np.zeros(bin_n + 1) r_tris_binned = np.zeros(bin_n) bin_areas = np.zeros(bin_n) r = r_min for b in range(bin_n + 1): bin_mins[b] = r if (b != bin_n): r_tris_binned[b] = r + r_seg / 2.0 r += r_seg bin_counts = [None] * bin_n for i in range(bin_n): bin_counts[i] = [] for i in range((res_count[t].size)): i_r = tridists[i] for b in range(bin_n): if (i_r >= bin_mins[b] and i_r < bin_mins[b + 1]): bin_counts[b].append(res_count[t][i]) bin_areas[b] += sim.getTriArea(int(patch_tris[i])) break bin_concs = np.zeros(bin_n) for c in range(bin_n): for d in range(bin_counts[c].__len__()): bin_concs[c] += bin_counts[c][d] bin_concs[c] /= (bin_areas[c] * 1.0e12) for i in range(bin_n): if (r_tris_binned[i] > -10.0 and r_tris_binned[i] < 10.0): dist = r_tris_binned[i] * 1e-6 det_conc = 1e-6 * (NINJECT / (4 * np.sqrt( (np.pi * DCST * tpnts[t])))) * (np.exp( (-1.0 * (dist * dist)) / (4 * DCST * tpnts[t]))) steps_conc = bin_concs[i] assert tol_funcs.tolerable(det_conc, steps_conc, tolerance)
def test_rallpack3(): print("Rallpack 3 with TetODE") #meshfile ='axon_cube_L1000um_D866m_600tets' meshfile = 'axon_cube_L1000um_D866m_1135tets' #meshfile = 'axon_cube_L1000um_D866nm_1978tets' # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Potassium conductance, Siemens/m^2 K_G = 360 # Sodium conductance, Siemens/m^2 Na_G = 1200 # Leak conductance, Siemens/m^2 L_G = 0.25 # Potassium reversal potential, V K_rev = -77e-3 # Sodium reversal potential, V Na_rev = 50e-3 # Leak reveral potential, V leak_rev = -65.0e-3 # Potassium channel density K_ro = 18.0e12 # Sodium channel density Na_ro = 60.0e12 # Total leak conductance for ideal cylinder: surfarea_cyl = 1.0 * np.pi * 1000 * 1e-12 L_G_tot = L_G * surfarea_cyl # A table of potassium density factors at -65mV, found in getpops. n0, n1, n2, n3, n4 K_FACS = [0.216750577045, 0.40366011853, 0.281904943772, \ 0.0874997924409, 0.0101845682113 ] # A table of sodium density factors. m0h1, m1h1, m2h1, m3h1, m0h0, m1h0, m2h0, m3h0 NA_FACS = [0.343079175644, 0.0575250437508, 0.00321512825945, 5.98988373918e-05, \ 0.506380603793, 0.0849062503811, 0.00474548939393, 8.84099403236e-05] # Ohm.m Ra = 1.0 # # # # # # # # # # # # # # # # SIMULATION CONTROLS # # # # # # # # # # # # # # # The simulation dt (seconds); for TetODE this is equivalent to EField dt SIM_DT = 5.0e-6 # Sim end time (seconds) SIM_END = 0.1 # The number of sim 'time points'; * SIM_DT = sim end time SIM_NTPNTS = int(SIM_END / SIM_DT) + 1 # The current injection in amps Iinj = 0.1e-9 # # # # # # # # # # # # # DATA COLLECTION # # # # # # # # # # # # # # # # # # # record potential at the two extremes along (z) axis POT_POS = np.array([0.0, 1.0e-03]) POT_N = len(POT_POS) # Length of the mesh, in m LENGTH = 1000.0e-6 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # mdl = smodel.Model() ssys = smodel.Surfsys('ssys', mdl) # K channel K = smodel.Chan('K', mdl) K_n0 = smodel.ChanState('K_n0', mdl, K) K_n1 = smodel.ChanState('K_n1', mdl, K) K_n2 = smodel.ChanState('K_n2', mdl, K) K_n3 = smodel.ChanState('K_n3', mdl, K) K_n4 = smodel.ChanState('K_n4', mdl, K) # Na channel Na = smodel.Chan('Na', mdl) Na_m0h1 = smodel.ChanState('Na_m0h1', mdl, Na) Na_m1h1 = smodel.ChanState('Na_m1h1', mdl, Na) Na_m2h1 = smodel.ChanState('Na_m2h1', mdl, Na) Na_m3h1 = smodel.ChanState('Na_m3h1', mdl, Na) Na_m0h0 = smodel.ChanState('Na_m0h0', mdl, Na) Na_m1h0 = smodel.ChanState('Na_m1h0', mdl, Na) Na_m2h0 = smodel.ChanState('Na_m2h0', mdl, Na) Na_m3h0 = smodel.ChanState('Na_m3h0', mdl, Na) # Leak L = smodel.Chan('L', mdl) Leak = smodel.ChanState('Leak', mdl, L) # Gating kinetics _a_m = lambda mV: ((((0.1 * (25 - (mV + 65.)) / (np.exp( (25 - (mV + 65.)) / 10.) - 1))))) _b_m = lambda mV: ((((4. * np.exp(-((mV + 65.) / 18.)))))) _a_h = lambda mV: ((((0.07 * np.exp((-(mV + 65.) / 20.)))))) _b_h = lambda mV: ((((1. / (np.exp((30 - (mV + 65.)) / 10.) + 1))))) _a_n = lambda mV: ((((0.01 * (10 - (mV + 65.)) / (np.exp( (10 - (mV + 65.)) / 10.) - 1))))) _b_n = lambda mV: ((((0.125 * np.exp(-(mV + 65.) / 80.))))) Kn0n1 = smodel.VDepSReac('Kn0n1', ssys, slhs=[K_n0], srhs=[K_n1], k=lambda V: 1.0e3 * 4. * _a_n(V * 1.0e3)) Kn1n2 = smodel.VDepSReac('Kn1n2', ssys, slhs=[K_n1], srhs=[K_n2], k=lambda V: 1.0e3 * 3. * _a_n(V * 1.0e3)) Kn2n3 = smodel.VDepSReac('Kn2n3', ssys, slhs=[K_n2], srhs=[K_n3], k=lambda V: 1.0e3 * 2. * _a_n(V * 1.0e3)) Kn3n4 = smodel.VDepSReac('Kn3n4', ssys, slhs=[K_n3], srhs=[K_n4], k=lambda V: 1.0e3 * 1. * _a_n(V * 1.0e3)) Kn4n3 = smodel.VDepSReac('Kn4n3', ssys, slhs=[K_n4], srhs=[K_n3], k=lambda V: 1.0e3 * 4. * _b_n(V * 1.0e3)) Kn3n2 = smodel.VDepSReac('Kn3n2', ssys, slhs=[K_n3], srhs=[K_n2], k=lambda V: 1.0e3 * 3. * _b_n(V * 1.0e3)) Kn2n1 = smodel.VDepSReac('Kn2n1', ssys, slhs=[K_n2], srhs=[K_n1], k=lambda V: 1.0e3 * 2. * _b_n(V * 1.0e3)) Kn1n0 = smodel.VDepSReac('Kn1n0', ssys, slhs=[K_n1], srhs=[K_n0], k=lambda V: 1.0e3 * 1. * _b_n(V * 1.0e3)) Na_m0h1_m1h1 = smodel.VDepSReac('Na_m0h1_m1h1', ssys, slhs=[Na_m0h1], srhs=[Na_m1h1], k=lambda V: 1.0e3 * 3. * _a_m(V * 1.0e3)) Na_m1h1_m2h1 = smodel.VDepSReac('Na_m1h1_m2h1', ssys, slhs=[Na_m1h1], srhs=[Na_m2h1], k=lambda V: 1.0e3 * 2. * _a_m(V * 1.0e3)) Na_m2h1_m3h1 = smodel.VDepSReac('Na_m2h1_m3h1', ssys, slhs=[Na_m2h1], srhs=[Na_m3h1], k=lambda V: 1.0e3 * 1. * _a_m(V * 1.0e3)) Na_m3h1_m2h1 = smodel.VDepSReac('Na_m3h1_m2h1', ssys, slhs=[Na_m3h1], srhs=[Na_m2h1], k=lambda V: 1.0e3 * 3. * _b_m(V * 1.0e3)) Na_m2h1_m1h1 = smodel.VDepSReac('Na_m2h1_m1h1', ssys, slhs=[Na_m2h1], srhs=[Na_m1h1], k=lambda V: 1.0e3 * 2. * _b_m(V * 1.0e3)) Na_m1h1_m0h1 = smodel.VDepSReac('Na_m1h1_m0h1', ssys, slhs=[Na_m1h1], srhs=[Na_m0h1], k=lambda V: 1.0e3 * 1. * _b_m(V * 1.0e3)) Na_m0h0_m1h0 = smodel.VDepSReac('Na_m0h0_m1h0', ssys, slhs=[Na_m0h0], srhs=[Na_m1h0], k=lambda V: 1.0e3 * 3. * _a_m(V * 1.0e3)) Na_m1h0_m2h0 = smodel.VDepSReac('Na_m1h0_m2h0', ssys, slhs=[Na_m1h0], srhs=[Na_m2h0], k=lambda V: 1.0e3 * 2. * _a_m(V * 1.0e3)) Na_m2h0_m3h0 = smodel.VDepSReac('Na_m2h0_m3h0', ssys, slhs=[Na_m2h0], srhs=[Na_m3h0], k=lambda V: 1.0e3 * 1. * _a_m(V * 1.0e3)) Na_m3h0_m2h0 = smodel.VDepSReac('Na_m3h0_m2h0', ssys, slhs=[Na_m3h0], srhs=[Na_m2h0], k=lambda V: 1.0e3 * 3. * _b_m(V * 1.0e3)) Na_m2h0_m1h0 = smodel.VDepSReac('Na_m2h0_m1h0', ssys, slhs=[Na_m2h0], srhs=[Na_m1h0], k=lambda V: 1.0e3 * 2. * _b_m(V * 1.0e3)) Na_m1h0_m0h0 = smodel.VDepSReac('Na_m1h0_m0h0', ssys, slhs=[Na_m1h0], srhs=[Na_m0h0], k=lambda V: 1.0e3 * 1. * _b_m(V * 1.0e3)) Na_m0h1_m0h0 = smodel.VDepSReac('Na_m0h1_m0h0', ssys, slhs=[Na_m0h1], srhs=[Na_m0h0], k=lambda V: 1.0e3 * _a_h(V * 1.0e3)) Na_m1h1_m1h0 = smodel.VDepSReac('Na_m1h1_m1h0', ssys, slhs=[Na_m1h1], srhs=[Na_m1h0], k=lambda V: 1.0e3 * _a_h(V * 1.0e3)) Na_m2h1_m2h0 = smodel.VDepSReac('Na_m2h1_m2h0', ssys, slhs=[Na_m2h1], srhs=[Na_m2h0], k=lambda V: 1.0e3 * _a_h(V * 1.0e3)) Na_m3h1_m3h0 = smodel.VDepSReac('Na_m3h1_m3h0', ssys, slhs=[Na_m3h1], srhs=[Na_m3h0], k=lambda V: 1.0e3 * _a_h(V * 1.0e3)) Na_m0h0_m0h1 = smodel.VDepSReac('Na_m0h0_m0h1', ssys, slhs=[Na_m0h0], srhs=[Na_m0h1], k=lambda V: 1.0e3 * _b_h(V * 1.0e3)) Na_m1h0_m1h1 = smodel.VDepSReac('Na_m1h0_m1h1', ssys, slhs=[Na_m1h0], srhs=[Na_m1h1], k=lambda V: 1.0e3 * _b_h(V * 1.0e3)) Na_m2h0_m2h1 = smodel.VDepSReac('Na_m2h0_m2h1', ssys, slhs=[Na_m2h0], srhs=[Na_m2h1], k=lambda V: 1.0e3 * _b_h(V * 1.0e3)) Na_m3h0_m3h1 = smodel.VDepSReac('Na_m3h0_m3h1', ssys, slhs=[Na_m3h0], srhs=[Na_m3h1], k=lambda V: 1.0e3 * _b_h(V * 1.0e3)) OC_K = smodel.OhmicCurr('OC_K', ssys, chanstate=K_n4, erev=K_rev, g=K_G / K_ro) OC_Na = smodel.OhmicCurr('OC_Na', ssys, chanstate=Na_m3h0, erev=Na_rev, g=Na_G / Na_ro) # Mesh geometry mesh = meshio.loadMesh('validation_efield/meshes/' + meshfile)[0] cyto = sgeom.TmComp('cyto', mesh, range(mesh.ntets)) # The tetrahedrons from which to record potential POT_TET = np.zeros(POT_N, dtype='uint') i = 0 for p in POT_POS: # Assuming axiz aligned with z-axis POT_TET[i] = mesh.findTetByPoint([0.0, 0.0, POT_POS[i]]) i = i + 1 # Find the tets connected to the bottom face # First find all the tets with ONE face on a boundary boundtets = [] #store the 0to3 index of the surface triangle for each of these boundary tets bt_srftriidx = [] for i in range(mesh.ntets): tettemp = mesh.getTetTetNeighb(i) if (tettemp[0] == -1 or tettemp[1] == -1 or tettemp[2] == -1 or tettemp[3] == -1): boundtets.append(i) templist = [] if (tettemp[0] == -1): templist.append(0) if (tettemp[1] == -1): templist.append(1) if (tettemp[2] == -1): templist.append(2) if (tettemp[3] == -1): templist.append(3) bt_srftriidx.append(templist) assert (boundtets.__len__() == bt_srftriidx.__len__()) # Find the tets on the z=0 and z=1000um boundaries, and the triangles minztets = [] minztris = [] maxztris = [] minzverts = set([]) boundminz = mesh.getBoundMin()[2] + LENGTH / mesh.ntets boundmaxz = mesh.getBoundMax()[2] - LENGTH / mesh.ntets for i in range(boundtets.__len__()): # get the boundary triangle for btriidx in bt_srftriidx[i]: zminboundtri = True tribidx = mesh.getTetTriNeighb(boundtets[i])[btriidx] tritemp = mesh.getTri(tribidx) trizs = [0.0, 0.0, 0.0] trizs[0] = mesh.getVertex(tritemp[0])[2] trizs[1] = mesh.getVertex(tritemp[1])[2] trizs[2] = mesh.getVertex(tritemp[2])[2] for j in range(3): if (trizs[j] > boundminz): zminboundtri = False if (zminboundtri): minztets.append(boundtets[i]) minztris.append(tribidx) minzverts.add(tritemp[0]) minzverts.add(tritemp[1]) minzverts.add(tritemp[2]) continue zmaxboundtri = True for j in range(3): if (trizs[j] < boundmaxz): zmaxboundtri = False if (zmaxboundtri): maxztris.append(tribidx) n_minztris = len(minztris) assert (n_minztris > 0) minzverts = list(minzverts) n_minzverts = len(minzverts) assert (n_minzverts > 0) memb_tris = list(mesh.getSurfTris()) # Doing this now, so will inject into first little z section for t in minztris: memb_tris.remove(t) for t in maxztris: memb_tris.remove(t) # Create the membrane with the tris removed at faces memb = sgeom.TmPatch('memb', mesh, memb_tris, cyto) memb.addSurfsys('ssys') membrane = sgeom.Memb('membrane', mesh, [memb], opt_method=2, search_percent=100.0) # Set the single-channel conductance: g_leak_sc = L_G_tot / len(memb_tris) OC_L = smodel.OhmicCurr('OC_L', ssys, chanstate=Leak, erev=leak_rev, g=g_leak_sc) # Create the solver objects sim = ssolver.TetODE(mdl, mesh, calcMembPot=True) sim.setTolerances(1.0e-6, 1e-6) surfarea_mesh = sim.getPatchArea('memb') surfarea_cyl = 1.0 * np.pi * 1000 * 1e-12 corr_fac_area = surfarea_mesh / surfarea_cyl vol_cyl = np.pi * 0.5 * 0.5 * 1000 * 1e-18 vol_mesh = sim.getCompVol('cyto') corr_fac_vol = vol_mesh / vol_cyl RES_POT = np.zeros((SIM_NTPNTS, POT_N)) for t in memb_tris: sim.setTriCount(t, 'Leak', 1) sim.setPatchCount('memb', 'Na_m0h1', (Na_ro * surfarea_cyl * NA_FACS[0])) sim.setPatchCount('memb', 'Na_m1h1', (Na_ro * surfarea_cyl * NA_FACS[1])) sim.setPatchCount('memb', 'Na_m2h1', (Na_ro * surfarea_cyl * NA_FACS[2])) sim.setPatchCount('memb', 'Na_m3h1', (Na_ro * surfarea_cyl * NA_FACS[3])) sim.setPatchCount('memb', 'Na_m0h0', (Na_ro * surfarea_cyl * NA_FACS[4])) sim.setPatchCount('memb', 'Na_m1h0', (Na_ro * surfarea_cyl * NA_FACS[5])) sim.setPatchCount('memb', 'Na_m2h0', (Na_ro * surfarea_cyl * NA_FACS[6])) sim.setPatchCount('memb', 'Na_m3h0', (Na_ro * surfarea_cyl * NA_FACS[7])) sim.setPatchCount('memb', 'K_n0', (K_ro * surfarea_cyl * K_FACS[0])) sim.setPatchCount('memb', 'K_n1', (K_ro * surfarea_cyl * K_FACS[1])) sim.setPatchCount('memb', 'K_n2', (K_ro * surfarea_cyl * K_FACS[2])) sim.setPatchCount('memb', 'K_n3', (K_ro * surfarea_cyl * K_FACS[3])) sim.setPatchCount('memb', 'K_n4', (K_ro * surfarea_cyl * K_FACS[4])) sim.setMembPotential('membrane', -65e-3) sim.setMembVolRes('membrane', Ra * corr_fac_vol) sim.setMembCapac('membrane', 0.01 / corr_fac_area) for v in minzverts: sim.setVertIClamp(v, Iinj / n_minzverts) for l in range(SIM_NTPNTS): sim.run(SIM_DT * l) for p in range(POT_N): RES_POT[l, p] = sim.getTetV(int(POT_TET[p])) * 1.0e3 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Benchmark # At 0um- the end of the mesh ifile_benchmark_x0 = open( 'validation_efield/data/rallpack3_benchmark/rallpack3_0_0.001dt_1000seg', 'r') # At 1000um- the end of the mesh ifile_benchmark_x1000 = open( 'validation_efield/data/rallpack3_benchmark/rallpack3_1000_0.001dt_1000seg', 'r') tpnt_benchmark = [] v_benchmark_x0 = [] v_benchmark_x1000 = [] lines_benchmark_x0 = ifile_benchmark_x0.readlines()[2:] # Read in mv and ms for line_benchmark_x0 in lines_benchmark_x0: nums = line_benchmark_x0.split() tpnt_benchmark.append(float(nums[0])) v_benchmark_x0.append(float(nums[1])) lines_benchmark_x1000 = ifile_benchmark_x1000.readlines()[2:] for line_benchmark_x1000 in lines_benchmark_x1000: nums = line_benchmark_x1000.split() v_benchmark_x1000.append(float(nums[1])) # Get rid of the last point which seems to be missing from STEPS v_benchmark_x0 = v_benchmark_x0[:-1] tpnt_benchmark = tpnt_benchmark[:-1] v_benchmark_x1000 = v_benchmark_x1000[:-1] rms0 = stats(v_benchmark_x0, RES_POT[:, 0]) assert (rms0 < 0.15) rms1000 = stats(v_benchmark_x1000, RES_POT[:, 1]) assert (rms1000 < 1.1)
def test_kis_ode(): "Reaction-diffusion - Degradation-diffusion (TetODE)" NITER = 1 # The number of iterations DT = 0.01 # Sampling time-step INT = 0.11 # Sim endtime DCSTA = 400 * 1e-12 DCSTB = DCSTA RCST = 100000.0e6 NA0 = 10000 # Initial number of A molecules NB0 = NA0 # Initial number of B molecules SAMPLE = 5000 # create the array of tet indices to be found at random tetidxs = np.zeros(SAMPLE, dtype='int') # further create the array of tet barycentre distance to centre tetrads = np.zeros(SAMPLE) #Small expected error tolerance = 1.5 / 100 ######################################################################## rng = srng.create('r123', 512) rng.initialize(1000) # The max unsigned long mdl = smod.Model() A = smod.Spec('A', mdl) B = smod.Spec('B', mdl) volsys = smod.Volsys('vsys', mdl) R1 = smod.Reac('R1', volsys, lhs=[A, B], rhs=[]) R1.setKcst(RCST) D_a = smod.Diff('D_a', volsys, A) D_a.setDcst(DCSTA) D_b = smod.Diff('D_b', volsys, B) D_b.setDcst(DCSTB) mesh = meshio.loadMesh('validation_rd/meshes/brick_40_4_4_STEPS')[0] ntets = mesh.countTets() VOLA = mesh.getMeshVolume() / 2.0 VOLB = VOLA comp1 = sgeom.TmComp('comp1', mesh, range(ntets)) comp1.addVolsys('vsys') # Now fill the array holding the tet indices to sample at random assert (SAMPLE <= ntets) numfilled = 0 while (numfilled < SAMPLE): if (ntets != SAMPLE): max = mesh.getBoundMax() min = mesh.getBoundMin() rnx = rng.getUnfII() rny = rng.getUnfII() rnz = rng.getUnfII() xpnt = min[0] + (max[0] - min[0]) * rnx ypnt = min[1] + (max[1] - min[1]) * rny zpnt = min[2] + (max[2] - min[2]) * rnz idx = mesh.findTetByPoint([xpnt, ypnt, zpnt]) if (idx == -1): continue if (idx not in tetidxs): tetidxs[numfilled] = idx numfilled += 1 else: tetidxs[numfilled] = numfilled numfilled += 1 tetidxs.sort() # Now find the distance of the centre of the tets to the Z lower face for i in range(SAMPLE): baryc = mesh.getTetBarycenter(int(tetidxs[i])) r = baryc[0] tetrads[i] = r * 1e6 Atets = [] Btets = [] for t in range(ntets): baryx = mesh.getTetBarycenter(t)[0] if (baryx < 0.0): Atets.append(t) continue if (baryx >= 0.0): Btets.append(t) continue assert (False) sim = ssolv.TetODE(mdl, mesh, rng) sim.setTolerances(1.0e-3, 1.0e-3) tpnts = np.arange(0.0, INT, DT) ntpnts = tpnts.shape[0] resA = np.zeros((NITER, ntpnts, SAMPLE)) resB = np.zeros((NITER, ntpnts, SAMPLE)) for i in range(0, NITER): sim.setCompCount('comp1', 'A', 2 * NA0) sim.setCompCount('comp1', 'B', 2 * NB0) for t in Btets: sim.setTetCount(t, 'A', 0) for t in Atets: sim.setTetCount(t, 'B', 0) for t in range(0, ntpnts): sim.run(tpnts[t]) for k in range(SAMPLE): resA[i, t, k] = sim.getTetCount(int(tetidxs[k]), 'A') resB[i, t, k] = sim.getTetCount(int(tetidxs[k]), 'B') itermeansA = np.mean(resA, axis=0) itermeansB = np.mean(resB, axis=0) def getdetc(t, x): N = 1000 # The number to represent infinity in the exponential calculation L = 20e-6 concA = 0.0 for n in range(N): concA += ((1.0 / (2 * n + 1)) * np.exp( (-(DCSTA / (20.0e-6)) * np.power( (2 * n + 1), 2) * np.power(np.pi, 2) * t) / (4 * L)) * np.sin(((2 * n + 1) * np.pi * x) / (2 * L))) concA *= ((4 * NA0 / np.pi) / (VOLA * 6.022e26)) * 1.0e6 return concA tpnt_compare = [5, 10] for tidx in tpnt_compare: NBINS = 50 radmax = 0.0 radmin = 10.0 for r in tetrads: if (r > radmax): radmax = r if (r < radmin): radmin = r rsec = (radmax - radmin) / NBINS binmins = np.zeros(NBINS + 1) tetradsbinned = np.zeros(NBINS) r = radmin bin_vols = np.zeros(NBINS) for b in range(NBINS + 1): binmins[b] = r if (b != NBINS): tetradsbinned[b] = r + rsec / 2.0 r += rsec bin_countsA = [None] * NBINS bin_countsB = [None] * NBINS for i in range(NBINS): bin_countsA[i] = [] bin_countsB[i] = [] filled = 0 for i in range(itermeansA[tidx].size): irad = tetrads[i] for b in range(NBINS): if (irad >= binmins[b] and irad < binmins[b + 1]): bin_countsA[b].append(itermeansA[tidx][i]) bin_vols[b] += sim.getTetVol(int(tetidxs[i])) filled += 1.0 break filled = 0 for i in range(itermeansB[tidx].size): irad = tetrads[i] for b in range(NBINS): if (irad >= binmins[b] and irad < binmins[b + 1]): bin_countsB[b].append(itermeansB[tidx][i]) filled += 1.0 break bin_concsA = np.zeros(NBINS) bin_concsB = np.zeros(NBINS) for c in range(NBINS): for d in range(bin_countsA[c].__len__()): bin_concsA[c] += bin_countsA[c][d] for d in range(bin_countsB[c].__len__()): bin_concsB[c] += bin_countsB[c][d] bin_concsA[c] /= (bin_vols[c]) bin_concsA[c] *= (1.0e-3 / 6.022e23) * 1.0e6 bin_concsB[c] /= (bin_vols[c]) bin_concsB[c] *= (1.0e-3 / 6.022e23) * 1.0e6 for i in range(NBINS): rad = abs(tetradsbinned[i]) * 1.0e-6 if (tetradsbinned[i] < -5): # compare A det_conc = getdetc(tpnts[tidx], rad) steps_conc = bin_concsA[i] assert tol_funcs.tolerable(det_conc, steps_conc, tolerance) if (tetradsbinned[i] > 5): # compare B det_conc = getdetc(tpnts[tidx], rad) steps_conc = bin_concsB[i] assert tol_funcs.tolerable(det_conc, steps_conc, tolerance)
def test_bounddiff_ode(): "Diffusion - Bounded (TetODE)" m = gen_model() g, area, a = gen_geom() # And fetch the total number of tets to make the data structures ntets = g.countTets() sim = solvmod.TetODE(m, g) sim.setTolerances(1e-3, 1e-3) tpnts = numpy.arange(0.0, INT, DT) ntpnts = tpnts.shape[0] # Create the big old data structure: iterations x time points x concentrations res = numpy.zeros((NITER, ntpnts, SAMPLE)) # Find the tets connected to the bottom face # First find all the tets with ONE face on a boundary boundtets = [] #store the 0to3 index of the surface triangle for each of these boundary tets bt_srftriidx = [] for i in range(ntets): tettemp = g.getTetTetNeighb(i) if (tettemp[0] == -1 or tettemp[1] == -1 or tettemp[2] == -1 or tettemp[3] == -1): boundtets.append(i) templist = [] if (tettemp[0] == -1): templist.append(0) if (tettemp[1] == -1): templist.append(1) if (tettemp[2] == -1): templist.append(2) if (tettemp[3] == -1): templist.append(3) bt_srftriidx.append(templist) assert (boundtets.__len__() == bt_srftriidx.__len__()) minztets = [] boundminz = g.getBoundMin()[2] + 0.01e-06 num2s = 0 for i in range(boundtets.__len__()): # get the boundary triangle if (bt_srftriidx[i].__len__() == 2): num2s += 1 for btriidx in bt_srftriidx[i]: zminboundtri = True tribidx = g.getTetTriNeighb(boundtets[i])[btriidx] tritemp = g.getTri(tribidx) trizs = [0.0, 0.0, 0.0] trizs[0] = g.getVertex(tritemp[0])[2] trizs[1] = g.getVertex(tritemp[1])[2] trizs[2] = g.getVertex(tritemp[2])[2] for j in range(3): if (trizs[j] > boundminz): zminboundtri = False if (zminboundtri): minztets.append(boundtets[i]) nztets = minztets.__len__() volztets = 0.0 for z in minztets: volztets += g.getTetVol(z) conc = NITER * 6.022e23 * 1.0e-3 / volztets for j in range(NITER): tetcount = int((1.0 * NINJECT) / nztets) totset = 0 for k in minztets: sim.setTetCount(k, 'X', tetcount) totset += tetcount for i in range(ntpnts): sim.run(tpnts[i]) for k in range(SAMPLE): res[j, i, k] = sim.getTetCount(int(tetidxs[k]), 'X') itermeans = numpy.mean(res, axis=0) ######################################################################## D = DCST pi = math.pi nmax = 1000 N = NINJECT N = int((1.0 * NINJECT) / nztets) * nztets def getprob(x, t): if (x > a): print('x out of bounds') return p = 0.0 for n in range(nmax): if (n == 0): A = math.sqrt(1.0 / a) else: A = math.sqrt(2.0 / a) p += math.exp(-D * math.pow( (n * pi / a), 2) * t) * A * math.cos(n * pi * x / a) * A * a return p * N / a tpnt_compare = [6, 8, 10] passed = True max_err = 0.0 for t in tpnt_compare: NBINS = 5 radmax = 0.0 radmin = 11.0 for r in tetrads: if (r > radmax): radmax = r if (r < radmin): radmin = r rsec = (radmax - radmin) / NBINS binmins = numpy.zeros(NBINS + 1) tetradsbinned = numpy.zeros(NBINS) r = radmin bin_vols = numpy.zeros(NBINS) for b in range(NBINS + 1): binmins[b] = r if (b != NBINS): tetradsbinned[b] = r + rsec / 2.0 r += rsec bin_counts = [None] * NBINS for i in range(NBINS): bin_counts[i] = [] filled = 0 for i in range(itermeans[t].size): irad = tetrads[i] for b in range(NBINS): if (irad >= binmins[b] and irad < binmins[b + 1]): bin_counts[b].append(itermeans[t][i]) bin_vols[b] += sim.getTetVol(int(tetidxs[i])) filled += 1.0 break bin_concs = numpy.zeros(NBINS) for c in range(NBINS): for d in range(bin_counts[c].__len__()): bin_concs[c] += bin_counts[c][d] bin_concs[c] /= (bin_vols[c]) bin_concs[c] *= (1.0e-3 / 6.022e23) * 1.0e6 for i in range(NBINS): if (tetradsbinned[i] > 2 and tetradsbinned[i] < 8): rad = tetradsbinned[i] * 1.0e-6 det_conc = (getprob(rad, tpnts[t]) / area) * (1.0 / 6.022e20) steps_conc = bin_concs[i] assert tol_funcs.tolerable(det_conc, steps_conc, tolerance)
def test_constsourcediff_reac_ode(): "Reaction-diffusion - Constant source from reaction (TetODE)" m = gen_model() g = gen_geom() real_vol = g.getMeshVolume() #Effective area area = real_vol / 10e-6 # And fetch the total number of tets to make the data structures ntets = g.countTets() sim = solvmod.TetODE(m, g) sim.setTolerances(1e-3, 1e-3) tpnts = np.arange(0.0, INT, DT) ntpnts = tpnts.shape[0] #Create the data structure: time points x concentrations res = np.zeros((ntpnts, SAMPLE)) # Find the tets connected to the bottom face # First find all the tets with ONE face on a boundary boundtets = [] #store the 0to3 index of the surface triangle for each of these boundary tets bt_srftriidx = [] for i in range(ntets): tettemp = g.getTetTetNeighb(i) if (tettemp[0] == -1 or tettemp[1] == -1 or tettemp[2] == -1 or tettemp[3] == -1): boundtets.append(i) templist = [] if (tettemp[0] == -1): templist.append(0) if (tettemp[1] == -1): templist.append(1) if (tettemp[2] == -1): templist.append(2) if (tettemp[3] == -1): templist.append(3) bt_srftriidx.append(templist) assert (boundtets.__len__() == bt_srftriidx.__len__()) minztets = [] maxztets = [] boundminz = g.getBoundMin()[2] + 0.01e-06 boundmaxz = g.getBoundMax()[2] - 0.01e-06 minztris = [] maxztris = [] num2s = 0 for i in range(boundtets.__len__()): # get the boundary triangle if (bt_srftriidx[i].__len__() == 2): num2s += 1 for btriidx in bt_srftriidx[i]: zminboundtri = True tribidx = g.getTetTriNeighb(boundtets[i])[btriidx] tritemp = g.getTri(tribidx) trizs = [0.0, 0.0, 0.0] trizs[0] = g.getVertex(tritemp[0])[2] trizs[1] = g.getVertex(tritemp[1])[2] trizs[2] = g.getVertex(tritemp[2])[2] for j in range(3): if (trizs[j] > boundminz): zminboundtri = False if (zminboundtri): minztets.append(boundtets[i]) minztris.append(zminboundtri) continue zmaxboundtri = True for j in range(3): if (trizs[j] < boundmaxz): zmaxboundtri = False if (zmaxboundtri): maxztets.append(boundtets[i]) maxztris.append(zmaxboundtri) nminztets = minztets.__len__() nmaxztets = maxztets.__len__() totset = 0 for k in minztets: sim.setTetReacK(k, 'reacX', FLUX / nminztets) sim.setTetCount(k, 'A', 1) totset += sim.getTetCount(k, 'X') for l in maxztets: sim.setTetReacK(l, 'reacX', FLUX / nmaxztets) sim.setTetCount(l, 'A', 1) totset += sim.getTetCount(l, 'X') for i in range(ntpnts): sim.run(tpnts[i]) for k in range(SAMPLE): res[i, k] = sim.getTetCount(int(tetidxs[k]), 'X') * 1.0e6 ######################################################################## L = 5.0e-6 a = 10e-6 D = DCST pi = np.pi J = FLUX / area tpnt_compare = [12, 24] for t in tpnt_compare: NBINS = 50 radmax = 0.0 radmin = 0.0 for r in tetrads: if (r > radmax): radmax = r if (r < radmin): radmin = r rsec = (radmax - radmin) / NBINS binmins = np.zeros(NBINS + 1) tetradsbinned = np.zeros(NBINS) r = radmin bin_vols = np.zeros(NBINS) for b in range(NBINS + 1): binmins[b] = r if (b != NBINS): tetradsbinned[b] = r + rsec / 2.0 r += rsec bin_counts = [None] * NBINS for i in range(NBINS): bin_counts[i] = [] filled = 0 for i in range(res[t].size): irad = tetrads[i] for b in range(NBINS): if (irad >= binmins[b] and irad < binmins[b + 1]): bin_counts[b].append(res[t][i]) bin_vols[b] += sim.getTetVol(int(tetidxs[i])) filled += 1.0 break bin_concs = np.zeros(NBINS) for c in range(NBINS): for d in range(bin_counts[c].__len__()): bin_concs[c] += bin_counts[c][d] bin_concs[c] /= (bin_vols[c]) bin_concs[c] *= (1.0e-3 / 6.022e23) for i in range(NBINS): if (tetradsbinned[i] > -5 and tetradsbinned[i] < -3) \ or (tetradsbinned[i] > 3 and tetradsbinned[i] < -5): rad = tetradsbinned[i] * 1.0e-6 nsum = 0.0 nmax = 100 for n in range(1, nmax): nsum+= (np.power(-1., n)/np.power(n, 2))*np.exp(-D*(np.power(((n*pi)/L), 2)*\ tpnts[t]))*np.cos((n*pi*rad)/L) det_conc = (1.0 / 6.022e20) * ((J * L) / D) * ( ((D * tpnts[t]) / np.power(L, 2)) + ((3 * np.power(rad, 2) - np.power(L, 2)) / (6 * np.power(L, 2))) - (2 / np.power(pi, 2)) * nsum) steps_conc = bin_concs[i] assert tol_funcs.tolerable(det_conc, steps_conc, tolerance)
# Create the membrane across which the potential will be solved membrane = sgeom.Memb('membrane', mesh, [patch], opt_method = 1) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Create the random number generator r = srng.create('mt19937',512) r.initialize(int(time.time()%10000)) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # SIMULATION # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Create solver object sim = ssolver.TetODE(mdl, mesh, r, True) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Inject channels surfarea = sim.getPatchArea('patch') sim.setPatchCount('patch', 'Na_m0h0', Na_ro*surfarea*Na_facs[0]) sim.setPatchCount('patch', 'Na_m1h0', Na_ro*surfarea*Na_facs[1]) sim.setPatchCount('patch', 'Na_m2h0', Na_ro*surfarea*Na_facs[2]) sim.setPatchCount('patch', 'Na_m3h0', Na_ro*surfarea*Na_facs[3]) sim.setPatchCount('patch', 'Na_m0h1', Na_ro*surfarea*Na_facs[4]) sim.setPatchCount('patch', 'Na_m1h1', Na_ro*surfarea*Na_facs[5]) sim.setPatchCount('patch', 'Na_m2h1', Na_ro*surfarea*Na_facs[6]) sim.setPatchCount('patch', 'Na_m3h1', Na_ro*surfarea*Na_facs[7])