Esempio n. 1
0
    def fenics_nonlinear_operator_factory():
        import dolfin as df
        from pymor.bindings.fenics import FenicsVectorSpace, FenicsOperator, FenicsMatrixOperator

        class DirichletBoundary(df.SubDomain):
            def inside(self, x, on_boundary):
                return abs(x[0] - 1.0) < df.DOLFIN_EPS and on_boundary

        mesh = df.UnitSquareMesh(10, 10)
        V = df.FunctionSpace(mesh, "CG", 2)

        g = df.Constant(1.)
        c = df.Constant(1.)
        db = DirichletBoundary()
        bc = df.DirichletBC(V, g, db)

        u = df.TrialFunction(V)
        v = df.TestFunction(V)
        w = df.Function(V)
        f = df.Expression("x[0]*sin(x[1])", degree=2)
        F = df.inner((1 + c*w**2)*df.grad(w), df.grad(v))*df.dx - f*v*df.dx

        space = FenicsVectorSpace(V)
        op = FenicsOperator(F, space, space, w, (bc,),
                            parameter_setter=lambda mu: c.assign(float(mu['c'])),
                            parameter_type={'c': ()},
                            solver_options={'inverse': {'type': 'newton', 'rtol': 1e-6}})

        prod = FenicsMatrixOperator(df.assemble(u*v*df.dx), V, V)
        return op, op.parse_parameter(42), op.source.random(), op.range.random(), prod, prod
Esempio n. 2
0
def _discretize_fenics():

    # assemble system matrices - FEniCS code
    ########################################

    import dolfin as df

    # discrete function space
    mesh = df.UnitSquareMesh(GRID_INTERVALS, GRID_INTERVALS, 'crossed')
    V = df.FunctionSpace(mesh, 'Lagrange', FENICS_ORDER)
    u = df.TrialFunction(V)
    v = df.TestFunction(V)

    # data functions
    bottom_diffusion = df.Expression('(x[0] > 0.45) * (x[0] < 0.55) * (x[1] < 0.7) * 1.',
                                     element=df.FunctionSpace(mesh, 'DG', 0).ufl_element())
    top_diffusion = df.Expression('(x[0] > 0.35) * (x[0] < 0.40) * (x[1] > 0.3) * 1. +'
                                  '(x[0] > 0.60) * (x[0] < 0.65) * (x[1] > 0.3) * 1.',
                                  element=df.FunctionSpace(mesh, 'DG', 0).ufl_element())
    initial_data = df.Expression('(x[0] > 0.45) * (x[0] < 0.55) * (x[1] < 0.7) * 10.',
                                 element=df.FunctionSpace(mesh, 'DG', 0).ufl_element())
    neumann_data = df.Expression('(x[0] > 0.45) * (x[0] < 0.55) * 1000.',
                                 element=df.FunctionSpace(mesh, 'DG', 0).ufl_element())

    # assemble matrices and vectors
    l2_mat = df.assemble(df.inner(u, v) * df.dx)
    l2_0_mat = l2_mat.copy()
    h1_mat = df.assemble(df.inner(df.nabla_grad(u), df.nabla_grad(v)) * df.dx)
    h1_0_mat = h1_mat.copy()
    mat0 = h1_mat.copy()
    mat0.zero()
    bottom_mat = df.assemble(bottom_diffusion * df.inner(df.nabla_grad(u), df.nabla_grad(v)) * df.dx)
    top_mat = df.assemble(top_diffusion * df.inner(df.nabla_grad(u), df.nabla_grad(v)) * df.dx)
    u0 = df.project(initial_data, V).vector()
    f = df.assemble(neumann_data * v * df.ds)

    # boundary treatment
    def dirichlet_boundary(x, on_boundary):
        tol = 1e-14
        return on_boundary and (abs(x[0]) < tol or abs(x[0] - 1) < tol or abs(x[1] - 1) < tol)

    bc = df.DirichletBC(V, df.Constant(0.), dirichlet_boundary)
    bc.apply(l2_0_mat)
    bc.apply(h1_0_mat)
    bc.apply(mat0)
    bc.zero(bottom_mat)
    bc.zero(top_mat)
    bc.apply(f)
    bc.apply(u0)

    # wrap everything as a pyMOR model
    ##################################

    from pymor.bindings.fenics import FenicsVectorSpace, FenicsMatrixOperator, FenicsVisualizer

    fom = InstationaryModel(
        T=1.,

        initial_data=FenicsVectorSpace(V).make_array([u0]),

        operator=LincombOperator([FenicsMatrixOperator(mat0, V, V),
                                  FenicsMatrixOperator(h1_0_mat, V, V),
                                  FenicsMatrixOperator(bottom_mat, V, V),
                                  FenicsMatrixOperator(top_mat, V, V)],
                                 [1.,
                                  1.,
                                  100. - 1.,
                                  ExpressionParameterFunctional('top[0] - 1.', {'top': 1})]),

        rhs=VectorOperator(FenicsVectorSpace(V).make_array([f])),

        mass=FenicsMatrixOperator(l2_0_mat, V, V, name='l2'),

        products={'l2': FenicsMatrixOperator(l2_mat, V, V, name='l2'),
                  'l2_0': FenicsMatrixOperator(l2_0_mat, V, V, name='l2_0'),
                  'h1': FenicsMatrixOperator(h1_mat, V, V, name='h1'),
                  'h1_0_semi': FenicsMatrixOperator(h1_0_mat, V, V, name='h1_0_semi')},

        time_stepper=ImplicitEulerTimeStepper(nt=NT),

        visualizer=FenicsVisualizer(FenicsVectorSpace(V))
    )

    return fom
