[pysph] 01/01: Add autopkgtest.
Anton Gladky
gladk at moszumanska.debian.org
Sun Dec 21 22:07:13 UTC 2014
This is an automated email from the git hooks/post-receive script.
gladk pushed a commit to branch master
in repository pysph.
commit 59a152cef9f43cb38516b6396fa9f064711f5833
Author: Anton Gladky <gladk at debian.org>
Date: Sun Dec 21 23:03:24 2014 +0100
Add autopkgtest.
---
debian/control | 2 +
debian/tests/control | 2 +
debian/tests/pysph-test-elliptical | 206 ++++++++++++++++++++++++
debian/tests/pysph-test-sphere | 322 +++++++++++++++++++++++++++++++++++++
4 files changed, 532 insertions(+)
diff --git a/debian/control b/debian/control
index a28f530..3a60b15 100644
--- a/debian/control
+++ b/debian/control
@@ -17,6 +17,7 @@ Build-Depends:
X-Python-Version: >= 2.7
Standards-Version: 3.9.6
Section: science
+XS-Testsuite: autopkgtest
Homepage: http://pysph.googlecode.com
Vcs-Git: git://anonscm.debian.org/debian-science/packages/pysph.git
Vcs-Browser: http://anonscm.debian.org/gitweb/?p=debian-science/packages/pysph.git
@@ -25,6 +26,7 @@ Package: python-pysph
Section: python
Architecture: any
Depends:
+ cython,
python (<<2.8),
python (>= 2.7),
python-mako,
diff --git a/debian/tests/control b/debian/tests/control
new file mode 100644
index 0000000..faedda7
--- /dev/null
+++ b/debian/tests/control
@@ -0,0 +1,2 @@
+Tests: pysph-test-sphere pysph-test-elliptical
+Depends: python-pysph
diff --git a/debian/tests/pysph-test-elliptical b/debian/tests/pysph-test-elliptical
new file mode 100755
index 0000000..38ac75e
--- /dev/null
+++ b/debian/tests/pysph-test-elliptical
@@ -0,0 +1,206 @@
+#!/bin/sh
+# autopkgtest check for python-pysph
+# (C) 2014 Anton Gladky
+
+set -e
+
+WORKDIR=$(mktemp -d)
+trap "rm -rf $WORKDIR" 0 INT QUIT ABRT PIPE TERM
+cd $WORKDIR
+
+cat <<EOF > test.py
+"""Evolution of a circular patch of incompressible fluid. See
+J. J. Monaghan "Simulating Free Surface Flows with SPH", JCP, 1994,
+100, pp 399 - 406
+
+This version uses the Implicit Incompressible SPH technique described by
+
+M. Ihmsen, J. Cornelis, B. Solenthaler, C. Horvath, M. Teschner, "Implicit
+Incompressible SPH," IEEE Transactions on Visualization and Computer Graphics,
+vol. 20, no. 3, pp. 426-435, March 2014.
+http://dx.doi.org/10.1109/TVCG.2013.105
+
+An initially circular patch of fluid is subjected to a velocity
+profile that causes it to deform into an ellipse. Incompressibility
+causes the initially circular patch to deform into an ellipse such
+that the area is conserved. An analytical solution for the locus of
+the patch is available (exact_solution)
+
+This is a standard test for the formulations for the incompressible
+SPH equations.
+
+"""
+# NumPy and standard library imports
+from numpy import ones_like, mgrid, sqrt
+
+# PySPH base and carray imports
+from pysph.base.utils import get_particle_array_iisph
+from pysph.base.kernels import CubicSpline
+
+# PySPH solver and integrator
+from pysph.solver.application import Application
+from pysph.solver.solver import Solver
+
+# PySPH sph imports
+from pysph.sph.equation import Group
+from pysph.sph.iisph import (AdvectionAcceleration, ComputeAII, ComputeDII,
+ ComputeDIJPJ, ComputeRhoAdvection, IISPHStep, PressureSolve, PressureForce,
+ SummationDensity)
+from pysph.sph.integrator import EulerIntegrator
+
+
+def exact_solution(tf=0.0075, dt=1e-4):
+ """Exact solution for the locus of the circular patch."""
+ import numpy
+
+ A0 = 100
+ a0 = 1.0
+
+ t = 0.0
+
+ theta = numpy.linspace(0,2*numpy.pi, 101)
+
+ Anew = A0
+ anew = a0
+
+ while t <= tf:
+ t += dt
+
+ Aold = Anew
+ aold = anew
+
+ Anew = Aold + dt*(Aold*Aold*(aold**4 - 1))/(aold**4 + 1)
+ anew = aold + dt*(-aold * Aold)
+
+ dadt = Anew**2 * (anew**4 - 1)/(anew**4 + 1)
+ po = 0.5*-anew**2 * (dadt - Anew**2)
+
+ return anew*numpy.cos(theta), 1/anew*numpy.sin(theta), po
+
+ro = 1.0
+hdx = 1.3
+def get_circular_patch(dx=0.025, **kwargs):
+ """Create the circular patch of fluid."""
+ name = 'fluid'
+ x,y = mgrid[-1.05:1.05+1e-4:dx, -1.05:1.05+1e-4:dx]
+ x = x.ravel()
+ y = y.ravel()
+
+ m = ones_like(x)*dx*dx
+ h = ones_like(x)*hdx*dx
+ rho = ones_like(x) * ro
+
+ p = ones_like(x)
+
+ u = -100*x
+ v = 100*y
+
+ # remove particles outside the circle
+ indices = []
+ for i in range(len(x)):
+ if sqrt(x[i]*x[i] + y[i]*y[i]) - 1 > 1e-10:
+ indices.append(i)
+
+ pa = get_particle_array_iisph(x=x, y=y, m=m, rho=rho, h=h, p=p, u=u, v=v,
+ name=name)
+ pa.remove_particles(indices)
+
+ print "Elliptical drop :: %d particles"%(pa.get_number_of_particles())
+
+ return [pa,]
+
+# Create the application.
+app = Application()
+
+# Set the SPH kernel. The spline based kernels are much more efficient
+#(but less accurate) than the Gaussian
+kernel = CubicSpline(dim=2)
+
+# Create the Integrator.
+integrator = EulerIntegrator(fluid=IISPHStep())
+
+# Construct the solver. tdamp determines the time until which smaller
+# time-steps are used when using adaptive time-steps. Use the output_at_times
+# list to specify instants of time at which the output solution is
+# required.
+dt = 2e-4;
+tf = 0.0075
+solver = Solver(kernel=kernel, dim=2, integrator=integrator,
+ dt=dt, tf=tf, adaptive_timestep=False,
+ cfl=0.05,
+ output_at_times=[0.0033, 0.0052])
+
+# select True if you want to dump out remote particle properties in
+# parallel runs. This can be over-ridden with the --output-remote
+# command line option
+solver.set_output_only_real(True)
+solver.set_print_freq(5)
+
+# Define the SPH equations used to solve this problem
+equations = [
+
+ #####################################################################
+ # "Predict advection" step as per algorithm 1 in paper.
+ Group(
+ equations=[
+ SummationDensity(dest='fluid', sources=['fluid']),
+ ],
+ real=False
+ ),
+
+ Group(
+ equations=[
+ AdvectionAcceleration(dest='fluid', sources=None),
+ ComputeDII(dest='fluid', sources=['fluid']),
+ ]
+ ),
+
+ Group(
+ equations=[
+ ComputeRhoAdvection(dest='fluid', sources=['fluid']),
+ ComputeAII(dest='fluid', sources=['fluid']),
+ ]
+ ),
+
+ #####################################################################
+ # "Pressure solve" step as per algorithm 1 in paper.
+ Group(
+ equations=[
+ Group(
+ equations=[ComputeDIJPJ(dest='fluid', sources=['fluid'])]
+ ),
+ Group(
+ equations=[
+ PressureSolve(
+ dest='fluid', sources=['fluid'], rho0=ro,
+ tolerance=1e-2, debug=False
+ ),
+ ]
+ ),
+ ],
+ iterate=True,
+ max_iterations=20
+ ),
+
+ Group(
+ equations=[
+ PressureForce(dest='fluid', sources=['fluid']),
+ ],
+ ),
+
+]
+
+# Setup the application and solver.
+app.setup(solver=solver, equations=equations,
+ particle_factory=get_circular_patch)
+
+# run the solver...
+app.run()
+EOF
+
+python test.py
+ls -ln
+ls -ln test_output/
+
+echo "run: OK"
+
diff --git a/debian/tests/pysph-test-sphere b/debian/tests/pysph-test-sphere
new file mode 100755
index 0000000..66988b7
--- /dev/null
+++ b/debian/tests/pysph-test-sphere
@@ -0,0 +1,322 @@
+#!/bin/sh
+# autopkgtest check for python-pysph
+# (C) 2014 Anton Gladky
+
+set -e
+
+WORKDIR=$(mktemp -d)
+trap "rm -rf $WORKDIR" 0 INT QUIT ABRT PIPE TERM
+cd $WORKDIR
+
+cat <<EOF > moving_square.py
+# math
+from math import exp
+
+# NumPy
+import numpy as np
+
+# PySPH imports
+from pysph.base.utils import get_particle_array
+from pysph.base.kernels import Gaussian, WendlandQuintic, CubicSpline, QuinticSpline
+from pysph.solver.solver import Solver
+from pysph.solver.application import Application
+
+from pysph.sph.integrator_step import TwoStageRigidBodyStep, TransportVelocityStep
+from pysph.sph.integrator import Integrator
+
+from pysph.tools import uniform_distribution
+
+# SPH equations for this problem
+from pysph.sph.equation import Group, Equation
+from pysph.sph.wc.transport_velocity import SummationDensity,\
+ StateEquation, MomentumEquationPressureGradient, MomentumEquationViscosity,\
+ MomentumEquationArtificialStress, SolidWallPressureBC, SolidWallNoSlipBC,\
+ ShepardFilteredVelocity
+
+# domain and reference values
+Lx = 10.0; Ly = 5.0
+Umax = 1.0
+c0 = 25.0 * Umax; rho0 = 1.0
+p0 = c0*c0*rho0
+
+# obstacle dimensions
+obstacle_width = 1.0
+obstacle_height = 1.0
+
+# Reynolds number and kinematic viscosity
+Re = 100; nu = Umax * obstacle_width/Re
+
+# Numerical setup
+nx = 50; dx = 0.20* Lx/nx
+nghost_layers = 4
+ghost_extent = nghost_layers * dx
+hdx = 1.2
+
+# adaptive time steps
+h0 = hdx * dx
+dt_cfl = 0.25 * h0/( c0 + Umax )
+dt_viscous = 0.125 * h0**2/nu
+dt_force = 1.0
+
+tf = 0.2
+dt = 0.8 * min(dt_cfl, dt_viscous, dt_force)
+
+# The SPH kernel to use
+kernel = QuinticSpline(dim=2)
+#kernel = CubicSpline(dim=2)
+
+def _get_interior(x, y):
+ indices = []
+ for i in range(x.size):
+ if ( (x[i] > 0.0) and (x[i] < Lx) ):
+ if ( (y[i] > 0.0) and (y[i] < Ly) ):
+ indices.append(i)
+
+ return indices
+
+def _get_obstacle(x, y):
+ indices = []
+ for i in range(x.size):
+ if ( (1.0 <= x[i] <= 2.0) and (2.0 <= y[i] <= 3.0) ):
+ indices.append(i)
+
+ return indices
+
+def _setup_particle_properties(particles, volume):
+ fluid, solid, obstacle = particles
+
+ #### ADD PROPS FOR THE PARTICLES ###
+
+ # volume from number density
+ fluid.add_property('V')
+ solid.add_property('V' )
+ obstacle.add_property('V' )
+
+ # Shepard filtered velocities for the fluid
+ for name in ['uf', 'vf', 'wf']:
+ fluid.add_property(name)
+
+ # advection velocities and accelerations for fluid
+ for name in ('uhat', 'vhat', 'what', 'auhat', 'avhat', 'awhat', 'au', 'av', 'aw'):
+ fluid.add_property(name)
+
+ # kernel summation correction for solids
+ solid.add_property('wij')
+ obstacle.add_property('wij')
+
+ # initial velocities and positions needed for the obstacle for
+ # rigid-body integration
+ obstacle.add_property('u0'); obstacle.u0[:] = 0.
+ obstacle.add_property('v0'); obstacle.v0[:] = 0.
+ obstacle.add_property('w0'); obstacle.w0[:] = 0.
+
+ obstacle.add_property('x0')
+ obstacle.add_property('y0')
+ obstacle.add_property('z0')
+
+ # imposed accelerations on the solid and obstacle
+ solid.add_property('ax')
+ solid.add_property('ay')
+ solid.add_property('az')
+
+ obstacle.add_property('ax')
+ obstacle.add_property('ay')
+ obstacle.add_property('az')
+
+ # magnitude of velocity squared
+ fluid.add_property('vmag2')
+
+ #### SETUP PARTICLE PROPERTIES ###
+
+ # mass is set to get the reference density of rho0
+ fluid.m[:] = volume * rho0
+ solid.m[:] = volume * rho0
+ obstacle.m[:] = volume * rho0
+
+ # volume is set as dx^2
+ fluid.V[:] = 1./volume
+ solid.V[:] = 1./volume
+ obstacle.V[:] = 1./volume
+
+ # smoothing lengths
+ fluid.h[:] = h0
+ solid.h[:] = h0
+ obstacle.h[:] = h0
+
+ # set the output arrays
+ fluid.set_output_arrays( ['x', 'y', 'u', 'v', 'vmag2', 'rho', 'p',
+ 'V', 'm', 'h'] )
+
+ solid.set_output_arrays( ['x', 'y', 'rho', 'p'] )
+ obstacle.set_output_arrays( ['x', 'y', 'u0', 'rho', 'p'] )
+
+ particles = [fluid, solid, obstacle]
+ return particles
+
+def create_particles(hcp=False, **kwargs):
+ "Initial distribution using Hexagonal close packing of particles"
+ # create all particles
+ global dx
+ if hcp:
+ x, y, dx, dy, xmin, xmax, ymin, ymax = uniform_distribution.uniform_distribution_hcp2D(
+ dx=dx, xmin=-ghost_extent, xmax=Lx+ghost_extent,
+ ymin=-ghost_extent, ymax=Ly+ghost_extent)
+ else:
+ x, y, dx, dy, xmin, xmax, ymin, ymax = uniform_distribution.uniform_distribution_cubic2D(
+ dx=dx, xmin=-ghost_extent, xmax=Lx+ghost_extent,
+ ymin=-ghost_extent, ymax=Ly+ghost_extent)
+
+ x = x.ravel(); y = y.ravel()
+
+ # create the basic particle array
+ solid = get_particle_array(name='solid', x=x, y=y)
+
+ # now sort out the interior from all particles
+ indices = _get_interior(solid.x, solid.y)
+ fluid = solid.extract_particles( indices )
+ fluid.set_name('fluid')
+
+ solid.remove_particles( indices )
+
+ # sort out the obstacle from the interior
+ indices = _get_obstacle(fluid.x, fluid.y)
+ obstacle = fluid.extract_particles( indices )
+ obstacle.set_name('obstacle')
+
+ fluid.remove_particles(indices)
+
+ print "SPHERIC benchmark 6 :: Re = %d, nfluid = %d, nsolid=%d, nobstacle = %d, dt = %g"%(
+ Re, fluid.get_number_of_particles(),
+ solid.get_number_of_particles(),
+ obstacle.get_number_of_particles(), dt)
+
+ # setup requisite particle properties and initial conditions
+
+ if hcp:
+ wij_sum = uniform_distribution.get_number_density_hcp(dx, dy, kernel, h0)
+ volume = 1./wij_sum
+ else:
+ volume = dx*dy
+
+ particles = _setup_particle_properties([fluid, solid, obstacle], volume=volume)
+
+ return particles
+
+# Create the application.
+app = Application()
+
+integrator = Integrator(fluid=TransportVelocityStep(),
+ obstacle=TwoStageRigidBodyStep())
+
+# Create a solver.
+solver = Solver(kernel=kernel, dim=2, integrator=integrator,
+ tf=tf, dt=dt, adaptive_timestep=False,
+ output_at_times=[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0])
+
+class SPHERICBenchmarkAcceleration(Equation):
+ r"""Equation to set the acceleration for the moving square
+ benchmark problem.
+
+ We use scipy.optimize to fit the Gaussian:
+
+ .. math::
+
+ a \exp( -\frac{(t-b)^2}{2c^2} ) + d
+
+ to the SPHERIC Motion.dat file. The values for the parameters are
+
+ a = 2.8209512
+ b = 0.525652151
+ c = 0.14142151
+ d = -2.55580905e-08
+
+ Notes:
+
+ This equation must be instantiated with no sources
+
+ """
+ def loop(self, d_idx, d_ax, t=0.0):
+ a = 2.8209512
+ b = 0.525652151
+ c = 0.14142151
+ d = -2.55580905e-08
+
+ # compute the acceleration and set it for the destination
+ d_ax[d_idx] = a*exp( -(t-b)*(t-b)/(2.0*c*c) ) + d
+
+equations = [
+
+ # set the acceleration for the obstacle using the special function
+ # mimicing 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 shepard filtered velocity
+ # for the fluid phase is determined.
+ Group(
+ equations=[
+ StateEquation(dest='fluid', sources=None, p0=p0, rho0=rho0, b=1.0),
+ ShepardFilteredVelocity(dest='fluid', 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),
+ ]
+
+# Setup the application and solver. This also generates the particles.
+app.setup(solver=solver, equations=equations,
+ particle_factory=create_particles)
+
+app.run()
+EOF
+
+python moving_square.py
+ls -ln
+ls -ln moving_square_output/
+
+echo "run: OK"
+
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/pysph.git
More information about the debian-science-commits
mailing list