Exemplo n.º 1
0
def test_de_rahm_2D(order):
    mesh = create_unit_square(MPI.COMM_WORLD, 3, 4)
    W = FunctionSpace(mesh, ("Lagrange", order))
    w = Function(W)
    w.interpolate(lambda x: x[0] + x[0] * x[1] + 2 * x[1]**2)

    g = ufl.grad(w)
    Q = FunctionSpace(mesh, ("N2curl", order - 1))
    q = Function(Q)
    q.interpolate(Expression(g, Q.element.interpolation_points))

    x = ufl.SpatialCoordinate(mesh)
    g_ex = ufl.as_vector((1 + x[1], 4 * x[1] + x[0]))
    assert np.isclose(
        np.abs(assemble_scalar(form(ufl.inner(q - g_ex, q - g_ex) * ufl.dx))),
        0)

    V = FunctionSpace(mesh, ("BDM", order - 1))
    v = Function(V)

    def curl2D(u):
        return ufl.as_vector((ufl.Dx(u[1], 0), -ufl.Dx(u[0], 1)))

    v.interpolate(
        Expression(curl2D(ufl.grad(w)), V.element.interpolation_points))
    h_ex = ufl.as_vector((1, -1))
    assert np.isclose(
        np.abs(assemble_scalar(form(ufl.inner(v - h_ex, v - h_ex) * ufl.dx))),
        0)
Exemplo n.º 2
0
def CubedSphereMesh(radius, refinement_level=0, degree=1,
                    reorder=None, comm=COMM_WORLD):
    """Generate an cubed approximation to the surface of the
    sphere.

    :arg radius: The radius of the sphere to approximate.
    :kwarg refinement_level: optional number of refinements (0 is a cube).
    :kwarg degree: polynomial degree of coordinate space (defaults
        to 1: bilinear quads)
    :kwarg reorder: (optional), should the mesh be reordered?
    """
    if refinement_level < 0 or refinement_level % 1:
            raise RuntimeError("Number of refinements must be a non-negative integer")

    if degree < 1:
        raise ValueError("Mesh coordinate degree must be at least 1")

    cells, coords = _cubedsphere_cells_and_coords(radius, refinement_level)
    plex = mesh._from_cell_list(2, cells, coords, comm)

    m = mesh.Mesh(plex, dim=3, reorder=reorder)

    if degree > 1:
        new_coords = function.Function(functionspace.VectorFunctionSpace(m, "Q", degree))
        new_coords.interpolate(ufl.SpatialCoordinate(m))
        # "push out" to sphere
        new_coords.dat.data[:] *= (radius / np.linalg.norm(new_coords.dat.data, axis=1)).reshape(-1, 1)
        m = mesh.Mesh(new_coords)
    m._radius = radius
    return m
Exemplo n.º 3
0
def test_nedelec_spatial(order, dim):
    if dim == 2:
        mesh = create_unit_square(MPI.COMM_WORLD, 4, 4)
    elif dim == 3:
        mesh = create_unit_cube(MPI.COMM_WORLD, 2, 2, 2)

    V = FunctionSpace(mesh, ("N1curl", order))
    u = Function(V)
    x = ufl.SpatialCoordinate(mesh)

    # The expression (x,y,z) is contained in the N1curl function space
    # order>1
    f_ex = x
    f = Expression(f_ex, V.element.interpolation_points)
    u.interpolate(f)
    assert np.isclose(
        np.abs(assemble_scalar(form(ufl.inner(u - f_ex, u - f_ex) * ufl.dx))),
        0)

    # The target expression is also contained in N2curl space of any
    # order
    V2 = FunctionSpace(mesh, ("N2curl", 1))
    w = Function(V2)
    f2 = Expression(f_ex, V2.element.interpolation_points)
    w.interpolate(f2)
    assert np.isclose(
        np.abs(assemble_scalar(form(ufl.inner(w - f_ex, w - f_ex) * ufl.dx))),
        0)
Exemplo n.º 4
0
    def __init__(self, mesh, lame, model):
        def sigma_law(u):
            return lame[0] * ufl.nabla_div(u) * ufl.Identity(
                2) + 2 * lame[1] * symgrad(u)

        self.sigma_law = sigma_law

        self.mesh = mesh
        self.model = model
        self.coord_min = np.min(self.mesh.coordinates(), axis=0)
        self.coord_max = np.max(self.mesh.coordinates(), axis=0)

        # it should be modified before computing tangent (if needed)
        self.others = {
            "polyorder": 1,
            "x0": self.coord_min[0],
            "x1": self.coord_max[0],
            "y0": self.coord_min[1],
            "y1": self.coord_max[1]
        }

        self.multiscale_model = list_multiscale_models[model]
        self.x = ufl.SpatialCoordinate(self.mesh)
        self.ndim = 2
        self.nvoigt = int(self.ndim * (self.ndim + 1) / 2)
        self.Chom_ = None  # will be computed by get_tangent
Exemplo n.º 5
0
def test_interpolate_subset(order, dim, affine):
    if dim == 2:
        ct = CellType.triangle if affine else CellType.quadrilateral
        mesh = create_unit_square(MPI.COMM_WORLD, 3, 4, ct)
    elif dim == 3:
        ct = CellType.tetrahedron if affine else CellType.hexahedron
        mesh = create_unit_cube(MPI.COMM_WORLD, 3, 2, 2, ct)

    V = FunctionSpace(mesh, ("DG", order))
    u = Function(V)

    cells = locate_entities(mesh, mesh.topology.dim,
                            lambda x: x[1] <= 0.5 + 1e-10)
    num_local_cells = mesh.topology.index_map(mesh.topology.dim).size_local
    cells_local = cells[cells < num_local_cells]

    x = ufl.SpatialCoordinate(mesh)
    f = x[1]**order
    expr = Expression(f, V.element.interpolation_points)
    u.interpolate(expr, cells_local)
    mt = MeshTags(mesh, mesh.topology.dim, cells_local,
                  np.ones(cells_local.size, dtype=np.int32))
    dx = ufl.Measure("dx", domain=mesh, subdomain_data=mt)
    assert np.isclose(
        np.abs(form(assemble_scalar(form(ufl.inner(u - f, u - f) * dx(1))))),
        0)
    integral = mesh.comm.allreduce(assemble_scalar(form(u * dx)), op=MPI.SUM)
    assert np.isclose(integral, 1 / (order + 1) * 0.5**(order + 1), 0)
