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 boundary setting problem of two-dimensional time-varying electric field #475

Closed Blackrobin15 closed 2 years ago

Blackrobin15 commented 2 years ago

Hello, Lu I am trying to use deepxde to solve the problems about time-varying electric field. With this tool, I have been able to calculate the one-dimensional electric field. When I tried to two-dimensional electric field and add a time-varying function to a boundary of the rectangular area, an error occurred. How to add different time-varying functions for different boundaries?

def pde(x, u):
    du_xx = dde.grad.hessian(u, x, i=0, j=0)
    du_yy = dde.grad.hessian(u, x, i=1, j=1)
    return du_xx+du_yy

geom=dde.geometry.Rectangle([0,0],[1,1])
timedomain = dde.geometry.TimeDomain(0, 0.02)
geomtime = dde.geometry.GeometryXTime(geom, timedomain)
def boundary1(x,on_boundary):
    return np.isclose(x[0], 0) and on_boundary

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

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

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

def func_bound1(x):
    return 100*np.sin(100*np.pi*x[:,2:3])
    return 0

def func_bound2(x):
    return 0

def func_bound3(x):
    return 0

def func_bound4(x):
    return 0

bc1 = dde.DirichletBC(geom, func_bound1, boundary1)
bc2 = dde.DirichletBC(geom, func_bound2, boundary2)
bc3 = dde.DirichletBC(geom, func_bound3, boundary3)
bc4 = dde.DirichletBC(geom, func_bound4, boundary4)
ic = dde.IC(
    geomtime, lambda x: 0, lambda _, on_initial: on_initial
)

data = dde.data.TimePDE(
    geomtime, pde, [bc1, bc2,bc3,bc4, ic], num_domain=2500, num_boundary=100, num_initial=160
)

ValueError: operands could not be broadcast together with shapes (2760,3) (2,)

The error occurred in the code:

data = dde.data.TimePDE(
    geomtime, pde, [bc1, bc2,bc3,bc4, ic], num_domain=2500, num_boundary=100, num_initial=160
)

The details are as follows :

ValueError Traceback (most recent call last)

