deepxde icon indicating copy to clipboard operation
deepxde copied to clipboard

2D Wave Equation With Initial Conditions and Disk Deformity.

Open hannanmustajab opened this issue 1 year ago • 4 comments

Hey @lululxvi, I am trying to solve the (2+1)D Wave equation using DeepXDE, based on what people have already done and by reading the GitHub issues forum, I was able to write this code and so far it has been working well. However, I have some issues which I tried looking up but I couldn't find a solution for. It would be really helpful if you can help me or direct me to some other issues where I might find some hint.

Problem setup: I solve the eq. Utt = C**2 ( Uxx + Uyy ) with zero direchlet conditions on the boundary. The training domain is between [-10,10] in x and y, and the time is [0,10]. I use the initial condition as a gaussian source which is centred at (0,0) with a sigma of 0.3.

In this I have two initial conditions, One is Ut(x,0) and another is U(x,0). From other threads I saw that it was suggested to use NeumannBC there. I did that, but my loss always remains 0. I am not sure if it is correct. Can you please comment on that ? I saw some other people also had this issue. Below is the code block for that part.

def initial_condition(X):
    x,y = torch.tensor(X[:, 0:1]), torch.tensor(X[:, 1:2])
    return gaussian_wave(x,y)


def boundary_initial(x,on_initial):
    return on_initial and np.isclose(x[2],0)


def boundary_initial_dt(x,_):
    on_boundary = (
        np.isclose(x[2],0)
        and not np.isclose(x[0],xmin)
        and not np.isclose(x[0],xmax)
        and not np.isclose(x[1],ymin)
        and not np.isclose(x[1],ymax)
    )
    return on_boundary


num_domain = 150*150*5
num_boundary = 15000
num_initial = 50000


bc_ic = dde.DirichletBC(geomtime,initial_condition,boundary_initial_dt)
dt_IBC0 = dde.NeumannBC(geomtime,func_zero_IC,boundary_initial_dt)


data = dde.data.TimePDE(
    geomtime, pde, [bc_x_l, bc_x_r, bc_y_b, bc_y_u,dt_IBC0,bc_ic,circle], num_domain=num_domain, num_boundary=num_boundary,num_initial=num_initial)


0         [2.22e-03, 2.39e-02, 1.48e-02, 1.45e-01, 2.49e-01, 0.00e+00, 1.18e-01, 1.84e-04]    [2.22e-03, 2.39e-02, 1.48e-02, 1.45e-01, 2.49e-01, 0.00e+00, 1.18e-01, 1.84e-04]    []  
1000      [2.41e-05, 8.10e-07, 1.16e-06, 1.75e-06, 9.72e-07, 0.00e+00, 6.26e-04, 1.89e-08]    [2.41e-05, 8.10e-07, 1.16e-06, 1.75e-06, 9.72e-07, 0.00e+00, 6.26e-04, 1.89e-08]    []  
2000      [2.34e-05, 3.86e-07, 4.74e-07, 3.39e-07, 2.80e-07, 0.00e+00, 5.89e-04, 9.25e-09]    [2.34e-05, 3.86e-07, 4.74e-07, 3.39e-07, 2.80e-07, 0.00e+00, 5.89e-04, 9.25e-09]    []  

Another problem is, I tried to add a circle in the geometry, and use it as a deformity to reflect the wave back. However, It did not perform as expected, and there are no reflections happening back from that part of the domain. This is how I define it.

disk_domain = dde.geometry.Disk([7, 7], 2)
geom = geom - disk_domain

circle = dde.NeumannBC(geomtime, func_zero, boundary_circle)


def boundary_circle(x, on_boundary):
    #centre (4, 1), radius 0.3disk_domain.on_boundary(x[1]) 
    return on_boundary and disk_domain.on_boundary(x[1]) and disk_domain.on_boundary(x[0]) 

These are the number of points that I used:

num_domain = 150*150*5
num_boundary = 15000
num_initial = 50000

I would really appreciate any support and feedback you can provide on this. Thank you in advanced. Hannan

hannanmustajab avatar Dec 05 '23 12:12 hannanmustajab

What is gaussian_wave() and func_zero_IC? Remember the function must take a tensor a return a tensor.

praksharma avatar Dec 05 '23 14:12 praksharma

@praksharma Hey, This is

def func_zero(X):
    return np.zeros((len(X),1))

def func_zero_IC(X):
    return np.zeros((len(X),1))

def gaussian_wave(x,y):
    return torch.exp(-0.5* (((x-0)/0.3)**2 + ((y-0)/0.3)**2))  

These conditions fit well, the only problem is with this condition:

dt_IBC0 = dde.NeumannBC(geomtime,func_zero_IC,boundary_initial_dt)

Regards Hannan

hannanmustajab avatar Dec 05 '23 14:12 hannanmustajab

The use of dde.NeumannBC looks good in the first code. But I don't really understand your second code.

lululxvi avatar Dec 13 '23 21:12 lululxvi

Hey, thanks for your response @lululxvi . Can you please mention the second code that you are referring to here ?

If you mean this one;

disk_domain = dde.geometry.Disk([7, 7], 2)
geom = geom - disk_domain

circle = dde.NeumannBC(geomtime, func_zero, boundary_circle)


def boundary_circle(x, on_boundary):
    #centre (4, 1), radius 0.3disk_domain.on_boundary(x[1]) 
    return on_boundary and disk_domain.on_boundary(x[1]) and disk_domain.on_boundary(x[0]) 

Here my goal is to first create rectangle, then remove a circle / disk from it. Which would be to depict a fracture / crack in the media. And then study the behaviour of wave when it hits that part. So basically the aim here is to create a reflective condition on the boundary of this circle. Can you please tell me if my approach here is right or not ?

Regards Hannan

hannanmustajab avatar Dec 14 '23 13:12 hannanmustajab