Esempio n. 1
0
def _compute_errors(mu, d, rd, rc, estimator, error_norms, condition, custom,
                    basis_sizes):
    import numpy as np
    import sys

    print('.', end='')
    sys.stdout.flush()

    estimates = np.empty(len(basis_sizes)) if estimator else None
    norms = np.empty(len(error_norms))
    errors = np.empty((len(error_norms), len(basis_sizes)))
    conditions = np.empty(len(basis_sizes)) if condition else None
    custom_values = np.empty((len(custom), len(basis_sizes)))

    if d:
        logging_disabled = d.logging_disabled
        d.disable_logging()
        U = d.solve(mu)
        d.disable_logging(logging_disabled)
        for i_norm, norm in enumerate(error_norms):
            n = norm(U)
            n = n[0] if hasattr(n, '__len__') else n
            norms[i_norm] = n

    for i_N, N in enumerate(basis_sizes):
        rrd, rrc = reduce_to_subbasis(rd, N, reconstructor=rc)[:2]
        u = rrd.solve(mu)
        if estimator:
            e = rrd.estimate(u, mu)
            e = e[0] if hasattr(e, '__len__') else e
            estimates[i_N] = e
        if d and rc:
            URB = rrc.reconstruct(u)
            for i_norm, norm in enumerate(error_norms):
                e = norm(U - URB)
                e = e[0] if hasattr(e, '__len__') else e
                errors[i_norm, i_N] = e
        if condition:
            conditions[i_N] = np.linalg.cond(
                rrd.operator.assemble(mu)._matrix) if N > 0 else 0.
        for i_custom, cust in enumerate(custom):
            c = cust(reduced_discretization=rrd,
                     discretization=d,
                     reconstructor=rrc,
                     mu=mu,
                     dim=N)
            c = c[0] if hasattr(c, '__len__') else c
            custom_values[i_custom, i_N] = c

    return norms, estimates, errors, conditions, custom_values
Esempio n. 2
0
def _compute_errors(mu, d, rd, rc, estimator, error_norms, condition, custom, basis_sizes):
    import numpy as np
    import sys

    print('.', end='')
    sys.stdout.flush()

    estimates = np.empty(len(basis_sizes)) if estimator else None
    norms = np.empty(len(error_norms))
    errors = np.empty((len(error_norms), len(basis_sizes)))
    conditions = np.empty(len(basis_sizes)) if condition else None
    custom_values = np.empty((len(custom), len(basis_sizes)))

    if d:
        logging_disabled = d.logging_disabled
        d.disable_logging()
        U = d.solve(mu)
        d.disable_logging(logging_disabled)
        for i_norm, norm in enumerate(error_norms):
            n = norm(U)
            n = n[0] if hasattr(n, '__len__') else n
            norms[i_norm] = n

    for i_N, N in enumerate(basis_sizes):
        rrd, rrc = reduce_to_subbasis(rd, N, reconstructor=rc)[:2]
        u = rrd.solve(mu)
        if estimator:
            e = rrd.estimate(u, mu)
            e = e[0] if hasattr(e, '__len__') else e
            estimates[i_N] = e
        if d and rc:
            URB = rrc.reconstruct(u)
            for i_norm, norm in enumerate(error_norms):
                e = norm(U - URB)
                e = e[0] if hasattr(e, '__len__') else e
                errors[i_norm, i_N] = e
        if condition:
            conditions[i_N] = np.linalg.cond(rrd.operator.assemble(mu)._matrix) if N > 0 else 0.
        for i_custom, cust in enumerate(custom):
            c = cust(reduced_discretization=rrd,
                     discretization=d,
                     reconstructor=rrc,
                     mu=mu,
                     dim=N)
            c = c[0] if hasattr(c, '__len__') else c
            custom_values[i_custom, i_N] = c

    return norms, estimates, errors, conditions, custom_values
Esempio n. 3
0
 def error_analysis(N, M):
     print('N = {}, M = {}: '.format(N, M), end='')
     rd, rc, _ = reduce_to_subbasis(rb_discretization, N, reconstructor)
     rd = rd.with_(operator=rd.operator.projected_to_subbasis(dim_collateral=M))
     l2_err_max = -1
     mumax = None
     for mu in mus:
         print('.', end='')
         sys.stdout.flush()
         u = rd.solve(mu)
         URB = rc.reconstruct(u)
         U = discretization.solve(mu)
         l2_err = np.max(discretization.l2_norm(U - URB))
         l2_err = np.inf if not np.isfinite(l2_err) else l2_err
         if l2_err > l2_err_max:
             l2_err_max = l2_err
             mumax = mu
     print()
     return l2_err_max, mumax
