Beispiel #1
0
 def test_properties_dict(self):
     world = World()
     world.add(Fluid(Domain([16, 16])), physics=IncompressibleFlow())
     world.add(Inflow(Sphere((8, 8), radius=4)))
     # world.add(ConstantDensity(box[0:2, 6:10], 1.0))
     world.add(Fan(Sphere((10, 8), 5), [-1, 0]))
     struct.properties_dict(world.state)
Beispiel #2
0
 def simulate(centers):
     world = World()
     fluid = world.add(Fluid(Domain([5, 4], boundaries=CLOSED, box=AABox(0, [40, 32])),
                             buoyancy_factor=0.1,
                             batch_size=centers.shape[0]),
                       physics=IncompressibleFlow(pressure_solver=SparseCG(max_iterations=3)))
     world.add(Inflow(Sphere(center=centers, radius=3), rate=0.2))
     world.add(Fan(Sphere(center=centers, radius=5), acceleration=[1.0, 0]))
     world.step(dt=1.5)
     world.step(dt=1.5)
     world.step(dt=1.5)
     print()
     return fluid.density.data[0, ...], fluid.velocity.unstack()[0].data[0, ...], fluid.velocity.unstack()[1].data[0, ...]
Beispiel #3
0
 def simulate(centers):
     world = World()
     fluid = world.add(Fluid(Domain(x=5, y=4, bounds=Box(0, [40, 32])),
                             buoyancy_factor=0.1,
                             batch_size=centers.shape[0]),
                       physics=IncompressibleFlow())
     world.add(Inflow(Sphere(center=centers, radius=3), rate=0.2))
     world.add(Fan(Sphere(center=centers, radius=5), acceleration=[1.0, 0]))
     world.step(dt=1.5)
     world.step(dt=1.5)
     world.step(dt=1.5)
     assert not math.close(fluid.density.values, 0)
     print()
     return fluid.density.values.batch[0], fluid.velocity.values.batch[0]
Beispiel #4
0
    def points(self,
               points: Tensor or Number or tuple or list,
               values: Tensor or Number = None,
               radius: Tensor or float or int or None = None,
               extrapolation: math.Extrapolation = math.extrapolation.ZERO,
               color: str or Tensor or tuple or list or None = None) -> PointCloud:
        """
        Create a `phi.field.PointCloud` from the given `points`.
        The created field has no channel dimensions and all points carry the value `1`.

        Args:
            points: point locations in physical units
            values: (optional) values of the particles, defaults to 1.
            radius: (optional) size of the particles
            extrapolation: (optional) extrapolation to use, defaults to extrapolation.ZERO
            color: (optional) color used when plotting the points

        Returns:
            `phi.field.PointCloud` object
        """
        extrapolation = extrapolation if isinstance(extrapolation, math.Extrapolation) else self.boundaries[extrapolation]
        if radius is None:
            radius = math.mean(self.bounds.size) * 0.005
        # --- Parse points: tuple / list ---
        if isinstance(points, (tuple, list)):
            if len(points) == 0:  # no points
                points = math.zeros(instance(points=0), channel(vector=1))
            elif isinstance(points[0], Number):  # single point
                points = math.tensor([points], instance('points'), channel('vector'))
            else:
                points = math.tensor(points, instance('points'), channel('vector'))
        elements = Sphere(points, radius)
        if values is None:
            values = math.tensor(1.)
        return PointCloud(elements, values, extrapolation, add_overlapping=False, bounds=self.bounds, color=color)
