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 739 forks source link

the loss of PDE cannot be convergenced #544

Closed whtwu closed 2 years ago

whtwu commented 2 years ago

I have read the F&Q and rescale the code again and again, but the results are not good. the loss of PDE cannot be convergenced(i guess maybe the PDE's problem, but the pde has addition operation, parameters cannot be rescaled to O(1)) all, If you can give me some suggestions to make me continue the work, I will be very grateful, one more question, how should the loss_weights be set, it seems that the smaller the loss_weights, the smaller the train loss, but the model is not necessarily very good, thanks for your time, here are the code and result。 `import deepxde as dde import numpy as np from deepxde.backend import tf import matplotlib.pyplot as plt

def main(): e_i = 2 / 3 rho_s = 3.14e-03 l = 1 f_trans = 5 omiga = 20 * np.pi

def ddx(x, y):
    return dde.grad.hessian(y, x, i=0, j=0)

def ddt(x, y):
    return dde.grad.hessian(y, x, i=0, j=1)

def pde(x, y):
    f_xt = f_trans * tf.sin(omiga * x[:, 1:])
    dy_tt = ddt(x,y)
    dy_xx = ddx(x,y)
    dy_xxxx = dde.grad.hessian(dy_xx, x, i=0, j=0)
    return e_i * dy_xxxx + rho_s * dy_tt - f_xt

def boundary_l(x, on_boundary):
    return on_boundary and np.isclose(x[0], 0)

def boundary_r(x, on_boundary):
    return on_boundary and np.isclose(x[0], 1)

def func(x):
    sum = 0
    for n in range(1,22,2):
        omiga_i = ((n ** 2 * np.pi ** 2) / l ** 2) * (e_i / rho_s) ** 0.5
        solve = (2 / (rho_s * l) * f_trans / (omiga_i ** 2 - omiga ** 2) * 2 * l / (n * np.pi) * \
        np.sin((n * np.pi * x[:, 0:1]) / l) * (np.sin(omiga * x[:, 1:]) - omiga / omiga_i * np.sin(omiga_i * x[:, 1:])))
        sum += solve
    return sum

geom = dde.geometry.Interval(0, 1)
timedomain = dde.geometry.TimeDomain(0, 1)
geomtime = dde.geometry.GeometryXTime(geom, timedomain)

bc1 = dde.DirichletBC(geomtime, lambda x: 0, boundary_l)
bc2 = dde.OperatorBC(geomtime, lambda x, y, _: ddx(x, y), boundary_l)
bc3 = dde.DirichletBC(geomtime, lambda x: 0, boundary_r)
bc4 = dde.OperatorBC(geomtime, lambda x, y, _: ddx(x, y), boundary_r)

data = dde.data.TimePDE(
    geomtime,
    pde,
    [bc1, bc2, bc3, bc4],
    num_domain=1000,
    num_boundary=60,
    #num_initial=300,
    solution=func,
    num_test=2000,
)

layer_size = [2] + [32] * 4 + [1]
activation = "tanh"
initializer = "Glorot uniform"
net = dde.nn.FNN(layer_size, activation, initializer)
net.apply_output_transform(lambda x, y: y * 10)
model = dde.Model(data, net)

model.compile("adam", lr=0.0001, loss_weights=[1e-5,1e-2,1e-2,1e-2,1e-2], metrics=["l2 relative error"])

losshistory, train_state = model.train(epochs=10000)
dde.saveplot(losshistory, train_state, issave=False, isplot=True)

x = np.linspace(0, 1, 20, endpoint=True)
t = [0.5]
xx, tt = np.meshgrid(x, t)
X = np.vstack((np.ravel(xx), np.ravel(tt))).T
y_pred = model.predict(X)
plt.plot(x,y_pred, color="blue", linewidth=2, linestyle="solid", label="predict")
plt.plot(x,func(X), color="red", linewidth=2.5, linestyle="dotted", label="exact")
plt.legend()
plt.xlabel("x")
plt.xticks(np.arange(0,1,0.1))
plt.ylabel("y")
plt.title("t=0.5s")
plt.show()

if name == "main": main() ` image image

whtwu commented 2 years ago

Later, I rescale the parameter's values, e_i = 4/3, rho_s = 0.157, let them has the scale of O(1), but the result also gets bad.