Giter VIP home page Giter VIP logo

Comments (8)

praksharma avatar praksharma commented on June 17, 2024 1

Glad it worked. I have solved similar problems, where the boundary is complicated.
Since your boundaries are straight lines, you could try using slope-intercept form of line: y=mx+c. You need to manually determine the slope (m) and intercept (c) for each boundary since they are straight line. Slope (m) is fairly easy: y/x and intercept (c) is the point where the line crosses the y-axis. You need to calculate them manually.

Once, you determine m and c. You could try this.

def boundary_left(x, on_boundary):
    return on_boundary and np.isclose(x[1], x[0] * m + c) # x[1] is y and x[0] is x

From the figure, I can say the slope is same for both left and right boundary, but the intercept will change.

DeepXDE solves inverse problem involving parameter estimation. You look in the DeepXDE's docs to learn inverse modelling. My research in not parameter estimation, thus I am using my own code. I am working on solution reconstruction without the knowldege of BCs.

I just noticed, the boundary normal in your figure is mostly correct. The normals are undefined on the corners, so just exclude those points. Mathematically, the derivative is undefined on corners.

from deepxde.

praksharma avatar praksharma commented on June 17, 2024

on_boundary will only work when you define the geometry using modules available in dde.geometry . Since you know the coordinates of the boundaries and from the plot i can see they are exactly, at x=0,20, you can directly specify the nodal coordinates.

def boundary_left(x, on_boundary):
    return x[0]== 0

def boundary_right(x, on_boundary):
    return x[0]==20

Coming to your second query. I could not understand the meaning of "order of points". Are you talking about the magnitude of the coodinates at those points?

No you can't do this.

  return np.ones(len(lbc_points), dtype=bool) + np.zeros(len(other_boundary_points), dtype=bool)

The boundaries of a particular BCs is defined using lambda function. Here is an example:

bc = dde.icbc.DirichletBC(geomtime, lambda x: 0, lambda _, on_boundary: on_boundary)

