Пример #1
0
def test_sph_calc():

    x = numpy.array([
        0,
    ])
    y = numpy.array([
        0,
    ])
    z = numpy.array([
        0,
    ])
    h = numpy.ones_like(x)

    pa = base.get_particle_array(name="test",
                                 x=x,
                                 y=y,
                                 z=z,
                                 h=h,
                                 _tmpx=z,
                                 _tmpy=z,
                                 _tmpz=z)
    particles = base.Particles(arrays=[
        pa,
    ])
    kernel = base.CubicSplineKernel(dim=1)

    vector_force1 = sph.VectorForce.withargs(force=base.Point(1, 1, 1))
    vector_force2 = sph.VectorForce.withargs(force=base.Point(1, 1, 1))

    func1 = vector_force1.get_func(pa, pa)
    func2 = vector_force2.get_func(pa, pa)

    calc = sph.SPHCalc(particles=particles,
                       sources=[pa, pa],
                       dest=pa,
                       kernel=kernel,
                       funcs=[func1, func2],
                       updates=['u', 'v', 'w'],
                       integrates=True)

    # evaluate the calc. Accelerations are stored in _tmpx, _tmpy and _tmpz

    calc.sph('_tmpx', '_tmpy', '_tmpz')

    tmpx, tmpy, tmpz = pa.get('_tmpx', '_tmpy', '_tmpz')

    # the acceleration should be 2 in each direction

    assert (abs(tmpx[0] - 2.0) < 1e-16)
    assert (abs(tmpy[0] - 2.0) < 1e-16)
    assert (abs(tmpz[0] - 2.0) < 1e-16)
Пример #2
0
def get_wall():
    """ Get the wall particles """

    left = base.Line(base.Point(), box_height, pi2)

    top = base.Line(base.Point(0, box_height), box_length, 0)

    right = base.Line(base.Point(box_length, box_height), box_height, pi + pi2)

    bottom = base.Line(base.Point(box_length), box_length, pi)

    box_geom = base.Geometry('box', [left, top, right, bottom], is_closed=True)
    box_geom.mesh_geometry(dx)
    box = box_geom.get_particle_array(re_orient=False)

    box.m[:] = m
    box.h[:] = h

    return box
Пример #3
0
    def get_reference_solution(self):
        """ Evaluate the force on each particle manually """
        
        pa = self.pa
        forces = []

        x,y,z,p,m,h,rho = pa.get('x','y','z','p','m','h','rho')

        kernel = base.CubicSplineKernel(dim=2)

        for i in range(self.np):

            force = base.Point()
            xi, yi, zi = x[i], y[i], z[i]

            ri = base.Point(xi,yi,zi)

            Pi, rhoi = p[i], rho[i]
            hi = h[i]

            for j in range(self.np):

                grad = base.Point()
                xj, yj, zj = x[j], y[j], z[j]
                Pj, rhoj = p[j], rho[j]
                hj, mj = m[j], h[j]

                havg = 0.5 * (hi + hj)

                rj = base.Point(xj, yj, zj)
        
                tmp = -mj * ( Pi/(rhoi*rhoi) + Pj/(rhoj*rhoj) )
                kernel.py_gradient(ri, rj, havg, grad)

                force.x += tmp*grad.x
                force.y += tmp*grad.y
                force.z += tmp*grad.z

            forces.append(force)

        return forces
Пример #4
0
    def eval(self, solver, count):

        if not ((count % self.count) == 0):
            return

        particles = solver.particles
        time = solver.t

        nnps = particles.nnps_manager
        locator_cache = nnps.particle_locator_cache

        num_locs = len(locator_cache)
        locators = locator_cache.values()

        fname_base = os.path.join(self.path + "/neighbors_" + str(self.rank))

        cell_manager = particles.cell_manager
        cell_size = cell_manager.cell_size

        for i in range(num_locs):
            loc = locators[i]
            dest = loc.dest

            particle_indices = dest.get('idx')

            x, y, z = dest.get("x", "y", "z")

            neighbor_idx = {}

            nrp = dest.num_real_particles

            for j in range(nrp):
                neighbors = loc.py_get_nearest_particles(j)

                temp = dest.extract_particles(neighbors)
                particle_idx = particle_indices[j]

                pnt = base.Point(x[j], y[j], z[j])
                cid = py_find_cell_id(pnt, cell_size)

                idx = temp.get_carray("idx")

                neighbor_idx[particle_idx] = {'neighbors': idx, 'cid': cid}

            fname = fname_base + "_" + dest.name + "_" + str(time)

            f = open(fname, 'w')
            pickle.dump(neighbor_idx, f)
            f.close()

            fname_cells = os.path.join(self.path + "/cells_" + str(self.rank))
            fname_cells += "_" + str(time)
            cell_manager.get_particle_representation(fname_cells)