Beispiel #5
0
def tensor_as_field(t: Tensor):
    """
    Interpret a `Tensor` as a `CenteredGrid` or `PointCloud` depending on its dimensions.

    Unlike the `CenteredGrid` constructor, this function will have the values sampled at integer points for each spatial dimension.

    Args:
        t: `Tensor` with either `spatial` or `instance` dimensions.

    Returns:
        `CenteredGrid` or `PointCloud`
    """
    if spatial(t):
        assert not instance(
            t
        ), f"Cannot interpret tensor as Field because it has both spatial and instance dimensions: {t.shape}"
        bounds = Box(-0.5, math.wrap(spatial(t), channel('vector')) - 0.5)
        return CenteredGrid(t, 0, bounds=bounds)
    if instance(t):
        assert not spatial(
            t
        ), f"Cannot interpret tensor as Field because it has both spatial and instance dimensions: {t.shape}"
        assert 'vector' in t.shape, f"Cannot interpret tensor as PointCloud because it has not vector dimension."
        point_count = instance(t).volume
        bounds = data_bounds(t)
        radius = math.vec_length(
            bounds.size) / (1 + point_count**(1 / t.vector.size))
        return PointCloud(Sphere(t, radius=radius))
Beispiel #6
0
def respect_boundaries(particles: PointCloud,
                       domain: Domain,
                       not_accessible: list,
                       offset: float = 0.5) -> PointCloud:
    """
    Enforces boundary conditions by correcting possible errors of the advection step and shifting particles out of 
    obstacles or back into the domain.
    
    Args:
        particles: PointCloud holding particle positions as elements
        domain: Domain for which any particles outside should get shifted inwards
        not_accessible: List of Obstacle or Geometry objects where any particles inside should get shifted outwards
        offset: Minimum distance between particles and domain boundary / obstacle surface after particles have been shifted.

    Returns:
        PointCloud where all particles are inside the domain / outside of obstacles.
    """
    new_positions = particles.elements.center
    for obj in not_accessible:
        if isinstance(obj, Obstacle):
            obj = obj.geometry
        new_positions = obj.push(new_positions, shift_amount=offset)
    new_positions = (~domain.bounds).push(new_positions, shift_amount=offset)
    return particles.with_(
        elements=Sphere(new_positions,
                        math.mean(particles.bounds.size) * 0.005))
Beispiel #7
0
 def _test_make_incompressible(self, grid_type: type,
                               extrapolation: math.Extrapolation,
                               **batch_dims):
     result = None
     for i, backend in enumerate(BACKENDS):
         with backend:
             smoke = CenteredGrid(Sphere(
                 center=(math.random_uniform(batch(**batch_dims)) * 100,
                         10),
                 radius=5),
                                  extrapolation,
                                  x=16,
                                  y=20,
                                  bounds=Box[0:100, 0:100])
             velocity = grid_type(0,
                                  extrapolation,
                                  x=16,
                                  y=20,
                                  bounds=Box[0:100, 0:100])
             for _ in range(2):
                 velocity += smoke * (0, 0.1) @ velocity
                 velocity, _ = fluid.make_incompressible(velocity)
             math.assert_close(divergence(velocity).values,
                               0,
                               abs_tolerance=2e-5)
             if result is None:
                 result = velocity
             else:
                 field.assert_close(
                     result,
                     abs_tolerance=1e-5,
                     msg=
                     f"Simulation with {backend} does not match {BACKENDS[:i]}"
                 )
Beispiel #8
0
    def test_gradient_batch_independence(self):
        session = Session(None)  # Used to run the TensorFlow graph

        world = World()
        fluid = world.add(Fluid(Domain([40, 32], boundaries=CLOSED), buoyancy_factor=0.1, batch_size=2), physics=IncompressibleFlow())
        world.add(Inflow(Sphere(center=numpy.array([[5, 4], [5, 8]]), radius=3), rate=0.2))
        fluid.velocity = variable(fluid.velocity)  # create TensorFlow variable
        # fluid.velocity *= 0
        initial_state = fluid.state  # Remember the state at t=0 for later visualization
        session.initialize_variables()

        for frame in range(3):
            world.step(dt=1.5)

        target = session.run(fluid.density).data[0, ...]

        loss = tf.nn.l2_loss(fluid.density.data[1, ...] - target)
        self_loss = tf.nn.l2_loss(fluid.density.data[0, ...] - target)
        # loss = self_loss
        optim = tf.train.GradientDescentOptimizer(learning_rate=0.2).minimize(loss)
        session.initialize_variables()

        for optim_step in range(3):
            _, loss_value, sl_value = session.run([optim, loss, self_loss])

        staggered_velocity = session.run(initial_state.velocity).staggered_tensor()
        numpy.testing.assert_equal(staggered_velocity[0, ...], 0)
        assert numpy.all(~numpy.isnan(staggered_velocity))