Esempio n. 4
0
 def error_analysis(N, M):
     print('N = {}, M = {}: '.format(N, M), end='')
     rd, rc, _ = reduce_to_subbasis(rb_discretization, N, reconstructor)
     rd = rd.with_(operator=rd.operator.projected_to_subbasis(dim_collateral=M))
     l2_err_max = -1
     mumax = None
     for mu in mus:
         print('.', end='')
         sys.stdout.flush()
         u = rd.solve(mu)
         URB = rc.reconstruct(u)
         U = discretization.solve(mu)
         l2_err = np.max(discretization.l2_norm(U - URB))
         l2_err = np.inf if not np.isfinite(l2_err) else l2_err
         if l2_err > l2_err_max:
             l2_err_max = l2_err
             mumax = mu
     print()
     return l2_err_max, mumax
Esempio n. 5
0
def analyze_pickle_convergence(args):
    args['SAMPLES'] = int(args['SAMPLES'])

    print('Loading reduced discretization ...')
    rb_discretization = load(open(args['REDUCED_DATA']))

    if args['--detailed']:
        print('Loading high-dimensional data ...')
        discretization, reconstructor = load(open(args['--detailed']))

    if not hasattr(rb_discretization, 'estimate') and not args['--detailed']:
        raise ValueError('Nothing to do! (Neither estimates nor true error can be computed.)')

    dim = rb_discretization.solution_space.dim
    if args['--ndim']:
        dims = np.linspace(0, dim, args['--ndim'], dtype=np.int)
    else:
        dims = np.arange(dim + 1)

    mus = rb_discretization.parameter_space.sample_randomly(args['SAMPLES'])

    ESTS = []
    ERRS = []
    T_SOLVES = []
    T_ESTS = []
    for N in dims:
        rd, rc, _ = reduce_to_subbasis(rb_discretization, N)
        print('N = {:3} '.format(N), end='')
        us = []
        print('solve ', end='')
        sys.stdout.flush()
        start = time.time()
        for mu in mus:
            us.append(rd.solve(mu))
        T_SOLVES.append((time.time() - start) * 1000. / len(mus))

        print('estimate ', end='')
        sys.stdout.flush()
        if hasattr(rb_discretization, 'estimate'):
            ests = []
            start = time.time()
            for u, mu in zip(us, mus):
                # print('e', end='')
                # sys.stdout.flush()
                ests.append(rd.estimate(u, mu=mu))
            ESTS.append(max(ests))
            T_ESTS.append((time.time() - start) * 1000. / len(mus))

        if args['--detailed']:
            print('errors', end='')
            sys.stdout.flush()
            errs = []
            for u, mu in zip(us, mus):
                err = discretization.solve(mu) - reconstructor.reconstruct(rc.reconstruct(u))
                if args['--error-norm']:
                    errs.append(np.max(getattr(discretization, args['--error-norm'] + '_norm')(err)))
                else:
                    errs.append(np.max(err.l2_norm()))
            ERRS.append(max(errs))

        print()

    print()

    try:
        plt.style.use('ggplot')
    except AttributeError:
        pass  # plt.style is only available in newer matplotlib versions

    plt.subplot(1, 2, 1)
    if hasattr(rb_discretization, 'estimate'):
        plt.semilogy(dims, ESTS, label='max. estimate')
    if args['--detailed']:
        plt.semilogy(dims, ERRS, label='max. error')
    plt.xlabel('dimension')
    plt.legend()

    plt.subplot(1, 2, 2)
    plt.plot(dims, T_SOLVES, label='avg. solve time')
    if hasattr(rb_discretization, 'estimate'):
        plt.plot(dims, T_ESTS, label='avg. estimate time')
    plt.xlabel('dimension')
    plt.ylabel('milliseconds')
    plt.legend()

    plt.show()