Пример #5
0
def draw_cell(cell, color="b"):
    centroid = base.Point()
    cell.get_centroid(centroid)
    
    half_size = 0.5 * cell.cell_size

    x1, y1 = centroid.x - half_size, centroid.y - half_size
    x2, y2 = x1 + cell.cell_size, y1
    x3, y3 = x2, y1 + cell.cell_size
    x4, y4 = x1, y3

    pylab.plot([x1,x2,x3,x4,x1], [y1, y2, y3, y4,y1], color)
Пример #6
0
def get_square():
    """ Get the square particle array """

    left = base.Line(base.Point(1, 2), square_side, pi2)

    top = base.Line(base.Point(1, 3), square_side, 0)

    right = base.Line(base.Point(2, 3), square_side, pi + pi2)

    bottom = base.Line(base.Point(2, 2), square_side, pi)

    square_geom = base.Geometry('square', [left, top, right, bottom],
                                is_closed=True)

    square_geom.mesh_geometry(dx)
    square = square_geom.get_particle_array(name="square", re_orient=True)

    square.m[:] = m
    square.h[:] = h

    return square
Пример #7
0
def get_fluid_particles():

    x, y = get_2D_staggered_grid(base.Point(dx, dx),
                                 base.Point(dx / 2, dx / 2),
                                 base.Point(1.0, 2.0), dx)

    print 'Number of fluid particles: ', len(x)

    hf = numpy.ones_like(x) * h
    mf = numpy.ones_like(x) * dx * dy * ro * 0.5
    rhof = numpy.ones_like(x) * ro
    csf = numpy.ones_like(x) * co

    fluid = base.get_particle_array(name="fluid",
                                    type=Fluid,
                                    x=x,
                                    y=y,
                                    h=hf,
                                    m=mf,
                                    rho=rhof,
                                    cs=csf)

    return fluid
Пример #8
0
    def get_reference_solution(self):
        """ Evaluate the force on each particle manually """

        pa = self.pa
        rhos = []

        x, y, z, p, m, h, rho = pa.get('x', 'y', 'z', 'p', 'm', 'h', 'rho')

        kernel = base.CubicSplineKernel(dim=2)

        for i in range(self.np):

            rho = 0.0
            xi, yi, zi = x[i], y[i], z[i]

            ri = base.Point(xi, yi, zi)

            hi = h[i]

            for j in range(self.np):

                grad = base.Point()
                xj, yj, zj = x[j], y[j], z[j]
                hj, mj = m[j], h[j]

                havg = 0.5 * (hi + hj)

                rj = base.Point(xj, yj, zj)

                wij = kernel.py_function(ri, rj, havg)

                rho += mj * wij

            rhos.append(rho)

        return rhos
Пример #9
0
    def test_build_cell(self):
        """ Test the building of the base cell """

        cm = self.cm

        cm.update_global_properties()

        cm.compute_block_size(0)

        cm.compute_cell_size(0,0)

        cm.py_rebuild_array_indices()

        cm.py_setup_cells_dict()
        
        cm.setup_processor_map()

        cm._build_cell()

        cells_dict = cm.cells_dict

        ncells = len(cells_dict)
        self.assertEqual(ncells, 1)

        cell = cells_dict.values()[0]

        centroid = base.Point()
        cell.get_centroid(centroid)

        self.assertAlmostEqual(centroid.x, 0.25, 10)
        self.assertAlmostEqual(centroid.y, 0.25, 10)
        self.assertAlmostEqual(centroid.z, 0.25, 10)

        indices = []
        cell.get_particle_ids(indices)
        index_array = indices[0]

        index_array_numpy = index_array.get_npy_array()
        index_array_numpy.sort()

        np = len(index_array_numpy)
        self.assertEqual(np, 25)

        for i in range(np):
            self.assertEqual(index_array_numpy[i], i)
Пример #10
0
        def get_force(i):
            xi = pa.x[i]
            yi = pa.y[i]

            force = base.Point()

            for j in range(self.np):
                xj = pa.x[j]
                yj = pa.y[j]

                xji = xj - xi
                yji = yj - yi
                dist = numpy.sqrt(xji**2 + yji**2)

                invr = 1.0 / (dist + self.eps)
                invr3 = invr * invr * invr

                if not (i == j):

                    force.x += invr3 * xji
                    force.y += invr3 * yji

            return force
