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

Defining a boundary Condition with operatorBC #104

Closed katayooneshkofti closed 4 years ago

katayooneshkofti commented 4 years ago

Dear @lululxvi Thanks for the amazing library. I am working on coupled partial differential equations and there is a boundary condition that is a bit challenging. There are 2 outputs: T as temperature and U as displacement. There are two inputs: r as distance and t as time. One of the boundary conditions is as follows: T(r_in, t)= H(t) where: H(t)=1 for t>=0 H(t)=0 for t<0

How can I define such a boundary condition? Best regards.

lululxvi commented 4 years ago

Is this just a Dirichlet BC?

katayooneshkofti commented 4 years ago

@lululxvi r_in is equal to 1.0. boundary and initial conditions are as follows: Temperature: T(r,t) Displacement: u(r,t) Initial conditions: T(r,0)=dT/dt(r,0)=0 U(r,0)=du/dt(r,0)=0 Boundary conditions: r_in=1 r_out=1.5 First BC: T(r_in, t)= H(t) where: H(t)=1 for t>=0 H(t)=0 for t<0 Second BC: T(r_out, t)= H(t) Third and fourth one: U(r_in, t)=u(r_out,t)=0 Can I code it by Dirichlet? I mean the H(t)? The only challenging part for me is this one.

lululxvi commented 4 years ago

Yes, it is just Dirichlet, and the value depends on t. You can use np.heaviside for H(t).

katayooneshkofti commented 4 years ago

@lululxvi Thank you for your prompt response. It was a great help.

katayooneshkofti commented 4 years ago

Yes, it is just Dirichlet, and the value depends on t. You can use np.heaviside for H(t).

Dear @lululxvi Sorry to bother you again. I have one more question: for initial conditions like this "dT/dt(r,0)=0" how should I define IC in Deepxde?

lululxvi commented 4 years ago

"dT/dt(r,0)=0" is not a standard IC. Just treat this as a Neumann BC.

katayooneshkofti commented 4 years ago

@lululxvi Thank you so much. Your dedication and commitment is adorable.

katayooneshkofti commented 4 years ago

Dear @lululxvi I Coded boundary and initial conditions according to your suggestions. But when I run the code, there are nan values in the training process. I will be grateful if you help me through this. The code is as follows: `

-->Boundary Conditions

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

# boundary definition

def boundary_rin (x, on_boundary):

    return on_boundary and np.isclose(x[0], 1.)  #rmin=1

def boundary_rout( x, on_boundary ):

    return on_boundary and np.isclose(x[0], 1.5)  #rmax=1.5  

def boundary_t_init(x, on_boundary):
    return on_boundary

def func(x):
    return np.zeros((len(x),1), dtype=np.float32)

def H(x):
    return np.heaviside(x[:,1:2],1)

def func_init(x):
    return np.zeros((len(x),1), dtype=np.float32)

bc1= dde.DirichletBC(geomtime,func,boundary_rin, component=0)
bc2= dde.DirichletBC(geomtime,func,boundary_rout,component=0)
bc3=dde.DirichletBC(geomtime,H,boundary_rin,component=1)
bc4=dde.DirichletBC(geomtime,func,boundary_rout,component=1)
####Considering Neumann Boundary Conditions for initial conditions with derivatives###
bc5=dde.NeumannBC(geomtime, func_init, boundary_t_init, component=0)
bc6=dde.NeumannBC(geomtime, func_init, boundary_t_init, component=1)

ic1= dde.IC(geomtime, func_init, lambda _, on_initial: on_initial,component=0)
ic2= dde.IC(geomtime, func_init, lambda _, on_initial: on_initial, component=1)   

data = dde.data.TimePDE(geometryxtime=geomtime, pde=pde_system, ic_bcs=[bc1, bc2, bc3, bc4, bc5, bc6, ic1, ic2], num_domain=10, num_boundary=80, num_test=1000)
layer_size = [2] + [20] * 3 + [2]
activation = "tanh"
initializer = "Glorot uniform"
net = dde.maps.FNN(layer_size, activation, initializer)

model = dde.Model(data, net)
model.compile("adam", lr=0.001)  #metrics=["l2 relative error"]
model.train(epochs=50000)
losshistory, train_state = model.train(epochs=10000)
dde.saveplot(losshistory, train_state, issave=True, isplot=True)`

