def compute_fluid_elevation(particles): one_time_equations = [ Group( equations=[ FluidBottomElevation(dest='fluid', sources=['bed']) ] ), Group( equations=[ GradientCorrectionPreStep(dest='bed', sources=['bed']) ] ), Group( equations=[ GradientCorrection(dest='bed', sources=['bed']) ] ), Group( equations=[ BedGradient(dest='bed', sources=['bed']), ] ), Group( equations=[ BedCurvature(dest='bed', sources=['bed']), ] ), ] kernel = CubicSpline(dim=2) sph_eval = SPHEvaluator(particles, one_time_equations, dim=2, kernel=kernel) sph_eval.evaluate()
def compute_initial_props(particles): one_time_equations = [Group(equations=[SWEOS(dest='fluid')], )] kernel = CubicSpline(dim=1) sph_eval = SPHEvaluator(particles, one_time_equations, dim=1, kernel=kernel) sph_eval.evaluate()
def remove_repeated_points(x, y, z, dx_triangle): EPS = np.finfo(float).eps pa_mesh = ParticleArray(name='mesh', x=x, y=y, z=z, h=EPS) pa_grid = ParticleArray(name='grid', x=x, y=y, z=z, h=EPS) pa_mesh.add_property(name='min_idx') equation = [FindRepeatedPoints(dest='mesh', sources=['grid'])] sph_eval = SPHEvaluator([pa_mesh, pa_grid], equation, dim=3) sph_eval.evaluate() idx = list(set(pa_mesh.min_idx)) idx = np.array(idx, dtype=int) return pa_mesh.x[idx], pa_mesh.y[idx], pa_mesh.z[idx]
def post_step(self, solver): from pysph.tools.sph_evaluator import SPHEvaluator if self._sph_eval is None: equations = [ UpdateTangentialContacts(dest='sand', sources=['sand', 'wall']) ] self._sph_eval = SPHEvaluator(arrays=self.particles, equations=equations, dim=2, kernel=CubicSpline(dim=2)) self._sph_eval.evaluate()
def test_evaluation(self): # Given xd = [0.5] hd = self.src.h[:1] dest = get_particle_array(name='dest', x=xd, h=hd) sph_eval = SPHEvaluator(arrays=[dest, self.src], equations=self.equations, dim=1) # When. sph_eval.evaluate() # Then. self.assertAlmostEqual(dest.rho[0], 9.0, places=2)
def compute_initial_props(particles): one_time_equations = [ Group(equations=[ CorrectionFactorVariableSmoothingLength(dest='fluid', sources=['fluid']) ]), Group(equations=[SWEOS(dest='fluid')], ) ] kernel = CubicSpline(dim=2) sph_eval = SPHEvaluator(particles, one_time_equations, dim=2, kernel=kernel) sph_eval.evaluate()
def _get_sph_eval(self, kind): from pysph.tools.sph_evaluator import SPHEvaluator from pysph.sph.equation import Group if self._sph_eval is None: arr = self.array eqns = [] name = arr.name if 'vmax' not in arr.constants.keys(): arr.add_constant('vmax', [0.0]) if 'dpos' not in arr.properties.keys(): arr.add_property('dpos', stride=3) if kind == 'simple': const = 0.04 if not self.parameter else self.parameter eqns.append( Group(equations=[SimpleShift(name, [name], const=const)], update_nnps=True)) elif kind == 'fickian': const = 4 if not self.parameter else self.parameter eqns.append( Group(equations=[ FickianShift(name, [name], fickian_const=const) ], update_nnps=True)) if self.correct_velocity: if 'gradv' not in arr.properties.keys(): arr.add_property('gradv', stride=9) eqns.append(Group(equations=[CorrectVelocities(name, [name])])) sph_eval = SPHEvaluator(arrays=[arr], equations=eqns, dim=self.dim, kernel=self.kernel) return sph_eval else: return self._sph_eval
def _create_io_eval(self): if self.io_eval is None: from pysph.sph.equation import Group from pysph.tools.sph_evaluator import SPHEvaluator o_name = self.outlet_pa.name f_name = self.source_pa.name eqns = [] eqns.append(Group(equations=[ IOEvaluate( o_name, [], x=self.x, y=self.y, z=self.z, xn=self.xn, yn=self.yn, zn=self.zn, maxdist=self.length)], real=False, update_nnps=False)) eqns.append(Group(equations=[ IOEvaluate( f_name, [], x=self.x, y=self.y, z=self.z, xn=self.xn, yn=self.yn, zn=self.zn,)], real=False, update_nnps=False)) arrays = [self.outlet_pa] + [self.source_pa] io_eval = SPHEvaluator(arrays=arrays, equations=eqns, dim=self.dim, kernel=self.kernel) return io_eval else: return self.io_eval
def compute_initial_props(particles): one_time_equations = [ Group(equations=[ FluidBottomElevation(dest='fluid', sources=['bed']), BedGradient(dest='bed', sources=['bed']), CorrectionFactorVariableSmoothingLength(dest='fluid', sources=['fluid']), SWEOS(dest='fluid') ]), ] kernel = CubicSpline(dim=2) sph_eval = SPHEvaluator(particles, one_time_equations, dim=2, kernel=kernel) sph_eval.evaluate()
def _make_accel_eval(self, equations): kernel = CubicSpline(dim=self.dim) seval = SPHEvaluator( arrays=[self.pa], equations=equations, dim=self.dim, kernel=kernel ) return seval
def compute_initial_props(particles): one_time_equations = [ Group(equations=[ CheckForParticlesToSplit(dest='fluid', A_max=2900, x_min=300, x_max=1100, y_min=300, y_max=1100) ], ) ] kernel = CubicSpline(dim=2) sph_eval = SPHEvaluator(particles, one_time_equations, dim=2, kernel=kernel) sph_eval.evaluate()
def _get_normals(self, pa): from pysph.tools.sph_evaluator import SPHEvaluator from pysph.sph.isph.wall_normal import ComputeNormals, SmoothNormals pa.add_property('normal', stride=3) pa.add_property('normal_tmp', stride=3) name = pa.name seval = SPHEvaluator( arrays=[pa], equations=[ Group(equations=[ComputeNormals(dest=name, sources=[name])]), Group(equations=[SmoothNormals(dest=name, sources=[name])]), ], dim=self.dim) seval.evaluate()
def test_evaluation_with_domain_manager(self): # Given xd = [0.0] hd = self.src.h[:1] dest = get_particle_array(name='dest', x=xd, h=hd) dx = self.dx dm = DomainManager(xmin=-dx / 2, xmax=1.0 + dx / 2, periodic_in_x=True) sph_eval = SPHEvaluator(arrays=[dest, self.src], equations=self.equations, dim=1, domain_manager=dm) # When. sph_eval.evaluate() # Then. self.assertAlmostEqual(dest.rho[0], 9.0, places=2)
def compute_initial_props(particles): one_time_equations = [ Group(equations=[ InitialTimeGatherSummationDensity(dest='fluid', sources=[ 'fluid', ]), CheckForParticlesToSplit(dest='fluid', h_max=h_max, A_max=2900) ], update_nnps=False) ] kernel = CubicSpline(dim=2) sph_eval = SPHEvaluator(particles, one_time_equations, dim=2, kernel=kernel) sph_eval.evaluate()
def test_tangential_contacts(self): # before updating the contact information lets check # tangential properties # number of contacts of each individual particles for i in range(len(self.pa.x)): self.assertAlmostEqual(self.pa.total_tng_contacts[i], 0.) for i in range(self.pa.total_dem_entities[0]): self.assertAlmostEqual(self.pa.tng_idx[i], -1) self.assertAlmostEqual(self.pa.tng_x[i], 0.) self.assertAlmostEqual(self.pa.tng_y[i], 0.) self.assertAlmostEqual(self.pa.tng_z[i], 0.) # ------------------------------ # execute the interparticle force equation # ------------------------------ # Given eqs = [ Group(equations=[ LinearSpringForceParticleParticle(dest='sand', sources=['sand']) ]) ] kernel = CubicSpline(dim=2) sph_eval = SPHEvaluator(arrays=[self.pa], equations=eqs, dim=2, kernel=kernel) # When sph_eval.evaluate(0.0, 0.1) # check the tangential contacts indices and displacements # number of contacts of each individual particles for i in range(len(self.pa.x)): self.assertAlmostEqual(self.pa.total_tng_contacts[i], 0) for i in range(self.pa.total_dem_entities[0]): self.assertAlmostEqual(self.pa.tng_idx[i], -1) self.assertAlmostEqual(self.pa.tng_x[i], 0.) self.assertAlmostEqual(self.pa.tng_y[i], 0.) self.assertAlmostEqual(self.pa.tng_z[i], 0.)
def _create_io_eval(self): """Evaluator to assign ioid to particles leaving a domain""" if self.io_eval is None: from pysph.sph.equation import Group from pysph.tools.sph_evaluator import SPHEvaluator o_name = self.outlet_pa.name f_name = self.source_pa.name eqns = [] if self.gpu: from pysph.base.gpu_nnps import ZOrderGPUNNPS as NNPS else: from pysph.base.nnps import LinkedListNNPS as NNPS eqns.append( Group(equations=[ IOEvaluate(o_name, [], x=self.x, y=self.y, z=self.z, xn=self.xn, yn=self.yn, zn=self.zn, maxdist=self.length) ], real=False, update_nnps=False)) eqns.append( Group(equations=[ IOEvaluate( f_name, [], x=self.x, y=self.y, z=self.z, xn=self.xn, yn=self.yn, zn=self.zn, ) ], real=False, update_nnps=False)) arrays = [self.outlet_pa] + [self.source_pa] io_eval = SPHEvaluator(arrays=arrays, equations=eqns, dim=self.dim, kernel=self.kernel, nnps_factory=NNPS) return io_eval else: return self.io_eval
def _get_sph_evaluator(self, array): if not hasattr(self, '_sph_eval'): from pysph.tools.sph_evaluator import SPHEvaluator equations = [ ComputeAveragePressure(dest='fluid', sources=['fluid']) ] dm = self.create_domain() sph_eval = SPHEvaluator( arrays=[array], equations=equations, dim=2, kernel=QuinticSpline(dim=2), domain_manager=dm ) self._sph_eval = sph_eval return self._sph_eval
def compute_initial_props(particles): one_time_equations = [ Group(equations=[ SWEOS(dest='fluid'), ]), Group(equations=[ BoundaryInnerReimannStateEval(dest='inlet', sources=['fluid']), BoundaryInnerReimannStateEval(dest='outlet', sources=['fluid']) ]), Group(equations=[ SubCriticalInFlow(dest='inlet'), SubCriticalOutFlow(dest='outlet') ]), Group(equations=[ CorrectionFactorVariableSmoothingLength( dest='fluid', sources=['fluid', 'inlet', 'outlet', 'boundary']) ]), ] kernel = CubicSpline(dim=2) sph_eval = SPHEvaluator(particles, one_time_equations, dim=2, kernel=kernel) sph_eval.evaluate()
def compute_initial_props(particles): one_time_equations = [ Group( equations=[ InitialTimeScatterSummationDensity(dest='fluid', sources=['fluid',]), ] ), Group( equations=[ SWEOS(dest='fluid'), ] ), Group( equations=[ CheckForParticlesToSplit(dest='fluid', h_max=h_max, A_max=A_max), ] ) ] kernel = CubicSpline(dim=2) sph_eval = SPHEvaluator(particles, one_time_equations, dim=2, kernel=kernel) sph_eval.evaluate()
def _get_force_evaluator(self): from pysph.solver.utils import load from pysph.base.kernels import QuinticSpline from pysph.tools.sph_evaluator import SPHEvaluator from pysph.sph.equation import Group from pysph.sph.wc.transport_velocity import ( SetWallVelocity, MomentumEquationPressureGradient, SolidWallNoSlipBC, VolumeSummation, MomentumEquationViscosity) data = load(self.output_files[0]) solid = data['arrays']['solid'] fluid = data['arrays']['fluid'] prop = [ 'awhat', 'auhat', 'avhat', 'wg', 'vg', 'ug', 'V', 'uf', 'vf', 'wf', 'wij', 'vmag' ] for p in prop: solid.add_property(p) fluid.add_property(p) equations = [ Group(equations=[ SetWallVelocity(dest='fluid', sources=['solid']), VolumeSummation(dest='fluid', sources=['fluid', 'solid']), VolumeSummation(dest='solid', sources=['fluid', 'solid']), ], real=False), Group( equations=[ # Pressure gradient terms MomentumEquationPressureGradient( dest='solid', sources=['fluid', 'solid'], pb=p0), MomentumEquationViscosity(dest='solid', sources=['fluid', 'solid'], nu=self.nu), SolidWallNoSlipBC(dest='solid', sources=['fluid'], nu=self.nu), ], real=True), ] sph_eval = SPHEvaluator(arrays=[solid, fluid], equations=equations, dim=2, kernel=QuinticSpline(dim=2)) return sph_eval
def test_updating_particle_arrays(self): # Given xd = [0.5] hd = self.src.h[:1] dest = get_particle_array(name='dest', x=xd, h=hd) sph_eval = SPHEvaluator([dest, self.src], equations=self.equations, dim=1) sph_eval.evaluate() rho0 = dest.rho[0] # When. dest.x[0] = 0.0 sph_eval.update_particle_arrays([dest, self.src]) sph_eval.evaluate() # Then. self.assertNotEqual(rho0, dest.rho[0]) self.assertAlmostEqual(dest.rho[0], 7.0, places=1)
def _get_sph_eval_mls3d_1(self): from pysph.sph.wc.density_correction import MLSFirstOrder3D from pysph.tools.sph_evaluator import SPHEvaluator from pysph.sph.equation import Group if self._sph_eval is None: arrs = self.arrs eqns = [] for arr in arrs: name = arr.name arr.add_property('rhotmp') eqns.append(Group(equations=[ MLSFirstOrder3D(name, [name])], real=False)) sph_eval = SPHEvaluator( arrays=arrs, equations=eqns, dim=self.dim, kernel=self.kernel(dim=self.dim)) return sph_eval else: return self._sph_eval
def _plot_cd_vs_t(self): from pysph.solver.utils import iter_output, load from pysph.tools.sph_evaluator import SPHEvaluator from pysph.sph.equation import Group from pysph.sph.wc.transport_velocity import (SetWallVelocity, MomentumEquationPressureGradient, SolidWallNoSlipBC, SolidWallPressureBC, VolumeSummation) data = load(self.output_files[0]) solid = data['arrays']['solid'] fluid = data['arrays']['fluid'] x, y = solid.x.copy(), solid.y.copy() cx = 0.5 * L; cy = 0.5 * H inside = np.sqrt((x-cx)**2 + (y-cy)**2) <= a dest = solid.extract_particles(inside.nonzero()[0]) # We use the same equations for this as the simulation, except that we # do not include the acceleration terms as these are externally # imposed. The goal of these is to find the force of the fluid on the # cylinder, thus, gx=0.0 is used in the following. equations = [ Group( equations=[ VolumeSummation( dest='fluid', sources=['fluid', 'solid'] ), VolumeSummation( dest='solid', sources=['fluid', 'solid'] ), ], real=False), Group( equations=[ SetWallVelocity(dest='solid', sources=['fluid']), ], real=False), Group( equations=[ SolidWallPressureBC(dest='solid', sources=['fluid'], gx=0.0, b=1.0, rho0=rho0, p0=p0), ], real=False), Group( equations=[ # Pressure gradient terms MomentumEquationPressureGradient( dest='fluid', sources=['solid'], gx=0.0, pb=pb), SolidWallNoSlipBC( dest='fluid', sources=['solid'], nu=nu), ], real=True), ] sph_eval = SPHEvaluator( arrays=[dest, fluid], equations=equations, dim=2, kernel=QuinticSpline(dim=2) ) t, cd = [], [] for sd, fluid in iter_output(self.output_files, 'fluid'): fluid.remove_property('vmag2') t.append(sd['t']) sph_eval.update_particle_arrays([dest, fluid]) sph_eval.evaluate() Fx = np.sum(-fluid.au*fluid.m) cd.append(Fx/(nu*rho0*Umax)) t, cd = list(map(np.asarray, (t, cd))) # Now plot the results. import matplotlib matplotlib.use('Agg') from matplotlib import pyplot as plt f = plt.figure() plt.plot(t, cd) plt.xlabel('$t$'); plt.ylabel(r'$C_D$') fig = os.path.join(self.output_dir, "cd_vs_t.png") plt.savefig(fig, dpi=300) plt.close() return t, cd
class HopperFlow(Application): def initialize(self): self._sph_eval = None self.dx = 1 def create_particles(self): x = np.linspace(-0.5, 0.5, 10) y = np.linspace(0.77, 1.77, 10) r = (x[1] - x[0]) / 2. x, y = np.meshgrid(x, y) x, y = x.ravel(), y.ravel() R = np.ones_like(x) * r _m = np.pi * 2 * r * 2 * r m = np.ones_like(x) * _m m_inverse = np.ones_like(x) * 1. / _m _I = 2. / 5. * _m * r**2 I_inverse = np.ones_like(x) * 1. / _I h = np.ones_like(x) * r sand = get_particle_array_dem(x=x, y=y, m=m, m_inverse=m_inverse, R=R, h=h, I_inverse=I_inverse, name="sand", dem_id=0, dim=2, total_dem_entities=2) x, y = create_hopper(r) m = np.ones_like(x) * _m m_inverse = np.ones_like(x) * 1. / _m R = np.ones_like(x) * r h = np.ones_like(x) * r _I = 2. / 5. * _m * r**2 I_inverse = np.ones_like(x) * 1. / _I wall = get_particle_array_dem(x=x, y=y, m=m, m_inverse=m_inverse, R=R, h=h, I_inverse=I_inverse, name="wall", dem_id=1, dim=2, total_dem_entities=2) return [sand, wall] def create_solver(self): kernel = CubicSpline(dim=2) integrator = EulerIntegrator(sand=EulerDEMStep()) dt = 5e-5 print("DT: %s" % dt) tf = 2 solver = Solver(kernel=kernel, dim=2, integrator=integrator, dt=dt, tf=tf, adaptive_timestep=False) return solver def create_equations(self): equations = [ Group(equations=[ BodyForce(dest='sand', sources=None, gy=-9.81), LinearSpringForceParticleParticle( dest='sand', sources=['sand', 'wall'], kn=1e3), ]), ] return equations def post_step(self, solver): from pysph.tools.sph_evaluator import SPHEvaluator if self._sph_eval is None: equations = [ UpdateTangentialContacts(dest='sand', sources=['sand', 'wall']) ] self._sph_eval = SPHEvaluator(arrays=self.particles, equations=equations, dim=2, kernel=CubicSpline(dim=2)) self._sph_eval.evaluate()
def _plot_force_vs_t(self): from pysph.solver.utils import iter_output, load from pysph.tools.sph_evaluator import SPHEvaluator from pysph.sph.equation import Group from pysph.base.kernels import QuinticSpline from pysph.sph.wc.transport_velocity import ( MomentumEquationPressureGradient, SummationDensity, SetWallVelocity) data = load(self.output_files[0]) solid = data['arrays']['solid'] fluid = data['arrays']['fluid'] prop = [ 'awhat', 'auhat', 'avhat', 'wg', 'vg', 'ug', 'V', 'uf', 'vf', 'wf', 'wij', 'vmag', 'pavg', 'nnbr', 'auf', 'avf', 'awf' ] for p in prop: solid.add_property(p) fluid.add_property(p) # We find the force of the solid on the fluid and the opposite of that # is the force on the solid. Note that the assumption is that the solid # is far from the inlet and outlet so those are ignored. print(self.nu, p0, self.dc, rho) equations = [ Group(equations=[ SummationDensity(dest='fluid', sources=['fluid', 'solid']), SummationDensity(dest='solid', sources=['fluid', 'solid']), SetWallVelocity(dest='solid', sources=['fluid']), ], real=False), Group( equations=[ # Pressure gradient terms MomentumEquationPressureGradient(dest='solid', sources=['fluid'], pb=p0), SolidWallNoSlipBCReverse(dest='solid', sources=['fluid'], nu=self.nu), ], real=True), ] sph_eval = SPHEvaluator(arrays=[solid, fluid], equations=equations, dim=2, kernel=QuinticSpline(dim=2)) t, cd, cl = [], [], [] import gc print(self.dc, self.dx, self.nu) print('fxf', 'fxp', 'fyf', 'fyp', 'cd', 'cl', 't') for sd, arrays in iter_output(self.output_files[:]): fluid = arrays['fluid'] solid = arrays['solid'] for p in prop: solid.add_property(p) fluid.add_property(p) t.append(sd['t']) sph_eval.update_particle_arrays([solid, fluid]) sph_eval.evaluate() fxp = sum(solid.m * solid.au) fyp = sum(solid.m * solid.av) fxf = sum(solid.m * solid.auf) fyf = sum(solid.m * solid.avf) fx = fxf + fxp fy = fyf + fyp cd.append(fx / (0.5 * rho * umax**2 * self.dc)) cl.append(fy / (0.5 * rho * umax**2 * self.dc)) print(fxf, fxp, fyf, fyp, cd[-1], cl[-1], t[-1]) gc.collect() t, cd, cl = list(map(np.asarray, (t, cd, cl))) # Now plot the results. import matplotlib matplotlib.use('Agg') from matplotlib import pyplot as plt plt.figure() plt.plot(t, cd, label=r'$C_d$') plt.plot(t, cl, label=r'$C_l$') plt.xlabel(r'$t$') plt.ylabel('cd/cl') plt.legend() plt.grid() fig = os.path.join(self.output_dir, "force_vs_t.png") plt.savefig(fig, dpi=300) plt.close() return t, cd, cl