Пример #11
0
    def get_reference_solution(self):
        """ Evaluate the force on each particle manually """

        pa = self.pa
        forces = []

        x, y, z, p, m, h, rho = pa.get('x', 'y', 'z', 'p', 'm', 'h', 'rho')
        u, v, w = pa.get('u', 'v', 'w')

        kernel = base.CubicSplineKernel(dim=2)

        for i in range(self.np):

            force = base.Point()
            xa, ya, za = x[i], y[i], z[i]
            ua, va, wa = u[i], v[i], w[i]

            ra = base.Point(xa, ya, za)
            Va = base.Point(ua, va, wa)

            Pa, rhoa = p[i], rho[i]
            ha = h[i]

            for j in range(self.np):

                grad = base.Point()
                xb, yb, zb = x[j], y[j], z[j]
                ub, vb, wb = u[j], v[j], w[j]

                Pb, rhob = p[j], rho[j]
                hb, mb = m[j], h[j]

                havg = 0.5 * (ha + hb)

                rb = base.Point(xb, yb, zb)
                Vb = base.Point(ub, vb, wb)

                tmp = 0.5 * mb * (Pa / (rhoa * rhoa) + Pb / (rhob * rhob))
                kernel.py_gradient(ra, rb, havg, grad)

                force.x += tmp * grad.dot(Va - Vb)

            forces.append(force)

        return forces
Пример #12
0
    def get_reference_solution(self):
        """ Evaluate the force on each particle manually """
        
        pa = self.pa
        result = []

        rho, e = pa.get('rho', 'e')

        kernel = base.CubicSplineKernel(dim=2)
        gamma = 1.4

        for i in range(self.np):

            force = base.Point()

            rhoa = rho[i]
            ea = e[i]

            force.x = (gamma - 1.0) * ea * rhoa
            force.y = numpy.sqrt( (gamma-1.0) * ea )

            result.append(force)

        return result
Пример #13
0
dx = dy = h/(1.3)
g = -9.81

xf = numpy.array([0])
yf = numpy.array([0.3])
hf = numpy.array([h])
mf = numpy.array([1.0])
vf = numpy.array([0.0])
cf = numpy.array([25.0])
rhof = numpy.array([1.0])

fluid = base.get_particle_array(name="fluid", type=Fluid, x=xf, y=yf,
                                h=hf, m=mf, rho=rhof, v=vf, cs=cf)

#generate the boundary
l = base.Line(base.Point(-.5), 1.0, 0)
g = base.Geometry('line', [l], False)
g.mesh_geometry(dx)
boundary = g.get_particle_array(re_orient=True)

boundary.m[:] = 1.0

particles = base.Particles(arrays=[fluid, boundary])
app.particles = particles


kernel = base.HarmonicKernel(dim=2, n=3)

s = solver.Solver(dim=2, integrator_type=solver.PredictorCorrectorIntegrator)

# set the kernel as the default for the solver
Пример #14
0
    def get_reference_solution(self):
        """ Evaluate the force on each particle manually """

        pa = self.pa
        forces = []

        x, y, z, p, m, h, rho = pa.get('x', 'y', 'z', 'p', 'm', 'h', 'rho')
        u, v, w, cs = pa.get('u', 'v', 'w', 'cs')

        kernel = base.CubicSplineKernel(dim=2)

        for i in range(self.np):

            force = base.Point()
            xa, ya, za = x[i], y[i], z[i]
            ua, va, wa = u[i], v[i], w[i]

            ra = base.Point(xa, ya, za)
            Va = base.Point(ua, va, wa)

            Pa, rhoa = p[i], rho[i]
            ha = h[i]

            for j in range(self.np):

                grad = base.Point()
                xb, yb, zb = x[j], y[j], z[j]
                Pb, rhob = p[j], rho[j]
                hb, mb = h[j], m[j]

                ub, vb, wb = u[j], v[j], w[j]
                Vb = base.Point(ub, vb, wb)

                havg = 0.5 * (hb + ha)

                rb = base.Point(xb, yb, zb)

                tmp = Pa / (rhoa * rhoa) + Pb / (rhob * rhob)
                kernel.py_gradient(ra, rb, havg, grad)

                vab = Va - Vb
                rab = ra - rb

                dot = vab.dot(rab)
                piab = 0.0

                if dot < 0.0:
                    alpha = 1.0
                    beta = 1.0
                    gamma = 1.4
                    eta = 0.1

                    cab = 0.5 * (cs[i] + cs[j])

                    rhoab = 0.5 * (rhoa + rhob)
                    muab = havg * dot

                    muab /= (rab.norm() + eta * eta * havg * havg)

                    piab = -alpha * cab * muab + beta * muab * muab
                    piab /= rhoab

                tmp += piab
                tmp *= 0.5 * mb

                force.x += tmp * (vab.dot(grad))

            forces.append(force)

        return forces