Beispiel #9
0
 def test_effects(self):
     world = World()
     fluid = world.add(Fluid(Domain([16, 16])))
     fan = world.add(Fan(Sphere((10, 8), 5), [-1, 0]))
     obstacle = world.add(Obstacle(box[0:1, 0:1]))
     world.step(dt=1)
     world.step(dt=0.5)
     assert fluid.age == fan.age == obstacle.age == 1.5
Beispiel #10
0
 def test_effects(self):
     world = World()
     fluid = world.add(Fluid(Domain(x=16, y=16)), physics=IncompressibleFlow())
     fan = world.add(Fan(Sphere((10, 8), 5), [-1, 0]))
     obstacle = world.add(Obstacle(Box[0:1, 0:1]))
     world.step(dt=1)
     world.step(dt=0.5)
     assert fluid.age == fan.age == obstacle.age == 1.5
Beispiel #11
0
 def test_plot_multiple(self):
     grid = CenteredGrid(Noise(batch(b=2)), 0, Box[0:1, 0:1], x=50, y=10)
     grid2 = CenteredGrid(grid, 0, Box[0:2, 0:1], x=20, y=50)
     points = wrap([(.2, .4), (.9, .8)], instance('points'),
                   channel('vector'))
     cloud = PointCloud(Sphere(points, radius=0.1), bounds=Box(0, [1, 1]))
     titles = math.wrap([['b=0', 'b=0', 'points'], ['b=1', 'b=1', '']],
                        spatial('rows,cols'))
     self._test_plot(grid, grid2, cloud, row_dims='b', title=titles)
Beispiel #12
0
 def _test_make_incompressible_batched(self, grid_type):
     DOMAIN = Domain(x=16, y=16, boundaries=CLOSED, bounds=Box[0:100, 0:100])
     smoke = DOMAIN.scalar_grid(Sphere(center=(math.random_uniform(batch=2) * 100, 10), radius=5))
     velocity = DOMAIN.vector_grid(0, grid_type)
     for _ in range(2):
         velocity += smoke * (0, 0.1) >> velocity
         velocity, pressure, _, _ = fluid.make_incompressible(velocity, DOMAIN)
     math.assert_close(divergence(velocity).values, 0, abs_tolerance=2e-5)
     return velocity.values
Beispiel #13
0
 def test_smoke_plume(self):
     world = World()
     world.batch_size = 3
     fluid = world.add(Fluid(Domain(x=16, y=16)), physics=IncompressibleFlow())
     inflow = world.add(Inflow(Sphere((8, 8), radius=4)))
     world.step()
     world.step(fluid)
     self.assertAlmostEqual(fluid.age, 2.0)
     self.assertAlmostEqual(inflow.age, 1.0)
Beispiel #14
0
 def test_simpleplume(self):
     world = World()
     world.batch_size = 3
     fluid = world.add(Fluid(Domain([16, 16])))
     inflow = world.add(Inflow(Sphere((8, 8), radius=4)))
     world.step()
     world.step(fluid)
     self.assertAlmostEqual(fluid.age, 2.0)
     self.assertAlmostEqual(inflow.age, 1.0)
