tum-pbs / PhiFlow

A differentiable PDE solving framework for machine learning
MIT License
1.43k stars 193 forks source link

Are there any ways to optimize inflow locations? #95

Closed somisawa closed 1 year ago

somisawa commented 1 year ago

In this demo, it is explained to obtain grad of grid values.

However, I'd like to optimize the center location of inflow like this:

# informal code
inflow_location = tensor(...)
initial_inflow = CenteredGrid(Sphere(inflow_location, ...), ...)

inflow_location_grad = # I want this

inflow_location -= 1e-2 * inflow_location_grad

Is it possible?

holl- commented 1 year ago

Yes, you can optimize any input to a simulation. You just need to make it a parameter of your simulation / objective function.

def simulate(smoke: CenteredGrid, velocity: StaggeredGrid, inflow: CenteredGrid):
  for _ in range(20):
    smoke = advect.mac_cormack(smoke, velocity, dt=1) + inflow
    buoyancy_force = smoke * (0, 0.5) @ velocity
    velocity = advect.semi_lagrangian(velocity, velocity, dt=1) + buoyancy_force
    velocity, _ = fluid.make_incompressible(velocity)
  loss = math.sum(field.l2_loss(diffuse.explicit(smoke - field.stop_gradient(smoke.inflow_loc[-1]), 1, 1, 10)))
  return loss, smoke, velocity

sim_grad = field.functional_gradient(simulate, wrt='inflow', get_output=False)

inflow_location_grad = sim_grad(...)
somisawa commented 1 year ago

@holl- Thank you for your comment.

I suspect that the gradient obtained by

inflow_location_grad = field.functional_gradient(simulate, wrt='inflow', get_output=False)(...)

is not a gradient of location but the gradient of the vector field of inflow, isn't it?

holl- commented 1 year ago

Right, the returned gradient will be for the inflow field. It's a scalar field so the gradient will also be a scalar field (CenteredGrid) of the same shape.