2.6 KiB
Variational Minimization
IDRLnet can solve variational minimization problems. In this section, we try to find a minimal surface of revolution.
Given two points P_1=(-1, \cosh(-1))
and P_2=(0.5, \cosh(0.5))
.
Consider a curve u(x)
connecting P_1
and P_2
.
The surface of revolution is generated by rotating the curve with respect to x-axis.
This section aims to find the curve that minimizes the surface area.
The surface area of revolution is obtained by integrating over cylinders of radius y
:
S=\int_{x_1}^{x_2} u(x)\sqrt{u'(x)^2+1}dx.
Load a Pretrained Network
IDRLnet supports loading pretrained networks.
For faster convergence, we take the initial network to be the segment connecting P_1
and P_2
,
which is accomplished by fitting the following domain:
@sc.datanode(loss_fn='L1')
class Interior(sc.SampleDomain):
def sampling(self, *args, **kwargs):
points = geo.sample_interior(100)
constraints = {'u': (np.cosh(0.5) - np.cosh(-1)) / 1.5 * (x + 1.0) + np.cosh(-1)}
return points, constraints
The training procedure is derivative-free, so it converges quite fast.
Starting another script, we load the network trained above as the initial network.
s = sc.Solver(sample_domains=(Boundary(), Interior(), InteriorInfer()),
netnodes=[net],
init_network_dirs=['pretrain_network_dir'], # where to find the pretrained network
pdes=[dx_exp, integral, ],
max_iter=1500)
Integral Domain
IDRLnet can calculate definite integration on a domain via Monte Carlo methods.
At the beginning of the script, define Function
u
:
u = sp.Function('u')(x)
The ICNode
is responsible for numerical integration.
The output of ICNode
is automatically prefixed with integral_
.
The following code generates a Node
with output (integral_dx,)
.
dx_exp = sc.ExpressionNode(expression=sp.Abs(u) * sp.sqrt((u.diff(x)) ** 2 + 1), name='dx')
integral = sc.ICNode('dx', dim=1, time=False)
Since the minimization model has an obvious lower bound 0
, we embed the problem into the constraints:
@sc.datanode(loss_fn='L1')
class Interior(sc.SampleDomain):
def sampling(self, *args, **kwargs):
points = geo.sample_interior(10000)
constraints = {'integral_dx': 0, }
return points, constraints
The iterations are show as follows:
The exact solution is:
See examples/minimal_surface_of_revolution
.