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)
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