Run this tutorial

Click here to run this tutorial on binder: try on binder
Please note that starting the notebook server may take a couple of minutes.

Tutorial: Exploring Models interactively in a jupyter environment

In this short tutorial we will show how to use pyMOR’s interact method to interactively explore a Model’s behavior in a jupyter environment.

Note

The user interface generated by interact requires a running Python kernel and will not be shown in the HTML version of this document.

First, we create a standard thermal-block benchmark model:

from pymor.basic import *

p = thermal_block_problem([2,2])
m, _ = discretize_stationary_cg(p)

interact will allow us to look at the solutions of m while varying its Parameters. In addition to m, we pass a ParameterSpace in order to specify the ranges in which the parameters are allowed to vary.

interact(m, p.parameter_space)

If the Model has outputs, these are shown as well:

p = p.with_(outputs=[('l2', ConstantFunction(1., 2)), ('l2', ExpressionFunction('x[0] >= 0.5', 2))])
m, _ = discretize_stationary_cg(p)
interact(m, m.parameters.space(0.1, 10))

In the following example, we only look at the output and specify new parameter ranges by creating a new ParameterSpace using the space method of m’s Parameters:

interact(m, m.parameters.space(0.1, 10), show_solution=False)

interact also works with time-dependent Models:

pp = InstationaryProblem(p, initial_data=ConstantFunction(0., 2), T=1.)
mm, _ = discretize_instationary_cg(pp, nt=10)
interact(mm, p.parameter_space)

This is also the case for LTIModels:

from pymor.algorithms.timestepping import ImplicitEulerTimeStepper

p = InstationaryProblem(
StationaryProblem(
    domain=LineDomain([0., 1.], left='robin', right='robin'),
    diffusion=LincombFunction([ExpressionFunction('(x[0] <= 0.5) * 1.', 1),
                               ExpressionFunction('(0.5 < x[0]) * 1.', 1)],
                              [1,
                               ProjectionParameterFunctional('diffusion')]),
    robin_data=(ConstantFunction(1., 1), ExpressionFunction('(x[0] < 1e-10) * 1.', 1)),
    outputs=(('l2_boundary', ExpressionFunction('(x[0] > (1 - 1e-10)) * 1.', 1)),),
),
ConstantFunction(0., 1),
T=3.
)

m, _ = discretize_instationary_cg(p, diameter=1/100, nt=100)
lti = m.to_lti().with_(T=1, time_stepper=ImplicitEulerTimeStepper(100))

interact(lti, lti.parameters.space(0.01, 1))

If we can also visualize the solutions of a reduced model by passing a visualizer and a transform of the solution:

p = thermal_block_problem([2,2])
m, _ = discretize_stationary_cg(p, diameter=1/20)

snapshots = cat_arrays([m.solve(mu) for mu in p.parameter_space.sample_randomly(20)])
basis, svals = pod(snapshots, product=m.h1_product, modes=5)
reductor = StationaryRBReductor(m, basis, product=m.h1_product)
rom = reductor.reduce()

interact(rom, p.parameter_space,
         visualizer=m.visualize, transform=lambda u, mu: reductor.reconstruct(u))

We can even show the reduced solution along the FOM solution and the error:

from functools import partial

def compare(u, mu):
    U = m.solve(mu)
    U_red = reductor.reconstruct(u)
    return (U, U_red, U-U_red)

interact(rom, p.parameter_space,
         visualizer=partial(m.visualize, separate_colorbars=True, legend=('FOM', 'ROM', 'ERR')),
         transform=compare)

Download the code: tutorial_interact.md, tutorial_interact.ipynb.