Esempio n. 6
0
def analyze_pickle_convergence(args):
    args['SAMPLES'] = int(args['SAMPLES'])

    print('Loading reduced discretization ...')
    rb_discretization = load(open(args['REDUCED_DATA']))

    if args['--detailed']:
        print('Loading high-dimensional data ...')
        discretization, reconstructor = load(open(args['--detailed']))

    if not hasattr(rb_discretization, 'estimate') and not args['--detailed']:
        raise ValueError('Nothing to do! (Neither estimates nor true error can be computed.)')

    dim = rb_discretization.solution_space.dim
    if args['--ndim']:
        dims = np.linspace(0, dim, args['--ndim'], dtype=np.int)
    else:
        dims = np.arange(dim + 1)

    mus = list(rb_discretization.parameter_space.sample_randomly(args['SAMPLES']))

    ESTS = []
    ERRS = []
    T_SOLVES = []
    T_ESTS = []
    for N in dims:
        rd, rc, _ = reduce_to_subbasis(rb_discretization, N)
        print('N = {:3} '.format(N), end='')
        us = []
        print('solve ', end='')
        sys.stdout.flush()
        start = time.time()
        for mu in mus:
            us.append(rd.solve(mu))
        T_SOLVES.append((time.time() - start) * 1000. / len(mus))

        print('estimate ', end='')
        sys.stdout.flush()
        if hasattr(rb_discretization, 'estimate'):
            ests = []
            start = time.time()
            for u, mu in zip(us, mus):
                # print('e', end='')
                # sys.stdout.flush()
                ests.append(rd.estimate(u, mu=mu))
            ESTS.append(max(ests))
            T_ESTS.append((time.time() - start) * 1000. / len(mus))

        if args['--detailed']:
            print('errors', end='')
            sys.stdout.flush()
            errs = []
            for u, mu in zip(us, mus):
                err = discretization.solve(mu) - reconstructor.reconstruct(rc.reconstruct(u))
                if args['--error-norm']:
                    errs.append(np.max(getattr(discretization, args['--error-norm'] + '_norm')(err)))
                else:
                    errs.append(np.max(err.l2_norm()))
            ERRS.append(max(errs))

        print()

    print()

    try:
        plt.style.use('ggplot')
    except AttributeError:
        pass  # plt.style is only available in newer matplotlib versions

    plt.subplot(1, 2, 1)
    if hasattr(rb_discretization, 'estimate'):
        plt.semilogy(dims, ESTS, label='max. estimate')
    if args['--detailed']:
        plt.semilogy(dims, ERRS, label='max. error')
    plt.xlabel('dimension')
    plt.legend()

    plt.subplot(1, 2, 2)
    plt.plot(dims, T_SOLVES, label='avg. solve time')
    if hasattr(rb_discretization, 'estimate'):
        plt.plot(dims, T_ESTS, label='avg. estimate time')
    plt.xlabel('dimension')
    plt.ylabel('milliseconds')
    plt.legend()

    plt.show()