Exemplo n.º 6
0
def fenics_cost(u, f):
    x = ufl.SpatialCoordinate(mesh)
    w = ufl.sin(ufl.pi * x[0]) * ufl.sin(ufl.pi * x[1])
    d = 1 / (2 * ufl.pi ** 2) * w
    alpha = fa.Constant(1e-6)
    J_form = (0.5 * ufl.inner(u - d, u - d)) * ufl.dx + alpha / 2 * f ** 2 * ufl.dx
    J = fa.assemble(J_form)
    return J
Exemplo n.º 7
0
 def __init__(self, functionSpace, value, xL, xR, eps=1e-10):
     cond = 1
     x = ufl.SpatialCoordinate(functionSpace)
     for l, r, c in zip(xL, xR, x):
         if l is not None:
             cond *= ufl.conditional(c > l - eps, 1, 0)
         if r is not None:
             cond *= ufl.conditional(c < r + eps, 1, 0)
     DirichletBC.__init__(self, functionSpace, value, cond)
Exemplo n.º 8
0
def test_ufl_only_spatialcoordinate():
    mesh = ufl.Mesh(ufl.VectorElement("P", ufl.triangle, 1))
    V = ufl.FunctionSpace(mesh, ufl.FiniteElement("P", ufl.triangle, 2))
    x, y = ufl.SpatialCoordinate(mesh)
    expr = x * y - y**2 + x
    W = V
    to_element = create_element(W.ufl_element())
    ast, oriented, needs_cell_sizes, coefficients, first_coeff_fake_coords, *_ = compile_expression_dual_evaluation(
        expr, to_element, coffee=False)
    assert first_coeff_fake_coords is True
Exemplo n.º 9
0
def test_conditional(mode, compile_args):
    cell = ufl.triangle
    element = ufl.FiniteElement("Lagrange", cell, 1)
    u, v = ufl.TrialFunction(element), ufl.TestFunction(element)
    x = ufl.SpatialCoordinate(cell)
    condition = ufl.Or(ufl.ge(ufl.real(x[0] + x[1]), 0.1),
                       ufl.ge(ufl.real(x[1] + x[1]**2), 0.1))
    c1 = ufl.conditional(condition, 2.0, 1.0)
    a = c1 * ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx

    x1x2 = ufl.real(x[0] + ufl.as_ufl(2) * x[1])
    c2 = ufl.conditional(ufl.ge(x1x2, 0), 6.0, 0.0)
    b = c2 * ufl.conj(v) * ufl.dx

    forms = [a, b]

    compiled_forms, module = ffcx.codegeneration.jit.compile_forms(
        forms,
        parameters={'scalar_type': mode},
        cffi_extra_compile_args=compile_args)

    form0 = compiled_forms[0][0].create_cell_integral(-1)
    form1 = compiled_forms[1][0].create_cell_integral(-1)

    ffi = cffi.FFI()
    c_type, np_type = float_to_type(mode)

    A1 = np.zeros((3, 3), dtype=np_type)
    w1 = np.array([1.0, 1.0, 1.0], dtype=np_type)
    c = np.array([], dtype=np.float64)

    coords = np.array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0], dtype=np.float64)

    form0.tabulate_tensor(
        ffi.cast('{type} *'.format(type=c_type), A1.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), w1.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), c.ctypes.data),
        ffi.cast('double *', coords.ctypes.data), ffi.NULL, ffi.NULL, 0)

    expected_result = np.array([[2, -1, -1], [-1, 1, 0], [-1, 0, 1]],
                               dtype=np_type)
    assert np.allclose(A1, expected_result)

    A2 = np.zeros(3, dtype=np_type)
    w2 = np.array([1.0, 1.0, 1.0], dtype=np_type)
    coords = np.array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0], dtype=np.float64)

    form1.tabulate_tensor(
        ffi.cast('{type} *'.format(type=c_type), A2.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), w2.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), c.ctypes.data),
        ffi.cast('double *', coords.ctypes.data), ffi.NULL, ffi.NULL, 0)

    expected_result = np.ones(3, dtype=np_type)
    assert np.allclose(A2, expected_result)
Exemplo n.º 10
0
def test_assemble_functional_dx(mode):
    mesh = create_unit_square(MPI.COMM_WORLD, 12, 12, ghost_mode=mode)
    M = form(1.0 * dx(domain=mesh))
    value = assemble_scalar(M)
    value = mesh.comm.allreduce(value, op=MPI.SUM)
    assert value == pytest.approx(1.0, 1e-12)
    x = ufl.SpatialCoordinate(mesh)
    M = form(x[0] * dx(domain=mesh))
    value = assemble_scalar(M)
    value = mesh.comm.allreduce(value, op=MPI.SUM)
    assert value == pytest.approx(0.5, 1e-12)
