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, ()) parameter_space = CubicParameterSpace({'diffusionl': 0}, 0.1, 1) f0 = ProjectionParameterFunctional('diffusionl', 0) f1 = ExpressionParameterFunctional('1', {}) problem = StationaryProblem( domain=LineDomain(), rhs=rhs, diffusion=LincombFunction([d0, d1], [f0, f1]), dirichlet_data=ConstantFunction(value=0, dim_domain=1), name='1DProblem' ) print('Discretize ...') discretizer = discretize_stationary_fv if args['--fv'] else discretize_stationary_cg d, data = discretizer(problem, diameter=1 / args['N']) print(data['grid']) print() print('Solve ...') U = d.solution_space.empty() for mu in parameter_space.sample_uniformly(10): U.append(d.solve(mu)) d.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 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']) rhss = [ ExpressionFunction('ones(x.shape[:-1]) * 10', 2, ()), ExpressionFunction('(x[..., 0] - 0.5)**2 * 1000', 2, ()) ] rhs = rhss[args['PROBLEM-NUMBER']] 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.1, 1), name='2DProblem') 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 m.parameter_space.sample_uniformly(10): U.append(m.solve(mu)) m.visualize(U, title='Solution for diffusionl in [0.1, 1]')
def thermal_block_problem(num_blocks=(3, 3), parameter_range=(0.1, 1)): """Analytical description of a 2D 'thermal block' diffusion problem. The problem is to solve the elliptic equation :: - ∇ ⋅ [ d(x, μ) ∇ u(x, μ) ] = f(x, μ) on the domain [0,1]^2 with Dirichlet zero boundary values. The domain is partitioned into nx x ny blocks and the diffusion function d(x, μ) is constant on each such block (i,j) with value μ_ij. :: ---------------------------- | | | | | μ_11 | μ_12 | μ_13 | | | | | |--------------------------- | | | | | μ_21 | μ_22 | μ_23 | | | | | ---------------------------- Parameters ---------- num_blocks The tuple `(nx, ny)` parameter_range A tuple `(μ_min, μ_max)`. Each |Parameter| component μ_ij is allowed to lie in the interval [μ_min, μ_max]. """ def parameter_functional_factory(ix, iy): return ProjectionParameterFunctional(component_name='diffusion', component_shape=(num_blocks[1], num_blocks[0]), index=(num_blocks[1] - iy - 1, ix), name=f'diffusion_{ix}_{iy}') def diffusion_function_factory(ix, iy): if ix + 1 < num_blocks[0]: X = '(x[..., 0] >= ix * dx) * (x[..., 0] < (ix + 1) * dx)' else: X = '(x[..., 0] >= ix * dx)' if iy + 1 < num_blocks[1]: Y = '(x[..., 1] >= iy * dy) * (x[..., 1] < (iy + 1) * dy)' else: Y = '(x[..., 1] >= iy * dy)' return ExpressionFunction(f'{X} * {Y} * 1.', 2, (), {}, {'ix': ix, 'iy': iy, 'dx': 1. / num_blocks[0], 'dy': 1. / num_blocks[1]}, name=f'diffusion_{ix}_{iy}') return StationaryProblem( domain=RectDomain(), rhs=ConstantFunction(dim_domain=2, value=1.), diffusion=LincombFunction([diffusion_function_factory(ix, iy) for ix, iy in product(range(num_blocks[0]), range(num_blocks[1]))], [parameter_functional_factory(ix, iy) for ix, iy in product(range(num_blocks[0]), range(num_blocks[1]))], name='diffusion'), parameter_space=CubicParameterSpace({'diffusion': (num_blocks[1], num_blocks[0])}, *parameter_range), name=f'ThermalBlock({num_blocks})' )
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']) rhss = [ ExpressionFunction('ones(x.shape[:-1]) * 10', 2, ()), LincombFunction([ ExpressionFunction('ones(x.shape[:-1]) * 10', 2, ()), ConstantFunction(1., 2) ], [ ProjectionParameterFunctional('mu', 0), ExpressionParameterFunctional('0.1', {}) ]) ] dirichlets = [ ExpressionFunction('zeros(x.shape[:-1])', 2, ()), LincombFunction([ ExpressionFunction('2 * x[..., 0]', 2, ()), ConstantFunction(1., 2) ], [ ProjectionParameterFunctional('mu', 0), ExpressionParameterFunctional('0.5', {}) ]) ] neumanns = [ None, LincombFunction([ ExpressionFunction('1 - x[..., 1]', 2, ()), ConstantFunction(1., 2) ], [ ProjectionParameterFunctional('mu', 0), ExpressionParameterFunctional('0.5**2', {}) ]) ] robins = [ None, (LincombFunction( [ExpressionFunction('x[..., 1]', 2, ()), ConstantFunction(1., 2)], [ ProjectionParameterFunctional('mu', 0), ExpressionParameterFunctional('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=RectDomain(), rhs=rhs, diffusion=LincombFunction([ ExpressionFunction('1 - x[..., 0]', 2, ()), ExpressionFunction('x[..., 0]', 2, ()) ], [ ProjectionParameterFunctional('mu', 0), ExpressionParameterFunctional('1', {}) ]), dirichlet_data=dirichlet, neumann_data=neumann, robin_data=robin, parameter_space=CubicParameterSpace({'mu': 0}, 0.1, 1), name='2DProblem') 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 m.parameter_space.sample_uniformly(10): U.append(m.solve(mu)) m.visualize(U, title='Solution for mu in [0.1, 1]')
def text_problem(text='pyMOR', font_name=None): import numpy as np from PIL import Image, ImageDraw, ImageFont from tempfile import NamedTemporaryFile font_list = [font_name] if font_name else [ 'DejaVuSansMono.ttf', 'VeraMono.ttf', 'UbuntuMono-R.ttf', 'Arial.ttf' ] font = None for filename in font_list: try: font = ImageFont.truetype( filename, 64) # load some font from file of given size except (OSError, IOError): pass if font is None: raise ValueError('Could not load TrueType font') size = font.getsize(text) # compute width and height of rendered text size = (size[0] + 20, size[1] + 20 ) # add a border of 10 pixels around the text def make_bitmap_function( char_num ): # we need to genereate a BitmapFunction for each character img = Image.new('L', size) # create new Image object of given dimensions d = ImageDraw.Draw(img) # create ImageDraw object for the given Image # in order to position the character correctly, we first draw all characters from the first # up to the wanted character d.text((10, 10), text[:char_num + 1], font=font, fill=255) # next we erase all previous character by drawing a black rectangle if char_num > 0: d.rectangle( ((0, 0), (font.getsize(text[:char_num])[0] + 10, size[1])), fill=0, outline=0) # open a new temporary file with NamedTemporaryFile( suffix='.png' ) as f: # after leaving this 'with' block, the temporary # file is automatically deleted img.save(f, format='png') return BitmapFunction(f.name, bounding_box=[(0, 0), size], range=[0., 1.]) # create BitmapFunctions for each character dfs = [make_bitmap_function(n) for n in range(len(text))] # create an indicator function for the background background = ConstantFunction(1., 2) - LincombFunction( dfs, np.ones(len(dfs))) # form the linear combination dfs = [background] + dfs coefficients = [1] + [ ProjectionParameterFunctional('diffusion', (len(text), ), (i, )) for i in range(len(text)) ] diffusion = LincombFunction(dfs, coefficients) return StationaryProblem(domain=RectDomain(dfs[1].bounding_box, bottom='neumann'), neumann_data=ConstantFunction(-1., 2), diffusion=diffusion, parameter_space=CubicParameterSpace( diffusion.parameter_type, 0.1, 1.))
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': ()}) for m in range(5)] ))] elliptic_problems = picklable_thermalblock_problems + non_picklable_elliptic_problems @pytest.fixture(params=elliptic_problems + thermalblock_problems + burgers_problems) def analytical_problem(request): return request.param @pytest.fixture(params=picklable_elliptic_problems + picklable_thermalblock_problems + burgers_problems) def picklable_analytical_problem(request):
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')