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


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/ and sympy_utils/ in the Modulus release prior to our new 22.03 release. In the new 22.03 release this has moved to geometry/csg/ 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")

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.