Exemplo n.º 1
0
 def test_consistency_implicit(self):
     DIFFUSIVITY = 0.5
     grid = CenteredGrid((1, ) * 100 + (0, ) * 100,
                         extrapolation.PERIODIC,
                         x=200)
     for extrap in (extrapolation.ZERO, extrapolation.BOUNDARY,
                    extrapolation.PERIODIC):
         grid = grid.with_extrapolation(extrap)
         implicit = diffuse.implicit(grid, DIFFUSIVITY, 1, order=10)
         back_implicit = diffuse.implicit(implicit,
                                          DIFFUSIVITY,
                                          -1,
                                          order=10)
         field.assert_close(grid,
                            back_implicit,
                            rel_tolerance=0,
                            abs_tolerance=0.1)
Exemplo n.º 2
0
def make_incompressible(
    velocity: GridType,
    obstacles: tuple or list = (),
    solve=math.Solve('auto',
                     1e-5,
                     1e-5,
                     gradient_solve=math.Solve('auto', 1e-5, 1e-5))
) -> Tuple[GridType, CenteredGrid]:
    """
    Projects the given velocity field by solving for the pressure and subtracting its spatial_gradient.
    
    This method is similar to :func:`field.divergence_free()` but differs in how the boundary conditions are specified.

    Args:
        velocity: Vector field sampled on a grid
        obstacles: List of Obstacles to specify boundary conditions inside the domain (Default value = ())
        solve: Parameters for the pressure solve as.

    Returns:
        velocity: divergence-free velocity of type `type(velocity)`
        pressure: solved pressure field, `CenteredGrid`
    """
    assert isinstance(
        obstacles,
        (tuple,
         list)), f"obstacles must be a tuple or list but got {type(obstacles)}"
    input_velocity = velocity
    accessible_extrapolation = _accessible_extrapolation(
        input_velocity.extrapolation)
    active = CenteredGrid(
        HardGeometryMask(~union(*[obstacle.geometry
                                  for obstacle in obstacles])),
        resolution=velocity.resolution,
        bounds=velocity.bounds,
        extrapolation=extrapolation.NONE)
    accessible = active.with_extrapolation(accessible_extrapolation)
    hard_bcs = field.stagger(accessible,
                             math.minimum,
                             input_velocity.extrapolation,
                             type=type(velocity))
    velocity = apply_boundary_conditions(velocity, obstacles)
    div = divergence(velocity) * active
    if not input_velocity.extrapolation.connects_to_outside:
        assert solve.preprocess_y is None, "fluid.make_incompressible() does not support custom preprocessing"
        solve = copy_with(solve,
                          preprocess_y=_balance_divergence,
                          preprocess_y_args=(active, ))
    if solve.x0 is None:
        pressure_extrapolation = _pressure_extrapolation(
            input_velocity.extrapolation)
        solve = copy_with(solve,
                          x0=CenteredGrid(
                              0,
                              resolution=div.resolution,
                              bounds=div.bounds,
                              extrapolation=pressure_extrapolation))
    pressure = math.solve_linear(masked_laplace,
                                 f_args=[hard_bcs, active],
                                 y=div,
                                 solve=solve)
    grad_pressure = field.spatial_gradient(
        pressure, input_velocity.extrapolation, type=type(velocity)) * hard_bcs
    velocity = velocity - grad_pressure
    return velocity, pressure