How is the parametric PINN applied?

I am trying to implement a problem linear elasticity problem with modulus. I want to parameterise my geometry. I am following the example given in chapter 16 from the user guide. And chapter 1.3.3 (see image)

I want to know where in the source code I can find out how the geometry parameters are incorporated within the network?

I know that they are added as inputs to the network but I want to see how they are sampled within the loss functions. Where is the code for equations 10 and 11?

If someone could point me in the right direction

2 Likes

Hello @mn17b2m , when you construct your geometry you can parameterize it with SymPy Symbols as shown in the three_fin_3d example. Then when you make the actual constraints to train your problem you can give a param_ranges. This is a dictionary of the following form, param_ranges={sympy_symbol: (lower_bound, upper_bound)} where sympy_symbol is your SymPy Symbol you used in the geometric parameterization. The lower_bound and upper_bound are floats that define the range you want to sample the parameter in. When Modulus is sampling these parameters it will sample uniformly randomly in this given range.

The source code for this is found in sympy_utils/geometry.py and sympy_utils/curves.py in the Modulus release prior to our new 22.03 release. In the new 22.03 release this has moved to geometry/csg/csg.py. You can interpret the geometric parameterization as adding an extra dimension to the geometry. For example, if you parameterized the radius of a 2D circle and sampled the boundary in effect you would sample a cone in 3D where the 3rd dimension is the radius parameter. You can experiment with this by using the sample_boundary method of the geometry and plotting it in paraview like the following snippet,

from simnet.sympy_utils.geometry_2d import Circle
from simnet.plot_utils.vtk import var_to_vtk
from sympy import Symbol

# define circle where the radius is changing in time
parameterized_circle = Circle((0, 0), 1 - Symbol('t'))

# sample parameterized surface
boundary = parameterized_circle.sample_boundary(10000, param_ranges={Symbol("t"): (0, 1)})
var_to_vtk(boundary, "parameterized_boundary")

# sample parameterized surface
interior = parameterized_circle.sample_interior(10000, bounds={Symbol('x'): (-2, 2), Symbol('y'): (-2, 2)}, param_ranges={Symbol("t"): (0, 1)})
var_to_vtk(interior, "parameterized_interior")
2 Likes

Hi! I want to add another twist to this parametrized problem. What if you have not just one dimension that is a parameter, but a whole function? Simple example: f(x)_xx + k(x)*f(x) = 0, but there are many possible functions k(x) and you want the network to learn the output f(x) under many different k(x), so in the future you have a new k(x) as an input, and want the network to output f(x). Any ideas? Thx.

1 Like

Adding this for reference.

As you said, one solution was to parametrize k(x) and I was thinking about a Fourier Transform parametrized version of the input function, but I knew that it won’t work for larger dimensions, so I gave up on the idea. Literature search brought me to DeepONets by Karniadiakis and other versions by Caltech groups and I was preparing my code to use their libraries but it is great to know that the last release of Modulus 22.03 included this really important extension. Thanks for the help.

Sorry, but after more than a month trying to figure out how to setup a simple equation F_x + k(x)*F = 0 on the new Physics-Based DeepOnet framework in Modulus 22.03, I give up. Because of the lack of manuals/explanations it took me a while to see how the new Branch-net <input_key> size was connected with the ‘x’_data sampling size in the Boundary and Interior constraints. It was also not easy to see how the deeponet <output_key> size must be the same as the interior and boundary constraints column size, something that is obvious from the papers but has no explanation in any of the Modulus examples. Unfortunately I still have no idea why the <input_key> on the Trunk-net has size 1, and more importantly, I am completely clueless on how to impose a simple equation like the one described before as an Interior constraint. I mean, in the “manual” there is an overly simplistic anti-derivative example where the Interior parameter is only a simple derivative “u__s”. The way to impose a new equation like "F_x + k(x)*F=0 should be through the PDES class, but I have tried that and I keep getting errors like matrix size mismatch, or something more complex than that. Besides, the Darcy PINO example doesn’t help much as it redefines the symbolic equation on 3 different types of numerical derivatives. It would have been much simpler to state basic examples like the one I am describing and people can grow from there.