def hapod_demo(args): args['--grid'] = int(args['--grid']) args['--nt'] = int(args['--nt']) args['--omega'] = float(args['--omega']) args['--procs'] = int(args['--procs']) args['--snap'] = int(args['--snap']) args['--threads'] = int(args['--threads']) args['TOL'] = float(args['TOL']) args['DIST'] = int(args['DIST']) args['INC'] = int(args['INC']) assert args['--procs'] == 0 or args['--threads'] == 0 tol = args['TOL'] omega = args['--omega'] executor = ProcessPoolExecutor(args['--procs']) if args['--procs'] > 0 else \ ThreadPoolExecutor(args['--threads']) if args['--threads'] > 0 else \ None p = burgers_problem_2d() d, data = discretize_instationary_fv(p, grid_type=RectGrid, diameter=np.sqrt(2)/args['--grid'], nt=args['--nt']) U = d.solution_space.empty() for mu in d.parameter_space.sample_randomly(args['--snap']): U.append(d.solve(mu)) tic = time() pod_modes = pod(U, l2_err=tol * np.sqrt(len(U)), product=d.l2_product, check=False)[0] pod_time = time() - tic tic = time() dist_modes = dist_vectorarray_hapod(args['DIST'], U, tol, omega, product=d.l2_product, executor=executor)[0] dist_time = time() - tic tic = time() inc_modes = inc_vectorarray_hapod(args['INC'], U, tol, omega, product=d.l2_product)[0] inc_time = time() - tic print('Snapshot matrix: {} x {}'.format(U.dim, len(U))) print(format_table([ ['Method', 'Error', 'Modes', 'Time'], ['POD', np.linalg.norm(d.l2_norm(U-pod_modes.lincomb(d.l2_product.apply2(U, pod_modes)))/np.sqrt(len(U))), len(pod_modes), pod_time], ['DIST HAPOD', np.linalg.norm(d.l2_norm(U-dist_modes.lincomb(d.l2_product.apply2(U, dist_modes)))/np.sqrt(len(U))), len(dist_modes), dist_time], ['INC HAPOD', np.linalg.norm(d.l2_norm(U-inc_modes.lincomb(d.l2_product.apply2(U, inc_modes)))/np.sqrt(len(U))), len(inc_modes), inc_time]] ))
def burgers_demo(args): args['--grid'] = int(args['--grid']) args['--grid-type'] = args['--grid-type'].lower() assert args['--grid-type'] in ('rect', 'tria') 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', 'simplified_engquist_osher') args['--vx'] = float(args['--vx']) args['--vy'] = float(args['--vy']) args['EXP'] = float(args['EXP']) print('Setup Problem ...') grid_type_map = {'rect': RectGrid, 'tria': TriaGrid} domain_discretizer = partial(discretize_domain_default, grid_type=grid_type_map[args['--grid-type']]) problem = burgers_problem_2d(vx=args['--vx'], vy=args['--vy'], initial_data_type=args['--initial-data'], parameter_range=(0, 1e42), torus=not args['--not-periodic']) print('Discretize ...') if args['--grid-type'] == 'rect': args['--grid'] *= 1. / m.sqrt(2) discretization, data = discretize_instationary_fv( problem, diameter=1. / args['--grid'], num_flux=args['--num-flux'], lxf_lambda=args['--lxf-lambda'], nt=args['--nt'], domain_discretizer=domain_discretizer ) print(discretization.operator.grid) print('The parameter type is {}'.format(discretization.parameter_type)) mu = args['EXP'] # U = discretization.solve(0) print('Solving for exponent = {} ... '.format(mu)) sys.stdout.flush() # pr = cProfile.Profile() # pr.enable() tic = time.time() U = discretization.solve(mu) # pr.disable() print('Solving took {}s'.format(time.time() - tic)) # pr.dump_stats('bla') discretization.visualize(U)
def burgers_demo(args): args['--grid'] = int(args['--grid']) args['--grid-type'] = args['--grid-type'].lower() assert args['--grid-type'] in ('rect', 'tria') 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', 'simplified_engquist_osher') args['--vx'] = float(args['--vx']) args['--vy'] = float(args['--vy']) args['EXP'] = float(args['EXP']) print('Setup Problem ...') problem = burgers_problem_2d(vx=args['--vx'], vy=args['--vy'], initial_data_type=args['--initial-data'], parameter_range=(0, 1e42), torus=not args['--not-periodic']) print('Discretize ...') if args['--grid-type'] == 'rect': args['--grid'] *= 1. / m.sqrt(2) discretization, data = discretize_instationary_fv( problem, diameter=1. / args['--grid'], grid_type=RectGrid if args['--grid-type'] == 'rect' else TriaGrid, num_flux=args['--num-flux'], lxf_lambda=args['--lxf-lambda'], nt=args['--nt']) print(discretization.operator.grid) print('The parameter type is {}'.format(discretization.parameter_type)) mu = args['EXP'] print('Solving for exponent = {} ... '.format(mu)) sys.stdout.flush() tic = time.time() U = discretization.solve(mu) print('Solving took {}s'.format(time.time() - tic)) discretization.visualize(U)
def burgers_demo(args): args['--grid'] = int(args['--grid']) args['--grid-type'] = args['--grid-type'].lower() assert args['--grid-type'] in ('rect', 'tria') 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', 'simplified_engquist_osher') args['--vx'] = float(args['--vx']) args['--vy'] = float(args['--vy']) args['EXP'] = float(args['EXP']) print('Setup Problem ...') problem = burgers_problem_2d(vx=args['--vx'], vy=args['--vy'], initial_data_type=args['--initial-data'], parameter_range=(0, 1e42), torus=not args['--not-periodic']) print('Discretize ...') if args['--grid-type'] == 'rect': args['--grid'] *= 1. / math.sqrt(2) m, data = discretize_instationary_fv( problem, diameter=1. / args['--grid'], grid_type=RectGrid if args['--grid-type'] == 'rect' else TriaGrid, num_flux=args['--num-flux'], lxf_lambda=args['--lxf-lambda'], nt=args['--nt'] ) print(m.operator.grid) print(f'The parameter type is {m.parameter_type}') mu = args['EXP'] print(f'Solving for exponent = {mu} ... ') sys.stdout.flush() tic = time.time() U = m.solve(mu) print(f'Solving took {time.time()-tic}s') m.visualize(U)
def main( exp_min: float = Argument(..., help='Minimal exponent'), exp_max: float = Argument(..., help='Maximal exponent'), ei_snapshots: int = Argument( ..., help='Number of snapshots for empirical interpolation.'), ei_size: int = Argument(..., help='Number of interpolation DOFs.'), snapshots: int = Argument( ..., help='Number of snapshots for basis generation.'), rb_size: int = Argument(..., help='Size of the reduced basis.'), cache_region: Choices('none memory disk persistent') = Option( 'disk', help='Name of cache region to use for caching solution snapshots.' ), ei_alg: Choices('ei_greedy deim') = Option( 'ei_greedy', help='Interpolation algorithm to use.'), grid: int = Option(60, help='Use grid with (2*NI)*NI elements.'), grid_type: Choices('rect tria') = Option('rect', help='Type of grid to use.'), initial_data: Choices('sin bump') = Option( 'sin', help='Select the initial data (sin, bump).'), ipython_engines: int = Option( 0, help= 'If positive, the number of IPython cluster engines to use for parallel greedy search. ' 'If zero, no parallelization is performed.'), ipython_profile: str = Option( None, help='IPython profile to use for parallelization.'), lxf_lambda: float = Option( 1., help='Parameter lambda in Lax-Friedrichs flux.'), periodic: bool = Option( True, help ='If not, solve with dirichlet boundary conditions on left and bottom boundary.' ), nt: int = Option(100, help='Number of time steps.'), num_flux: Choices('lax_friedrichs engquist_osher') = Option( 'engquist_osher', help='Numerical flux to use.'), plot_err: bool = Option(False, help='Plot error.'), plot_ei_err: bool = Option(False, help='Plot empirical interpolation error.'), plot_error_landscape: bool = Option( False, help='Calculate and show plot of reduction error vs. basis sizes.' ), plot_error_landscape_M: int = Option( 10, help='Number of collateral basis sizes to test.'), plot_error_landscape_N: int = Option( 10, help='Number of basis sizes to test.'), plot_solutions: bool = Option(False, help='Plot some example solutions.'), test: int = Option( 10, help='Number of snapshots to use for stochastic error estimation.' ), vx: float = Option(1., help='Speed in x-direction.'), vy: float = Option(1., help='Speed in y-direction.'), ): """Model order reduction of a two-dimensional Burgers-type equation (see pymor.analyticalproblems.burgers) using the reduced basis method with empirical operator interpolation. """ print('Setup Problem ...') problem = burgers_problem_2d(vx=vx, vy=vy, initial_data_type=initial_data.value, parameter_range=(exp_min, exp_max), torus=periodic) print('Discretize ...') if grid_type == 'rect': grid *= 1. / math.sqrt(2) fom, _ = discretize_instationary_fv( problem, diameter=1. / grid, grid_type=RectGrid if grid_type == 'rect' else TriaGrid, num_flux=num_flux.value, lxf_lambda=lxf_lambda, nt=nt) if cache_region != 'none': # building a cache_id is only needed for persistent CacheRegions cache_id = ( f"pymordemos.burgers_ei {vx} {vy} {initial_data}" f"{periodic} {grid} {grid_type} {num_flux} {lxf_lambda} {nt}") fom.enable_caching(cache_region.value, cache_id) print(fom.operator.grid) print(f'The parameters are {fom.parameters}') if plot_solutions: print('Showing some solutions') Us = () legend = () for mu in problem.parameter_space.sample_uniformly(4): print(f"Solving for exponent = {mu['exponent']} ... ") sys.stdout.flush() Us = Us + (fom.solve(mu), ) legend = legend + (f"exponent: {mu['exponent']}", ) fom.visualize(Us, legend=legend, title='Detailed Solutions', block=True) pool = new_parallel_pool(ipython_num_engines=ipython_engines, ipython_profile=ipython_profile) eim, ei_data = interpolate_operators( fom, ['operator'], problem.parameter_space.sample_uniformly(ei_snapshots), error_norm=fom.l2_norm, product=fom.l2_product, max_interpolation_dofs=ei_size, alg=ei_alg.value, pool=pool) if plot_ei_err: print('Showing some EI errors') ERRs = () legend = () for mu in problem.parameter_space.sample_randomly(2): print(f"Solving for exponent = \n{mu['exponent']} ... ") sys.stdout.flush() U = fom.solve(mu) U_EI = eim.solve(mu) ERR = U - U_EI ERRs = ERRs + (ERR, ) legend = legend + (f"exponent: {mu['exponent']}", ) print(f'Error: {np.max(fom.l2_norm(ERR))}') fom.visualize(ERRs, legend=legend, title='EI Errors', separate_colorbars=True) print('Showing interpolation DOFs ...') U = np.zeros(U.dim) dofs = eim.operator.interpolation_dofs U[dofs] = np.arange(1, len(dofs) + 1) U[eim.operator.source_dofs] += int(len(dofs) / 2) fom.visualize(fom.solution_space.make_array(U), title='Interpolation DOFs') print('RB generation ...') reductor = InstationaryRBReductor(eim) greedy_data = rb_greedy( fom, reductor, problem.parameter_space.sample_uniformly(snapshots), use_error_estimator=False, error_norm=lambda U: np.max(fom.l2_norm(U)), extension_params={'method': 'pod'}, max_extensions=rb_size, pool=pool) rom = greedy_data['rom'] print('\nSearching for maximum error on random snapshots ...') tic = time.perf_counter() mus = problem.parameter_space.sample_randomly(test) def error_analysis(N, M): print(f'N = {N}, M = {M}: ', end='') rom = reductor.reduce(N) rom = rom.with_(operator=rom.operator.with_cb_dim(M)) l2_err_max = -1 mumax = None for mu in mus: print('.', end='') sys.stdout.flush() u = rom.solve(mu) URB = reductor.reconstruct(u) U = fom.solve(mu) l2_err = np.max(fom.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(reductor.bases['RB']) real_cb_size = len(ei_data['basis']) if plot_error_landscape: N_count = min(real_rb_size - 1, plot_error_landscape_N) M_count = min(real_cb_size - 1, 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.perf_counter() t_est = toc - tic print(''' *** RESULTS *** Problem: parameter range: ({exp_min}, {exp_max}) h: sqrt(2)/{grid} grid-type: {grid_type} initial-data: {initial_data} lxf-lambda: {lxf_lambda} nt: {nt} not-periodic: {periodic} num-flux: {num_flux} (vx, vy): ({vx}, {vy}) Greedy basis generation: number of ei-snapshots: {ei_snapshots} prescribed collateral basis size: {ei_size} actual collateral basis size: {real_cb_size} number of snapshots: {snapshots} prescribed basis size: {rb_size} actual basis size: {real_rb_size} elapsed time: {greedy_data[time]} Stochastic error estimation: number of samples: {test} maximal L2-error: {l2_err_max} (mu = {mumax}) elapsed time: {t_est} '''.format(**locals())) sys.stdout.flush() if plot_error_landscape: import matplotlib.pyplot as plt import mpl_toolkits.mplot3d # NOQA fig = plt.figure() ax = fig.add_subplot(111, projection='3d') # 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 plot_err: U = fom.solve(mumax) URB = reductor.reconstruct(rom.solve(mumax)) fom.visualize( (U, URB, U - URB), legend=('Detailed Solution', 'Reduced Solution', 'Error'), title='Maximum Error Solution', separate_colorbars=True) global test_results test_results = (ei_data, greedy_data)
def main(args): args = docopt(__doc__, args) args['--cache-region'] = args['--cache-region'].lower() args['--grid'] = int(args['--grid']) args['--grid-type'] = args['--grid-type'].lower() assert args['--grid-type'] in ('rect', 'tria') 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['--ipython-engines'] = int(args['--ipython-engines']) args['EXP_MIN'] = int(args['EXP_MIN']) args['EXP_MAX'] = int(args['EXP_MAX']) args['EI_SNAPSHOTS'] = int(args['EI_SNAPSHOTS']) args['EISIZE'] = int(args['EISIZE']) args['SNAPSHOTS'] = int(args['SNAPSHOTS']) args['RBSIZE'] = int(args['RBSIZE']) print('Setup Problem ...') problem = burgers_problem_2d(vx=args['--vx'], vy=args['--vy'], initial_data_type=args['--initial-data'], parameter_range=(args['EXP_MIN'], args['EXP_MAX']), torus=not args['--not-periodic']) print('Discretize ...') if args['--grid-type'] == 'rect': args['--grid'] *= 1. / m.sqrt(2) d, _ = discretize_instationary_fv( problem, diameter=1. / args['--grid'], grid_type=RectGrid if args['--grid-type'] == 'rect' else TriaGrid, num_flux=args['--num-flux'], lxf_lambda=args['--lxf-lambda'], nt=args['--nt'] ) if args['--cache-region'] != 'none': d.enable_caching(args['--cache-region']) print(d.operator.grid) print('The parameter type is {}'.format(d.parameter_type)) if args['--plot-solutions']: print('Showing some solutions') Us = () legend = () for mu in d.parameter_space.sample_uniformly(4): print('Solving for exponent = {} ... '.format(mu['exponent'])) sys.stdout.flush() Us = Us + (d.solve(mu),) legend = legend + ('exponent: {}'.format(mu['exponent']),) d.visualize(Us, legend=legend, title='Detailed Solutions', block=True) pool = new_parallel_pool(ipython_num_engines=args['--ipython-engines'], ipython_profile=args['--ipython-profile']) ei_d, ei_data = interpolate_operators(d, ['operator'], d.parameter_space.sample_uniformly(args['EI_SNAPSHOTS']), # NOQA error_norm=d.l2_norm, max_interpolation_dofs=args['EISIZE'], pool=pool) if args['--plot-ei-err']: print('Showing some EI errors') ERRs = () legend = () for mu in d.parameter_space.sample_randomly(2): print('Solving for exponent = \n{} ... '.format(mu['exponent'])) sys.stdout.flush() U = d.solve(mu) U_EI = ei_d.solve(mu) ERR = U - U_EI ERRs = ERRs + (ERR,) legend = legend + ('exponent: {}'.format(mu['exponent']),) print('Error: {}'.format(np.max(d.l2_norm(ERR)))) d.visualize(ERRs, legend=legend, title='EI Errors', separate_colorbars=True) print('Showing interpolation DOFs ...') U = np.zeros(U.dim) dofs = ei_d.operator.interpolation_dofs U[dofs] = np.arange(1, len(dofs) + 1) U[ei_d.operator.source_dofs] += int(len(dofs)/2) d.visualize(d.solution_space.make_array(U), title='Interpolation DOFs') print('RB generation ...') reductor = GenericRBReductor(ei_d) greedy_data = greedy(d, reductor, d.parameter_space.sample_uniformly(args['SNAPSHOTS']), use_estimator=False, error_norm=lambda U: np.max(d.l2_norm(U)), extension_params={'method': 'pod'}, max_extensions=args['RBSIZE'], pool=pool) rd = greedy_data['rd'] print('\nSearching for maximum error on random snapshots ...') tic = time.time() mus = d.parameter_space.sample_randomly(args['--test']) def error_analysis(N, M): print('N = {}, M = {}: '.format(N, M), end='') rd = reductor.reduce(N) rd = rd.with_(operator=rd.operator.with_cb_dim(M)) l2_err_max = -1 mumax = None for mu in mus: print('.', end='') sys.stdout.flush() u = rd.solve(mu) URB = reductor.reconstruct(u) U = d.solve(mu) l2_err = np.max(d.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(reductor.RB) 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]}) h: sqrt(2)/{args[--grid]} grid-type: {args[--grid-type]} 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 ei-snapshots: {args[EI_SNAPSHOTS]} prescribed collateral basis size: {args[EISIZE]} actual collateral basis size: {real_cb_size} number of snapshots: {args[SNAPSHOTS]} 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 L2-error: {l2_err_max} (mu = {mumax}) elapsed time: {t_est} '''.format(**locals())) sys.stdout.flush() if args['--plot-error-landscape']: import matplotlib.pyplot as plt import mpl_toolkits.mplot3d # NOQA 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-err']: U = d.solve(mumax) URB = reductor.reconstruct(rd.solve(mumax)) d.visualize((U, URB, U - URB), legend=('Detailed Solution', 'Reduced Solution', 'Error'), title='Maximum Error Solution', separate_colorbars=True) return ei_data, greedy_data
def hapod_demo(args): args['--grid'] = int(args['--grid']) args['--nt'] = int(args['--nt']) args['--omega'] = float(args['--omega']) args['--procs'] = int(args['--procs']) args['--snap'] = int(args['--snap']) args['--threads'] = int(args['--threads']) args['TOL'] = float(args['TOL']) args['DIST'] = int(args['DIST']) args['INC'] = int(args['INC']) assert args['--procs'] == 0 or args['--threads'] == 0 tol = args['TOL'] omega = args['--omega'] executor = ProcessPoolExecutor(args['--procs']) if args['--procs'] > 0 else \ ThreadPoolExecutor(args['--threads']) if args['--threads'] > 0 else \ None p = burgers_problem_2d() m, data = discretize_instationary_fv(p, grid_type=RectGrid, diameter=np.sqrt(2) / args['--grid'], nt=args['--nt']) U = m.solution_space.empty() for mu in m.parameter_space.sample_randomly(args['--snap']): U.append(m.solve(mu)) tic = time() pod_modes = pod(U, l2_err=tol * np.sqrt(len(U)), product=m.l2_product, check=False)[0] pod_time = time() - tic tic = time() dist_modes = dist_vectorarray_hapod(args['DIST'], U, tol, omega, product=m.l2_product, executor=executor)[0] dist_time = time() - tic tic = time() inc_modes = inc_vectorarray_hapod(args['INC'], U, tol, omega, product=m.l2_product)[0] inc_time = time() - tic print(f'Snapshot matrix: {U.dim} x {len(U)}') print( format_table([ ['Method', 'Error', 'Modes', 'Time'], [ 'POD', np.linalg.norm( m.l2_norm(U - pod_modes.lincomb( m.l2_product.apply2(U, pod_modes))) / np.sqrt(len(U))), len(pod_modes), pod_time ], [ 'DIST HAPOD', np.linalg.norm( m.l2_norm(U - dist_modes.lincomb( m.l2_product.apply2(U, dist_modes))) / np.sqrt(len(U))), len(dist_modes), dist_time ], [ 'INC HAPOD', np.linalg.norm( m.l2_norm(U - inc_modes.lincomb( m.l2_product.apply2(U, inc_modes))) / np.sqrt(len(U))), len(inc_modes), inc_time ] ]))
thermal_block_problem(num_blocks=(2, 2), parameter_range=(1., 100.))] non_picklable_thermalblock_problems = \ [thermal_block_problem(num_blocks=(1, 3), parameter_range=(0.4, 0.5)).with_( rhs=GenericFunction(dim_domain=2, mapping=lambda X: X[..., 0] + X[..., 1]))] thermalblock_problems = picklable_thermalblock_problems + non_picklable_thermalblock_problems burgers_problems = \ [burgers_problem(), burgers_problem(v=0.2, circle=False), burgers_problem(v=0.4, initial_data_type='bump'), burgers_problem(parameter_range=(1., 1.3)), burgers_problem_2d(), burgers_problem_2d(torus=False, initial_data_type='bump', parameter_range=(1.3, 1.5))] picklable_elliptic_problems = \ [StationaryProblem(domain=RectDomain(), rhs=ConstantFunction(dim_domain=2, value=1.)), helmholtz_problem()] non_picklable_elliptic_problems = \ [StationaryProblem(domain=RectDomain(), rhs=ConstantFunction(dim_domain=2, value=21.), diffusion=LincombFunction( [GenericFunction(dim_domain=2, mapping=lambda X, p=p: X[..., 0]**p) for p in range(5)], [ExpressionParameterFunctional('max(mu["exp"], {})'.format(m), parameter_type={'exp': ()})
def main(args): args = docopt(__doc__, args) args['--cache-region'] = args['--cache-region'].lower() args['--ei-alg'] = args['--ei-alg'].lower() assert args['--ei-alg'] in ('ei_greedy', 'deim') args['--grid'] = int(args['--grid']) args['--grid-type'] = args['--grid-type'].lower() assert args['--grid-type'] in ('rect', 'tria') 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['--ipython-engines'] = int(args['--ipython-engines']) args['EXP_MIN'] = int(args['EXP_MIN']) args['EXP_MAX'] = int(args['EXP_MAX']) args['EI_SNAPSHOTS'] = int(args['EI_SNAPSHOTS']) args['EISIZE'] = int(args['EISIZE']) args['SNAPSHOTS'] = int(args['SNAPSHOTS']) args['RBSIZE'] = int(args['RBSIZE']) print('Setup Problem ...') problem = burgers_problem_2d(vx=args['--vx'], vy=args['--vy'], initial_data_type=args['--initial-data'], parameter_range=(args['EXP_MIN'], args['EXP_MAX']), torus=not args['--not-periodic']) print('Discretize ...') if args['--grid-type'] == 'rect': args['--grid'] *= 1. / math.sqrt(2) fom, _ = discretize_instationary_fv( problem, diameter=1. / args['--grid'], grid_type=RectGrid if args['--grid-type'] == 'rect' else TriaGrid, num_flux=args['--num-flux'], lxf_lambda=args['--lxf-lambda'], nt=args['--nt']) if args['--cache-region'] != 'none': fom.enable_caching(args['--cache-region']) print(fom.operator.grid) print(f'The parameter type is {fom.parameter_type}') if args['--plot-solutions']: print('Showing some solutions') Us = () legend = () for mu in fom.parameter_space.sample_uniformly(4): print(f"Solving for exponent = {mu['exponent']} ... ") sys.stdout.flush() Us = Us + (fom.solve(mu), ) legend = legend + (f"exponent: {mu['exponent']}", ) fom.visualize(Us, legend=legend, title='Detailed Solutions', block=True) pool = new_parallel_pool(ipython_num_engines=args['--ipython-engines'], ipython_profile=args['--ipython-profile']) eim, ei_data = interpolate_operators( fom, ['operator'], fom.parameter_space.sample_uniformly(args['EI_SNAPSHOTS']), # NOQA error_norm=fom.l2_norm, product=fom.l2_product, max_interpolation_dofs=args['EISIZE'], alg=args['--ei-alg'], pool=pool) if args['--plot-ei-err']: print('Showing some EI errors') ERRs = () legend = () for mu in fom.parameter_space.sample_randomly(2): print(f"Solving for exponent = \n{mu['exponent']} ... ") sys.stdout.flush() U = fom.solve(mu) U_EI = eim.solve(mu) ERR = U - U_EI ERRs = ERRs + (ERR, ) legend = legend + (f"exponent: {mu['exponent']}", ) print(f'Error: {np.max(fom.l2_norm(ERR))}') fom.visualize(ERRs, legend=legend, title='EI Errors', separate_colorbars=True) print('Showing interpolation DOFs ...') U = np.zeros(U.dim) dofs = eim.operator.interpolation_dofs U[dofs] = np.arange(1, len(dofs) + 1) U[eim.operator.source_dofs] += int(len(dofs) / 2) fom.visualize(fom.solution_space.make_array(U), title='Interpolation DOFs') print('RB generation ...') reductor = InstationaryRBReductor(eim) greedy_data = rb_greedy(fom, reductor, fom.parameter_space.sample_uniformly( args['SNAPSHOTS']), use_estimator=False, error_norm=lambda U: np.max(fom.l2_norm(U)), extension_params={'method': 'pod'}, max_extensions=args['RBSIZE'], pool=pool) rom = greedy_data['rom'] print('\nSearching for maximum error on random snapshots ...') tic = time.time() mus = fom.parameter_space.sample_randomly(args['--test']) def error_analysis(N, M): print(f'N = {N}, M = {M}: ', end='') rom = reductor.reduce(N) rom = rom.with_(operator=rom.operator.with_cb_dim(M)) l2_err_max = -1 mumax = None for mu in mus: print('.', end='') sys.stdout.flush() u = rom.solve(mu) URB = reductor.reconstruct(u) U = fom.solve(mu) l2_err = np.max(fom.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(reductor.bases['RB']) 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]}) h: sqrt(2)/{args[--grid]} grid-type: {args[--grid-type]} 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 ei-snapshots: {args[EI_SNAPSHOTS]} prescribed collateral basis size: {args[EISIZE]} actual collateral basis size: {real_cb_size} number of snapshots: {args[SNAPSHOTS]} 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 L2-error: {l2_err_max} (mu = {mumax}) elapsed time: {t_est} '''.format(**locals())) sys.stdout.flush() if args['--plot-error-landscape']: import matplotlib.pyplot as plt import mpl_toolkits.mplot3d # NOQA 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-err']: U = fom.solve(mumax) URB = reductor.reconstruct(rom.solve(mumax)) fom.visualize( (U, URB, U - URB), legend=('Detailed Solution', 'Reduced Solution', 'Error'), title='Maximum Error Solution', separate_colorbars=True) return ei_data, greedy_data
non_picklable_thermalblock_problems = \ [thermal_block_problem(num_blocks=(1, 3), parameter_range=(0.4, 0.5)).with_( rhs=GenericFunction(dim_domain=2, mapping=lambda X: X[..., 0] + X[..., 1]))] thermalblock_problems = picklable_thermalblock_problems + non_picklable_thermalblock_problems burgers_problems = \ [burgers_problem(), burgers_problem(v=0.2, circle=False), burgers_problem(v=0.4, initial_data_type='bump'), burgers_problem(parameter_range=(1., 1.3)), burgers_problem_2d(), burgers_problem_2d(torus=False, initial_data_type='bump', parameter_range=(1.3, 1.5))] picklable_elliptic_problems = \ [StationaryProblem(domain=RectDomain(), rhs=ConstantFunction(dim_domain=2, value=1.)), helmholtz_problem()] non_picklable_elliptic_problems = \ [StationaryProblem(domain=RectDomain(), rhs=ConstantFunction(dim_domain=2, value=21.), diffusion=LincombFunction( [GenericFunction(dim_domain=2, mapping=lambda X, p=p: X[..., 0]**p) for p in range(5)], [ExpressionParameterFunctional('max(mu["exp"], {})'.format(m), parameter_type={'exp': ()})
def main( tol: float = Argument(..., help='Prescribed mean l2 approximation error.'), dist: int = Argument(..., help='Number of slices for distributed HAPOD.'), inc: int = Argument(..., help='Number of steps for incremental HAPOD.'), grid: int = Option(60, help='Use grid with (2*NI)*NI elements.'), nt: int = Option(100, help='Number of time steps.'), omega: float = Option(0.9, help='Parameter omega from HAPOD algorithm.'), procs: int = Option( 0, help='Number of processes to use for parallelization.'), snap: int = Option(20, help='Number of snapshot trajectories to compute.'), threads: int = Option( 0, help='Number of threads to use for parallelization.'), ): """Compression of snapshot data with the HAPOD algorithm from [HLR18].""" assert procs == 0 or threads == 0 executor = ProcessPoolExecutor(procs) if procs > 0 else \ ThreadPoolExecutor(threads) if threads > 0 else \ None p = burgers_problem_2d() m, data = discretize_instationary_fv(p, grid_type=RectGrid, diameter=np.sqrt(2) / grid, nt=nt) U = m.solution_space.empty() for mu in p.parameter_space.sample_randomly(snap): U.append(m.solve(mu)) tic = time.perf_counter() pod_modes = pod(U, l2_err=tol * np.sqrt(len(U)), product=m.l2_product)[0] pod_time = time.perf_counter() - tic tic = time.perf_counter() dist_modes = dist_vectorarray_hapod(dist, U, tol, omega, product=m.l2_product, executor=executor)[0] dist_time = time.perf_counter() - tic tic = time.perf_counter() inc_modes = inc_vectorarray_hapod(inc, U, tol, omega, product=m.l2_product)[0] inc_time = time.perf_counter() - tic print(f'Snapshot matrix: {U.dim} x {len(U)}') print( format_table([ ['Method', 'Error', 'Modes', 'Time'], [ 'POD', np.linalg.norm( m.l2_norm(U - pod_modes.lincomb( m.l2_product.apply2(U, pod_modes))) / np.sqrt(len(U))), len(pod_modes), pod_time ], [ 'DIST HAPOD', np.linalg.norm( m.l2_norm(U - dist_modes.lincomb( m.l2_product.apply2(U, dist_modes))) / np.sqrt(len(U))), len(dist_modes), dist_time ], [ 'INC HAPOD', np.linalg.norm( m.l2_norm(U - inc_modes.lincomb( m.l2_product.apply2(U, inc_modes))) / np.sqrt(len(U))), len(inc_modes), inc_time ] ]))