Esempio n. 7
0
def thermalblock_demo(args):
    args['XBLOCKS'] = int(args['XBLOCKS'])
    args['YBLOCKS'] = int(args['YBLOCKS'])
    args['--grid'] = int(args['--grid'])
    args['SNAPSHOTS'] = int(args['SNAPSHOTS'])
    args['RBSIZE'] = int(args['RBSIZE'])
    args['--test'] = int(args['--test'])
    args['--estimator-norm'] = args['--estimator-norm'].lower()
    assert args['--estimator-norm'] in {'trivial', 'h1'}
    args['--extension-alg'] = args['--extension-alg'].lower()
    assert args['--extension-alg'] in {'trivial', 'gram_schmidt', 'h1_gram_schmidt'}
    args['--reductor'] = args['--reductor'].lower()
    assert args['--reductor'] in {'traditional', 'residual_basis'}

    print('Solving on TriaGrid(({0},{0}))'.format(args['--grid']))

    print('Setup Problem ...')
    problem = ThermalBlockProblem(num_blocks=(args['XBLOCKS'], args['YBLOCKS']))

    print('Discretize ...')
    discretization, _ = discretize_elliptic_cg(problem, diameter=1. / args['--grid'])

    print('The parameter type is {}'.format(discretization.parameter_type))

    if args['--plot-solutions']:
        print('Showing some solutions')
        Us = tuple()
        legend = tuple()
        for mu in discretization.parameter_space.sample_randomly(2):
            print('Solving for diffusion = \n{} ... '.format(mu['diffusion']))
            sys.stdout.flush()
            Us = Us + (discretization.solve(mu),)
            legend = legend + (str(mu['diffusion']),)
        discretization.visualize(Us, legend=legend, title='Detailed Solutions for different parameters', block=True)

    print('RB generation ...')

    error_product = discretization.h1_product if args['--estimator-norm'] == 'h1' else None
    coercivity_estimator=ExpressionParameterFunctional('min(diffusion)', discretization.parameter_type)
    reductors = {'residual_basis': partial(reduce_stationary_coercive, error_product=error_product,
                                   coercivity_estimator=coercivity_estimator),
                 'traditional': partial(reduce_stationary_affine_linear, error_product=error_product,
                                        coercivity_estimator=coercivity_estimator)}
    reductor = reductors[args['--reductor']]
    extension_algorithms = {'trivial': trivial_basis_extension,
                            'gram_schmidt': gram_schmidt_basis_extension,
                            'h1_gram_schmidt': partial(gram_schmidt_basis_extension, product=discretization.h1_product)}
    extension_algorithm = extension_algorithms[args['--extension-alg']]
    greedy_data = greedy(discretization, reductor, discretization.parameter_space.sample_uniformly(args['SNAPSHOTS']),
                         use_estimator=args['--with-estimator'], error_norm=discretization.h1_norm,
                         extension_algorithm=extension_algorithm, max_extensions=args['RBSIZE'])
    rb_discretization, reconstructor = greedy_data['reduced_discretization'], greedy_data['reconstructor']

    if args['--pickle']:
        print('\nWriting reduced discretization to file {} ...'.format(args['--pickle'] + '_reduced'))
        with open(args['--pickle'] + '_reduced', 'w') as f:
            dump(rb_discretization, f)
        print('Writing detailed discretization and reconstructor to file {} ...'.format(args['--pickle'] + '_detailed'))
        with open(args['--pickle'] + '_detailed', 'w') as f:
            dump((discretization, reconstructor), f)

    print('\nSearching for maximum error on random snapshots ...')

    def error_analysis(d, rd, rc, mus):
        print('N = {}: '.format(rd.operator.source.dim), end='')
        h1_err_max = -1
        h1_est_max = -1
        cond_max = -1
        for mu in mus:
            print('.', end='')
            sys.stdout.flush()
            u = rd.solve(mu)
            URB = rc.reconstruct(u)
            U = d.solve(mu)
            h1_err = d.h1_norm(U - URB)[0]
            h1_est = rd.estimate(u, mu=mu)
            cond = np.linalg.cond(rd.operator.assemble(mu)._matrix)
            if h1_err > h1_err_max:
                h1_err_max = h1_err
                mumax = mu
            if h1_est > h1_est_max:
                h1_est_max = h1_est
                mu_est_max = mu
            if cond > cond_max:
                cond_max = cond
                cond_max_mu = mu
        print()
        return h1_err_max, mumax, h1_est_max, mu_est_max, cond_max, cond_max_mu

    tic = time.time()

    real_rb_size = len(greedy_data['basis'])
    if args['--plot-error-sequence']:
        N_count = min(real_rb_size - 1, 25)
        Ns = np.linspace(1, real_rb_size, N_count).astype(np.int)
    else:
        Ns = np.array([real_rb_size])
    rd_rcs = [reduce_to_subbasis(rb_discretization, N, reconstructor)[:2] for N in Ns]
    mus = list(discretization.parameter_space.sample_randomly(args['--test']))

    errs, err_mus, ests, est_mus, conds, cond_mus = zip(*(error_analysis(discretization, rd, rc, mus)
                                                        for rd, rc in rd_rcs))
    h1_err_max = errs[-1]
    mumax = err_mus[-1]
    cond_max = conds[-1]
    cond_max_mu = cond_mus[-1]
    toc = time.time()
    t_est = toc - tic

    print('''
    *** RESULTS ***

    Problem:
       number of blocks:                   {args[XBLOCKS]}x{args[YBLOCKS]}
       h:                                  sqrt(2)/{args[--grid]}

    Greedy basis generation:
       number of snapshots:                {args[SNAPSHOTS]}^({args[XBLOCKS]}x{args[YBLOCKS]})
       used estimator:                     {args[--with-estimator]}
       estimator norm:                     {args[--estimator-norm]}
       extension method:                   {args[--extension-alg]}
       prescribed basis size:              {args[RBSIZE]}
       actual basis size:                  {real_rb_size}
       elapsed time:                       {greedy_data[time]}

    Stochastic error estimation:
       number of samples:                  {args[--test]}
       maximal H1-error:                   {h1_err_max}  (mu = {mumax})
       maximal condition of system matrix: {cond_max}  (mu = {cond_max_mu})
       elapsed time:                       {t_est}
    '''.format(**locals()))

    sys.stdout.flush()

    if args['--plot-error-sequence']:
        plt.semilogy(Ns, errs, Ns, ests)
        plt.legend(('error', 'estimator'))
        plt.show()
    if args['--plot-err']:
        U = discretization.solve(mumax)
        URB = reconstructor.reconstruct(rb_discretization.solve(mumax))
        discretization.visualize((U, URB, U - URB), legend=('Detailed Solution', 'Reduced Solution', 'Error'),
                                 title='Maximum Error Solution', separate_colorbars=True, block=True)