Exemplo n.º 11
0
    def to_reference_coordinates(ufl_coordinate_element):
        # Set up UFL form
        cell = ufl_coordinate_element.cell()
        domain = ufl.Mesh(ufl_coordinate_element)
        K = ufl.JacobianInverse(domain)
        x = ufl.SpatialCoordinate(domain)
        x0_element = ufl.VectorElement("Real", cell, 0)
        x0 = ufl.Coefficient(ufl.FunctionSpace(domain, x0_element))
        expr = ufl.dot(K, x - x0)

        # Translation to GEM
        C = ufl_utils.coordinate_coefficient(domain)
        expr = ufl_utils.preprocess_expression(expr)
        expr = ufl_utils.replace_coordinates(expr, C)
        expr = ufl_utils.simplify_abs(expr)

        builder = firedrake_interface.KernelBuilderBase()
        builder._coefficient(C, "C")
        builder._coefficient(x0, "x0")

        dim = cell.topological_dimension()
        point = gem.Variable('X', (dim, ))
        context = tsfc.fem.GemPointContext(
            interface=builder,
            ufl_cell=cell,
            precision=parameters["precision"],
            point_indices=(),
            point_expr=point,
        )
        translator = tsfc.fem.Translator(context)
        ir = map_expr_dag(translator, expr)

        # Unroll result
        ir = [gem.Indexed(ir, alpha) for alpha in numpy.ndindex(ir.shape)]

        # Unroll IndexSums
        max_extent = parameters["unroll_indexsum"]
        if max_extent:

            def predicate(index):
                return index.extent <= max_extent

        ir = gem.optimise.unroll_indexsum(ir, predicate=predicate)

        # Translate to COFFEE
        ir = impero_utils.preprocess_gem(ir)
        return_variable = gem.Variable('dX', (dim, ))
        assignments = [(gem.Indexed(return_variable, (i, )), e)
                       for i, e in enumerate(ir)]
        impero_c = impero_utils.compile_gem(assignments, ())
        body = tsfc.coffee.generate(impero_c, {}, parameters["precision"])
        body.open_scope = False

        return body
Exemplo n.º 12
0
def test_assemble_functional_dx(mode):
    mesh = UnitSquareMesh(MPI.COMM_WORLD, 12, 12, ghost_mode=mode)
    M = 1.0 * dx(domain=mesh)
    value = dolfinx.fem.assemble_scalar(M)
    value = mesh.mpi_comm().allreduce(value, op=MPI.SUM)
    assert value == pytest.approx(1.0, 1e-12)
    x = ufl.SpatialCoordinate(mesh)
    M = x[0] * dx(domain=mesh)
    value = dolfinx.fem.assemble_scalar(M)
    value = mesh.mpi_comm().allreduce(value, op=MPI.SUM)
    assert value == pytest.approx(0.5, 1e-12)
Exemplo n.º 13
0
def transfer_form(F, newmesh, transfer=firedrake.prolong, replace_map={}):
    """
    Given a form defined on some mesh, generate a new form with all
    the same components, but transferred onto a different mesh.

    :arg F: the form to be transferred
    :arg newmesh: the mesh to transfer the form to
    :kwarg transfer: the transfer operator to use
    :kwarg replace_map: user-provided replace map
    """
    f = 0

    # We replace at least the coordinate map
    replace_map = {
        ufl.SpatialCoordinate(F.ufl_domain()): ufl.SpatialCoordinate(newmesh)
    }

    # Test and trial functions are also replaced
    if len(F.arguments()) > 0:
        Vold = F.arguments()[0].function_space()
        Vnew = firedrake.FunctionSpace(newmesh, Vold.ufl_element())
        replace_map[firedrake.TestFunction(Vold)] = firedrake.TestFunction(
            Vnew)
        replace_map[firedrake.TrialFunction(Vold)] = firedrake.TrialFunction(
            Vnew)

    # As well as any spatially varying coefficients
    for c in F.coefficients():
        if isinstance(c, firedrake.Function) and c not in replace_map:
            replace_map[c] = firedrake.Function(
                firedrake.FunctionSpace(newmesh, c.ufl_element()))
            transfer(c, replace_map[c])

    # The form is reconstructed by cell type
    for cell_type, dX in zip(("cell", "exterior_facet", "interior_facet"),
                             (ufl.dx, ufl.ds, ufl.dS)):
        for integral in F.integrals_by_type(cell_type):
            differential = dX(integral.subdomain_id(), domain=newmesh)
            f += ufl.replace(integral.integrand(), replace_map) * differential

    return f
Exemplo n.º 14
0
def SpatialCoordinate(mesh: cpp.mesh.Mesh) -> ufl.SpatialCoordinate:
    """Return symbolic physical coordinates for given mesh.

    *Example of usage*

        .. code-block:: python

            mesh = UnitSquare(4,4)
            x = SpatialCoordinate(mesh)

    """

    return ufl.SpatialCoordinate(mesh.ufl_domain())
Exemplo n.º 15
0
def test_projection():
    mesh = dolfin.UnitCubeMesh(dolfin.MPI.comm_world, 4, 4, 4)
    V = dolfin.function.FunctionSpace(mesh, ("CG", 1))

    x = ufl.SpatialCoordinate(mesh)
    expr = x[0]**2

    f = dolfin.project(expr, V)
    integral = dolfin.fem.assemble_scalar(f * ufl.dx)
    integral = dolfin.MPI.sum(mesh.mpi_comm(), integral)

    integral_analytic = 1.0 / 3
    assert integral == pytest.approx(integral_analytic, rel=1.e-6, abs=1.e-12)
