Euler–Bernoulli beam

We consider the Euler–Bernoulli beam equation,

$$ \begin{align} \frac{\partial^{2}}{\partial x^{2}}\left(\frac{\partial^{2} u}{\partial x^{2}}\right)=-1 \ u|{x=0}=0, u^{\prime}|{x=0}=0, \ u^{\prime \prime}|{x=1}=0, u^{\prime \prime \prime}|{x=1}=0, \end{align} $$ which models the following beam with external forces.

euler_beam

Expression Node

The Euler-Bernoulli beam equation is not implemented inside IDRLnet. Users may add the equation to idrlnet.pde_op.equations. However, one may also define the differential equation via symbol expressions directly.

First, we define a function symbol in the symbol definition part.

x = sp.symbols('x')
y = sp.Function('y')(x)

In the PDE definition part, we add these PDE nodes:

pde1 = sc.ExpressionNode(name='dddd_y', expression=y.diff(x).diff(x).diff(x).diff(x) + 1)
pde2 = sc.ExpressionNode(name='d_y', expression=y.diff(x))
pde3 = sc.ExpressionNode(name='dd_y', expression=y.diff(x).diff(x))
pde4 = sc.ExpressionNode(name='ddd_y', expression=y.diff(x).diff(x).diff(x))

These are instances of idrl.pde.PdeNode, which are also computational nodes. For example, pde1 is an instance of Node with

  • inputs=tuple();

  • derivatives=(y__x__x__x__x, );

  • outputs=('dddd_y',).

The four PDE nodes match the following operators, respectively:

  • $dy^4/d^4x+1$;

  • $dy/dx$;

  • $dy^2/d^2x$;

  • $dy^3/d^3x$.

Seperate Inference Domain

In this example, we define a domain specified for inference.

@sc.datanode(name='infer')
class Infer(sc.SampleDomain):
    def sampling(self, *args, **kwargs):
        return {'x': np.linspace(0, 1, 1000).reshape(-1, 1)}, {}

Its instance is not be passed to the solver initializer, which may improve the performance since Infer().sampling After the solving procedure ends, we change the sample_domains of the solver,

solver.sample_domains = (Infer(),)

which triggers the regeneration of the computational graph. Then solver.infer_step() is called.

points = solver.infer_step({'infer': ['x', 'y']})
xs = points['infer']['x'].detach().cpu().numpy().ravel()
y_pred = points['infer']['y'].detach().cpu().numpy().ravel()

The result is shown as follows.

euler

See examples/euler_beam.