Esempio n. 8
0
def thermalblock_demo(args):
    args['XBLOCKS'] = int(args['XBLOCKS'])
    args['YBLOCKS'] = int(args['YBLOCKS'])
    args['--grid'] = int(args['--grid'])
    args['SNAPSHOTS'] = int(args['SNAPSHOTS'])
    args['RBSIZE'] = int(args['RBSIZE'])
    args['--test'] = int(args['--test'])
    args['--estimator-norm'] = args['--estimator-norm'].lower()
    assert args['--estimator-norm'] in {'trivial', 'h1'}
    args['--extension-alg'] = args['--extension-alg'].lower()
    assert args['--extension-alg'] in {
        'trivial', 'gram_schmidt', 'h1_gram_schmidt'
    }
    args['--reductor'] = args['--reductor'].lower()
    assert args['--reductor'] in {'traditional', 'residual_basis'}

    print('Solving on TriaGrid(({0},{0}))'.format(args['--grid']))

    print('Setup Problem ...')
    problem = ThermalBlockProblem(num_blocks=(args['XBLOCKS'],
                                              args['YBLOCKS']))

    print('Discretize ...')
    discretization, _ = discretize_elliptic_cg(problem,
                                               diameter=1. / args['--grid'])

    print('The parameter type is {}'.format(discretization.parameter_type))

    if args['--plot-solutions']:
        print('Showing some solutions')
        Us = tuple()
        legend = tuple()
        for mu in discretization.parameter_space.sample_randomly(2):
            print('Solving for diffusion = \n{} ... '.format(mu['diffusion']))
            sys.stdout.flush()
            Us = Us + (discretization.solve(mu), )
            legend = legend + (str(mu['diffusion']), )
        discretization.visualize(
            Us,
            legend=legend,
            title='Detailed Solutions for different parameters',
            block=True)

    print('RB generation ...')

    error_product = discretization.h1_product if args[
        '--estimator-norm'] == 'h1' else None
    coercivity_estimator = ExpressionParameterFunctional(
        'min(diffusion)', discretization.parameter_type)
    reductors = {
        'residual_basis':
        partial(reduce_stationary_coercive,
                error_product=error_product,
                coercivity_estimator=coercivity_estimator),
        'traditional':
        partial(reduce_stationary_affine_linear,
                error_product=error_product,
                coercivity_estimator=coercivity_estimator)
    }
    reductor = reductors[args['--reductor']]
    extension_algorithms = {
        'trivial':
        trivial_basis_extension,
        'gram_schmidt':
        gram_schmidt_basis_extension,
        'h1_gram_schmidt':
        partial(gram_schmidt_basis_extension,
                product=discretization.h1_product)
    }
    extension_algorithm = extension_algorithms[args['--extension-alg']]
    greedy_data = greedy(discretization,
                         reductor,
                         discretization.parameter_space.sample_uniformly(
                             args['SNAPSHOTS']),
                         use_estimator=args['--with-estimator'],
                         error_norm=discretization.h1_norm,
                         extension_algorithm=extension_algorithm,
                         max_extensions=args['RBSIZE'])
    rb_discretization, reconstructor = greedy_data[
        'reduced_discretization'], greedy_data['reconstructor']

    if args['--pickle']:
        print('\nWriting reduced discretization to file {} ...'.format(
            args['--pickle'] + '_reduced'))
        with open(args['--pickle'] + '_reduced', 'w') as f:
            dump(rb_discretization, f)
        print(
            'Writing detailed discretization and reconstructor to file {} ...'.
            format(args['--pickle'] + '_detailed'))
        with open(args['--pickle'] + '_detailed', 'w') as f:
            dump((discretization, reconstructor), f)

    print('\nSearching for maximum error on random snapshots ...')

    def error_analysis(d, rd, rc, mus):
        print('N = {}: '.format(rd.operator.source.dim), end='')
        h1_err_max = -1
        h1_est_max = -1
        cond_max = -1
        for mu in mus:
            print('.', end='')
            sys.stdout.flush()
            u = rd.solve(mu)
            URB = rc.reconstruct(u)
            U = d.solve(mu)
            h1_err = d.h1_norm(U - URB)[0]
            h1_est = rd.estimate(u, mu=mu)
            cond = np.linalg.cond(rd.operator.assemble(mu)._matrix)
            if h1_err > h1_err_max:
                h1_err_max = h1_err
                mumax = mu
            if h1_est > h1_est_max:
                h1_est_max = h1_est
                mu_est_max = mu
            if cond > cond_max:
                cond_max = cond
                cond_max_mu = mu
        print()
        return h1_err_max, mumax, h1_est_max, mu_est_max, cond_max, cond_max_mu

    tic = time.time()

    real_rb_size = len(greedy_data['basis'])
    if args['--plot-error-sequence']:
        N_count = min(real_rb_size - 1, 25)
        Ns = np.linspace(1, real_rb_size, N_count).astype(np.int)
    else:
        Ns = np.array([real_rb_size])
    rd_rcs = [
        reduce_to_subbasis(rb_discretization, N, reconstructor)[:2] for N in Ns
    ]
    mus = list(discretization.parameter_space.sample_randomly(args['--test']))

    errs, err_mus, ests, est_mus, conds, cond_mus = zip(
        *(error_analysis(discretization, rd, rc, mus) for rd, rc in rd_rcs))
    h1_err_max = errs[-1]
    mumax = err_mus[-1]
    cond_max = conds[-1]
    cond_max_mu = cond_mus[-1]
    toc = time.time()
    t_est = toc - tic

    print('''
    *** RESULTS ***

    Problem:
       number of blocks:                   {args[XBLOCKS]}x{args[YBLOCKS]}
       h:                                  sqrt(2)/{args[--grid]}

    Greedy basis generation:
       number of snapshots:                {args[SNAPSHOTS]}^({args[XBLOCKS]}x{args[YBLOCKS]})
       used estimator:                     {args[--with-estimator]}
       estimator norm:                     {args[--estimator-norm]}
       extension method:                   {args[--extension-alg]}
       prescribed basis size:              {args[RBSIZE]}
       actual basis size:                  {real_rb_size}
       elapsed time:                       {greedy_data[time]}

    Stochastic error estimation:
       number of samples:                  {args[--test]}
       maximal H1-error:                   {h1_err_max}  (mu = {mumax})
       maximal condition of system matrix: {cond_max}  (mu = {cond_max_mu})
       elapsed time:                       {t_est}
    '''.format(**locals()))

    sys.stdout.flush()

    if args['--plot-error-sequence']:
        plt.semilogy(Ns, errs, Ns, ests)
        plt.legend(('error', 'estimator'))
        plt.show()
    if args['--plot-err']:
        U = discretization.solve(mumax)
        URB = reconstructor.reconstruct(rb_discretization.solve(mumax))
        discretization.visualize(
            (U, URB, U - URB),
            legend=('Detailed Solution', 'Reduced Solution', 'Error'),
            title='Maximum Error Solution',
            separate_colorbars=True,
            block=True)