in ----> 1 data = dde.data.TimePDE( 2 geomtime, pde, [bc1, bc2,bc3,bc4, ic], num_domain=2500, num_boundary=100, num_initial=160 3 ) D:\Anaconda3\lib\site-packages\deepxde\data\pde.py in __init__(self, geometryxtime, pde, ic_bcs, num_domain, num_boundary, num_initial, train_distribution, anchors, exclusions, solution, num_test, auxiliary_var_function) 273 ): 274 self.num_initial = num_initial --> 275 super(TimePDE, self).__init__( 276 geometryxtime, 277 pde, D:\Anaconda3\lib\site-packages\deepxde\data\pde.py in __init__(self, geometry, pde, bcs, num_domain, num_boundary, train_distribution, anchors, exclusions, solution, num_test, auxiliary_var_function) 120 self.train_aux_vars, self.test_aux_vars = None, None 121 --> 122 self.train_next_batch() 123 self.test() 124 D:\Anaconda3\lib\site-packages\deepxde\utils\internal.py in wrapper(self, *args, **kwargs) 35 x = [getattr(self, a) for a in attr] 36 if all(i is None for i in x): ---> 37 return func(self, *args, **kwargs) 38 return x if len(x) > 1 else x[0] 39 D:\Anaconda3\lib\site-packages\deepxde\data\pde.py in train_next_batch(self, batch_size) 159 def train_next_batch(self, batch_size=None): 160 self.train_x_all = self.train_points() --> 161 self.train_x = self.bc_points() 162 if self.pde is not None: 163 self.train_x = np.vstack((self.train_x, self.train_x_all)) D:\Anaconda3\lib\site-packages\deepxde\utils\internal.py in wrapper(self, *args, **kwargs) 35 x = [getattr(self, a) for a in attr] 36 if all(i is None for i in x): ---> 37 return func(self, *args, **kwargs) 38 return x if len(x) > 1 else x[0] 39 D:\Anaconda3\lib\site-packages\deepxde\data\pde.py in bc_points(self) 233 @run_if_all_none("train_x_bc") 234 def bc_points(self): --> 235 x_bcs = [bc.collocation_points(self.train_x_all) for bc in self.bcs] 236 self.num_bcs = list(map(len, x_bcs)) 237 self.train_x_bc = ( D:\Anaconda3\lib\site-packages\deepxde\data\pde.py in (.0) 233 @run_if_all_none("train_x_bc") 234 def bc_points(self): --> 235 x_bcs = [bc.collocation_points(self.train_x_all) for bc in self.bcs] 236 self.num_bcs = list(map(len, x_bcs)) 237 self.train_x_bc = ( D:\Anaconda3\lib\site-packages\deepxde\icbcs\boundary_conditions.py in collocation_points(self, X) 48 49 def collocation_points(self, X): ---> 50 return self.filter(X) 51 52 def normal_derivative(self, X, inputs, outputs, beg, end): D:\Anaconda3\lib\site-packages\deepxde\icbcs\boundary_conditions.py in filter(self, X) 45 46 def filter(self, X): ---> 47 return X[self.on_boundary(X, self.geom.on_boundary(X))] 48 49 def collocation_points(self, X): D:\Anaconda3\lib\site-packages\deepxde\geometry\geometry_nd.py in on_boundary(self, x) 32 def on_boundary(self, x): 33 _on_boundary = np.logical_or( ---> 34 np.any(np.isclose(x, self.xmin), axis=-1), 35 np.any(np.isclose(x, self.xmax), axis=-1), 36 ) <__array_function__ internals> in isclose(*args, **kwargs) D:\Anaconda3\lib\site-packages\numpy\core\numeric.py in isclose(a, b, rtol, atol, equal_nan) 2288 yfin = isfinite(y) 2289 if all(xfin) and all(yfin): -> 2290 return within_tol(x, y, atol, rtol) 2291 else: 2292 finite = xfin & yfin D:\Anaconda3\lib\site-packages\numpy\core\numeric.py in within_tol(x, y, atol, rtol) 2274 def within_tol(x, y, atol, rtol): 2275 with errstate(invalid='ignore'): -> 2276 return less_equal(abs(x-y), atol + rtol * abs(y)) 2277 2278 x = asanyarray(a) ValueError: operands could not be broadcast together with shapes (2760,3) (2,)
lshil00 commented 2 years ago

Try this : def func_bound1(x): return 100 * np.sin(100*np.pi*x[:,2:3]) * np.ones((len(x),1)) Also, func_bound2, 3 and 4 should have the same form

Blackrobin15 commented 2 years ago

Thank you for your help. I try this code just now, but it does not work, and it also shows the same error.

In 1-d field, the code below worked:

def func_bound2(x):
    return 100*np.sin(100*np.pi*x[:,1:2])

Does the error appear in the definition of the boundary ?

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

Try this : def func_bound1(x): return 100 * np.sin(100*np.pi*x[:,2:3]) * np.ones((len(x),1)) Also, func_bound2, 3 and 4 should have the same form

lshil00 commented 2 years ago

Sorry for giving you the wrong answer... I think there is no error in the boundary definition. Maybe you could try the following codes instead? bc1 = dde.DirichletBC(geom, lambda x: 100*np.sin(100*np.pi*x[:,2:3]), boundary1 )

Blackrobin15 commented 2 years ago

No need to apologize, and thank you for your help. This writing and the above method actually have the same meaning, so the same error still occurs.

Sorry for giving you the wrong answer... I think there is no error in the boundary definition. Maybe you could try the following codes instead? bc1 = dde.DirichletBC(geom, lambda x: 100*np.sin(100*np.pi*x[:,2:3]), boundary1 )

lshil00 commented 2 years ago

No need to apologize, and thank you for your help. This writing and the above method actually have the same meaning, so the same error still occurs.

Sorry for giving you the wrong answer... I think there is no error in the boundary definition. Maybe you could try the following codes instead? bc1 = dde.DirichletBC(geom, lambda x: 100*np.sin(100*np.pi*x[:,2:3]), boundary1 )

I ran your code and found the problem: bc1 = dde.DirichletBC(geomtime, func_bound1, boundary1) NOT bc1 = dde.DirichletBC(geom, func_bound1, boundary1) It should work

Blackrobin15 commented 2 years ago

Thank you very much! The problem is solved.