[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