You are returning the same array each time the lambda function is called for a particular value of x. This will give you very unexpected results (if DeepXDE doesn't throw an error) as you are trying to assign same BC to the same input each time irrespective of your x.

from deepxde.

DeepaMahm avatar DeepaMahm commented on June 17, 2024

@praksharma Thanks a lot for the clarification and thanks for always guiding me towards the right direction.

I was actually trying to figure out if I can still use the dde.icbc.NeumannBC() for geometries that are not created using modules available in dde.geometry (i.e. for geometries created using pointcould).

From your response, I understand that it wouldn't be possible since on_boundary works only when geom is created using dde.geometry. I had a look at the NeumannBC class to try and implement PointSetBCNeumann for pointcloud geometries.
Unfortunately, I am not sure how to proceed. Do we need the boundary_normals (which is an input argument in ) to create a PointSetBCNeumann function ?

n.dy/dn = 0 (#22 (comment))

class NeumannBC(BC):
    """Neumann boundary conditions: dy/dn(x) = func(x)."""

    def __init__(self, geom, func, on_boundary, component=0):
        super().__init__(geom, on_boundary, component)
        self.func = npfunc_range_autocache(utils.return_tensor(func))

    def error(self, X, inputs, outputs, beg, end, aux_var=None):
        values = self.func(X, beg, end, aux_var)
        return self.normal_derivative(X, inputs, outputs, beg, end) - values

I have geometries which include sections like the below (and Neumann needs to be specified on the edge points)

image

and I am not sure if boundary_normals are required.

If your implementation of PointSetBCNeumann is available elsewhere, could you please direct me to it?

from deepxde.

praksharma avatar praksharma commented on June 17, 2024

You can only use Neumann BC when you provide the normal vectors. In DeepXDE, the base geometry class has a function named boundary_normal, which stores the normal vectors.

def boundary_normal(self, x):

The point cloud class allows you to manually input the normal vectors for each boundary, as it inherits the Geometry base class.

def __init__(self, points, boundary_points=None, boundary_normals=None):

So, here when you define your pointcloud. You can easily add normal vectors for each boundary_points you have specified.

geom = dde.geometry.PointCloud(
     points=np.asarray(domain_points),
     boundary_points=np.asarray(boundary_points),
 )

You can use if-else condition to assign normal vectors. For your left boundary, i.e. x=0, all entries in boundary_normals must be -1 and for right boundary it must be +1. This is because boundary_normals indicates normally outward vector to the boundary. I hope this is the correct convention, I haven't used FEM for a long time.

Once you have created a vector of boundary_normals using if-else condition. You can add them in your geom and use dde.icbc.NeumannBC just like you'd use with a circle or a rectangle.

geom = dde.geometry.PointCloud(
     points=np.asarray(domain_points),
     boundary_points=np.asarray(boundary_points),
     boundary_normals=<your array here>
 )

I never implemented the PointSetBCNeumann because calculating normal vectors requires external libraries that implement k-nearest neighbors.

In my case, I had a MED file of my geometry, which automatically stores the boundary normals vectors. Also, I am not using DeepXDE because I am doing inverse modelling.

from deepxde.

DeepaMahm avatar DeepaMahm commented on June 17, 2024

Hi @praksharma ,

Thanks a ton!

I never implemented the PointSetBCNeumann because calculating normal vectors requires external libraries that implement k-nearest neighbors.
And sorry, I got a bit confused reading this comment #1633 (comment).

I managed to get the boundary normals of my geometry.
For a simple 2D geometry shared in the initial post, it looks like the below
image.

I've specified the boundary_normals as inputs in the PointCloud function, and it works nicely. Thank you.

geom = dde.geometry.PointCloud(
points=np.asarray(domain_points),
boundary_points=boundary_points,
boundary_normals=boundary_normals
)

Now, for a regular geometry e.g. rectangle created using pointcloud, we could specify NeumannBC as follows

def func_neumann_bc(x):
    return np.zeros((len(x), 1), dtype=np.float64)

def boundary_right(x, on_boundary):
    """
    NC boundary for model_v1
    :param x:
    :param on_boundary:
    :return:
    """
    return on_boundary and np.isclose(x[0], 20)  # x[0]==20


   right_bc = dde.icbc.NeumannBC(geomtime, func_neumann_bc, boundary_right)

Question

For a point cloud geometry like the below , I am not sure how to specify the NeumannBC for the face indicated by the red arrow since x[0] is not a constant value due to the geometry tilt. This is the reason I was trying to figure out how to write a function for PointSetBCNeumann.
image.

Also, I am not using DeepXDE because I am doing inverse modeling.

Could you please let me know if there are other libraries for inverse modeling?
I'm still a beginner in this field but I need to do inverse modeling. If you could give some suggestions, it would be really helpful.

from deepxde.

DeepaMahm avatar DeepaMahm commented on June 17, 2024

Hi @praksharma ,

Really sorry for the late reply.

Thanks a lot for the detailed explanation. I'm excluding the corner points too, thanks. Happy to know about the interesting research area you are working on.

If I may ask another doubt,
The actual geometry is a bit more complicated.

I now have the boundary normals of the boundary vertices for the geometry. But I am not sure how to specify the
Neumann BC.

I have the coordinates of points for which Neumann has to be applied saved in an array. But not sure how to specify it

Here, can we specify single points and use multiple and or use for loop in this function below?


def boundary_neumann(x, on_boundary):
    return on_boundary and np.isclose(x[1], x[0] * m + c) # x[1] is y and x[0] is x

For instance, should I split the lines forming the boundary and compute slope and intercept for each line and set up Neumann as
return on_boundary and np.isclose(x[1], x[0] * m1 + c1) and np.isclose(x[1], x[0] * m2 + c2) and ... # x[1] is y and x[0] is x

Thanks a lot for your kind attention.

from deepxde.

praksharma avatar praksharma commented on June 17, 2024

For such complex geometry, you can't use filter function which is a combination of on_boundary and np.isclose. You could try writing a code from scratch. Here is a code I wrote for my work, 2 years ago. You can easily modify it to include Neumann BC. There is no need to calculate the normal vectors. You can just supply coordinates and corresponding BC. The code is bit long and might take time to understand.

https://github.com/praksharma/Stiff-PDEs-and-Physics-Informed-Neural-Networks/blob/main/1.%20Problem%201/1.%20Model%201/Improved_structure.ipynb

from deepxde.

DeepaMahm avatar DeepaMahm commented on June 17, 2024

Thanks a ton for sharing your code. This is of great value. I will share the updates here soon

from deepxde.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.