Thanks for your consideration.

lululxvi commented 4 years ago
katayooneshkofti commented 4 years ago
  • Because on_boundary will test if a point is on boundary, not on the initial location, You need to define boundary_t_init excitability, i.e., check if x is on the initial location based on the value of x.
  • nan may come from different factors, e.g., wrong value of training data, training stability, etc. You need to check step by step.

Dear @lululxvi , Thank you for all the great suggestions. I've read all the issues opened by other users but I couldn't find a problem similar to mine. I want to ask you if I want to define the initial condition as Neumann boundary conditions, is it ok to code this as follows: my initial conditions are ("dT/dt(r,0)=0" and du/dt(r,0)=0) 1-

def boundary_t_init (x,_):
        return np.isclose(x[1],0)
def func_init(x):
        return np.zeros((len(x),1), dtype=np.float32)
bc5=dde.NeumannBC(geomtime, func_init, boundary_t_init, component=0)
    bc6=dde.NeumannBC(geomtime, func_init, boundary_t_init, component=1)

or should I do it as number 2 2-

` def boundary_t_init(x, on_initial):
        return on_initial 
def func_init(x):
        return np.zeros((len(x),1), dtype=np.float32)
bc5=dde.NeumannBC(geomtime, lambda x: func_init(x[:, 1:]), boundary_t_init, component=0)
    bc6=dde.NeumannBC(geomtime, lambda x: func_init(x[:, 1:]), boundary_t_init, component=1)`

3- I think this one is the right one:

`def boundary_t_init(x, on_initial):
        return np.isclose(x[1],0)`

Thank you so much. Best Regards.

katayooneshkofti commented 4 years ago

Dear @lululxvi, I sort of got stuck in defining initial conditions as Neumann BC. Would you please help me with this? dT/dt(r,0)=0 du/dt(r,0)=0 is the following code ok?

  def boundary_for_initial( x, on_initial):
        return on_initial
 def func_init(x):
        return np.full_like(x[:,0:1], 0)
   bc5=dde.NeumannBC(geomtime, func_init , boundary_for_initial, component=0)
    bc6=dde.NeumannBC(geomtime, func_init , boundary_for_initial, component=1)
lululxvi commented 4 years ago
def boundary_t_init (x, _):
        return np.isclose(x[1], 0)

is correct

aminetazarine commented 2 years ago

Dear @lululxvi I am working on coupled partial differential equations and there is a boundary condition that is a bit challenging. the problem is: dy1/dx=-dy2/dt dy2/dx=-dy1/dt with the boundary condition y1(0,t)=y1(1,t)=0 the solution is: y1=sin(pin)cons(pit)

I have defined the boundary condition as follows: bc = dde.icbc.DirichletBC(geomtime, 0, lambda _, on_boundary: on_boundary, derivative_order=0, component=0)

it is correct???? Best regards.

lululxvi commented 2 years ago

Not correct. This is a standard Dirichlet BC. Check the examples and FAQ.

aminetazarine commented 2 years ago

Dear @lululxvi Can i send my code and you take a look please.

lululxvi commented 2 years ago

This is a very basic usage of DirichletBC. You should find the answer by reading the examples https://deepxde.readthedocs.io/en/latest/demos/pinn_forward.html

aminetazarine commented 2 years ago

Dear @lululxvi I know this is a standard Dirichlet BC, but in this case we have two outputs Y1 and Y2.

lululxvi commented 2 years ago

Use component, see https://deepxde.readthedocs.io/en/latest/modules/deepxde.icbc.html#deepxde.icbc.boundary_conditions.DirichletBC

aminetazarine commented 2 years ago

Dear @lululxvi thank you very much for your answers. One last question please can you tell me the interpretation of this graph Figure_1 Best regards.

lululxvi commented 2 years ago

See FAQ "Q: What is the output of DeepXDE? How can I visualize the results?"

aminetazarine commented 2 years ago

Dear @lululxvi thank you very much for your answers. One last question please what is the interest of num_test in the loss function? data = dde.data.TimePDE(....,....,..., num_test=10000,) in other words, what is it for?

Best regards.

lululxvi commented 2 years ago

See https://deepxde.readthedocs.io/en/latest/modules/deepxde.data.html#deepxde.data.pde.PDE