def elliptic_oned_demo(args): args['PROBLEM-NUMBER'] = int(args['PROBLEM-NUMBER']) assert 0 <= args['PROBLEM-NUMBER'] <= 1, ValueError( 'Invalid problem number.') args['N'] = int(args['N']) rhss = [ ExpressionFunction('ones(x.shape[:-1]) * 10', 1, ()), ExpressionFunction('(x - 0.5)**2 * 1000', 1, ()) ] rhs = rhss[args['PROBLEM-NUMBER']] d0 = ExpressionFunction('1 - x', 1, ()) d1 = ExpressionFunction('x', 1, ()) f0 = ProjectionParameterFunctional('diffusionl') f1 = 1. problem = StationaryProblem(domain=LineDomain(), rhs=rhs, diffusion=LincombFunction([d0, d1], [f0, f1]), dirichlet_data=ConstantFunction(value=0, dim_domain=1), name='1DProblem') parameter_space = problem.parameters.space(0.1, 1) print('Discretize ...') discretizer = discretize_stationary_fv if args[ '--fv'] else discretize_stationary_cg m, data = discretizer(problem, diameter=1 / args['N']) print(data['grid']) print() print('Solve ...') U = m.solution_space.empty() for mu in parameter_space.sample_uniformly(10): U.append(m.solve(mu)) m.visualize(U, title='Solution for diffusionl in [0.1, 1]')
def helmholtz_problem(domain=RectDomain(), rhs=None, parameter_range=(0., 100.), dirichlet_data=None, neumann_data=None): """Helmholtz equation problem. This problem is to solve the Helmholtz equation :: - ∆ u(x, k) - k^2 u(x, k) = f(x, k) on a given domain. Parameters ---------- domain A |DomainDescription| of the domain the problem is posed on. rhs The |Function| f(x, μ). parameter_range A tuple `(k_min, k_max)` describing the interval in which k is allowd to vary. dirichlet_data |Function| providing the Dirichlet boundary values. neumann_data |Function| providing the Neumann boundary values. """ return StationaryProblem( domain=domain, rhs=rhs or ConstantFunction(1., dim_domain=domain.dim), dirichlet_data=dirichlet_data, neumann_data=neumann_data, diffusion=ConstantFunction(1., dim_domain=domain.dim), reaction=LincombFunction( [ConstantFunction(1., dim_domain=domain.dim)], [ExpressionParameterFunctional('-k**2', {'k': ()})]), parameter_space=CubicParameterSpace({'k': ()}, *parameter_range), name='helmholtz_problem')
def elliptic_gmsh_demo(args): args['ANGLE'] = float(args['ANGLE']) args['NUM_POINTS'] = int(args['NUM_POINTS']) args['CLSCALE'] = float(args['CLSCALE']) problem = StationaryProblem( domain=CircularSectorDomain(args['ANGLE'], radius=1, num_points=args['NUM_POINTS']), diffusion=ConstantFunction(1, dim_domain=2), rhs=ConstantFunction(np.array(0.), dim_domain=2, name='rhs'), dirichlet_data=ExpressionFunction('sin(polar(x)[1] * pi/angle)', 2, (), {}, {'angle': args['ANGLE']}, name='dirichlet')) print('Discretize ...') discretizer = discretize_stationary_fv if args[ '--fv'] else discretize_stationary_cg d, data = discretizer(analytical_problem=problem, diameter=args['CLSCALE']) grid = data['grid'] print(grid) print() print('Solve ...') U = d.solve() solution = ExpressionFunction( '(lambda r, phi: r**(pi/angle) * sin(phi * pi/angle))(*polar(x))', 2, (), {}, {'angle': args['ANGLE']}) U_ref = U.space.make_array( solution(grid.centers(0)) if args['--fv'] else solution(grid.centers(2) )) d.visualize((U, U_ref, U - U_ref), legend=('Solution', 'Analytical solution (circular boundary)', 'Error'), separate_colorbars=True)
def elliptic2_demo(args): args['PROBLEM-NUMBER'] = int(args['PROBLEM-NUMBER']) assert 0 <= args['PROBLEM-NUMBER'] <= 1, ValueError('Invalid problem number.') args['N'] = int(args['N']) norm = args['NORM'] norm = float(norm) if not norm.lower() in ('h1', 'l2') else norm.lower() rhss = [ExpressionFunction('ones(x.shape[:-1]) * 10', 2, ()), LincombFunction( [ExpressionFunction('ones(x.shape[:-1]) * 10', 2, ()), ConstantFunction(1.,2)], [ProjectionParameterFunctional('mu'), 0.1])] dirichlets = [ExpressionFunction('zeros(x.shape[:-1])', 2, ()), LincombFunction( [ExpressionFunction('2 * x[..., 0]', 2, ()), ConstantFunction(1.,2)], [ProjectionParameterFunctional('mu'), 0.5])] neumanns = [None, LincombFunction( [ExpressionFunction('1 - x[..., 1]', 2, ()), ConstantFunction(1.,2)], [ProjectionParameterFunctional('mu'), 0.5**2])] robins = [None, (LincombFunction( [ExpressionFunction('x[..., 1]', 2, ()), ConstantFunction(1.,2)], [ProjectionParameterFunctional('mu'), 1]), ConstantFunction(1.,2))] domains = [RectDomain(), RectDomain(right='neumann', top='dirichlet', bottom='robin')] rhs = rhss[args['PROBLEM-NUMBER']] dirichlet = dirichlets[args['PROBLEM-NUMBER']] neumann = neumanns[args['PROBLEM-NUMBER']] domain = domains[args['PROBLEM-NUMBER']] robin = robins[args['PROBLEM-NUMBER']] problem = StationaryProblem( domain=domain, rhs=rhs, diffusion=LincombFunction( [ExpressionFunction('1 - x[..., 0]', 2, ()), ExpressionFunction('x[..., 0]', 2, ())], [ProjectionParameterFunctional('mu'), 1] ), dirichlet_data=dirichlet, neumann_data=neumann, robin_data=robin, parameter_ranges=(0.1, 1), name='2DProblem' ) if isinstance(norm, float) and not args['--fv']: # use a random parameter to construct an energy product mu_bar = problem.parameters.parse(norm) else: mu_bar = None print('Discretize ...') if args['--fv']: m, data = discretize_stationary_fv(problem, diameter=1. / args['N']) else: m, data = discretize_stationary_cg(problem, diameter=1. / args['N'], mu_energy_product=mu_bar) print(data['grid']) print() print('Solve ...') U = m.solution_space.empty() for mu in problem.parameter_space.sample_uniformly(10): U.append(m.solve(mu)) if mu_bar is not None: # use the given energy product norm_squared = U[-1].norm(m.products['energy'])[0] print('Energy norm of the last snapshot: ', np.sqrt(norm_squared)) if not args['--fv']: if args['NORM'] == 'h1': norm_squared = U[-1].norm(m.products['h1_0_semi'])[0] print('H^1_0 semi norm of the last snapshot: ', np.sqrt(norm_squared)) if args['NORM'] == 'l2': norm_squared = U[-1].norm(m.products['l2_0'])[0] print('L^2_0 norm of the last snapshot: ', np.sqrt(norm_squared)) m.visualize(U, title='Solution for mu in [0.1, 1]')
def main( problem_number: int = Argument(..., min=0, max=1, help='Selects the problem to solve [0 or 1].'), n: int = Argument(..., help='Triangle count per direction'), norm: str = Argument( ..., help="h1: compute the h1-norm of the last snapshot.\n\n" "l2: compute the l2-norm of the last snapshot.\n\n" "k: compute the energy norm of the last snapshot, where the energy-product" "is constructed with a parameter {'mu': k}." ), fv: bool = Option(False, help='Use finite volume discretization instead of finite elements.'), ): """Solves the Poisson equation in 2D using pyMOR's builtin discreization toolkit.""" norm = float(norm) if not norm.lower() in ('h1', 'l2') else norm.lower() rhss = [ExpressionFunction('ones(x.shape[:-1]) * 10', 2, ()), LincombFunction( [ExpressionFunction('ones(x.shape[:-1]) * 10', 2, ()), ConstantFunction(1., 2)], [ProjectionParameterFunctional('mu'), 0.1])] dirichlets = [ExpressionFunction('zeros(x.shape[:-1])', 2, ()), LincombFunction( [ExpressionFunction('2 * x[..., 0]', 2, ()), ConstantFunction(1., 2)], [ProjectionParameterFunctional('mu'), 0.5])] neumanns = [None, LincombFunction( [ExpressionFunction('1 - x[..., 1]', 2, ()), ConstantFunction(1., 2)], [ProjectionParameterFunctional('mu'), 0.5**2])] robins = [None, (LincombFunction( [ExpressionFunction('x[..., 1]', 2, ()), ConstantFunction(1., 2)], [ProjectionParameterFunctional('mu'), 1]), ConstantFunction(1., 2))] domains = [RectDomain(), RectDomain(right='neumann', top='dirichlet', bottom='robin')] rhs = rhss[problem_number] dirichlet = dirichlets[problem_number] neumann = neumanns[problem_number] domain = domains[problem_number] robin = robins[problem_number] problem = StationaryProblem( domain=domain, rhs=rhs, diffusion=LincombFunction( [ExpressionFunction('1 - x[..., 0]', 2, ()), ExpressionFunction('x[..., 0]', 2, ())], [ProjectionParameterFunctional('mu'), 1] ), dirichlet_data=dirichlet, neumann_data=neumann, robin_data=robin, parameter_ranges=(0.1, 1), name='2DProblem' ) if isinstance(norm, float) and not fv: # use a random parameter to construct an energy product mu_bar = problem.parameters.parse(norm) else: mu_bar = None print('Discretize ...') if fv: m, data = discretize_stationary_fv(problem, diameter=1. / n) else: m, data = discretize_stationary_cg(problem, diameter=1. / n, mu_energy_product=mu_bar) print(data['grid']) print() print('Solve ...') U = m.solution_space.empty() for mu in problem.parameter_space.sample_uniformly(10): U.append(m.solve(mu)) if mu_bar is not None: # use the given energy product norm_squared = U[-1].norm(m.products['energy'])[0] print('Energy norm of the last snapshot: ', np.sqrt(norm_squared)) if not fv: if norm == 'h1': norm_squared = U[-1].norm(m.products['h1_0_semi'])[0] print('H^1_0 semi norm of the last snapshot: ', np.sqrt(norm_squared)) if norm == 'l2': norm_squared = U[-1].norm(m.products['l2_0'])[0] print('L^2_0 norm of the last snapshot: ', np.sqrt(norm_squared)) m.visualize(U, title='Solution for mu in [0.1, 1]')
def main( problem_number: int = Argument( ..., min=0, max=1, help='Selects the problem to solve [0 or 1].'), dirichlet_number: int = Argument( ..., min=0, max=2, help='Selects the Dirichlet data function [0 to 2].'), neumann_number: int = Argument( ..., min=0, max=2, help='Selects the Neumann data function.'), neumann_count: int = Argument( ..., min=0, max=3, help='0: no neumann boundary\n\n' '1: right edge is neumann boundary\n\n' '2: right+top edges are neumann boundary\n\n' '3: right+top+bottom edges are neumann boundary\n\n'), fv: bool = Option( False, help='Use finite volume discretization instead of finite elements.' ), rect: bool = Option(False, help='Use RectGrid instead of TriaGrid.'), ): """Solves the Poisson equation in 2D using pyMOR's builtin discreization toolkit.""" rhss = [ ExpressionFunction('ones(x.shape[:-1]) * 10', 2, ()), ExpressionFunction('(x[..., 0] - 0.5) ** 2 * 1000', 2, ()) ] dirichlets = [ ExpressionFunction('zeros(x.shape[:-1])', 2, ()), ExpressionFunction('ones(x.shape[:-1])', 2, ()), ExpressionFunction('x[..., 0]', 2, ()) ] neumanns = [ None, ConstantFunction(3., dim_domain=2), ExpressionFunction( '50*(0.1 <= x[..., 1]) * (x[..., 1] <= 0.2)' '+50*(0.8 <= x[..., 1]) * (x[..., 1] <= 0.9)', 2, ()) ] domains = [ RectDomain(), RectDomain(right='neumann'), RectDomain(right='neumann', top='neumann'), RectDomain(right='neumann', top='neumann', bottom='neumann') ] rhs = rhss[problem_number] dirichlet = dirichlets[dirichlet_number] neumann = neumanns[neumann_number] domain = domains[neumann_count] problem = StationaryProblem(domain=domain, diffusion=ConstantFunction(1, dim_domain=2), rhs=rhs, dirichlet_data=dirichlet, neumann_data=neumann) for n in [32, 128]: print('Discretize ...') discretizer = discretize_stationary_fv if fv else discretize_stationary_cg m, data = discretizer(analytical_problem=problem, grid_type=RectGrid if rect else TriaGrid, diameter=np.sqrt(2) / n if rect else 1. / n) grid = data['grid'] print(grid) print() print('Solve ...') U = m.solve() m.visualize(U, title=repr(grid)) print()
def main( diameter: float = Argument( 0.1, help='Diameter option for the domain discretizer.'), r: int = Argument(5, help='Order of the ROMs.'), ): r"""2D heat equation demo. Discretization of the PDE: .. math:: :nowrap: \begin{align*} \partial_t z(x, y, t) &= \Delta z(x, y, t), & 0 < x, y < 1,\ t > 0 \\ -\nabla z(0, y, t) \cdot n &= z(0, y, t) - u(t), & 0 < y < 1, t > 0 \\ -\nabla z(1, y, t) \cdot n &= z(1, y, t), & 0 < y < 1, t > 0 \\ -\nabla z(0, x, t) \cdot n &= z(0, x, t), & 0 < x < 1, t > 0 \\ -\nabla z(1, x, t) \cdot n &= z(1, x, t), & 0 < x < 1, t > 0 \\ z(x, y, 0) &= 0 & 0 < x, y < 1 \\ y(t) &= \int_0^1 z(1, y, t) dy, & t > 0 \\ \end{align*} where :math:`u(t)` is the input and :math:`y(t)` is the output. """ set_log_levels({'pymor.algorithms.gram_schmidt.gram_schmidt': 'WARNING'}) p = InstationaryProblem(StationaryProblem( domain=RectDomain([[0., 0.], [1., 1.]], left='robin', right='robin', top='robin', bottom='robin'), diffusion=ConstantFunction(1., 2), robin_data=(ConstantFunction(1., 2), ExpressionFunction('(x[...,0] < 1e-10) * 1.', 2)), outputs=[('l2_boundary', ExpressionFunction('(x[...,0] > (1 - 1e-10)) * 1.', 2))]), ConstantFunction(0., 2), T=1.) fom, _ = discretize_instationary_cg(p, diameter=diameter, nt=100) fom.visualize(fom.solve()) lti = fom.to_lti() print(f'order of the model = {lti.order}') print(f'number of inputs = {lti.dim_input}') print(f'number of outputs = {lti.dim_output}') # System poles poles = lti.poles() fig, ax = plt.subplots() ax.plot(poles.real, poles.imag, '.') ax.set_title('System poles') plt.show() # Magnitude plot of the full model w = np.logspace(-1, 3, 100) fig, ax = plt.subplots() lti.mag_plot(w, ax=ax) ax.set_title('Magnitude plot of the full model') plt.show() # Hankel singular values hsv = lti.hsv() fig, ax = plt.subplots() ax.semilogy(range(1, len(hsv) + 1), hsv, '.-') ax.set_title('Hankel singular values') plt.show() # Norms of the system print(f'FOM H_2-norm: {lti.h2_norm():e}') if config.HAVE_SLYCOT: print(f'FOM H_inf-norm: {lti.hinf_norm():e}') else: print('Skipped H_inf-norm calculation due to missing slycot.') print(f'FOM Hankel-norm: {lti.hankel_norm():e}') # Model order reduction run_mor_method(lti, w, BTReductor(lti), 'BT', r, tol=1e-5) run_mor_method(lti, w, LQGBTReductor(lti), 'LQGBT', r, tol=1e-5) run_mor_method(lti, w, BRBTReductor(lti), 'BRBT', r, tol=1e-5) run_mor_method(lti, w, IRKAReductor(lti), 'IRKA', r) run_mor_method(lti, w, TSIAReductor(lti), 'TSIA', r) run_mor_method(lti, w, OneSidedIRKAReductor(lti, 'V'), 'OS-IRKA', r)
if __name__ == '__main__': argvs = sys.argv parser = OptionParser() parser.add_option("--dir", dest="dir", default="./") opt, argc = parser.parse_args(argvs) print(opt, argc) rhs = ExpressionFunction('(x[..., 0] - 0.5)**2 * 1000', 2, ()) problem = StationaryProblem( domain=RectDomain(), rhs=rhs, diffusion=LincombFunction( [ExpressionFunction('1 - x[..., 0]', 2, ()), ExpressionFunction('x[..., 0]', 2, ())], [ProjectionParameterFunctional( 'diffusionl', 0), ExpressionParameterFunctional('1', {})] ), parameter_space=CubicParameterSpace({'diffusionl': 0}, 0.01, 0.1), name='2DProblem' ) args = {'N': 100, 'samples': 10} m, data = discretize_stationary_cg(problem, diameter=1. / args['N']) U = m.solution_space.empty() for mu in m.parameter_space.sample_uniformly(args['samples']): U.append(m.solve(mu)) Us = U * 1.5 plot = m.visualize((U, Us), title='Solution for diffusionl=0.5')
def main( diameter: float = Argument( 0.01, help='Diameter option for the domain discretizer.'), r: int = Argument(5, help='Order of the ROMs.'), ): """Parametric 1D heat equation example.""" set_log_levels({'pymor.algorithms.gram_schmidt.gram_schmidt': 'WARNING'}) # Model 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.) fom, _ = discretize_instationary_cg(p, diameter=diameter, nt=100) fom.visualize(fom.solve(mu=0.1)) fom.visualize(fom.solve(mu=1)) fom.visualize(fom.solve(mu=10)) lti = fom.to_lti() print(f'order of the model = {lti.order}') print(f'number of inputs = {lti.dim_input}') print(f'number of outputs = {lti.dim_output}') mu_list = [0.1, 1, 10] w_list = np.logspace(-1, 3, 100) # System poles fig, ax = plt.subplots() for mu in mu_list: poles = lti.poles(mu=mu) ax.plot(poles.real, poles.imag, '.', label=fr'$\mu = {mu}$') ax.set_title('System poles') ax.legend() plt.show() # Magnitude plots fig, ax = plt.subplots() for mu in mu_list: lti.mag_plot(w_list, ax=ax, mu=mu, label=fr'$\mu = {mu}$') ax.set_title('Magnitude plot of the full model') ax.legend() plt.show() # Hankel singular values fig, ax = plt.subplots() for mu in mu_list: hsv = lti.hsv(mu=mu) ax.semilogy(range(1, len(hsv) + 1), hsv, label=fr'$\mu = {mu}$') ax.set_title('Hankel singular values') ax.legend() plt.show() # System norms for mu in mu_list: print(f'mu = {mu}:') print(f' H_2-norm of the full model: {lti.h2_norm(mu=mu):e}') if config.HAVE_SLYCOT: print( f' H_inf-norm of the full model: {lti.hinf_norm(mu=mu):e}') print(f' Hankel-norm of the full model: {lti.hankel_norm(mu=mu):e}') # Model order reduction run_mor_method_param(lti, r, w_list, mu_list, BTReductor, 'BT') run_mor_method_param(lti, r, w_list, mu_list, LQGBTReductor, 'LQGBT') run_mor_method_param(lti, r, w_list, mu_list, BRBTReductor, 'BRBT') run_mor_method_param(lti, r, w_list, mu_list, IRKAReductor, 'IRKA') run_mor_method_param(lti, r, w_list, mu_list, TSIAReductor, 'TSIA') run_mor_method_param(lti, r, w_list, mu_list, OneSidedIRKAReductor, 'OS-IRKA', version='V')