Пример #15
0
 def get_particle_position(self, idx):
     
     if idx < 0 or idx > self.np:
         raise RunTimeError, "Invalid Particle Index!"
     
     return base.Point(*self.particle_positions[idx].values())
Пример #16
0
    def get_reference_solution(self):
        """ Evaluate the force on each particle manually """
        
        pa = self.pa
        forces = []

        x,y,z,p,m,h,rho = pa.get('x','y','z','p','m','h','rho')
        u,v,w,cs = pa.get('u','v','w','cs')

        kernel = base.CubicSplineKernel(dim=2)

        for i in range(self.np):

            force = base.Point()
            xi, yi, zi = x[i], y[i], z[i]
            ui, vi, wi = u[i], v[i], w[i]

            ri = base.Point(xi,yi,zi)
            Va = base.Point(ui,vi,wi)

            Pi, rhoi = p[i], rho[i]
            hi = h[i]

            for j in range(self.np):

                grad = base.Point()
                xj, yj, zj = x[j], y[j], z[j]
                Pj, rhoj = p[j], rho[j]
                hj, mj = h[j], m[j]

                uj, vj, wj = u[j], v[j], w[j]
                Vb = base.Point(uj,vj,wj)

                havg = 0.5 * (hi + hj)

                rj = base.Point(xj, yj, zj)
        
                tmp = Pi/(rhoi*rhoi) + Pj/(rhoj*rhoj)
                kernel.py_gradient(ri, rj, havg, grad)

                vab = Va-Vb
                rab = ri-rj

                dot = vab.dot(rab)
                piab = 0.0

                if dot < 0.0:
                    alpha = 1.0
                    beta = 1.0
                    gamma = 1.4
                    eta = 0.1

                    cab = 0.5 * (cs[i] + cs[j])

                    rhoab = 0.5 * (rhoi + rhoj)
                    muab = havg * dot

                    muab /= ( rab.norm() + eta*eta*havg*havg )

                    piab = -alpha*cab*muab + beta*muab*muab
                    piab /= rhoab

                tmp += piab
                tmp *= -mj
                    
                force.x += tmp*grad.x
                force.y += tmp*grad.y
                force.z += tmp*grad.z

            forces.append(force)

        return forces
Пример #17
0
    def setUp(self):
        """ A simple simulation in 2D with boundary particles spaced with a
        distance dp. The fluid particles are in a row just above as shown
        in the fgure. 

                   dx
                  o   o   o   o   o
            x x x x x x x x x x x x x x x  

        Y
        |  Z
        | /
        |/___ X
            

        Expected Behavior:
        -------------------
        The Monaghan Boundary force is defned such that a particle moving 
        parallel to the wall experiences a constant force.
        Each fluid particle can be thought of successive instances of a 
        moving particle and hence each of them should experience the same
        force.

        """

        #fluid particle spacing
        self.dx = dx = 0.1

        #solid particle spacing
        self.dp = dp = 0.05

        #the fluid properties
        xf = numpy.array([-.2, -.1, 0.0, 0.1, 0.2])
        yf = numpy.array([dp, dp, dp, dp, dp])
        hf = numpy.ones_like(xf) * 2 * dx
        mf = numpy.ones_like(xf) * dx
        cs = numpy.ones_like(xf)
        rhof = numpy.ones_like(xf)

        self.fluid = base.get_particle_array(x=xf,
                                             y=yf,
                                             h=hf,
                                             m=mf,
                                             rho=rhof,
                                             cs=cs,
                                             ax=mf,
                                             ay=mf,
                                             az=mf,
                                             name='fluid',
                                             type=Fluid)

        l = base.Line(base.Point(-0.35), 0.70, 0.0)
        g = base.Geometry('line', lines=[l], is_closed=False)
        g.mesh_geometry(dp)
        self.solid = g.get_particle_array(re_orient=True)

        self.particles = particles = base.Particles(
            arrays=[self.fluid, self.solid])

        self.kernel = kernel = base.CubicSplineKernel(dim=2)

        self.solver = solver.Solver(kernel.dim, solver.EulerIntegrator)

        self.solver.add_operation(
            solver.SPHIntegration(sph.MonaghanBoundaryForce.withargs(delp=dp),
                                  from_types=[Solid],
                                  on_types=[Fluid],
                                  updates=['u', 'v', 'w'],
                                  id='boundary'))

        self.solver.setup_integrator(particles)

        self.integrator = self.solver.integrator