Exemplo n.º 16
0
def test_complex_assembly():
    """Test assembly of complex matrices and vectors"""

    mesh = dolfinx.generation.UnitSquareMesh(MPI.COMM_WORLD, 10, 10)
    P2 = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), 2)
    V = dolfinx.function.FunctionSpace(mesh, P2)

    u = ufl.TrialFunction(V)
    v = ufl.TestFunction(V)

    g = -2 + 3.0j
    j = 1.0j

    a_real = inner(u, v) * dx
    L1 = inner(g, v) * dx

    b = dolfinx.fem.assemble_vector(L1)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    bnorm = b.norm(PETSc.NormType.N1)
    b_norm_ref = abs(-2 + 3.0j)
    assert bnorm == pytest.approx(b_norm_ref)

    A = dolfinx.fem.assemble_matrix(a_real)
    A.assemble()
    A0_norm = A.norm(PETSc.NormType.FROBENIUS)

    x = ufl.SpatialCoordinate(mesh)

    a_imag = j * inner(u, v) * dx
    f = 1j * ufl.sin(2 * np.pi * x[0])
    L0 = inner(f, v) * dx
    A = dolfinx.fem.assemble_matrix(a_imag)
    A.assemble()
    A1_norm = A.norm(PETSc.NormType.FROBENIUS)
    assert A0_norm == pytest.approx(A1_norm)

    b = dolfinx.fem.assemble_vector(L0)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    b1_norm = b.norm(PETSc.NormType.N2)

    a_complex = (1 + j) * inner(u, v) * dx
    f = ufl.sin(2 * np.pi * x[0])
    L2 = inner(f, v) * dx
    A = dolfinx.fem.assemble_matrix(a_complex)
    A.assemble()
    A2_norm = A.norm(PETSc.NormType.FROBENIUS)
    assert A1_norm == pytest.approx(A2_norm / np.sqrt(2))
    b = dolfinx.fem.assemble_vector(L2)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    b2_norm = b.norm(PETSc.NormType.N2)
    assert b2_norm == pytest.approx(b1_norm)
Exemplo n.º 17
0
def test_complex_assembly_solve():
    """Solve a positive definite helmholtz problem and verify solution
    with the method of manufactured solutions

    """

    degree = 3
    mesh = dolfinx.generation.UnitSquareMesh(MPI.COMM_WORLD, 20, 20)
    P = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), degree)
    V = dolfinx.function.FunctionSpace(mesh, P)

    x = ufl.SpatialCoordinate(mesh)

    # Define source term
    A = 1.0 + 2.0 * (2.0 * np.pi)**2
    f = (1. + 1j) * A * ufl.cos(2 * np.pi * x[0]) * ufl.cos(2 * np.pi * x[1])

    # Variational problem
    u = ufl.TrialFunction(V)
    v = ufl.TestFunction(V)
    C = 1.0 + 1.0j
    a = C * inner(grad(u), grad(v)) * dx + C * inner(u, v) * dx
    L = inner(f, v) * dx

    # Assemble
    A = dolfinx.fem.assemble_matrix(a)
    A.assemble()
    b = dolfinx.fem.assemble_vector(L)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)

    # Create solver
    solver = PETSc.KSP().create(mesh.mpi_comm())
    solver.setOptionsPrefix("test_lu_")
    opts = PETSc.Options("test_lu_")
    opts["ksp_type"] = "preonly"
    opts["pc_type"] = "lu"
    solver.setFromOptions()
    x = A.createVecRight()
    solver.setOperators(A)
    solver.solve(b, x)

    # Reference Solution
    def ref_eval(x):
        return np.cos(2 * np.pi * x[0]) * np.cos(2 * np.pi * x[1])

    u_ref = dolfinx.function.Function(V)
    u_ref.interpolate(ref_eval)

    diff = (x - u_ref.vector).norm(PETSc.NormType.N2)
    assert diff == pytest.approx(0.0, abs=1e-1)
Exemplo n.º 18
0
def test_vector_interpolation_spatial(order, dim, affine):
    if dim == 2:
        ct = CellType.triangle if affine else CellType.quadrilateral
        mesh = create_unit_square(MPI.COMM_WORLD, 3, 4, ct)
    elif dim == 3:
        ct = CellType.tetrahedron if affine else CellType.hexahedron
        mesh = create_unit_cube(MPI.COMM_WORLD, 3, 2, 2, ct)

    V = VectorFunctionSpace(mesh, ("Lagrange", order))
    u = Function(V)
    x = ufl.SpatialCoordinate(mesh)

    # The expression (x,y,z)^n is contained in space
    f = ufl.as_vector([x[i]**order for i in range(dim)])
    u.interpolate(Expression(f, V.element.interpolation_points))
    assert np.isclose(
        np.abs(assemble_scalar(form(ufl.inner(u - f, u - f) * ufl.dx))), 0)
def SpatialCoordinate(mesh):
    """Return symbolic physical coordinates for given mesh.

    *Arguments*
        mesh
            a :py:class:`Mesh <dolfin.cpp.Mesh>`.

    *Example of usage*

        .. code-block:: python

            mesh = UnitSquare(4,4)
            x = SpatialCoordinate(mesh)

    """

    return ufl.SpatialCoordinate(_mesh2domain(mesh))