Beispiel #15
0
 def test_convert_point_cloud(self):
     loc = math.random_uniform(instance(points=4), channel(vector=2))
     val = math.random_normal(instance(points=4), channel(vector=2))
     points = PointCloud(Sphere(loc, radius=1), val)
     for backend in BACKENDS:
         converted = field.convert(points, backend)
         self.assertEqual(converted.values.default_backend, backend)
         self.assertEqual(converted.elements.center.default_backend,
                          backend)
         self.assertEqual(converted.elements.radius.default_backend,
                          backend)
Beispiel #16
0
 def test_overlay(self):
     grid = CenteredGrid(Noise(),
                         extrapolation.ZERO,
                         x=64,
                         y=8,
                         bounds=Box(0, [1, 1]))
     points = wrap([(.2, .4), (.9, .8)], instance('points'),
                   channel('vector'))
     cloud = PointCloud(Sphere(points, radius=.1))
     self._test_plot(overlay(grid, grid * (0.1, 0.02), cloud),
                     title='Overlay')
Beispiel #17
0
 def test_plot_point_cloud_2d_large(self):
     spheres = PointCloud(
         Sphere(wrap([(2, 4), (9, 8), (7, 8)], instance('points'),
                     channel('vector')),
                radius=1))
     cells = PointCloud(
         geom.pack_dims(
             CenteredGrid(0, 0, x=3, y=3, bounds=Box[4:6, 2:4]).elements,
             'x,y', instance('points')))
     cloud = field.stack([spheres, cells], instance('stack'))
     self._test_plot(cloud)
Beispiel #18
0
 def test_plot_point_cloud_2d(self):
     spheres = PointCloud(
         Sphere(wrap([(.2, .4), (.9, .8), (.7, .8)], instance('points'),
                     channel('vector')),
                radius=.1))
     cells = PointCloud(
         geom.pack_dims(
             CenteredGrid(0, 0, x=3, y=3,
                          bounds=Box[.4:.6, .2:.4]).elements, 'x,y',
             instance('points')))
     cloud = field.stack([spheres, cells], instance('stack'))
     self._test_plot(cloud)
Beispiel #19
0
 def test_fluid_tf(self):
     world = World()
     fluid = Fluid(Domain([16, 16]))
     world.add(fluid)
     world.add(Inflow(Sphere((8, 8), radius=4)))
     world.add(Obstacle(box[4:16, 0:8]))
     fluid_in = fluid.copied_with(density=placeholder, velocity=placeholder)
     fluid_out = world.step(fluid_in)
     self.assertIsInstance(fluid_out, Fluid)
     session = Session(Scene.create('data', copy_calling_script=False))
     fluid = session.run(fluid_out, {fluid_in: fluid})
     fluid = session.run(fluid_out, {fluid_in: fluid})
     self.assertIsInstance(fluid, Fluid)
Beispiel #20
0
 def test_plot_vector_3d_batched(self):
     sphere = CenteredGrid(SoftGeometryMask(
         Sphere(x=.5, y=.5, z=.5, radius=.4)),
                           x=10,
                           y=10,
                           z=10,
                           bounds=Box(x=1, y=1, z=1)) * (.1, 0, 0)
     cylinder = CenteredGrid(geom.infinite_cylinder(
         x=16, y=16, inf_dim='z', radius=10),
                             x=32,
                             y=32,
                             z=32) * (0, 0, .1)
     self._test_plot(sphere, cylinder)
Beispiel #21
0
 def test_batched_sphere(self):
     moving_sphere = Sphere(center=np.stack(
         [np.ones(10), np.linspace(0, 10, 10)], axis=-1),
                            radius=1)
     growing_sphere = Sphere(center=0, radius=np.linspace(0, 10, 10))
     # 0D indexing
     values = moving_sphere.value_at(np.zeros([10, 2]) + [1, 4])
     np.testing.assert_equal(values[:, 0], [0, 0, 0, 1, 1, 0, 0, 0, 0, 0])
     values = growing_sphere.value_at(np.zeros([10, 2]) + [0, 4])
     np.testing.assert_equal(values[:, 0], [0, 0, 0, 0, 1, 1, 1, 1, 1, 1])
     # 1D indexing
     values = moving_sphere.value_at(np.zeros([10, 3, 2]) + [1, 4])
     np.testing.assert_equal(values.shape, [10, 3, 1])
     np.testing.assert_equal(values[:, 0, 0],
                             [0, 0, 0, 1, 1, 0, 0, 0, 0, 0])
     values = growing_sphere.value_at(np.zeros([10, 3, 2]) + [0, 4])
     np.testing.assert_equal(values.shape, [10, 3, 1])
     np.testing.assert_equal(values[:, 0, 0],
                             [0, 0, 0, 0, 1, 1, 1, 1, 1, 1])