def _discretize_fenics():

    # assemble system matrices - FEniCS code
    ########################################

    import dolfin as df

    mesh = df.UnitSquareMesh(GRID_INTERVALS, GRID_INTERVALS, 'crossed')
    V = df.FunctionSpace(mesh, 'Lagrange', FENICS_ORDER)
    u = df.TrialFunction(V)
    v = df.TestFunction(V)

    diffusion = df.Expression(
        '(lower0 <= x[0]) * (open0 ? (x[0] < upper0) : (x[0] <= upper0)) *'
        '(lower1 <= x[1]) * (open1 ? (x[1] < upper1) : (x[1] <= upper1))',
        lower0=0.,
        upper0=0.,
        open0=0,
        lower1=0.,
        upper1=0.,
        open1=0,
        element=df.FunctionSpace(mesh, 'DG', 0).ufl_element())

    def assemble_matrix(x, y, nx, ny):
        diffusion.user_parameters['lower0'] = x / nx
        diffusion.user_parameters['lower1'] = y / ny
        diffusion.user_parameters['upper0'] = (x + 1) / nx
        diffusion.user_parameters['upper1'] = (y + 1) / ny
        diffusion.user_parameters['open0'] = (x + 1 == nx)
        diffusion.user_parameters['open1'] = (y + 1 == ny)
        return df.assemble(
            df.inner(diffusion * df.nabla_grad(u), df.nabla_grad(v)) * df.dx)

    mats = [
        assemble_matrix(x, y, XBLOCKS, YBLOCKS) for x in range(XBLOCKS)
        for y in range(YBLOCKS)
    ]
    mat0 = mats[0].copy()
    mat0.zero()
    h1_mat = df.assemble(df.inner(df.nabla_grad(u), df.nabla_grad(v)) * df.dx)

    f = df.Constant(1.) * v * df.dx
    F = df.assemble(f)

    bc = df.DirichletBC(V, 0., df.DomainBoundary())
    for m in mats:
        bc.zero(m)
    bc.apply(mat0)
    bc.apply(h1_mat)
    bc.apply(F)

    # wrap everything as a pyMOR model
    ##################################

    # FEniCS wrappers
    from pymor.bindings.fenics import FenicsVectorSpace, FenicsMatrixOperator, FenicsVisualizer

    # define parameter functionals (same as in pymor.analyticalproblems.thermalblock)
    parameter_functionals = [
        ProjectionParameterFunctional(component_name='diffusion',
                                      component_shape=(YBLOCKS, XBLOCKS),
                                      index=(YBLOCKS - y - 1, x))
        for x in range(XBLOCKS) for y in range(YBLOCKS)
    ]

    # wrap operators
    ops = [FenicsMatrixOperator(mat0, V, V)
           ] + [FenicsMatrixOperator(m, V, V) for m in mats]
    op = LincombOperator(ops, [1.] + parameter_functionals)
    rhs = VectorOperator(FenicsVectorSpace(V).make_array([F]))
    h1_product = FenicsMatrixOperator(h1_mat, V, V, name='h1_0_semi')

    # build model
    visualizer = FenicsVisualizer(FenicsVectorSpace(V))
    parameter_space = CubicParameterSpace(op.parameter_type, 0.1, 1.)
    fom = StationaryModel(op,
                          rhs,
                          products={'h1_0_semi': h1_product},
                          parameter_space=parameter_space,
                          visualizer=visualizer)

    return fom
