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 solve PDE with parametric geometry? #653

Open praksharma opened 2 years ago

praksharma commented 2 years ago

I am solving a 2D steady-state heat conduction problem as follows:

image

Here, I have parametrized the upper limit of y-boundary condition. For this, I introduced another input in the network i.e. u(x,y,L).

geom = dde.geometry.geometry_nd.Hypercube(xmin=[-0.5,0.0,1.0], xmax=[0.5, 10.0,10.0])

I set the top boundary (the parametrized one) as follows:

def boundary_top(X, on_boundary):
    # The top boundary is applied at all points on X[2] i.e. np.isclose(param_geo, param_geo)
    param_geo = X[2] # X[:, 1:2] is equivalent to X[:,1]
    # third dim is the parameter L
    return on_boundary and np.isclose(param_geo, param_geo) # when y = 1

The PDE loss reduces the residual as follows:

def pde(X,u):   
    dy_xx = dde.grad.hessian(u, X, i=0, j=0) # x from -0.5 to 0.5
    dy_yy = dde.grad.hessian(u, X, i=1, j=1) # y from 0 to 10.0
    return dy_xx + dy_yy

I set num_domain = 25000 and num_boundary = 10000.

This solution looks good. image

I do not think this is the correct way. The geometry should be variable like this

training_dataset = np.array([]) # the training dataset
L = np.linspace(1.0,10.0,1000) # the 3rd input
x = np.linspace(-0.5, 0.5, 512) # x coordinates

for length_parameter in L: # for each length parameter
    # y is used to satisfy the PDE i.e the collocation points
    y = np.linspace(0, length_parameter, 1000) # y coodinates should be less the length_parameter i.e. inside the variable upper boundary
    mesh_x, mesh_y = np.meshgrid(x, y, indexing="ij") # create x,y meshgrid

    # extracting individual x, y coordinates
    x_temp = np.expand_dims(mesh_x.flatten(), axis=-1)
    y_temp = np.expand_dims(mesh_y.flatten(), axis=-1)

    # L contains the same coordinate for the entire length of x,y coordinates
    L_temp = np.ones_like(y_temp)*length_parameter

    # stacking the (x,y,L) coordinates to the training dataset.
    temp_dataset = np.hstack([x_temp, y_temp, L_temp]) 
    training_dataset = np.vstack([training_dataset, temp_dataset]) if training_dataset.size else temp_dataset

How to implement a sampling like this in DeepXDE?

lululxvi commented 2 years ago

Use an arbitrary 3D geometry. Don't let DeepXDE sample the points, but provide the points as anchors in dde.data.PDE.