def get_equations(self): all = self.fluids + self.solids stage0 = [] eq1 = [] if self.solids: for solid in self.solids: eq1.append(EvaluateNumberDensity(dest=solid, sources=self.fluids)) for fluid in self.fluids: eq1.append(GradientCorrectionPreStep(dest=fluid, sources=all, dim=self.dim)) eq1.append(GradientCorrection(dest=fluid, sources=all, dim=self.dim)) eq1.append(ContinuityEquationDeltaSPHPreStep(dest=fluid, sources=all)) stage0.append(Group(equations=eq1, real=False)) eq2 = [] for fluid in self.fluids: eq2.append(ContinuityEquation(dest=fluid, sources=all)) eq2.append(ContinuityEquationDeltaSPH(dest=fluid, sources=all, c0=self.c0)) stage0.append(Group(equations=eq2, real=False)) eq3 = [] for fluid in self.fluids: eq3.append(IsothermalEOS(dest=fluid, sources=None, rho0=self.rho0, c0=self.c0, p0=0.0)) stage0.append(Group(equations=eq3, real=False)) if self.solids: eq4 = [] for solid in self.solids: eq4.append(SetWallVelocity(dest=solid, sources=self.fluids)) eq4.append(SetPressureSolid(dest=solid, sources=self.fluids, rho0=self.rho0, p0=self.p0)) stage0.append(Group(equations=eq4, real=False)) eq5 = [] for fluid in self.fluids: eq5.append(LaminarViscosityDeltaSPHPreStep(dest=fluid, sources=self.fluids)) eq5.append(LaminarViscosityDeltaSPH(dest=fluid, sources=self.fluids, dim=self.dim, rho0=self.rho0, nu=self.nu)) if self.solids: eq5.append(SolidWallNoSlipBC(dest=fluid, sources=self.solids, nu=self.nu)) eq5.append(Spatial_Acceleration(dest=fluid, sources=self.fluids)) stage0.append(Group(equations=eq5, real=True)) stage1 = [] eq6 = [] for fluid in self.fluids: eq6.append(GradientCorrectionPreStep(dest=fluid, sources=all, dim=self.dim)) eq6.append(GradientCorrection(dest=fluid, sources=all, dim=self.dim)) eq6.append(PST_PreStep_1(dest=fluid, sources=all, dim=self.dim, boundedFlow=self.boundedFlow)) eq6.append(PST_PreStep_2(dest=fluid, sources=all, boundedFlow=self.boundedFlow)) stage1.append(Group(equations=eq6, real=False)) eq7 = [] for fluid in self.fluids: eq7.append(PST(dest=fluid, sources=all, h=self.h0, dt=self.dt, dx=self.dx, c0=self.c0, boundedFlow=self.boundedFlow, gamma=self.gamma)) stage1.append(Group(equations=eq7, real=False)) return MultiStageEquations([stage0,stage1])
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 get_equations(self): from pysph.sph.wc.transport_velocity import ( StateEquation, SetWallVelocity, SolidWallPressureBC, VolumeSummation, SolidWallNoSlipBC, MomentumEquationArtificialViscosity, ContinuitySolid) all = self.fluids + self.solids stage1 = [] if self.solids: eq0 = [] for solid in self.solids: eq0.append(SetWallVelocity(dest=solid, sources=self.fluids)) stage1.append(Group(equations=eq0, real=False)) eq1 = [] for fluid in self.fluids: eq1.append(ContinuityEquationGTVF(dest=fluid, sources=self.fluids)) if self.solids: eq1.append(ContinuitySolid(dest=fluid, sources=self.solids)) stage1.append(Group(equations=eq1, real=False)) eq2, stage2 = [], [] for fluid in self.fluids: eq2.append(CorrectDensity(dest=fluid, sources=all)) stage2.append(Group(equations=eq2, real=False)) eq3 = [] for fluid in self.fluids: eq3.append( StateEquation(dest=fluid, sources=None, p0=self.pref, rho0=self.rho0, b=1.0)) stage2.append(Group(equations=eq3, real=False)) g2_s = [] for solid in self.solids: g2_s.append(VolumeSummation(dest=solid, sources=all)) g2_s.append( SolidWallPressureBC(dest=solid, sources=self.fluids, b=1.0, rho0=self.rho0, p0=self.pref, gx=self.gx, gy=self.gy, gz=self.gz)) if g2_s: stage2.append(Group(equations=g2_s, real=False)) eq4 = [] for fluid in self.fluids: eq4.append( MomentumEquationPressureGradient(dest=fluid, sources=all, pref=self.pref, gx=self.gx, gy=self.gy, gz=self.gz)) if self.alpha > 0.0: eq4.append( MomentumEquationArtificialViscosity(dest=fluid, sources=all, c0=self.c0, alpha=self.alpha)) if self.nu > 0.0: eq4.append( MomentumEquationViscosity(dest=fluid, sources=all, nu=self.nu)) if self.solids: eq4.append( SolidWallNoSlipBC(dest=fluid, sources=self.solids, nu=self.nu)) eq4.append( MomentumEquationArtificialStress(dest=fluid, sources=self.fluids, dim=self.dim)) stage2.append(Group(equations=eq4, real=True)) return MultiStageEquations([stage1, stage2])
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
def get_equations(self): from pysph.sph.equation import Group from pysph.sph.wc.basic import TaitEOS from pysph.sph.basic_equations import XSPHCorrection from pysph.sph.wc.transport_velocity import ( ContinuityEquation, MomentumEquationPressureGradient, MomentumEquationViscosity, MomentumEquationArtificialViscosity, SolidWallPressureBC, SolidWallNoSlipBC, SetWallVelocity, VolumeSummation) equations = [] all = self.fluids + self.solids g2 = [] for fluid in self.fluids: g2.append(VolumeSummation(dest=fluid, sources=all)) g2.append( TaitEOS(dest=fluid, sources=None, rho0=self.rho0, c0=self.c0, gamma=self.gamma, p0=self.p0)) for solid in self.solids: g2.append(VolumeSummation(dest=solid, sources=all)) g2.append(SetWallVelocity(dest=solid, sources=self.fluids)) equations.append(Group(equations=g2, real=False)) g3 = [] for solid in self.solids: g3.append( SolidWallPressureBC(dest=solid, sources=self.fluids, b=1.0, rho0=self.rho0, p0=self.B, gx=self.gx, gy=self.gy, gz=self.gz)) equations.append(Group(equations=g3, real=False)) g4 = [] for fluid in self.fluids: g4.append(ContinuityEquation(dest=fluid, sources=all)) g4.append( MomentumEquationPressureGradient(dest=fluid, sources=all, pb=0.0, gx=self.gx, gy=self.gy, gz=self.gz, tdamp=self.tdamp)) if self.alpha > 0.0: g4.append( MomentumEquationArtificialViscosity(dest=fluid, sources=all, c0=self.c0, alpha=self.alpha)) if self.nu > 0.0: g4.append( MomentumEquationViscosity(dest=fluid, sources=self.fluids, nu=self.nu)) if len(self.solids) > 0: g4.append( SolidWallNoSlipBC(dest=fluid, sources=self.solids, nu=self.nu)) g4.append(XSPHCorrection(dest=fluid, sources=[fluid])) equations.append(Group(equations=g4)) return equations
def get_equations(self): from pysph.sph.equation import Group from pysph.sph.wc.transport_velocity import ( SummationDensity, StateEquation, MomentumEquationPressureGradient, MomentumEquationArtificialViscosity, MomentumEquationViscosity, MomentumEquationArtificialStress, SolidWallPressureBC, SolidWallNoSlipBC, SetWallVelocity) equations = [] all = self.fluids + self.solids g1 = [] for fluid in self.fluids: g1.append(SummationDensity(dest=fluid, sources=all)) equations.append(Group(equations=g1, real=False)) g2 = [] for fluid in self.fluids: g2.append( StateEquation(dest=fluid, sources=None, p0=self.p0, rho0=self.rho0, b=1.0)) for solid in self.solids: g2.append(SetWallVelocity(dest=solid, sources=self.fluids)) equations.append(Group(equations=g2, real=False)) g3 = [] for solid in self.solids: g3.append( SolidWallPressureBC(dest=solid, sources=self.fluids, b=1.0, rho0=self.rho0, p0=self.p0, gx=self.gx, gy=self.gy, gz=self.gz)) equations.append(Group(equations=g3, real=False)) g4 = [] for fluid in self.fluids: g4.append( MomentumEquationPressureGradient(dest=fluid, sources=all, pb=self.pb, gx=self.gx, gy=self.gy, gz=self.gz, tdamp=self.tdamp)) if self.alpha > 0.0: g4.append( MomentumEquationArtificialViscosity(dest=fluid, sources=all, c0=self.c0, alpha=self.alpha)) if self.nu > 0.0: g4.append( MomentumEquationViscosity(dest=fluid, sources=self.fluids, nu=self.nu)) if len(self.solids) > 0: g4.append( SolidWallNoSlipBC(dest=fluid, sources=self.solids, nu=self.nu)) g4.append( MomentumEquationArtificialStress(dest=fluid, sources=self.fluids)) equations.append(Group(equations=g4)) return equations
def create_equations(self): tvf_equations = [ # We first compute the mass and number density of the fluid # phase. This is used in all force computations henceforth. The # number density (1/volume) is explicitly set for the solid phase # and this isn't modified for the simulation. Group(equations=[ SummationDensity(dest='fluid', sources=['fluid', 'wall']) ]), # Given the updated number density for the fluid, we can update # the fluid pressure. Additionally, we can extrapolate the fluid # velocity to the wall for the no-slip boundary # condition. Also compute the smoothed color based on the color # index for a particle. Group(equations=[ StateEquation( dest='fluid', sources=None, rho0=rho0, p0=p0, b=1.0), SetWallVelocity(dest='wall', sources=['fluid']), SmoothedColor(dest='fluid', sources=['fluid']), ]), ################################################################# # Begin Surface tension formulation ################################################################# # Scale the smoothing lengths to determine the interface # quantities. The NNPS need not be updated since the smoothing # length is decreased. Group(equations=[ ScaleSmoothingLength(dest='fluid', sources=None, factor=0.8) ], update_nnps=False), # Compute the gradient of the color function with respect to the # new smoothing length. At the end of this Group, we will have the # interface normals and the discretized dirac delta function for # the fluid-fluid interface. Group(equations=[ ColorGradientUsingNumberDensity(dest='fluid', sources=['fluid', 'wall'], epsilon=0.01 / h0), ], ), # Compute the interface curvature using the modified smoothing # length and interface normals computed in the previous Group. Group(equations=[ InterfaceCurvatureFromNumberDensity( dest='fluid', sources=['fluid'], with_morris_correction=True), ], ), # Now rescale the smoothing length to the original value for the # rest of the computations. Group( equations=[ ScaleSmoothingLength(dest='fluid', sources=None, factor=1.25) ], update_nnps=False, ), ################################################################# # End Surface tension formulation ################################################################# # Once the pressure for the fluid phase has been updated via the # state-equation, we can extrapolate the pressure to the wall # ghost particles. After this group, the density and pressure of # the boundary particles has been updated and can be used in the # integration equations. Group(equations=[ SolidWallPressureBC(dest='wall', sources=['fluid'], p0=p0, rho0=rho0, gy=gy), ], ), # The main acceleration block Group( equations=[ # Gradient of pressure for the fluid phase using the # number density formulation. No penetration boundary # condition using Adami et al's generalized wall boundary # condition. The extrapolated pressure and density on the # wall particles is used in the gradient of pressure to # simulate a repulsive force. MomentumEquationPressureGradient(dest='fluid', sources=['fluid', 'wall'], pb=p0, gy=gy), # Artificial viscosity for the fluid phase. MomentumEquationViscosity(dest='fluid', sources=['fluid'], nu=nu), # No-slip boundary condition using Adami et al's # generalized wall boundary condition. This equation # basically computes the viscous contribution on the fluid # from the wall particles. SolidWallNoSlipBC(dest='fluid', sources=['wall'], nu=nu), # Surface tension force for the SY11 formulation ShadlooYildizSurfaceTensionForce(dest='fluid', sources=None, sigma=sigma), # Artificial stress for the fluid phase MomentumEquationArtificialStress(dest='fluid', sources=['fluid']), ], ) ] return tvf_equations
def create_equations(self): equations = [ # set the acceleration for the obstacle using the special function # mimicking the accelerations provided in the test. Group(equations=[ SPHERICBenchmarkAcceleration(dest='obstacle', sources=None), ], real=False), # Summation density along with volume summation for the fluid # phase. This is done for all local and remote particles. At the # end of this group, the fluid phase has the correct density # taking into consideration the fluid and solid # particles. Group(equations=[ SummationDensity(dest='fluid', sources=['fluid', 'solid', 'obstacle']), ], real=False), # Once the fluid density is computed, we can use the EOS to set # the fluid pressure. Additionally, the dummy velocity for the # channel is set, which is later used in the no-slip wall BC. Group(equations=[ StateEquation(dest='fluid', sources=None, p0=p0, rho0=rho0, b=1.0), SetWallVelocity(dest='solid', sources=['fluid']), SetWallVelocity(dest='obstacle', sources=['fluid']), ], real=False), # Once the pressure for the fluid phase has been updated, we can # extrapolate the pressure to the ghost particles. After this # group, the fluid density, pressure and the boundary pressure has # been updated and can be used in the integration equations. Group(equations=[ SolidWallPressureBC(dest='obstacle', sources=['fluid'], b=1.0, rho0=rho0, p0=p0), SolidWallPressureBC(dest='solid', sources=['fluid'], b=1.0, rho0=rho0, p0=p0), ], real=False), # The main accelerations block. The acceleration arrays for the # fluid phase are upadted in this stage for all local particles. Group( equations=[ # Pressure gradient terms MomentumEquationPressureGradient( dest='fluid', sources=['fluid', 'solid', 'obstacle'], pb=p0), # fluid viscosity MomentumEquationViscosity(dest='fluid', sources=['fluid'], nu=nu), # No-slip boundary condition. This is effectively a # viscous interaction of the fluid with the ghost # particles. SolidWallNoSlipBC(dest='fluid', sources=['solid', 'obstacle'], nu=nu), # Artificial stress for the fluid phase MomentumEquationArtificialStress(dest='fluid', sources=['fluid']), ], real=True), ] return equations
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
def create_equations(self): sy11_equations = [ # We first compute the mass and number density of the fluid # phase. This is used in all force computations henceforth. The # number density (1/volume) is explicitly set for the solid phase # and this isn't modified for the simulation. Group( equations=[ SummationDensity(dest='fluid', sources=['fluid', 'wall']), # SummationDensity(dest='wall', sources=['fluid', 'wall']) ], real=False), # Given the updated number density for the fluid, we can update # the fluid pressure. Additionally, we can compute the Shepard # Filtered velocity required for the no-penetration boundary # condition. Also compute the gradient of the color function to # compute the normal at the interface. Group( equations=[ StateEquation(dest='fluid', sources=None, rho0=rho0, b=0.0, p0=p0), SetWallVelocity(dest='wall', sources=['fluid']), # SmoothedColor(dest='fluid', sources=['fluid']), ], real=False), Group(equations=[ SolidWallPressureBC(dest='wall', sources=['fluid'], p0=p0, rho0=rho0, gy=gy, b=1.0), ], real=False), ################################################################# # Begin Surface tension formulation ################################################################# # Scale the smoothing lengths to determine the interface # quantities. Group(equations=[ ScaleSmoothingLength(dest='fluid', sources=None, factor=factor1) ], update_nnps=True), # Compute the discretized dirac delta with respect to the new # smoothing length. Group(equations=[ SY11DiracDelta(dest='fluid', sources=['fluid', 'wall']) ], real=False), # Compute the interface curvature using the modified smoothing # length and interface normals computed in the previous Group. Group(equations=[ InterfaceCurvatureFromNumberDensity(dest='fluid', sources=['fluid']), ], real=False), # Now rescale the smoothing length to the original value for the # rest of the computations. Group(equations=[ ScaleSmoothingLength(dest='fluid', sources=None, factor=factor2) ], update_nnps=True), ################################################################# # End Surface tension formulation ################################################################# # The main acceleration block Group( equations=[ # Gradient of pressure for the fluid phase using the # number density formulation. No penetration boundary # condition using Adami et al's generalized wall boundary # condition. The extrapolated pressure and density on the # wall particles is used in the gradient of pressure to # simulate a repulsive force. BodyForce(dest='fluid', sources=None, fy=gy), MomentumEquationPressureGradient(dest='fluid', sources=['fluid', 'wall']), # Artificial viscosity for the fluid phase. ShadlooArtificialViscosity(dest='fluid', sources=['fluid', 'wall']), # Surface tension force for the SY11 formulation ShadlooYildizSurfaceTensionForce(dest='fluid', sources=None, sigma=sigma), ], ) ] return sy11_equations