Exemplo n.º 20
0
 def methods(self,code):
     predefined = {}
     x = ufl.SpatialCoordinate(ufl.triangle) # NOTE: to do get right dimension
     predefined[x] = self.spatialCoordinate('x')
     self.predefineCoefficients(predefined, False)
     codegen.generateMethod(code, self.expr,
         'typename FunctionSpaceType::RangeType', 'evaluate',
         returnResult=False,
         args=['const Point &x'],
         targs=['class Point'], const=True,
         predefined=predefined)
     if checks.is_globally_constant(self.expr):
         code.append( Method('void', 'jacobian', targs=['class Point'],
             args=['const Point &x','typename FunctionSpaceType::JacobianRangeType &result'],
             code=['result=typename FunctionSpaceType::JacobianRangeType(0);'], const=True))
         code.append( Method('void', 'hessian', targs=['class Point'],
             args=['const Point &x','typename FunctionSpaceType::HessianRangeType &result'],
             code=['result=typename FunctionSpaceType::HessianRangeType(0);'], const=True))
     else:
         try:
             codegen.generateMethod(code, ufl.grad(self.expr),
                 'typename FunctionSpaceType::JacobianRangeType', 'jacobian',
                 returnResult=False,
                 args=['const Point &x'],
                 targs=['class Point'], const=True,
                 predefined=predefined)
         except Exception as e:
             code.append( Method('void', 'jacobian', targs=['class Point'],
                 args=['const Point &x','typename FunctionSpaceType::JacobianRangeType &result'],
                 code=['DUNE_THROW(Dune::NotImplemented,"jacobian method could not be generated for local function ('+repr(e)+').");',
                       'result=typename FunctionSpaceType::JacobianRangeType(0);'], const=True))
             pass
         try:
             codegen.generateMethod(code, ufl.grad(ufl.grad(self.expr)),
                 'typename FunctionSpaceType::HessianRangeType', 'hessian',
                 returnResult=False,
                 args=['const Point &x'],
                 targs=['class Point'], const=True,
                 predefined=predefined)
         except Exception as e:
             code.append( Method('void', 'hessian', targs=['class Point'],
                 args=['const Point &x','typename FunctionSpaceType::HessianRangeType &result'],
                 code=['DUNE_THROW(Dune::NotImplemented,"hessian method could not be generated for local function ('+repr(e)+')");',
                       'result=typename FunctionSpaceType::HessianRangeType(0);'], const=True))
             pass
Exemplo n.º 21
0
def test_mpc_assembly(master_point, degree, celltype,
                      get_assemblers):  # noqa: F811

    _, assemble_vector = get_assemblers

    # Create mesh and function space
    mesh = create_unit_square(MPI.COMM_WORLD, 3, 5, celltype)
    V = fem.FunctionSpace(mesh, ("Lagrange", degree))

    # Generate reference vector
    v = ufl.TestFunction(V)
    x = ufl.SpatialCoordinate(mesh)
    f = ufl.sin(2 * ufl.pi * x[0]) * ufl.sin(ufl.pi * x[1])
    rhs = ufl.inner(f, v) * ufl.dx
    linear_form = fem.form(rhs)

    def l2b(li):
        return np.array(li, dtype=np.float64).tobytes()

    s_m_c = {
        l2b([1, 0]): {
            l2b([0, 1]): 0.43,
            l2b([1, 1]): 0.11
        },
        l2b([0, 0]): {
            l2b(master_point): 0.69
        }
    }
    mpc = dolfinx_mpc.MultiPointConstraint(V)
    mpc.create_general_constraint(s_m_c)
    mpc.finalize()
    b = assemble_vector(linear_form, mpc)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES,
                  mode=PETSc.ScatterMode.REVERSE)

    # Reduce system with global matrix K after assembly
    L_org = fem.petsc.assemble_vector(linear_form)
    L_org.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES,
                      mode=PETSc.ScatterMode.REVERSE)
    root = 0
    comm = mesh.comm
    with Timer("~TEST: Compare"):
        dolfinx_mpc.utils.compare_mpc_rhs(L_org, b, mpc, root=root)

    list_timings(comm, [TimingType.wall])
Exemplo n.º 22
0
def test_diff():
    f = dolfinx.fem.Function(CG1)
    f.vector.set(1.0)
    f.vector.ghostUpdate()

    x = ufl.SpatialCoordinate(mesh)
    expr = x[0] + x[1] + f

    h_project = dolfinx.fem.Function(CG1)
    dolfiny.projection.project(expr, h_project)

    h_interp = dolfinx.fem.Function(CG1)
    dolfiny.interpolation.interpolate(expr, h_interp)

    diff = dolfinx.fem.Function(CG1)
    dolfiny.interpolation.interpolate(h_interp - h_project, diff)

    assert diff.vector.norm(3) < 1.0e-3
Exemplo n.º 23
0
    def get_tangent(self):
        if self.Chom_ is None:
            self.Chom_ = np.zeros((self.nvoigt, self.nvoigt))

            dy = ufl.Measure("dx", self.mesh)
            vol = df.assemble(df.Constant(1.0) * dy)
            y = ufl.SpatialCoordinate(self.mesh)
            Eps = df.Constant(((0., 0.), (0., 0.)))  # just placeholder

            form = self.multiscale_model(self.mesh, self.sigma_law, Eps,
                                         self.others)
            a, f, bcs, W = form()

            start = timer()
            A = mp.block_assemble(a)
            if len(bcs) > 0:
                bcs.apply(A)

            # decompose just once, since the matrix A is the same in every solve
            solver = df.PETScLUSolver("superlu")
            sol = mp.BlockFunction(W)

            end = timer()
            print("time assembling system", end - start)

            for i in range(self.nvoigt):
                start = timer()
                Eps.assign(df.Constant(self.macro_strain(i)))
                F = mp.block_assemble(f)
                if len(bcs) > 0:
                    bcs.apply(F)

                solver.solve(A, sol.block_vector(), F)
                sol.block_vector().block_function().apply("to subfunctions")

                sig_mu = self.sigma_law(df.dot(Eps, y) + sol[0])
                sigma_hom = self.integrate(sig_mu, dy, (2, 2)) / vol

                self.Chom_[:, i] = sigma_hom.flatten()[[0, 3, 1]]

                end = timer()
                print("time in solving system", end - start)

        return self.Chom_
