def setUp(self): # model setup mdl = smodel.Model() spc = smodel.Spec('A', mdl) vsys = smodel.Volsys('A', mdl) diff = smodel.Diff('diff_A', vsys, spc) diff.setDcst(0.0) # mesh vertCoos = [0.0, 0.0, 0.0, \ 1.0e-6, 0.0, 0.0, \ 0.0, 1.0e-6, 0.0, \ 0.0, 0.0, 1.0e-6, \ 1.0e-6, 1.0e-6, 1.0e-6 ] vertIds = [0, 1, 2, 3, \ 1, 2, 3, 4 ] # geom setup msh = sgeom.Tetmesh(vertCoos, vertIds) ntets = msh.countTets() comp = sgeom.TmComp('comp', msh, range(ntets)) comp.addVolsys('A') # init sim rng = srng.create('mt19937', 512) rng.initialize(2903) tet_hosts = sgd.linearPartition(msh, [1, 1, smpi.nhosts]) self.sim = spsolver.TetOpSplit(mdl, msh, rng, spsolver.EF_NONE, tet_hosts)
def setUp(self): DCST = 0.08e-10 self.model = smodel.Model() A = smodel.Spec('A', self.model) self.vsys = smodel.Volsys('vsys', self.model) self.ssys = smodel.Surfsys('ssys', self.model) self.diff = smodel.Diff("diff", self.vsys, A, DCST) self.sdiff = smodel.Diff("diff", self.ssys, A, DCST) if __name__ == "__main__": self.mesh = meshio.importAbaqus('meshes/test_mesh.inp', 1e-7)[0] else: self.mesh = meshio.importAbaqus( 'parallel_std_string_bugfix_test/meshes/test_mesh.inp', 1e-7)[0] self.tmcomp = sgeom.TmComp('comp', self.mesh, range(self.mesh.ntets)) self.tmcomp.addVolsys('vsys') self.surf_tris = self.mesh.getSurfTris() self.tmpatch = sgeom.TmPatch('patch', self.mesh, self.surf_tris, icomp=self.tmcomp) self.tmpatch.addSurfsys('ssys') self.rng = srng.create('r123', 512) self.rng.initialize(1000) tet_hosts = gd.binTetsByAxis(self.mesh, steps.mpi.nhosts) tri_hosts = gd.partitionTris(self.mesh, tet_hosts, self.surf_tris) self.solver = solv.TetOpSplit(self.model, self.mesh, self.rng, solv.EF_NONE, tet_hosts, tri_hosts) self.solver.reset()
def testSetGetTriCount(self): tet_hosts = gd.binTetsByAxis(self.mesh, steps.mpi.nhosts) tri_hosts = gd.partitionTris(self.mesh, tet_hosts, self.surf_tris) solver = solv.TetOpSplit(self.model, self.mesh, self.rng, solv.EF_NONE, tet_hosts, tri_hosts) for tri in self.surf_tris: solver.setTriCount(tri, 'A', tri) get_count = solver.getTriCount(tri, 'A') self.assertEqual(get_count, tri)
def testDiffSel(self): tet_hosts = gd.binTetsByAxis(self.mesh, steps.mpi.nhosts) solver = solv.TetOpSplit(self.model, self.mesh, self.rng, solv.EF_NONE, tet_hosts) solver.setCompCount('comp', 'A', 1) if __name__ == "__main__": print("Running...") solver.run(0.001) if __name__ == "__main__": print("") print("A:", solver.getCompCount("comp", "A")) print("steps:", solver.getNSteps()) self.assertEqual(solver.getCompCount("comp", "A"), 1) self.assertNotEqual(solver.getNSteps(), 0)
def setUp(self): self.model = smodel.Model() A = smodel.Spec("A", self.model) B = smodel.Spec("B", self.model) C = smodel.Spec("C", self.model) D = smodel.Spec("D", self.model) E = smodel.Spec("E", self.model) self.vsys1 = smodel.Volsys('vsys1', self.model) self.vsys2 = smodel.Volsys('vsys2', self.model) self.ssys1 = smodel.Surfsys('ssys1', self.model) self.reac1 = smodel.Reac('reac1', self.vsys1, lhs = [A], rhs = [A], kcst = 1e5) self.reac2 = smodel.Reac('reac2', self.vsys2, lhs = [E], rhs = [E], kcst = 1e4) self.sreac = smodel.SReac('sreac', self.ssys1, slhs = [B], srhs = [B], kcst = 1e3) if __name__ == "__main__": self.mesh = meshio.loadMesh('meshes/cyl_len10_diam1')[0] else: self.mesh = meshio.loadMesh('getROIArea_bugfix_test/meshes/cyl_len10_diam1')[0] ntets = self.mesh.countTets() comp1Tets, comp2Tets = [], [] comp1Tris, comp2Tris = set(), set() for i in range(ntets): if self.mesh.getTetBarycenter(i)[0] > 0: comp1Tets.append(i) comp1Tris |= set(self.mesh.getTetTriNeighb(i)) else: comp2Tets.append(i) comp2Tris |= set(self.mesh.getTetTriNeighb(i)) patch1Tris = list(comp1Tris & comp2Tris) self.comp1 = sgeom.TmComp('comp1', self.mesh, comp1Tets) self.comp2 = sgeom.TmComp('comp2', self.mesh, comp2Tets) self.comp1.addVolsys('vsys1') self.comp2.addVolsys('vsys2') self.patch1 = sgeom.TmPatch('patch1', self.mesh, patch1Tris, self.comp1, self.comp2) self.patch1.addSurfsys('ssys1') self.ROI1 = self.mesh.addROI('ROI1', sgeom.ELEM_TET, comp1Tets) self.ROI2 = self.mesh.addROI('ROI2', sgeom.ELEM_TET, comp2Tets) self.ROI3 = self.mesh.addROI('ROI3', sgeom.ELEM_TRI, patch1Tris) self.rng = srng.create('r123', 512) self.rng.initialize(1000) tet_hosts = gd.linearPartition(self.mesh, [steps.mpi.nhosts, 1, 1]) tri_hosts = gd.partitionTris(self.mesh, tet_hosts, patch1Tris) self.solver = solv.TetOpSplit(self.model, self.mesh, self.rng, solv.EF_NONE, tet_hosts, tri_hosts)
def init_sim(model, mesh, seed, param): rng = srng.create('r123', 512) # previous setup # rng.initialize(seed) rng.initialize(steps.mpi.rank + 1000) memb = sgeom.castToTmPatch(mesh.getPatch('memb')) # partition geometry across hosts (tet_hosts, tri_hosts) = host_assignment_by_axis(mesh, memb.tris) # sim = ssolver.TetOpSplit(model, mesh, rng, True, tet_hosts, tri_hosts) sim = ssolver.TetOpSplit(model, mesh, rng, param['EF_solver'], tet_hosts, tri_hosts) # 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 sim.reset() for t in memb.tris: sim.setTriCount(t, 'Leak', 1) sim.setEfieldDT(param['EF_dt']) 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
return mesh ######################################################################## m = gen_model() g = gen_geom() ######################################################################## rng = srng.create('mt19937', 512) rng.initialize(int(time.time() % 4294967295)) # The max unsigned long # Partitioning tet_hosts = gd.linearPartition(g, [1, 5, steps.mpi.nhosts / 5]) sim = parallel_solver.TetOpSplit(m, g, rng, False, tet_hosts) ######################################################################## # recording sim_result_dir = RESULT_DIR + "/%e_%s_%ihosts" % (MOLECULE_RATIO, MESHFILE, steps.mpi.nhosts) if steps.mpi.rank == 0: try: os.mkdir(RESULT_DIR) except: pass sim_result_dir = RESULT_DIR + "/%e_%s_%ihosts" % (MOLECULE_RATIO, MESHFILE, steps.mpi.nhosts) try: os.mkdir(sim_result_dir)
r = math.sqrt(r2) # Convert to microns trirads_B[i] = -r*1.0e6 triareas_B[i] = mesh.getTriArea(patchB_tris[i])*1.0e12 ######################################################################## # Create the biochemical model model = gen_model() # Create rnadom number generator object rng = srng.create('r123', 512) rng.initialize(234) # Create solver object sim = solvmod.TetOpSplit(model, mesh, rng, solvmod.EF_NONE, tet_hosts, tri_hosts) # Create the simulation data structures tpnts = pylab.arange(0.0, INT, DT) ntpnts = tpnts.shape[0] res_A = pylab.zeros((NITER, ntpnts, len(patchA_tris))) res_B = pylab.zeros((NITER, ntpnts, len(patchB_tris))) # Run NITER number of iterations: for j in range(NITER): print "Running iteration", j sim.reset() sim.setTriCount(ctri_idx, 'X', NINJECT) sim.setSDiffBoundaryDiffusionActive('sdiffb', 'X', True) sim.setSDiffBoundaryDcst('sdiffb', 'X', 0.008e-12 , 'patchB')
def test_kisilevich(): "Reaction-diffusion - Degradation-diffusion (Parallel TetOpSplit)" NITER = 50 # The number of iterations DT = 0.1 # Sampling time-step INT = 0.3 # Sim endtime DCSTA = 400 * 1e-12 DCSTB = DCSTA RCST = 100000.0e6 #NA0 = 100000 # 1000000 # Initial number of A molecules NA0 = 1000 NB0 = NA0 # Initial number of B molecules SAMPLE = 1686 # <1% fail with a tolerance of 7.5% tolerance = 7.5 / 100 # create the array of tet indices to be found at random tetidxs = numpy.zeros(SAMPLE, dtype='int') # further create the array of tet barycentre distance to centre tetrads = numpy.zeros(SAMPLE) 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_mpi/meshes/brick_40_4_4_1686tets')[0] VOLA = mesh.getMeshVolume() / 2.0 VOLB = VOLA ntets = mesh.countTets() acomptets = [] bcomptets = [] max = mesh.getBoundMax() min = mesh.getBoundMax() midz = 0.0 compatris = set() compbtris = set() for t in range(ntets): barycz = mesh.getTetBarycenter(t)[0] tris = mesh.getTetTriNeighb(t) if barycz < midz: acomptets.append(t) compatris.add(tris[0]) compatris.add(tris[1]) compatris.add(tris[2]) compatris.add(tris[3]) else: bcomptets.append(t) compbtris.add(tris[0]) compbtris.add(tris[1]) compbtris.add(tris[2]) compbtris.add(tris[3]) dbset = compatris.intersection(compbtris) dbtris = list(dbset) compa = sgeom.TmComp('compa', mesh, acomptets) compb = sgeom.TmComp('compb', mesh, bcomptets) compa.addVolsys('vsys') compb.addVolsys('vsys') diffb = sgeom.DiffBoundary('diffb', mesh, dbtris) # Now fill the array holding the tet indices to sample at random assert (SAMPLE <= ntets) numfilled = 0 while (numfilled < SAMPLE): tetidxs[numfilled] = numfilled numfilled += 1 # 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 * 1.0e6 Atets = acomptets Btets = bcomptets rng = srng.create('r123', 512) rng.initialize(1000) tet_hosts = gd.binTetsByAxis(mesh, steps.mpi.nhosts) sim = solvmod.TetOpSplit(mdl, mesh, rng, False, tet_hosts) tpnts = numpy.arange(0.0, INT, DT) ntpnts = tpnts.shape[0] resA = numpy.zeros((NITER, ntpnts, SAMPLE)) resB = numpy.zeros((NITER, ntpnts, SAMPLE)) for i in range(0, NITER): sim.reset() sim.setDiffBoundaryDiffusionActive('diffb', 'A', True) sim.setDiffBoundaryDiffusionActive('diffb', 'B', True) sim.setCompCount('compa', 'A', NA0) sim.setCompCount('compb', 'B', NB0) 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 = numpy.mean(resA, axis=0) itermeansB = numpy.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)) * math.exp( (-(DCSTA / (20.0e-6)) * math.pow( (2 * n + 1), 2) * math.pow(math.pi, 2) * t) / (4 * L)) * math.sin(((2 * n + 1) * math.pi * x) / (2 * L))) concA *= ((4 * NA0 / math.pi) / (VOLA * 6.022e26)) * 1.0e6 return concA tpnt_compare = [1, 2] passed = True max_err = 0.0 for tidx in tpnt_compare: NBINS = 10 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 = 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_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 = numpy.zeros(NBINS) bin_concsB = numpy.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_unbdiff2D_linesource_ring(): "Surface Diffusion - Unbounded, line source (Parallel TetOpSplit)" m = gen_model() g, patch_tris, partition_tris, patch_tris_n, inject_tris, tridists, triareas = gen_geom( ) tet_hosts = gd.binTetsByAxis(g, steps.mpi.nhosts) tri_hosts = gd.partitionTris(g, tet_hosts, partition_tris) sim = solvmod.TetOpSplit(m, g, rng, False, tet_hosts, tri_hosts) tpnts = np.arange(0.0, INT, DT) ntpnts = tpnts.shape[0] #Create the big old data structure: iterations x time points x concentrations res_count = np.zeros((NITER, ntpnts, patch_tris_n)) res_conc = np.zeros((NITER, ntpnts, patch_tris_n)) for j in range(NITER): sim.reset() 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[j, i, k] = sim.getTriCount(patch_tris[k], 'X') res_conc[j, i, k] = 1e-12 * (sim.getTriCount(patch_tris[k], 'X') / sim.getTriArea(patch_tris[k])) itermeans_count = np.mean(res_count, axis=0) itermeans_conc = np.mean(res_conc, axis=0) ######################################################################## tpnt_compare = [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((itermeans_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(itermeans_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] < -2.0) \ or (r_tris_binned[i] > 2.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_unbdiff(): "Diffusion - Unbounded (Parallel TetOpSplit)" m = gen_model() g = gen_geom() # Fetch the index of the centre tet ctetidx = g.findTetByPoint([0.0, 0.0, 0.0]) # And fetch the total number of tets to make the data structures ntets = g.countTets() tet_hosts = gd.binTetsByAxis(g, steps.mpi.nhosts) sim = solvmod.TetOpSplit(m, g, rng, False, tet_hosts) 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)) for j in range(NITER): sim.reset() sim.setTetCount(ctetidx, 'X', NINJECT) 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) tpnt_compare = [10, 15, 20] passed = True max_err = 0.0 for t in tpnt_compare: bin_n = 20 r_max = tetrads.max() r_min = 0.0 r_seg = (r_max-r_min)/bin_n bin_mins = numpy.zeros(bin_n+1) r_tets_binned = numpy.zeros(bin_n) bin_vols = numpy.zeros(bin_n) r = r_min for b in range(bin_n + 1): bin_mins[b] = r if (b!=bin_n): r_tets_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((itermeans[t].size)): i_r = tetrads[i] for b in range(bin_n): if(i_r>=bin_mins[b] and i_r<bin_mins[b+1]): bin_counts[b].append(itermeans[t][i]) bin_vols[b]+=sim.getTetVol(int(tetidxs[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_vols[c]*1.0e18) for i in range(bin_n): if (r_tets_binned[i] > 2.0 and r_tets_binned[i] < 6.0): rad = r_tets_binned[i]*1.0e-6 det_conc = 1e-18*((NINJECT/(math.pow((4*math.pi*DCST*tpnts[t]),1.5)))*(math.exp((-1.0*(rad*rad))/(4*DCST*tpnts[t])))) steps_conc = bin_concs[i] assert tol_funcs.tolerable(det_conc, steps_conc, tolerance)
def test_csd_clamped(): "Diffusion - Clamped (Parallel TetOpSplit)" m = gen_model() g = gen_geom() # And fetch the total number of tets to make the data structures ntets = g.countTets() tet_hosts = gd.binTetsByAxis(g, steps.mpi.nhosts) sim = solvmod.TetOpSplit(m, g, rng, False, tet_hosts) 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) for j in range(NITER): sim.reset() totset = 0 for k in minztets: sim.setTetConc(k, 'X', CONC) sim.setTetClamped(k, 'X', True) totset += sim.getTetCount(k, 'X') for i in range(ntpnts): sim.run(tpnts[i]) for k in range(SAMPLE): res[j, i, k] = sim.getTetCount(int(tetidxs[k]), 'X') #print('{0} / {1}'.format(j + 1, NITER)) itermeans = numpy.mean(res, axis=0) ######################################################################## tpnt_compare = [3, 4] passed = True max_err = 0.0 for t in tpnt_compare: NBINS = 10 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] > 1 and tetradsbinned[i] < 4): rad = tetradsbinned[i] * 1.0e-6 det_conc = (getConc(CONC * 6.022e26, DCST, rad, tpnts[t]) / 6.022e26) * 1.0e6 steps_conc = bin_concs[i] assert tol_funcs.tolerable(det_conc, steps_conc, tolerance)
def test_masteq_diff(): "Reaction-diffusion - Production and second order degradation (Parallel TetOpSplit)" ### NOW A+B-> B, 0->A (see Erban and Chapman, 2009) ######################################################################## SCALE = 1.0 KCST_f = 100e6 * SCALE # The reaction constant, degradation KCST_b = (20.0e-10 * SCALE) # The reaction constant, production DCST_A = 20e-12 DCST_B = 20e-12 B0 = 1 # The number of B moleucles DT = 0.1 # Sampling time-step INT = 50000.1 # Sim endtime filename = 'cube_1_1_1_73tets.inp' # A tolerance of 7.5% will fail <1% of the time tolerance = 7.5 / 100 ######################################################################## mdl = smod.Model() A = smod.Spec('A', mdl) B = smod.Spec('B', mdl) volsys = smod.Volsys('vsys', mdl) diffA = smod.Diff('diffA', volsys, A) diffA.setDcst(DCST_A) diffB = smod.Diff('diffB', volsys, B) diffB.setDcst(DCST_B) # Production R1 = smod.Reac('R1', volsys, lhs=[A, B], rhs=[B], kcst=KCST_f) R2 = smod.Reac('R2', volsys, lhs=[], rhs=[A], kcst=KCST_b) geom = meshio.loadMesh('validation_rd_mpi/meshes/' + filename)[0] comp1 = sgeom.TmComp('comp1', geom, range(geom.ntets)) comp1.addVolsys('vsys') rng = srng.create('r123', 512) rng.initialize(1000) tet_hosts = gd.binTetsByAxis(geom, steps.mpi.nhosts) sim = solvmod.TetOpSplit(mdl, geom, rng, False, tet_hosts) sim.reset() tpnts = numpy.arange(0.0, INT, DT) ntpnts = tpnts.shape[0] res = numpy.zeros([ntpnts]) res_std1 = numpy.zeros([ntpnts]) res_std2 = numpy.zeros([ntpnts]) sim.reset() sim.setCompCount('comp1', 'A', 0) sim.setCompCount('comp1', 'B', B0) b_time = time.time() for t in range(0, ntpnts): sim.run(tpnts[t]) res[t] = sim.getCompCount('comp1', 'A') def fact(x): return (1 if x == 0 else x * fact(x - 1)) # Do cumulative count, but not comparing them all. # Don't get over 50 (I hope) steps_n_res = numpy.zeros(50) for r in res: steps_n_res[int(r)] += 1 for s in range(50): steps_n_res[s] = steps_n_res[s] / ntpnts k1 = KCST_f / 6.022e23 k2 = KCST_b * 6.022e23 v = comp1.getVol() * 1.0e3 # litres for m in range(5, 11): analy = (1.0 / fact(m)) * math.pow( (k2 * v * v) / (B0 * k1), m) * math.exp(-((k2 * v * v) / (k1 * B0))) assert tol_funcs.tolerable(steps_n_res[m], analy, tolerance)
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 = 100000 # The number of iterations # Tolerance for the comparison: # In test runs, with good code, < 1% will fail with a 1.5% tolerance tolerance_foi = 2.0 / 100 ####################### First order reversible ######################### global KCST_f_for, KCST_b_for, COUNT_for, tolerance_for KCST_f_for = 10.0 # The reaction constant KCST_b_for = 2.0 COUNT_for = 100000 # Can set count or conc NITER_for = 10 # The number of iterations # In test runs, with good code, <0.1% will fail with a tolerance of 1% tolerance_for = 1.0 / 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 = 1000 # The number of iterations # In test runs, with good code, <0.1% will fail with a tolerance of 2% tolerance_soA2 = 3.0 / 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 = 1000 # The number of iterations # In test runs, with good code, <0.1% will fail with a tolerance of 1% tolerance_soAA = 2.0 / 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 = 1000 # The number of iterations # In test runs, with good code, <0.1% will fail with a tolerance of 1% tolerance_soAB = 1.0 / 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 = 1000 # The number of iterations # In test runs, with good code, <0.1% will fail with a tolerance of 1% tolerance_toA3 = 3.0 / 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 = 1000 # The number of iterations # In test runs, with good code, <0.1% will fail with a tolerance of 1% tolerance_toA2B = 1.0 / 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 = 1000 # The number of iterations # In tests fewer than 0.1% fail with tolerance of 2% tolerance_so2d = 2.0 / 100 ############################ Common parameters ######################## global VOL DT = 0.1 # Sampling time-step INT = 1.1 # Sim endtime NITER_max = 100000 ######################################################################## 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_mpi/meshes/sphere_rad1_37tets.inp', 1e-6)[0] VOL = mesh.getMeshVolume() comp1 = sgeom.TmComp('comp1', mesh, range(mesh.ntets)) comp1.addVolsys('vsys') patch_tris = mesh.getSurfTris() patch1 = sgeom.TmPatch('patch1', mesh, patch_tris, comp1) patch1.addSurfsys('ssys') CCST_so2d = KCST_so2d / (6.02214179e23 * patch1.getArea()) rng = srng.create('r123', 512) rng.initialize(100) tet_hosts = gd.binTetsByAxis(mesh, steps.mpi.nhosts) tri_hosts = gd.partitionTris(mesh, tet_hosts, patch_tris) sim = ssolv.TetOpSplit(mdl, mesh, rng, ssolv.EF_NONE, tet_hosts, tri_hosts) sim.reset() global tpnts, ntpnts tpnts = numpy.arange(0.0, INT, DT) ntpnts = tpnts.shape[0] res_m_foi = numpy.zeros([NITER_foi, ntpnts, 1]) res_std1_foi = numpy.zeros([ntpnts, 1]) res_std2_foi = numpy.zeros([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): sim.reset() 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, std_res_foi mean_res_foi = numpy.mean(res_m_foi, 0) std_res_foi = numpy.std(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
pass ########################### PARTITIONING ########################### partition_file = 'meshes/partition/branch.metis.epart.' + str(steps.mpi.nhosts) mpi_tet_partitions = metis_support.readPartition(partition_file) mpi_tri_partitions = gd.partitionTris(mesh, mpi_tet_partitions, mesh.getSurfTris()) ########################### CREATE SOLVER ########################### r = srng.create_mt19937(512) r.initialize(int(time.time()) * steps.mpi.rank) sim = mpisolver.TetOpSplit(mdl, mesh, r, tet_hosts=mpi_tet_partitions, tri_hosts=mpi_tri_partitions) ########################### LOAD PRESET CALCIUM INFLUX DATA ########################### # convert P type calcium current data to calcium influx profile ca_curr_data = data_presets.readData(CA_P_CURR_DATA_FILE) ca_influx_profile = data_presets.genCaInfluxProfile( ca_curr_data, roi_areas, roi_vols, PRESET_DATA_START_TIME, PRESET_DATA_START_TIME + SIM_TIME + INFLUX_UPDATE_INTERVAL, INFLUX_UPDATE_INTERVAL) # load preset background calcium concerntrations ca_conc_preset_file = open(CA_CONC_PRESET, 'r') ca_conc_preset = cPickle.load(ca_conc_preset_file)
# 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 using SuperLU EField solver sim = mpi_solver.TetOpSplit(mdl, mesh, r, mpi_solver.EF_DV_SLUSYS, tet_hosts, tri_hosts) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 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])
# 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 = mpi_solver.TetOpSplit(mdl, mesh, r, True, tet_hosts, tri_hosts) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 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])
######################################################################## # recording if steps.mpi.rank == 0: try: os.mkdir(RESULT_DIR) except: pass summary_file = open(RESULT_DIR + "/result.csv", 'w', 0) summary_file.write("Simulation Time,A,B,C,D,E,F,G,H,I,J\n") ######################################################################## rng = srng.create('mt19937', 512) rng.initialize(int(time.time()%4294967295)) sim = parallel_solver.TetOpSplit(m, g, rng, parallel_solver.EF_NONE, tet_hosts) # Set initial conditions sim.setCompCount('comp', 'A', N0A) sim.setCompCount('comp', 'B', N0B) sim.setCompCount('comp', 'C', N0C) sim.setCompCount('comp', 'D', N0D) sim.setCompCount('comp', 'E', N0E) sim.setCompCount('comp', 'F', N0F) sim.setCompCount('comp', 'G', N0G) sim.setCompCount('comp', 'H', N0H) sim.setCompCount('comp', 'I', N0I) sim.setCompCount('comp', 'J', N0J) n_tpns = int(ENDTIME / RECORDING_INTERVAL) + 1
def setUp(self): mdl = smodel.Model() S1 = smodel.Spec('S1', mdl) vsys = smodel.Volsys('vsys', mdl) ssys = smodel.Surfsys('ssys', mdl) smodel.Reac('R01', vsys, lhs=[S1], rhs=[S1], kcst=1) smodel.SReac('SR01', ssys, slhs=[S1], srhs=[S1], kcst=1) vrange = [-200.0e-3, 50e-3, 1e-3] vrate = lambda v: 2.0 Chan1 = smodel.Chan('Chan1', mdl) chanop = smodel.ChanState('chanop', mdl, Chan1) chancl = smodel.ChanState('chancl', mdl, Chan1) smodel.VDepSReac('VDSR01', ssys, slhs=[chancl], srhs=[chanop], k=vrate, vrange=vrange) smodel.VDepSReac('VDSR02', ssys, srhs=[chancl], slhs=[chanop], k=vrate, vrange=vrange) Chan1_Ohm_I = smodel.OhmicCurr('Chan1_Ohm_I', ssys, chanstate=chanop, g=20e-12, erev=-77e-3) if __name__ == "__main__": self.mesh = meshio.importAbaqus('meshes/test.inp', 1e-7)[0] else: self.mesh = meshio.importAbaqus( 'missing_solver_methods_test/meshes/test.inp', 1e-7)[0] comp1 = sgeom.TmComp('comp1', self.mesh, range(self.mesh.countTets())) comp1.addVolsys('vsys') patch1 = sgeom.TmPatch('patch1', self.mesh, self.mesh.getSurfTris(), comp1) patch1.addSurfsys('ssys') self.c1ROIInds = range(10) self.p1ROIInds = range(5) self.mesh.addROI('comp1ROI', sgeom.ELEM_TET, self.c1ROIInds) self.mesh.addROI('patch1ROI', sgeom.ELEM_TRI, self.p1ROIInds) membrane = sgeom.Memb('membrane', self.mesh, [patch1], opt_method=1) rng = srng.create('mt19937', 512) rng.initialize(1234) tet_hosts = gd.linearPartition(self.mesh, [1, 1, steps.mpi.nhosts]) tri_hosts = gd.partitionTris(self.mesh, tet_hosts, self.mesh.getSurfTris()) self.sim = ssolver.TetOpSplit(mdl, self.mesh, rng, ssolver.EF_DEFAULT, tet_hosts, tri_hosts) self.sim.setEfieldDT(1e-4) self.sim.reset()
def get_solver(mdl, geom): r = srng.create('r123', 1000) tet_hosts = gd.binTetsByAxis(geom, steps.mpi.nhosts) solver = ssolv.TetOpSplit(mdl, geom, r, ssolv.EF_NONE, tet_hosts) return solver
def test_bounddiff(): "Diffusion - Bounded (Parallel TetOpSplit)" m = gen_model() g, area, a = gen_geom() # And fetch the total number of tets to make the data structures ntets = g.countTets() tet_hosts = gd.binTetsByAxis(g, steps.mpi.nhosts) sim = solvmod.TetOpSplit(m, g, rng, False, tet_hosts) 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): sim.reset() 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)