lululxvi / deepxde

A library for scientific machine learning and physics-informed learning
https://deepxde.readthedocs.io
GNU Lesser General Public License v2.1
2.64k stars 741 forks source link

How to obtain coefficient of PDE using finite differences and DEEPXDE #114

Closed alexpapados closed 4 years ago

alexpapados commented 4 years ago

Hello Lu Lu,

I came across an article on Medium.com (attached below): The neural network approach to solving inverse problems for physics, and was wonder how I could use DEEPXDE to solve this problem. Suppose I have a transport equation u_t + au_x, and I am provided the solution data to this PDE, which has been approximated using finite-differences. Moreover, suppose I would like to solve the advection speed, a. How may I use Deepxde/PINNs to solve for the advection speed by having Deepxde/PINNs provide the advection speed, then the user solves the transport by finite difference using the neural network provided a, then measure the error with the solution data, then backpropagate? Is this possible to do using Deepxde?

Thank you, Axle

Article Link: https://medium.com/@kailaix16/the-neural-network-approach-to-solving-inverse-problems-for-physics-1b3177f11872

lululxvi commented 4 years ago

It seems that the only difference between this inverse problem and the inverse problems in DeepXDE paper is that here a is a function of x. This can be easily done in DeepXDE, see examples in the paper. The way to do it is that the network has two outputs: the first one is the solution u, and the second on is a, and then construct the loss as usual.

alexpapados commented 4 years ago

Hello Lu Lu,

Thank you from your prompt response. I will read the paper tomorrow and attach the attempted code if I run into issues. I'm enjoying using Deepxde and it's inversion capabilities. Great work!

alexpapados commented 4 years ago

Hello Lu Lu,

Is there any code from the paper that I may reference?

Best, Axle

lululxvi commented 4 years ago

You may send an email to the first author to ask for the code.

alexpapados commented 4 years ago

Hello Lu Lu,

Sounds good! Do would you mind providing his official email?

Thank you, Axle

lululxvi commented 4 years ago

It is yuyao at bu dot edu

alexpapados commented 4 years ago

Hello Lu Lu,

I wrote to Yuyao a few days back, and he has still not gotten back to me. Is there any way you may contact him, please? If you prefer discussing this in an email, I'd be more than happy to.

Best, Axle

lululxvi commented 4 years ago

Actually the implementation is not hard. I can guide you. For example, the PDE is u_t + au_x = 0, here u(x, t) is a function of x and t, and a(x, t) is also an unknown function of x and t. (If a is an unknown constant, then there are many examples in Github) We have some IC, BC, and some measurements for u(x, t), and we try to infer u(x, t) and a(x, t). To solve this problem, and make it easy to explain, let us replace u with u1 and a with u2, then we have the PDE u1_t + u2 u1_x = 0. We just assume we try to solve u1 and u2 from only one PDE with IC/BC for u1 and some measurements for u1. Then this is similar to the example Lorenz_inverse.py, where we want to solve more than one functions. (Of course, you don't need the C1, C2, C3 in Lorenz example) DeepXDE dose not care how many PDE we have, how many IC/BC, etc. You just define all the information, and solve. You can try to implement and let me know if you have any questions.

alexpapados commented 4 years ago

Hello Lu Lu,

This makes sense! I've solved a few inverse problems using DEEPXDE in this manner. The approach is remarkable, and the results have been superb. I believe what I am asking is slightly different. My apologies for not being clear. Below I've attached an image of the general logic for which I'd like to use DEEPXDE/PINNs. The problem is for a simple diffusion equation. Is it possible to use DEEPXDE with this framework?

Best, Axle PINNs

lululxvi commented 4 years ago

This problem is the same as what I described, right? We just use the results from FDM as the measurements of u, and don't care where the u values comes from.

alexpapados commented 4 years ago

I've attached the code for which I am using to have a better idea of what I mean! Once again my apologies for not explaining this clearly! I receive an error when running this code

from future import absolute_import from future import division from future import print_function

import numpy as np

import deepxde as dde from deepxde.backend import tf

def main(): C = tf.Variable(1.0) def pde_fd(y): diff = C .1 # Diffusion Number dx = .1 # Spatial Step dt = diff (dx * 2) # Time Step x = np.arange(0, 3, dx) # x domain t = np.arange(0, 1, dt) # t domain N = len(t) # Number of points in t M = len(x) # Number of points in x ############################################################## u = np.zeros((M, N)) u[:, 0] = np.sin(np.pi x) # Initial Condition

    for n in range(0, N - 1):
        for i in range(1, M - 2):
            u[i, n + 1] = u[i, n] + diff * (u[i + 1, n] - 2 * u[i, n] + u[i - 1, n])

    u_hat = np.reshape(u, (-1, 1))
    return y - u_hat

data = np.load('Diffusion.npz')
xx = data['x']
tt = data['t']
uu = data['u']

geom = dde.geometry.Interval(0, 3)
timedomain = dde.geometry.TimeDomain(0, 1.0)
geomtime = dde.geometry.GeometryXTime(geom, timedomain)
bc = dde.DirichletBC(geomtime, lambda x: np.zeros((len(x), 1)), lambda _, on_boundary: on_boundary)
ic = dde.IC(geomtime, lambda x: np.zeros((len(x), 1)), lambda _, on_initial: on_initial)

observe_x, observe_u = np.hstack((xx, tt)), uu
ptset = dde.bc.PointSet(observe_x)
observe_y = dde.DirichletBC(
    geomtime, ptset.values_to_func(observe_u[:, 0:1]), lambda x, _: ptset.inside(x)
)
data = dde.data.TimePDE(
    geomtime,
    pde_fd,
    [bc, ic, observe_y],
    num_domain=100,
    num_boundary=80,
    num_initial=20,
    anchors=observe_x,

)
layer_size = [2] + [32] * 2 + [1]
activation = "tanh"
initializer = "Glorot uniform"
net = dde.maps.FNN(layer_size, activation, initializer)

model = dde.Model(data, net)

model.compile("adam", lr=0.001)
variable = dde.callbacks.VariableValue(C, period=1000)
losshistory, train_state = model.train(epochs=250000, callbacks=[variable])
dde.saveplot(losshistory, train_state, issave=True, isplot=True)

if name == "main": main()

lululxvi commented 4 years ago

Don't use the FEM. Assume you don't know FEM. Just the original PDE u_t - v u_xx = 0.