예제 #1
0
    def update(self, delta_t=None, *args, **kwargs):
        """ Update all the particles in the bucket to the next time level."""

        logger.info("In ParticleBucket.Update: %d particles",
                    len(self.particles))

        # redistribute particles to partitions in case of parallel adaptivity
        if Parallel.is_parallel():
            self.redistribute()
        # reset the particle timestep
        if delta_t is not None:
            self.delta_t = delta_t
        self.system.temporal_cache.range(self.time, self.time + self.delta_t)
        live = self.system.in_system(self.pos(), len(self), self.time)
        _ = []
        for k, part in enumerate(self):
            if live[k]:
                part.update(self.delta_t, *args, **kwargs)
            else:
                self.dead_particles.append(part)
                _.append(part)
        for part in _:
            self.particles.remove(part)
        self.redistribute()
        self.insert_particles(*args, **kwargs)
        self.time += self.delta_t
        for part in self:
            part.time = self.time
예제 #2
0
def mclaury_mass_coeff(collision, material=None):
    """ Wear rate coefficient of collision from Mclaury correlation"""
    material = material or STANDARD_MATERIAL

    n_exp = material['n']
    coeff = material['k']
    hardness = material['H']
    sharpness_factor = material['F_s']
    penetration_factor = material['F_B']

    logger.info('collision angle: %s', collision.angle)
    logger.info('collision normal: %s', collision.normal)

    def fun(theta):
        """ Mclaury angle response function"""
        if numpy.tan(theta) > 1.0 / 3.0:
            return numpy.cos(theta)**2 / 3.0
        #otherwise
        return numpy.sin(2.0 * theta) - 3.0 * numpy.sin(theta)**2

    vel = numpy.sqrt(numpy.dot(collision.vel, collision.vel))
    vel0 = 0.1
    beta = 1.0

    return (coeff * hardness * sharpness_factor * penetration_factor *
            (vel**n_exp * fun(collision.angle) +
             max(0.0,
                 beta * (vel * numpy.sin(collision.angle) - vel0)**2)))
예제 #3
0
    def __init__(self,
                 X,
                 V,
                 time=0,
                 delta_t=1.0e-3,
                 parameters=ParticleBase.PhysicalParticle(),
                 system=System.System(),
                 field_data=None,
                 online=True,
                 **kwargs):
        """Initialize the bucket

        Args:
            X (float): Initial particle positions.
            V (float): Initial velocities
        """

        logger.info("Initializing ParticleBucket")

        field_data = field_data or {}

        self.system = system

        ### pick only points which are actually in our test box
        live = system.in_system(X, len(X), time)
        X = X.compress(live, axis=0)
        V = V.compress(live, axis=0)

        self.particles = []
        self.dead_particles = []
        self.parameters = parameters
        for _, (dummy_pos, dummy_vel) in enumerate(zip(X, V)):
            par = Particle((dummy_pos, dummy_vel, time, delta_t),
                           system=self.system,
                           parameters=parameters.randomize(),
                           **kwargs)
            if par.pure_lagrangian:
                par.vel = par.picker(par.pos, time)[0]
            for name, value in field_data.items():
                par.fields[name] = copy.deepcopy(value[_])
            if self.system.temporal_cache:
                dummy_u, dummy_p = par.get_fluid_properties()
                if dummy_u is not None:
                    self.particles.append(par)
            else:
                self.particles.append(par)
        self.time = time
        self.delta_t = delta_t
        self._online = online
        self.solid_pressure_gradient = numpy.zeros((len(self.particles), 3))
        for particle, gsp in zip(self, self.solid_pressure_gradient):
            particle.solid_pressure_gradient = gsp

        self.redistribute()
예제 #4
0
def point_average(model, bucket):
    """ Calculate a volume fraction estimate at the level of the grid."""

    ugrid = vtk.vtkUnstructuredGrid()
    ugrid.DeepCopy(model)

    locator = vtk.vtkPointLocator()
    locator.SetDataSet(ugrid)
    locator.BuildLocator()

    LENGTH = 0.05

    volfrac = numpy.zeros(ugrid.GetNumberOfPoints())
    volume = numpy.zeros(ugrid.GetNumberOfPoints())
    cell_volume = numpy.zeros(ugrid.GetNumberOfPoints())
    temperature = numpy.zeros(ugrid.GetNumberOfPoints())
    solid_pressure = numpy.zeros(ugrid.GetNumberOfPoints())
    velocity = numpy.zeros((ugrid.GetNumberOfPoints(), 3))

    for _ in range(ugrid.GetNumberOfCells()):
        cell = ugrid.GetCell(_)

        loc_vol = get_measure(cell) / cell.GetNumberOfPoints()

        for i in range(cell.GetNumberOfPoints()):
            logger.info(cell.GetPointIds().GetId(i))
            cell_volume[cell.GetPointIds().GetId(i)] += loc_vol

    for particle in bucket:
        point_list = vtk.vtkIdList()
        locator.FindPointsWithinRadius(LENGTH, particle.pos, point_list)

        for _ in range(point_list.GetNumberOfIds()):
            point_index = point_list.GetId(_)

            rad2 = 0.0 * distance2(ugrid.GetPoints().GetPoint(point_index),
                                   particle.pos)
            rad2 /= LENGTH**2

            gamma = particle.volume * numpy.exp(-rad2)

            volume[point_index] += gamma
            velocity[point_index, :] += particle.vel * gamma

    for _ in range(ugrid.GetNumberOfPoints()):
        if volume[_] > 1.0e-12:
            velocity[_, :] /= volume[_]

    volfrac = volume / cell_volume

    for particle in bucket:
        point_list = vtk.vtkIdList()
        locator.FindPointsWithinRadius(LENGTH, particle.pos, point_list)

        for _ in range(point_list.GetNumberOfIds()):
            point_index = point_list.GetId(_)

            rad2 = distance2(ugrid.GetPoints().GetPoint(point_index),
                             particle.pos)
            rad2 /= LENGTH**2

            gamma = particle.volume * numpy.exp(-rad2)

            c = distance2(particle.vel, velocity[point_index, :])

            temperature[point_index] += c * gamma

    for _ in range(ugrid.GetNumberOfPoints()):
        if volume[_] > 1.0e-12:
            temperature[_] /= volume[_]

    solid_pressure = (bucket.particles[0].parameters.rho * volfrac *
                      radial_distribution_function(volfrac) * temperature)

    data = [vtk.vtkDoubleArray()]
    data[0].SetName('SolidVolumeFraction')
    data.append(vtk.vtkDoubleArray())
    data[1].SetName('SolidVolumeVelocity')
    data[1].SetNumberOfComponents(3)
    data.append(vtk.vtkDoubleArray())
    data[2].SetName('GranularTemperature')
    data.append(vtk.vtkDoubleArray())
    data[3].SetName('SolidPressure')

    for _ in range(ugrid.GetNumberOfPoints()):
        data[0].InsertNextValue(cell_volume[_])
        data[1].InsertNextTuple3(*(velocity[_]))
        data[2].InsertNextValue(temperature[_])
        data[3].InsertNextValue(solid_pressure[_])

    pdata = vtk.vtkDoubleArray()
    pdata.SetName('Time')

    for _ in range(ugrid.GetNumberOfPoints()):
        pdata.InsertNextValue(bucket.time)

    for _ in data:
        ugrid.GetPointData().AddArray(_)
    ugrid.GetPointData().AddArray(pdata)

    return ugrid