Esempio n. 4
0
def _discretize_fenics(xblocks, yblocks, grid_num_intervals, element_order):

    # assemble system matrices - FEniCS code
    ########################################

    import dolfin as df
    mesh = df.UnitSquareMesh(grid_num_intervals, grid_num_intervals, 'crossed')
    V = df.FunctionSpace(mesh, 'Lagrange', element_order)
    u = df.TrialFunction(V)
    v = df.TestFunction(V)

    diffusion = df.Expression('(lower0 <= x[0]) * (open0 ? (x[0] < upper0) : (x[0] <= upper0)) *'
                              '(lower1 <= x[1]) * (open1 ? (x[1] < upper1) : (x[1] <= upper1))',
                              lower0=0., upper0=0., open0=0,
                              lower1=0., upper1=0., open1=0,
                              element=df.FunctionSpace(mesh, 'DG', 0).ufl_element())

    def assemble_matrix(x, y, nx, ny):
        diffusion.user_parameters['lower0'] = x/nx
        diffusion.user_parameters['lower1'] = y/ny
        diffusion.user_parameters['upper0'] = (x + 1)/nx
        diffusion.user_parameters['upper1'] = (y + 1)/ny
        diffusion.user_parameters['open0'] = (x + 1 == nx)
        diffusion.user_parameters['open1'] = (y + 1 == ny)
        return df.assemble(df.inner(diffusion * df.nabla_grad(u), df.nabla_grad(v)) * df.dx)

    mats = [assemble_matrix(x, y, xblocks, yblocks)
            for x in range(xblocks) for y in range(yblocks)]
    mat0 = mats[0].copy()
    mat0.zero()
    h1_mat = df.assemble(df.inner(df.nabla_grad(u), df.nabla_grad(v)) * df.dx)
    l2_mat = df.assemble(u * v * df.dx)

    f = df.Constant(1.) * v * df.dx
    F = df.assemble(f)

    bc = df.DirichletBC(V, 0., df.DomainBoundary())
    for m in mats:
        bc.zero(m)
    bc.apply(mat0)
    bc.apply(h1_mat)
    bc.apply(F)

    # wrap everything as a pyMOR model
    ##################################

    # FEniCS wrappers
    from pymor.bindings.fenics import FenicsVectorSpace, FenicsMatrixOperator, FenicsVisualizer

    # generic pyMOR classes
    from pymor.models.basic import StationaryModel
    from pymor.operators.constructions import LincombOperator, VectorOperator
    from pymor.parameters.functionals import ProjectionParameterFunctional
    from pymor.parameters.spaces import CubicParameterSpace

    # define parameter functionals (same as in pymor.analyticalproblems.thermalblock)
    def parameter_functional_factory(x, y):
        return ProjectionParameterFunctional(component_name='diffusion',
                                             component_shape=(yblocks, xblocks),
                                             index=(yblocks - y - 1, x),
                                             name=f'diffusion_{x}_{y}')
    parameter_functionals = tuple(parameter_functional_factory(x, y)
                                  for x in range(xblocks) for y in range(yblocks))

    # wrap operators
    ops = [FenicsMatrixOperator(mat0, V, V)] + [FenicsMatrixOperator(m, V, V) for m in mats]
    op = LincombOperator(ops, (1.,) + parameter_functionals)
    rhs = VectorOperator(FenicsVectorSpace(V).make_array([F]))
    h1_product = FenicsMatrixOperator(h1_mat, V, V, name='h1_0_semi')
    l2_product = FenicsMatrixOperator(l2_mat, V, V, name='l2')

    # build model
    visualizer = FenicsVisualizer(FenicsVectorSpace(V))
    parameter_space = CubicParameterSpace(op.parameter_type, 0.1, 1.)
    fom = StationaryModel(op, rhs, products={'h1_0_semi': h1_product,
                                             'l2': l2_product},
                          parameter_space=parameter_space,
                          visualizer=visualizer)

    return fom