Exemplo n.º 24
0
def test_2D_lagrange_to_curl(order):
    mesh = create_unit_square(MPI.COMM_WORLD, 3, 4)
    V = FunctionSpace(mesh, ("N1curl", order))
    u = Function(V)

    W = FunctionSpace(mesh, ("Lagrange", order))
    u0 = Function(W)
    u0.interpolate(lambda x: -x[1])
    u1 = Function(W)
    u1.interpolate(lambda x: x[0])

    f = ufl.as_vector((u0, u1))
    f_expr = Expression(f, V.element.interpolation_points)
    u.interpolate(f_expr)
    x = ufl.SpatialCoordinate(mesh)
    f_ex = ufl.as_vector((-x[1], x[0]))
    assert np.isclose(
        np.abs(assemble_scalar(form(ufl.inner(u - f_ex, u - f_ex) * ufl.dx))),
        0)
Exemplo n.º 25
0
def dg_injection_kernel(Vf, Vc, ncell):
    from firedrake import Tensor, AssembledVector, TestFunction, TrialFunction
    from firedrake.slate.slac import compile_expression
    macro_builder = MacroKernelBuilder(ScalarType_c, ncell)
    f = ufl.Coefficient(Vf)
    macro_builder.set_coefficients([f])
    macro_builder.set_coordinates(Vf.mesh())

    Vfe = create_element(Vf.ufl_element())
    macro_quadrature_rule = make_quadrature(
        Vfe.cell, estimate_total_polynomial_degree(ufl.inner(f, f)))
    index_cache = {}
    parameters = default_parameters()
    integration_dim, entity_ids = lower_integral_type(Vfe.cell, "cell")
    macro_cfg = dict(interface=macro_builder,
                     ufl_cell=Vf.ufl_cell(),
                     precision=parameters["precision"],
                     integration_dim=integration_dim,
                     entity_ids=entity_ids,
                     index_cache=index_cache,
                     quadrature_rule=macro_quadrature_rule)

    fexpr, = fem.compile_ufl(f, **macro_cfg)
    X = ufl.SpatialCoordinate(Vf.mesh())
    C_a, = fem.compile_ufl(X, **macro_cfg)
    detJ = ufl_utils.preprocess_expression(
        abs(ufl.JacobianDeterminant(f.ufl_domain())))
    macro_detJ, = fem.compile_ufl(detJ, **macro_cfg)

    Vce = create_element(Vc.ufl_element())

    coarse_builder = firedrake_interface.KernelBuilder("cell", "otherwise", 0,
                                                       ScalarType_c)
    coarse_builder.set_coordinates(Vc.mesh())
    argument_multiindices = (Vce.get_indices(), )
    argument_multiindex, = argument_multiindices
    return_variable, = coarse_builder.set_arguments((ufl.TestFunction(Vc), ),
                                                    argument_multiindices)

    integration_dim, entity_ids = lower_integral_type(Vce.cell, "cell")
    # Midpoint quadrature for jacobian on coarse cell.
    quadrature_rule = make_quadrature(Vce.cell, 0)

    coarse_cfg = dict(interface=coarse_builder,
                      ufl_cell=Vc.ufl_cell(),
                      precision=parameters["precision"],
                      integration_dim=integration_dim,
                      entity_ids=entity_ids,
                      index_cache=index_cache,
                      quadrature_rule=quadrature_rule)

    X = ufl.SpatialCoordinate(Vc.mesh())
    K = ufl_utils.preprocess_expression(ufl.JacobianInverse(Vc.mesh()))
    C_0, = fem.compile_ufl(X, **coarse_cfg)
    K, = fem.compile_ufl(K, **coarse_cfg)

    i = gem.Index()
    j = gem.Index()

    C_0 = gem.Indexed(C_0, (j, ))
    C_0 = gem.index_sum(C_0, quadrature_rule.point_set.indices)
    C_a = gem.Indexed(C_a, (j, ))
    X_a = gem.Sum(C_0, gem.Product(gem.Literal(-1), C_a))

    K_ij = gem.Indexed(K, (i, j))
    K_ij = gem.index_sum(K_ij, quadrature_rule.point_set.indices)
    X_a = gem.index_sum(gem.Product(K_ij, X_a), (j, ))
    C_0, = quadrature_rule.point_set.points
    C_0 = gem.Indexed(gem.Literal(C_0), (i, ))
    # fine quad points in coarse reference space.
    X_a = gem.Sum(C_0, gem.Product(gem.Literal(-1), X_a))
    X_a = gem.ComponentTensor(X_a, (i, ))

    # Coarse basis function evaluated at fine quadrature points
    phi_c = fem.fiat_to_ufl(
        Vce.point_evaluation(0, X_a, (Vce.cell.get_dimension(), 0)), 0)

    tensor_indices = tuple(gem.Index(extent=d) for d in f.ufl_shape)

    phi_c = gem.Indexed(phi_c, argument_multiindex + tensor_indices)
    fexpr = gem.Indexed(fexpr, tensor_indices)
    quadrature_weight = macro_quadrature_rule.weight_expression
    expr = gem.Product(gem.IndexSum(gem.Product(phi_c, fexpr), tensor_indices),
                       gem.Product(macro_detJ, quadrature_weight))

    quadrature_indices = macro_builder.indices + macro_quadrature_rule.point_set.indices

    reps = spectral.Integrals([expr], quadrature_indices,
                              argument_multiindices, parameters)
    assignments = spectral.flatten([(return_variable, reps)], index_cache)
    return_variables, expressions = zip(*assignments)
    expressions = impero_utils.preprocess_gem(expressions,
                                              **spectral.finalise_options)
    assignments = list(zip(return_variables, expressions))
    impero_c = impero_utils.compile_gem(assignments,
                                        quadrature_indices +
                                        argument_multiindex,
                                        remove_zeros=True)

    index_names = []

    def name_index(index, name):
        index_names.append((index, name))
        if index in index_cache:
            for multiindex, suffix in zip(index_cache[index],
                                          string.ascii_lowercase):
                name_multiindex(multiindex, name + suffix)

    def name_multiindex(multiindex, name):
        if len(multiindex) == 1:
            name_index(multiindex[0], name)
        else:
            for i, index in enumerate(multiindex):
                name_index(index, name + str(i))

    name_multiindex(quadrature_indices, 'ip')
    for multiindex, name in zip(argument_multiindices, ['j', 'k']):
        name_multiindex(multiindex, name)

    index_names.extend(zip(macro_builder.indices, ["entity"]))
    body = generate_coffee(impero_c, index_names, parameters["precision"],
                           ScalarType_c)

    retarg = ast.Decl(ScalarType_c,
                      ast.Symbol("R", rank=(Vce.space_dimension(), )))
    local_tensor = coarse_builder.local_tensor
    local_tensor.init = ast.ArrayInit(
        numpy.zeros(Vce.space_dimension(), dtype=ScalarType_c))
    body.children.insert(0, local_tensor)
    args = [retarg] + macro_builder.kernel_args + [
        macro_builder.coordinates_arg, coarse_builder.coordinates_arg
    ]

    # Now we have the kernel that computes <f, phi_c>dx_c
    # So now we need to hit it with the inverse mass matrix on dx_c

    u = TrialFunction(Vc)
    v = TestFunction(Vc)
    expr = Tensor(ufl.inner(u, v) * ufl.dx).inv * AssembledVector(
        ufl.Coefficient(Vc))
    Ainv, = compile_expression(expr)
    Ainv = Ainv.kinfo.kernel
    A = ast.Symbol(local_tensor.sym.symbol)
    R = ast.Symbol("R")
    body.children.append(
        ast.FunCall(Ainv.name, R, coarse_builder.coordinates_arg.sym, A))
    from coffee.base import Node
    assert isinstance(Ainv._code, Node)
    return op2.Kernel(ast.Node([
        Ainv._code,
        ast.FunDecl("void",
                    "pyop2_kernel_injection_dg",
                    args,
                    body,
                    pred=["static", "inline"])
    ]),
                      name="pyop2_kernel_injection_dg",
                      cpp=True,
                      include_dirs=Ainv._include_dirs,
                      headers=Ainv._headers)
