deepxde
deepxde copied to clipboard
2D Wave Equation With Initial Conditions and Disk Deformity.
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
What is gaussian_wave()
and func_zero_IC
? Remember the function must take a tensor a return a tensor.
@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
The use of dde.NeumannBC
looks good in the first code. But I don't really understand your second code.
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