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 ...') m, data = discretize_stationary_cg(analytical_problem=problem, diameter=args['CLSCALE']) grid = data['grid'] print(grid) print() print('Solve ...') U = m.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(2))) m.visualize((U, U_ref, U - U_ref), legend=('Solution', 'Analytical solution (circular boundary)', 'Error'), separate_colorbars=True)
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 burgers_problem_2d(vx=1., vy=1., torus=True, initial_data_type='sin', parameter_range=(1., 2.)): """Two-dimensional Burgers-type problem. The problem is to solve :: ∂_t u(x, t, μ) + ∇ ⋅ (v * u(x, t, μ)^μ) = 0 u(x, 0, μ) = u_0(x) for u with t in [0, 0.3], x in [0, 2] x [0, 1]. Parameters ---------- vx The x component of the velocity vector v. vy The y component of the velocity vector v. torus If `True`, impose periodic boundary conditions. Otherwise, Dirichlet left and bottom, outflow top and right. initial_data_type Type of initial data (`'sin'` or `'bump'`). parameter_range The interval in which μ is allowed to vary. """ assert initial_data_type in ('sin', 'bump') if initial_data_type == 'sin': initial_data = ExpressionFunction( "0.5 * (sin(2 * pi * x[..., 0]) * sin(2 * pi * x[..., 1]) + 1.)", 2, ()) dirichlet_data = ConstantFunction(dim_domain=2, value=0.5) else: initial_data = ExpressionFunction( "(x[..., 0] >= 0.5) * (x[..., 0] <= 1) * 1", 2, ()) dirichlet_data = ConstantFunction(dim_domain=2, value=0.) return InstationaryProblem( StationaryProblem( domain=TorusDomain([[0, 0], [2, 1]]) if torus else RectDomain([[0, 0], [2, 1]], right=None, top=None), dirichlet_data=dirichlet_data, rhs=None, nonlinear_advection=ExpressionFunction("abs(x)**exponent * v", 1, (2, ), {'exponent': ()}, {'v': np.array([vx, vy])}), nonlinear_advection_derivative=ExpressionFunction( "exponent * abs(x)**(exponent-1) * sign(x) * v", 1, (2, ), {'exponent': ()}, {'v': np.array([vx, vy])}), ), initial_data=initial_data, T=0.3, parameter_space=CubicParameterSpace({'exponent': 0}, *parameter_range), name="burgers_problem_2d({}, {}, {}, '{}')".format( vx, vy, torus, initial_data_type))
def burgers_problem(v=1., circle=True, initial_data_type='sin', parameter_range=(1., 2.)): """One-dimensional Burgers-type problem. The problem is to solve :: ∂_t u(x, t, μ) + ∂_x (v * u(x, t, μ)^μ) = 0 u(x, 0, μ) = u_0(x) for u with t in [0, 0.3] and x in [0, 2]. Parameters ---------- v The velocity v. circle If `True`, impose periodic boundary conditions. Otherwise Dirichlet left, outflow right. initial_data_type Type of initial data (`'sin'` or `'bump'`). parameter_range The interval in which μ is allowed to vary. """ assert initial_data_type in ('sin', 'bump') if initial_data_type == 'sin': initial_data = ExpressionFunction('0.5 * (sin(2 * pi * x) + 1.)', 1, ()) dirichlet_data = ConstantFunction(dim_domain=1, value=0.5) else: initial_data = ExpressionFunction('(x >= 0.5) * (x <= 1) * 1.', 1, ()) dirichlet_data = ConstantFunction(dim_domain=1, value=0.) return InstationaryProblem( StationaryProblem( domain=CircleDomain([0, 2]) if circle else LineDomain([0, 2], right=None), dirichlet_data=dirichlet_data, rhs=None, nonlinear_advection=ExpressionFunction('abs(x)**exponent * v', 1, (1, ), {'exponent': ()}, {'v': v}), nonlinear_advection_derivative=ExpressionFunction( 'exponent * abs(x)**(exponent-1) * sign(x) * v', 1, (1, ), {'exponent': ()}, {'v': v}), ), T=0.3, initial_data=initial_data, parameter_space=CubicParameterSpace({'exponent': 0}, *parameter_range), name="burgers_problem({}, {}, '{}')".format(v, circle, initial_data_type))
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}')
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 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('{} * {} * 1.'.format(X, Y), 2, (), {}, { 'ix': ix, 'iy': iy, 'dx': 1. / num_blocks[0], 'dy': 1. / num_blocks[1] }, name='diffusion_{}_{}'.format(ix, iy))
def elliptic_demo(args): args['PROBLEM-NUMBER'] = int(args['PROBLEM-NUMBER']) assert 0 <= args['PROBLEM-NUMBER'] <= 1, ValueError('Invalid problem number') args['DIRICHLET-NUMBER'] = int(args['DIRICHLET-NUMBER']) assert 0 <= args['DIRICHLET-NUMBER'] <= 2, ValueError('Invalid Dirichlet boundary number.') args['NEUMANN-NUMBER'] = int(args['NEUMANN-NUMBER']) assert 0 <= args['NEUMANN-NUMBER'] <= 2, ValueError('Invalid Neumann boundary number.') args['NEUMANN-COUNT'] = int(args['NEUMANN-COUNT']) assert 0 <= args['NEUMANN-COUNT'] <= 3, ValueError('Invalid Neumann boundary count.') 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[args['PROBLEM-NUMBER']] dirichlet = dirichlets[args['DIRICHLET-NUMBER']] neumann = neumanns[args['NEUMANN-NUMBER']] domain = domains[args['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 args['--fv'] else discretize_stationary_cg m, data = discretizer( analytical_problem=problem, grid_type=RectGrid if args['--rect'] else TriaGrid, diameter=np.sqrt(2) / n if args['--rect'] else 1. / n ) grid = data['grid'] print(grid) print() print('Solve ...') U = m.solve() m.visualize(U, title=repr(grid)) print()
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]')
return function_with_closure generic_functions = \ [GenericFunction(lambda x: x, dim_domain=2, shape_range=(2,)), GenericFunction(lambda x, mu: mu['c']*x, dim_domain=1, shape_range=(1,), parameter_type={'c': ()}), GenericFunction(A.unimportable_function, dim_domain=7, shape_range=()), GenericFunction(get_function_with_closure(42), dim_domain=1, shape_range=(2,))] picklable_generic_functions = \ [GenericFunction(importable_function, dim_domain=3, shape_range=(1,))] expression_functions = \ [ExpressionFunction('x', dim_domain=2, shape_range=(2,)), ExpressionFunction("c*x", dim_domain=1, shape_range=(1,), parameter_type={'c': ()}), ExpressionFunction("c[2]*sin(x)", dim_domain=1, shape_range=(1,), parameter_type={'c': (3,)})] @pytest.fixture(params=constant_functions + generic_functions + picklable_generic_functions + expression_functions) def function(request): return request.param @pytest.fixture(params=constant_functions + picklable_generic_functions + expression_functions) def picklable_function(request): return request.param
from ipywidgets import interact, widgets sys.path.append(os.path.join("../")) from src.base import plot2d import logging logging.getLogger('matplotlib').setLevel(logging.ERROR) 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}