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:

miniface

The exact solution is:

miniface_exact

See examples/minimal_surface_of_revolution.