tum-pbs / PhiFlow

A differentiable PDE solving framework for machine learning
MIT License
1.39k stars 189 forks source link

How to implement the karman vortex street with rotation cylinder #121

Closed xfdywy closed 1 month ago

xfdywy commented 1 year ago

Hi,

I want to use the Phiflow to simulate the karman vortex street with rotation cylinder. But I don't really understand the demo https://github.com/tum-pbs/PhiFlow/blob/master/demos/karman_vortex_street.py.

Specifically, I don't understand how to set the boundary condition? For example, my boundary conditions are:

  1. (0,0) at top and bottom boundary
  2. (y^2, 0) at the left boundary
  3. tangential speed=2 in the cylinder boundary

Thanks for your wonderful tool and thanks for your help.

holl- commented 1 year ago

Hi! For the domain boundaries, you can pass a dictionary to the grid constructor. You can enforce the y^2 condition by setting the left-most elements of the velocity to the specified values each time step. The cylinder can be passed to make_incompressible.

Here is a modified version of the pipe.py demo that sets the boundary conditions:

from phi.torch.flow import *

bounds = Box(x=2, y=2)
velocity = StaggeredGrid(0, {'y': 0, 'x': ZERO_GRADIENT}, bounds, x=64, y=64)
inlet = velocity.with_values(lambda x, y: vec(x=.1 * y**2, y=0))
inlet_pos = velocity.with_values(lambda x, y: vec(x=x <= 0, y=0))
cylinder = Obstacle(Sphere(vec(x=.5, y=1), radius=.2), angular_velocity=2/.2/PI)
velocity, pressure = fluid.make_incompressible(velocity, cylinder)
show(velocity, inlet, inlet_pos['x'])

def step(v, p, dt=1.):
    v = field.where(inlet_pos, inlet, v)
    v = advect.semi_lagrangian(v, v, dt)
    v = diffuse.explicit(v, 0.1, dt)
    v, p = fluid.make_incompressible(v, cylinder, solve=Solve(x0=p))
    return v, p

velocity, pressure = step(velocity, pressure)

Make sure to run this on the 2.4 version, pip install --force-reinstall git+https://github.com/tum-pbs/PhiFlow@2.4-develop

xfdywy commented 1 year ago

Thank you very much for your reply. Your explanation was clear, and I will try your suggestion.

By the way, I was wondering if you could recommend any documentation or resources for me to learn more about this type of usage. The document is quite brief and doesn't provide enough information for me to solve problems like this in the future.

For instance, if I need to set a complex boundary condition, I wouldn't have thought to use the method you suggested. The only approach I found in the document was to use extrapolation.combine_sides in the pipe.py example.

holl- commented 1 year ago

Right, the dictionary is just a recently-added shorthand for combine_sides.