Beispiel #22
0
 def test_staggered_grid_sizes_by_extrapolation(self):
     s = spatial(x=20, y=10)
     for initializer in [0, Noise(vector=2), (0, 1), Sphere((0, 0), 1)]:
         g_const = StaggeredGrid(initializer,
                                 extrapolation.ZERO,
                                 resolution=s)
         self.assertEqual(g_const.shape,
                          spatial(x=20, y=10) & channel(vector=2))
         self.assertEqual(g_const.values.vector[0].shape, spatial(x=19,
                                                                  y=10))
         g_periodic = StaggeredGrid(initializer,
                                    extrapolation.PERIODIC,
                                    resolution=s)
         self.assertEqual(g_periodic.shape,
                          spatial(x=20, y=10) & channel(vector=2))
         self.assertEqual(g_periodic.values.vector[0].shape,
                          spatial(x=20, y=10))
         g_boundary = StaggeredGrid(initializer,
                                    extrapolation.BOUNDARY,
                                    resolution=s)
         self.assertEqual(g_boundary.shape,
                          spatial(x=20, y=10) & channel(vector=2))
         self.assertEqual(g_boundary.values.vector[0].shape,
                          spatial(x=21, y=10))
Beispiel #23
0
 def test_union_varying(self):
     box = Box[0:1, 0:1]
     sphere = Sphere((0, 0), radius=1)
     union = geom.union(box, sphere)
     math.assert_close(union.approximate_signed_distance((1, 1)),
                       union.approximate_signed_distance((0, -1)), 0)
Beispiel #24
0
 def test_sphere_constructor_kwargs(self):
     s = Sphere(x=0.5, y=2, radius=1.)
     self.assertEqual(s.center.shape.get_item_names('vector'), ('x', 'y'))
Beispiel #25
0
 def test_sphere_volume(self):
     sphere = Sphere(math.tensor([(0, 0, 0), (1, 1, 1)], batch('batch'),
                                 channel('vector')),
                     radius=math.tensor([1, 2], batch('batch')))
     math.assert_close(sphere.volume,
                       [4 / 3 * math.PI, 4 / 3 * 8 * math.PI])
Beispiel #26
0
 def test_circle_area(self):
     sphere = Sphere(math.tensor([(0, 0), (1, 1)], batch('batch'),
                                 channel('vector')),
                     radius=math.tensor([1, 2], batch('batch')))
     math.assert_close(sphere.volume, [math.PI, 4 * math.PI])
Beispiel #27
0
def geometry_at(time):
    return Sphere([time], radius=5)
Beispiel #28
0
 def test_properties_dict(self):
     world = World()
     world.add(Fluid(Domain(x=16, y=16)), physics=IncompressibleFlow())
     world.add(Inflow(Sphere((8, 8), radius=4)))
     world.add(Fan(Sphere((10, 8), 5), [-1, 0]))
     struct.properties_dict(world.state)
Beispiel #29
0
 def test_effects(self):
     world = World()
     world.add(Fluid(Domain([16, 16])))
     world.add(Fan(Sphere((10, 8), 5), [-1, 0]))
     world.step()
     world.step()
Beispiel #30
0
 def elements(self):
     return Sphere(self.sample_points, radius=0.0)