def burgers_demo(args):
    args['--grid'] = int(args['--grid'])
    args['--initial-data'] = args['--initial-data'].lower()
    assert args['--initial-data'] in ('sin', 'bump')
    args['--lxf-lambda'] = float(args['--lxf-lambda'])
    args['--nt'] = int(args['--nt'])
    args['--not-periodic'] = bool(args['--not-periodic'])
    args['--num-flux'] = args['--num-flux'].lower()
    assert args['--num-flux'] in ('lax_friedrichs', 'engquist_osher')
    args['--plot-error-landscape-N'] = int(args['--plot-error-landscape-N'])
    args['--plot-error-landscape-M'] = int(args['--plot-error-landscape-M'])
    args['--test'] = int(args['--test'])
    args['--vx'] = float(args['--vx'])
    args['--vy'] = float(args['--vy'])
    args['EXP_MIN'] = int(args['EXP_MIN'])
    args['EXP_MAX'] = int(args['EXP_MAX'])
    args['DIFF_MIN'] = float(args['DIFF_MIN'])
    args['DIFF_MAX'] = float(args['DIFF_MAX'])
    args['RBSIZE'] = int(args['RBSIZE'])
    args['EXP_SNAPSHOTS'] = int(args['EXP_SNAPSHOTS'])
    args['DIFF_SNAPSHOTS'] = int(args['DIFF_SNAPSHOTS'])
    args['INIT_EISIZE'] = int(args['INIT_EISIZE'])
    args['EXP_INIT_SNAPSHOTS'] = int(args['EXP_INIT_SNAPSHOTS'])
    args['DIFF_INIT_SNAPSHOTS'] = int(args['DIFF_INIT_SNAPSHOTS'])

    print('Setup Problem ...')
    domain_discretizer = partial(discretize_domain_default, grid_type=RectGrid)
    problem = ViscousBurgersProblem(vx=args['--vx'], vy=args['--vy'], initial_data=args['--initial-data'],
                             parameter_range={'exponent': (args['EXP_MIN'], args['EXP_MAX']), 'diffusion': (args['DIFF_MIN'], args['DIFF_MAX'])}, 
                             torus=not args['--not-periodic'])

    print('Discretize ...')
    discretizer = discretize_nonlinear_instationary_advection_diffusion_fv
    discretization, _ = discretizer(problem, diameter=m.sqrt(2) / args['--grid'],
                                    num_flux=args['--num-flux'], lxf_lambda=args['--lxf-lambda'],
                                    nt=args['--nt'], domain_discretizer=domain_discretizer)

    print(discretization.explicit_operator.grid)

    print('The parameter type is {}'.format(discretization.parameter_type))

    if args['--plot-solutions']:
        print('Showing some solutions')
        for mu in discretization.parameter_space.sample_randomly(2):
            print('Solving for exponent = \n{} ... '.format(mu['exponent']))
            print('Solving for diffusion = \n{} ... '.format(mu['diffusion']))
            sys.stdout.flush()
            U = discretization.solve(mu)
            discretization.visualize(U)

    print('CB an RB generation ...')
 
    extension_algorithm = partial(pod_basis_extension)
    
    if args['EXP_MIN'] == args['EXP_MAX']:
        init_samples = discretization.parameter_space.sample_uniformly({'exponent': 1, 'diffusion': args['DIFF_INIT_SNAPSHOTS']})
        samples = discretization.parameter_space.sample_uniformly({'exponent': 1, 'diffusion': args['DIFF_SNAPSHOTS']})
    elif args['DIFF_MIN'] == args['DIFF_MAX']:
        init_samples = discretization.parameter_space.sample_uniformly({'exponent': args['EXP_INIT_SNAPSHOTS'], 'diffusion': 1})
        samples = discretization.parameter_space.sample_uniformly({'exponent': args['EXP_SNAPSHOTS'], 'diffusion': 1})
    else:
        init_samples = discretization.parameter_space.sample_uniformly({'exponent': args['EXP_INIT_SNAPSHOTS'], 'diffusion': args['DIFF_INIT_SNAPSHOTS']})
        samples = discretization.parameter_space.sample_uniformly({'exponent': args['EXP_SNAPSHOTS'], 'diffusion': args['DIFF_SNAPSHOTS']})
    
    _, ei_initial_data = interpolate_operators(discretization, ['explicit_operator'],
                                            init_samples,
                                            error_norm=discretization.l2_norm, target_error=1e-10,
                                            max_interpolation_dofs=args['INIT_EISIZE'], projection='orthogonal',
                                            product=discretization.l2_product)
    
    rb_initial_data = discretization.initial_data.as_vector()
    rb_initial_data *= 1 / rb_initial_data.l2_norm()[0]

    ei_greedy_data = ei_rb_greedy(discretization, 
                               operator_names=['explicit_operator'], samples=samples,
                               error_norm=discretization.l2_norm,
                               target_error=1e-10, rb_initial_data=rb_initial_data, ei_initial_data=ei_initial_data,
                               max_extensions=args['RBSIZE'], use_estimator=False,
                               extension_algorithm=extension_algorithm)

    rb_discretization, reconstructor = ei_greedy_data['reduced_discretization'], ei_greedy_data['reconstructor']
    ei_discretization, ei_data = ei_greedy_data['ei_discretization'], ei_greedy_data['ei_data']
    
    if args['--plot-ei-err']:
        print('Showing some EI errors')
        for mu in discretization.parameter_space.sample_randomly(2):
            print('Solving for exponent = \n{} ... '.format(mu['exponent']))
            print('Solving for diffusion = \n{} ... '.format(mu['diffusion']))
            sys.stdout.flush()
            U = discretization.solve(mu)
            U_EI = ei_discretization.solve(mu)
            ERR = U - U_EI
            print('Error: {}'.format(np.max(discretization.l2_norm(ERR))))
            discretization.visualize(ERR)
 
        print('Showing interpolation DOFs ...')
        U = np.zeros(U.dim)
        dofs = ei_discretization.operator.interpolation_dofs
        U[dofs] = np.arange(1, len(dofs) + 1)
        U[ei_discretization.operator.source_dofs] += int(len(dofs)/2)
        discretization.visualize(NumpyVectorArray(U))

    print('\nSearching for maximum error on random snapshots ...')

    tic = time.time()
    
    mus = list(discretization.parameter_space.sample_randomly(args['--test']))
    #mus.append({'diffusion': np.array([0.0]), 'exponent': np.array(2.0)})

    def error_analysis(N, M):
        print('N = {}, M = {}: '.format(N, M), end='')
        rd, rc, _ = reduce_to_subbasis(rb_discretization, N, reconstructor)
        rd = rd.with_(explicit_operator=rd.explicit_operator.projected_to_subbasis(dim_collateral=M))
        l2_err_max = -1
        mumax = None
        for mu in mus:
            print('.', end='')
            sys.stdout.flush()
            u = rd.solve(mu)
            URB = rc.reconstruct(u)
            U = discretization.solve(mu)
            l2_err = np.max(discretization.l2_norm(U - URB))
            l2_err = np.inf if not np.isfinite(l2_err) else l2_err
            if l2_err > l2_err_max:
                l2_err_max = l2_err
                mumax = mu
        print()
        return l2_err_max, mumax
    error_analysis = np.frompyfunc(error_analysis, 2, 2)
    
    real_rb_size = len(ei_greedy_data['data'])
    real_cb_size = len(ei_data['basis'])
    
    if args['--plot-error-landscape']:
        N_count = min(real_rb_size - 1, args['--plot-error-landscape-N'])
        M_count = min(real_cb_size - 1, args['--plot-error-landscape-M'])
        Ns = np.linspace(1, real_rb_size, N_count).astype(np.int)
        Ms = np.linspace(1, real_cb_size, M_count).astype(np.int)
    else:
        Ns = np.array([real_rb_size])
        Ms = np.array([real_cb_size])

    N_grid, M_grid = np.meshgrid(Ns, Ms)

    errs, err_mus = error_analysis(N_grid, M_grid)
    errs = errs.astype(np.float)

    l2_err_max = errs[-1, -1]
    mumax = err_mus[-1, -1]
    toc = time.time()
    t_est = toc - tic

    print('''
    *** RESULTS ***

    Problem:
       parameter range:                    ({args[EXP_MIN]}, {args[EXP_MAX]}), ({args[DIFF_MIN]}, {args[DIFF_MAX]})
       h:                                  sqrt(2)/{args[--grid]}
       initial-data:                       {args[--initial-data]}
       lxf-lambda:                         {args[--lxf-lambda]}
       nt:                                 {args[--nt]}
       not-periodic:                       {args[--not-periodic]}
       num-flux:                           {args[--num-flux]}
       (vx, vy):                           ({args[--vx]}, {args[--vy]})

    Greedy basis generation:
       number of initial snapshots:        ({args[EXP_INIT_SNAPSHOTS]}, {args[DIFF_INIT_SNAPSHOTS]})
       initial collateral basis size:      {args[INIT_EISIZE]}
       actual collateral basis size:       {real_cb_size}
       number of snapshots:                ({args[EXP_SNAPSHOTS]}, {args[DIFF_SNAPSHOTS]})
       prescribed basis size:              {args[RBSIZE]}
       actual basis size:                  {real_rb_size}
       elapsed time:                       {ei_greedy_data[time]}

    Stochastic error estimation:
       number of samples:                  {args[--test]}
       maximal L2-error:                   {l2_err_max}  (mu = {mumax})
       
       maximum errors:                     {errs}
       N_grid (RB size):                   {N_grid}
       M_grid (CB size):                   {M_grid}
       
       elapsed time:                       {t_est}
    '''.format(**locals()))

    sys.stdout.flush()
    if args['--plot-error-landscape']:
        import matplotlib.pyplot as plt
        import mpl_toolkits.mplot3d
        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')
        # we have to rescale the errors since matplotlib does not support logarithmic scales on 3d plots
        # https://github.com/matplotlib/matplotlib/issues/209
        surf = ax.plot_surface(M_grid, N_grid, np.log(np.minimum(errs, 1)) / np.log(10),
                               rstride=1, cstride=1, cmap='jet')
        plt.show()
        
    if args['--plot-error-correlation']:
        import matplotlib.pyplot as plt
        from matplotlib.ticker import FuncFormatter
        errs = []
        Ns = ei_greedy_data['N_M_correlation'][0]
        Ms = ei_greedy_data['N_M_correlation'][1]
        corr = []
        for i in np.arange(real_rb_size):
            N = Ns[i]
            M = Ms[i]
            if M > real_cb_size:
                M = real_cb_size
            corr.append(M/N)
            print('N = {}, M = {}: '.format(N, M), end='')
            rd, rc, _ = reduce_to_subbasis(rb_discretization, N, reconstructor)
            rd = rd.with_(explicit_operator=rd.explicit_operator.projected_to_subbasis(dim_collateral=M))
            l2_err_max = -1
            mumax = None
            for mu in mus:
                print('.', end='')
                sys.stdout.flush()
                u = rd.solve(mu)
                URB = rc.reconstruct(u)
                U = discretization.solve(mu)
                l2_err = np.max(discretization.l2_norm(U - URB))
                l2_err = np.inf if not np.isfinite(l2_err) else l2_err
                if l2_err > l2_err_max:
                    l2_err_max = l2_err
                    mumax = mu
            errs.append(l2_err_max)
            print(mumax)
            print()
            
        def tick_function(x, pos):
            N = int(x)
            if not N == 0:
                if N > real_rb_size:
                    value = (N, Ms[-1])
                else:
                    value = (N, Ms[N-1])
            else:
                value = (1, Ms[0])
            return str(value)
        
        plt.semilogy(Ns, errs)
        plt.xlabel('(RB size, CRB size)')
        plt.ylabel('max. L2-error')
        ax = plt.axes()
        ax.xaxis.set_major_formatter( FuncFormatter(tick_function))
        plt.show()
        
        plt.plot(Ns, corr)
        plt.xlabel('(RB size, CRB size)')
        plt.ylabel('M/N correlation')
        ax = plt.axes()
        ax.xaxis.set_major_formatter( FuncFormatter(tick_function))
        plt.show()
    
    if args['--plot-err']:
        discretization.visualize(U - URB)