Exemplo n.º 26
0
import ufl
from ufl import grad, div, dot, dx, ds, inner, sin, cos, pi, exp, sqrt
import dune.ufl
import dune.grid
import dune.fem

endTime  = 0.1
saveInterval = 1 # for VTK

gridView = dune.grid.structuredGrid([-1,-1],[1,1],[40,40])

space = dune.fem.space.lagrange(gridView, order=1)
u     = ufl.TrialFunction(space)
phi   = ufl.TestFunction(space)
x     = ufl.SpatialCoordinate(space)
dt    = dune.ufl.Constant(5e-2, "timeStep")
t     = dune.ufl.Constant(0.0, "time")

# define storage for discrete solutions
uh     = space.interpolate(0, name="uh")
uh_old = uh.copy()

# initial solution
initial = 0

# problem definition

# moving oven
ROven = 0.6
omegaOven = 0.01 * pi * t
P = ufl.as_vector([ROven*cos(omegaOven*t), ROven*sin(omegaOven*t)])
Exemplo n.º 27
0
# ===========================

# In the previous sections we have considered CG-1 spaces, which have a
# 1-1 correspondence with the vertices of the geometry. To be able to
# plot higher order function spaces, both CG and DG spaces, we have to
# adjust our plotting technique.

# We start by projecting a discontinuous function into a second order DG
# space Note that we use the `cell_tags` from the previous section to
# restrict the integration domain on the RHS.
dx = ufl.Measure("dx", subdomain_data=cell_tags)
V = dolfinx.FunctionSpace(mesh, ("DG", 2))
uh = dolfinx.Function(V)
u = ufl.TrialFunction(V)
v = ufl.TestFunction(V)
x = ufl.SpatialCoordinate(mesh)
a = ufl.inner(u, v) * dx
L = ufl.inner(x[0], v) * dx(1) + ufl.inner(0.01, v) * dx(0)
problem = dolfinx.fem.LinearProblem(a,
                                    L,
                                    u=uh,
                                    petsc_options={
                                        "ksp_type": "preonly",
                                        "pc_type": "lu"
                                    })
problem.solve()

# To get a topology that has a 1-1 correspondence with the degrees of
# freedom in the function space, we call
# `dolfinx.plot.create_vtk_topology`. We obtain the geometry for
# the dofs owned on this process by tabulation of the dof coordinates.
Exemplo n.º 28
0
    spiral_b = 0.02
    spiral_eps = 0.02
    spiral_D = 1. / 100

    def spiral_h(u, v):
        return u - v
else:
    spiral_a = 0.75
    spiral_b = 0.0006
    spiral_eps = 0.08

    def spiral_h(u, v):
        return u**3 - v


x = ufl.SpatialCoordinate(ufl.triangle)
initial_u = ufl.conditional(x[1] > 1.25, 1, 0)
initial_v = ufl.conditional(x[0] < 1.25, 0.5, 0)

# <markdowncell>
# Now we set up the reference domain, the Lagrange finite element space (second order), and discrete functions for $(u^n,v^n($, $(u^{n+1},v^{n+1})$:
# <codecell>

gridView = dune.grid.structuredGrid([0, 0], [2.5, 2.5], [30, 30])
space = dune.fem.space.lagrange(gridView, dimRange=dimRange, order=1)