Esempio n. 5
0
def make_pymor_bindings(V, dx, ds, solver_options):
    '''Assemble the Fenics operator and binds them to pymor.Operator with parameter separation
    Returns the full order model (pymor.Model)'''
    import pymor.basic as pmb
    from pymor.bindings.fenics import FenicsVectorSpace, FenicsMatrixOperator
    from pymor.algorithms.timestepping import ImplicitEulerTimeStepper

    space = FenicsVectorSpace(V)

    # Operators matrix
    u = df.TrialFunction(V)
    v = df.TestFunction(V)
    mass_mat = [
        df.assemble(df.inner(u, v) * dx(i)) for i in domain_dict.values()
    ]
    diff_mat = [
        df.assemble(df.inner(df.grad(u), df.grad(v)) * dx(i))
        for i in domain_dict.values()
    ]
    robin_left_mat = df.assemble(u * v * ds(1))
    source_mat = df.assemble(v * dx(domain_dict['die']))

    # Norms matrix
    l2_mat = df.assemble(df.inner(u, v) * df.dx)
    l2_0_mat = l2_mat.copy()
    h1_mat = df.assemble(df.inner(df.grad(u), df.grad(v)) * dx)
    h1_0_mat = h1_mat.copy()

    # Operators
    mass_op = [
        FenicsMatrixOperator(M, V, V, solver_options=solver_options)
        for M in mass_mat
    ]
    diff_op = [
        FenicsMatrixOperator(M, V, V, solver_options=solver_options)
        for M in diff_mat
    ]
    robin_left_op = FenicsMatrixOperator(robin_left_mat,
                                         V,
                                         V,
                                         solver_options=solver_options)
    source_op = pmb.VectorOperator(space.make_array([source_mat]))

    # Param projection
    project_lamb = [
        pmb.ProjectionParameterFunctional(f'lamb_{dom}', 1, 0)
        for dom in domain_dict.keys()
    ]
    project_capa = [
        pmb.ProjectionParameterFunctional(f'capa_{dom}', 1, 0)
        for dom in domain_dict.keys()
    ]

    # Separated operator
    mass = pmb.LincombOperator(mass_op, project_capa)

    op = pmb.LincombOperator(
        [*diff_op, robin_left_op],
        [*project_lamb,
         pmb.ExpressionParameterFunctional('h[0]', {'h': 1})])

    rhs = pmb.LincombOperator(
        [source_op], [pmb.ExpressionParameterFunctional('phi[0]', {'phi': 1})])

    end_time = 10 * 60
    dt = 5
    fom = InstationaryParametricMassModel(
        T=end_time,
        initial_data=space.make_array([df.project(df.Constant(0),
                                                  V).vector()]),
        operator=op,
        rhs=rhs,
        mass=mass,
        time_stepper=ImplicitEulerTimeStepper(end_time // dt),
        num_values=None,
        products={
            'l2': FenicsMatrixOperator(l2_mat, V, V),
            'l2_0': FenicsMatrixOperator(l2_0_mat, V, V),
            'h1': FenicsMatrixOperator(h1_mat, V, V),
            'h1_0_semi': FenicsMatrixOperator(h1_0_mat, V, V)
        },
        visualizer=None)
    return fom