def setup_in_volume(volume, count, h, spc=1., orig=(0.,0.,0.), offset=0., offset_inner=None, steps=100, fact=0.0001, maxneighs=1000, radius=0.): max_x_cl = CLScalar(volume.shape[0]*spc) max_y_cl = CLScalar(volume.shape[1]*spc) max_z_cl = CLScalar(volume.shape[2]*spc) particles_cl = CLReal4() oi = None if not offset_inner == None: oi = offset_inner - radius particles_cl.value = rand_particles_in_volume(volume, count, spc=spc, orig=(0.,0.,0.), offset=offset + radius, offset_inner=oi) maxneighs_cl = CLScalar(maxneighs) volume.shape = (volume.shape[0],volume.shape[1],volume.shape[2],1) vol_cl = CLReal() vol_cl.value = volume neighsearch = Neighsearch(particles_cl, h=h, maxneighs=int(maxneighs_cl.value)) neighsearch.search() h_cl = CLScalar(h) fact_cl = CLScalar(fact) vol_shp0_cl = CLScalar(volume.shape[0]) vol_shp1_cl = CLScalar(volume.shape[1]) vol_shp2_cl = CLScalar(volume.shape[2]) offset_cl = CLScalar(offset) if offset_inner == None: offset_inner = -pow(10., 38) offset_inner_cl = CLScalar(offset_inner) print "offsets: ", offset_cl, offset_inner_cl gradient_cl = CLReal4() gradient_cl.value = gradient_field(volume) kern = CLTemplateKernel(src=_RELAXPART_SRC, pre=_GET_DIST_GRAD_SRC) kern.pos = particles_cl kern.h = h_cl kern.maxneighs = maxneighs_cl kern.neighbors = neighsearch.neighbors kern.fact = fact_cl kern.volume = vol_cl kern.spacing = CLScalar(spc) kern.vol_shp0 = vol_shp0_cl kern.vol_shp1 = vol_shp1_cl kern.vol_shp2 = vol_shp2_cl kern.offset = offset_cl kern.offset_inner = offset_inner_cl kern.gradient = gradient_cl kern.max_x = max_x_cl kern.max_y = max_y_cl kern.max_z = max_z_cl kern.compile() print 'Particle initialization' for i in range(steps): neighsearch.search() kern() kern.finish() print 'Step', i+1, 'of', steps ret = particles_cl.value ret[:,0] += orig[0] ret[:,1] += orig[1] ret[:,2] += orig[2] return ret
def __init__(self): self.env = SPHEnv() self.env.h = 1.0 self.env.maxneighs = 100 self.env.dt = 0.0001 self.env.g = 9.81 self.env.avgneighs = 50 self.env.maxdvar = 0.1 self.env.avgdvar = 0.1 self.env.maxiter = 500 self.env.slipcoeff = 1. self.env.auto_dt_coeff = 0.01 self.env.dt_min = 0.01 self.wkernels = {} self.wkernels['WendlandC2'] = WendC2_mod(self.h, self.avgneighs) self.wkernels['WendlandC4'] = WendC4_mod(self.h, self.avgneighs) self.wkernels['WendlandC6'] = WendC6_mod(self.h, self.avgneighs) self.wkrn = 'WendlandC2' self.particles = ParticleField() self.particles.setup_vec('pos', 'vel', 'vel_adv', 'force', 'pforce', 'dii', 'sum_dijpjl') self.particles.setup_scal('press', 'new_press', 'rho0', 'rho', 'rho_adv', 'new_rho', 'mass', 'visc', 'dcorr', 'aii', 'kappa', 'rho_err') self.particles.info = CLChar() self.particles.index = CLUInt() self.particles.indvec = CLUInt4() self.neighsearch = Neighsearch(posarg=self.particles.pos, group=self.particles._group, h=self.h, maxneighs=self.maxneighs, index=self.particles.index, indvec=self.particles.indvec) self.steps = {}
def setup_with_particles(particles_in, volume, count, h, spc=1., orig=(0.,0.,0.), offset=0., offset_inner=None, steps=100, fact=0.0001, maxneighs=300): max_x_cl = CLScalar(volume.shape[0]*spc + orig[0]) max_y_cl = CLScalar(volume.shape[1]*spc + orig[1]) max_z_cl = CLScalar(volume.shape[2]*spc + orig[2]) min_x_cl = CLScalar(orig[0]) min_y_cl = CLScalar(orig[1]) min_z_cl = CLScalar(orig[2]) maxneighs_cl = CLScalar(maxneighs) parts_new = rand_particles_in_volume(volume, count, spc=spc, orig=orig, offset=offset, offset_inner=offset_inner) particles_cl = CLReal4() particles_cl.value = np.vstack((parts_new, particles_in)) flag_cl = CLChar() flag_cl.value = np.vstack((np.zeros((len(parts_new),1)), np.ones((len(particles_in),1))))# 1->boundary particle, 0->movable particle grp = Syncgroup(particles_cl, flag_cl) neighsearch = Neighsearch(particles_cl, h=h, maxneighs=int(maxneighs_cl.value), group=grp) neighsearch.search() h_cl = CLScalar(h) fact_cl = CLScalar(fact) kern = CLTemplateKernel(src=_RELAXPART_WITH_PART_SRC) kern.pos = particles_cl kern.flag = flag_cl kern.h = h_cl kern.maxneighs = maxneighs_cl kern.neighbors = neighsearch.neighbors kern.fact = fact_cl kern.max_x = max_x_cl kern.max_y = max_y_cl kern.max_z = max_z_cl kern.min_x = min_x_cl kern.min_y = min_y_cl kern.min_z = min_z_cl kern.compile() print 'Particle initialization' for i in range(steps): neighsearch.search() kern() print 'Step', i+1, 'of', steps parts = particles_cl.value ret = [] flags = flag_cl.value for i in range(len(parts)): if flags[i,0] == 0: ret.append(parts[i]) return np.array(ret)
class IISPHSolver(object): consts = {} consts['MAT_IGNORE'] = - 1 consts['MAT_FLUID'] = 0 consts['MAT_FIXEDBOUND'] = 1 CONSTS_SRC = '' for i in consts.iteritems(): CONSTS_SRC += 'constant int ' + i[0] + ' = ' + str(i[1]) + ';\n' CONSTS_SRC += NEIGHSEARCH_MACRO def __init__(self): self.env = SPHEnv() self.env.h = 1.0 self.env.maxneighs = 100 self.env.dt = 0.0001 self.env.g = 9.81 self.env.avgneighs = 50 self.env.maxdvar = 0.1 self.env.avgdvar = 0.1 self.env.maxiter = 500 self.env.slipcoeff = 1. self.env.auto_dt_coeff = 0.01 self.env.dt_min = 0.01 self.wkernels = {} self.wkernels['WendlandC2'] = WendC2_mod(self.h, self.avgneighs) self.wkernels['WendlandC4'] = WendC4_mod(self.h, self.avgneighs) self.wkernels['WendlandC6'] = WendC6_mod(self.h, self.avgneighs) self.wkrn = 'WendlandC2' self.particles = ParticleField() self.particles.setup_vec('pos', 'vel', 'vel_adv', 'force', 'pforce', 'dii', 'sum_dijpjl') self.particles.setup_scal('press', 'new_press', 'rho0', 'rho', 'rho_adv', 'new_rho', 'mass', 'visc', 'dcorr', 'aii', 'kappa', 'rho_err') self.particles.info = CLChar() self.particles.index = CLUInt() self.particles.indvec = CLUInt4() self.neighsearch = Neighsearch(posarg=self.particles.pos, group=self.particles._group, h=self.h, maxneighs=self.maxneighs, index=self.particles.index, indvec=self.particles.indvec) self.steps = {} @property def wkrn(self): return self._wkrn @wkrn.setter def wkrn(self, value): self._wkrn = self.wkernels[value] @property def h(self): return self.env.h.value @h.setter def h(self, value): self.env.h.value = value for kernel in self.wkernels.values(): kernel.update(self.h, self.avgneighs) @property def maxneighs(self): return int(self.env.maxneighs.value) @maxneighs.setter def maxneighs(self, value): self.env.maxneighs.value = value @property def dt(self): return self.env.dt.value @dt.setter def dt(self, value): self.env.dt.value = value @property def g(self): return self.env.g.value @g.setter def g(self, value): self.env.g.value = value @property def avgneighs(self): return self.env.avgneighs.value @avgneighs.setter def avgneighs(self, value): self.env.avgneighs.value = value for kernel in self.wkernels.values(): kernel.update(self.h, self.avgneighs) @property def maxdvar(self): return self.env.maxdvar.value @maxdvar.setter def maxdvar(self, value): self.env.maxdvar.value = value @property def avgdvar(self): return self.env.avgdvar.value @avgdvar.setter def avgdvar(self, value): self.env.avgdvar.value = value @property def maxiter(self): return self.env.maxiter.value @maxiter.setter def maxiter(self, value): self.env.maxiter.value = value @property def auto_dt_coeff(self): return self.env.auto_dt_coeff.value @auto_dt_coeff.setter def auto_dt_coeff(self, value): self.env.auto_dt_coeff.value = value @property def dt_min(self): return self.env.dt_min.value @dt_min.setter def dt_min(self, value): self.env.dt_min.value = value def setup(self): self.steps['compute_bound_mass'] = SolverStep(src=COMPUTE_BOUND_MASS, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_bound_mass') self.steps['compute_density'] = SolverStep(src=COMPUTE_DENSITY, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_density') self.steps['reset_force'] = SolverStep(src=RESET_FORCE, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='reset_force') self.steps['apply_gravity'] = SolverStep(src=APPLY_GRAVITY, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='apply_gravity') self.steps['apply_viscosity'] = SolverStep(src=APPLY_VISCOSITY, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='apply_viscosity') self.steps['apply_surface_tension'] = SolverStep(src=APPLY_SURFACE_TENSION, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='apply_surface_tension') self.steps['compute_vel_adv'] = SolverStep(src=COMPUTE_VEL_ADV, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_vel_adv') self.steps['compute_dii'] = SolverStep(src=COMPUTE_DII, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_dii') self.steps['compute_rho_adv_init_press'] = SolverStep(src=COMPUTE_RHO_ADV_INIT_PRESS, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_rho_adv_init_press') self.steps['compute_aii'] = SolverStep(src=COMPUTE_AII, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_aii') self.steps['compute_sum_dijpjl'] = SolverStep(src=COMPUTE_SUM_DIJPJL, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_sum_dijpjl') self.steps['compute_pressure'] = SolverStep(src=COMPUTE_PRESSURE, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_pressure') self.steps['set_pressure_clamped'] = SolverStep(src=SET_PRESSURE_CLAMPED, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='set_pressure_clamped') self.steps['compute_new_rho'] = SolverStep(src=COMPUTE_NEW_RHO, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_new_rho') self.steps['compute_density_error'] = SolverStep(src=COMPUTE_DENSITY_ERROR, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_density_error') self.steps['compute_pressure_force'] = SolverStep(src=COMPUTE_PRESSURE_FORCE, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_pressure_force') self.steps['integrate'] = SolverStep(src=INTEGRATE, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='integrate') def autoset_dt(self): vmax = max_length_real4(self.particles.vel) vadvmax = max_length_real4(self.particles.vel_adv) dt_new_v = self.dt dt_new_adv = self.dt if (vmax > 0.0): dt_new_v = self.auto_dt_coeff*self.h/vmax if (vadvmax > 0.0): dt_new_adv = self.auto_dt_coeff*self.h/vadvmax if dt_new_v < dt_new_adv: self.dt = min(dt_new_v, self.dt_min) #print 'vel', self.dt else: self.dt = min(dt_new_adv, self.dt_min) #print 'vel_adv', self.dt @timing def update(self): self.neighsearch.search(h=self.h, maxneighs=self.maxneighs) self.autoset_dt() self.steps['compute_bound_mass']() self.steps['compute_density']() self.steps['reset_force']() self.steps['apply_gravity']() self.steps['apply_viscosity']() self.steps['apply_surface_tension']() self.steps['compute_vel_adv']() self.steps['compute_dii']() self.steps['compute_rho_adv_init_press']() self.steps['compute_aii']() for i in range(self.maxiter): self.steps['compute_sum_dijpjl']() self.steps['compute_pressure']() self.steps['set_pressure_clamped']() self.steps['compute_new_rho']() self.steps['compute_density_error']() maxerr = max_reduce(self.particles.rho_err) avgerr = maxerr/len(self.particles.rho_err) if ((maxerr < self.maxdvar) or (avgerr < self.avgdvar)) and (i >= 2): #print 'pressure solve iterations: ', i break self.steps['compute_pressure_force']() self.steps['integrate']()
ret[n][0] = x_n*h + rx ret[n][1] = y_n*h + ry ret[n][2] = z_n*h + rz n += 1 return ret ax_cnt = 7 spacing = 0.1 maxneighs = 100 h = 2.*spacing pos_np = create_pos_cube(ax_cnt, spacing) pos = CLReal4(name='pos') pos.value = pos_np ns = Neighsearch(posarg=pos, h=h, maxneighs=maxneighs) t1 = timeit.default_timer() ns.search() t2 = timeit.default_timer() print 'Finding each max. ' + str(maxneighs) + ' neighbors took ' + str(t2-t1) + 's for ' + str(len(pos)) + ' items on ' + str(ncl._ctrl.cldevice) + '.' #assert p = pos.value n = np.zeros((len(p), maxneighs), np.int32) - 1 for i in range(len(p)): count = 0 for j in range(len(p)): if not(i == j): pi = np.array(p[i,:3])
def do_test(ax_cnt): def create_pos_cube(n_ax, h): ret = np.zeros((n_ax*n_ax*n_ax, 4), np.float) n = 0 for x_n in range(n_ax): for y_n in range(n_ax): for z_n in range(n_ax): rx = random()*spacing*0.0#0.1 ry = random()*spacing*0.0#0.1 rz = random()*spacing*0.0#0.1 ret[n][0] = x_n*h + rx ret[n][1] = y_n*h + ry ret[n][2] = z_n*h + rz n += 1 return ret spacing = 0.1 maxneighs = 100 h = 2.*spacing pos_np = create_pos_cube(ax_cnt, spacing) pos = CLReal4(name='pos') pos.value = pos_np ns = Neighsearch(posarg=pos, h=h, maxneighs=maxneighs) t1 = timeit.default_timer() ns.search() t2 = timeit.default_timer() print 'Finding each max. ' + str(maxneighs) + ' neighbors took ' + str(t2-t1) + 's for ' + str(len(pos)) + ' items.' #assert p = pos.value n = np.zeros((len(p), maxneighs), np.int32) - 1 for i in range(len(p)): count = 0 for j in range(len(p)): if not(i == j): pi = np.array(p[i,:3]) pj = np.array(p[j,:3]) d = np.linalg.norm(pi - pj) if d < h: n[i,count] = j count += 1 n_cl = ns.neighbors.value.reshape((len(p), maxneighs)) err = 0 errind = [] for i in range(len(p)): nu = np.sort(n[i][(n[i] > -1)]) nc = np.sort(n_cl[i][(n_cl[i] > -1)]) #print nu, nc if not np.all((nu == nc)): err += 1 errind.append(i) #print nu, nc print 'neigh search errors:', str(err), '\n---\n' return err