uh = space.interpolate(initial_u, name="u")
uh_n = uh.copy()
vh = space.interpolate(initial_v, name="v")
vh_n = vh.copy()
Exemplo n.º 29
0
def test_pipeline(u_from_mpc):

    # Create mesh and function space
    mesh = create_unit_square(MPI.COMM_WORLD, 5, 5)
    V = fem.FunctionSpace(mesh, ("Lagrange", 1))

    # Solve Problem without MPC for reference
    u = ufl.TrialFunction(V)
    v = ufl.TestFunction(V)
    d = fem.Constant(mesh, PETSc.ScalarType(0.01))
    x = ufl.SpatialCoordinate(mesh)
    f = ufl.sin(2 * ufl.pi * x[0]) * ufl.sin(ufl.pi * x[1])
    a = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx - d * ufl.inner(u, v) * ufl.dx
    rhs = ufl.inner(f, v) * ufl.dx
    bilinear_form = fem.form(a)
    linear_form = fem.form(rhs)

    # Generate reference matrices
    A_org = fem.petsc.assemble_matrix(bilinear_form)
    A_org.assemble()
    L_org = fem.petsc.assemble_vector(linear_form)
    L_org.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES, mode=PETSc.ScatterMode.REVERSE)

    # Create multipoint constraint
    def periodic_relation(x):
        out_x = np.copy(x)
        out_x[0] = 1 - x[0]
        return out_x

    def PeriodicBoundary(x):
        return np.isclose(x[0], 1)

    facets = locate_entities_boundary(mesh, mesh.topology.dim - 1, PeriodicBoundary)
    arg_sort = np.argsort(facets)
    mt = meshtags(mesh, mesh.topology.dim - 1, facets[arg_sort], np.full(len(facets), 2, dtype=np.int32))

    mpc = dolfinx_mpc.MultiPointConstraint(V)
    mpc.create_periodic_constraint_topological(V, mt, 2, periodic_relation, [], 1)
    mpc.finalize()

    if u_from_mpc:
        uh = fem.Function(mpc.function_space)
        problem = dolfinx_mpc.LinearProblem(bilinear_form, linear_form, mpc, bcs=[], u=uh,
                                            petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
        problem.solve()

        root = 0
        dolfinx_mpc.utils.compare_mpc_lhs(A_org, problem.A, mpc, root=root)
        dolfinx_mpc.utils.compare_mpc_rhs(L_org, problem.b, mpc, root=root)

        # Gather LHS, RHS and solution on one process
        A_csr = dolfinx_mpc.utils.gather_PETScMatrix(A_org, root=root)
        K = dolfinx_mpc.utils.gather_transformation_matrix(mpc, root=root)
        L_np = dolfinx_mpc.utils.gather_PETScVector(L_org, root=root)
        u_mpc = dolfinx_mpc.utils.gather_PETScVector(uh.vector, root=root)

        if MPI.COMM_WORLD.rank == root:
            KTAK = K.T * A_csr * K
            reduced_L = K.T @ L_np
            # Solve linear system
            d = scipy.sparse.linalg.spsolve(KTAK, reduced_L)
            # Back substitution to full solution vector
            uh_numpy = K @ d
            assert np.allclose(uh_numpy, u_mpc)

    else:
        uh = fem.Function(V)
        with pytest.raises(ValueError):
            problem = dolfinx_mpc.LinearProblem(bilinear_form, linear_form, mpc, bcs=[], u=uh,
                                                petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
            problem.solve()
Exemplo n.º 30
0
def derivative(form, u, du=None, coefficient_derivatives=None):
    """Compute the derivative of a form.

    Given a form, this computes its linearization with respect to the
    provided :class:`.Function`.  The resulting form has one
    additional :class:`Argument` in the same finite element space as
    the Function.

    :arg form: a :class:`~ufl.classes.Form` to compute the derivative of.
    :arg u: a :class:`.Function` to compute the derivative with
         respect to.
    :arg du: an optional :class:`Argument` to use as the replacement
         in the new form (constructed automatically if not provided).
    :arg coefficient_derivatives: an optional :class:`dict` to
         provide the derivative of a coefficient function.

    :raises ValueError: If any of the coefficients in ``form`` were
        obtained from ``u.split()``.  UFL doesn't notice that these
        are related to ``u`` and so therefore the derivative is
        wrong (instead one should have written ``split(u)``).

    See also :func:`ufl.derivative`.
    """
    # TODO: What about Constant?
    u_is_x = isinstance(u, ufl.SpatialCoordinate)
    if not u_is_x and len(u.split()) > 1 and set(
            extract_coefficients(form)) & set(u.split()):
        raise ValueError(
            "Taking derivative of form wrt u, but form contains coefficients from u.split()."
            "\nYou probably meant to write split(u) when defining your form.")

    mesh = form.ufl_domain()
    is_dX = u_is_x or u is mesh.coordinates
    args = form.arguments()

    def argument(V):
        if du is None:
            n = max(a.number() for a in args) if args else -1
            return Argument(V, n + 1)
        else:
            return du

    if is_dX:
        coords = mesh.coordinates
        u = ufl.SpatialCoordinate(mesh)
        V = coords.function_space()
        du = argument(V)
        cds = {coords: du}
        if coefficient_derivatives is not None:
            cds.update(coefficient_derivatives)
        coefficient_derivatives = cds
    elif isinstance(u, firedrake.Function):
        V = u.function_space()
        du = argument(V)
    elif isinstance(u, firedrake.Constant):
        if u.ufl_shape != ():
            raise ValueError(
                "Real function space of vector elements not supported")
        V = firedrake.FunctionSpace(mesh, "Real", 0)
        du = argument(V)
    else:
        raise RuntimeError("Can't compute derivative for form")

    return ufl.derivative(form, u, du, coefficient_derivatives)