def test_vector_p1_3d():
    meshc = UnitCubeMesh(MPI.comm_world, 2, 3, 4)
    meshf = UnitCubeMesh(MPI.comm_world, 3, 4, 5)

    Vc = VectorFunctionSpace(meshc, ("CG", 1))
    Vf = VectorFunctionSpace(meshf, ("CG", 1))

    def u(x):
        values0 = x[:, 0] + 2.0 * x[:, 1]
        values1 = 4.0 * x[:, 0]
        values2 = 3.0 * x[:, 2] + x[:, 0]
        return np.stack([values0, values1, values2], axis=1)

    uc, uf = Function(Vc), Function(Vf)
    uc.interpolate(u)
    uf.interpolate(u)

    mat = PETScDMCollection.create_transfer_matrix(Vc._cpp_object,
                                                   Vf._cpp_object)
    Vuc = Function(Vf)
    mat.mult(uc.vector, Vuc.vector)

    diff = Vuc.vector
    diff.axpy(-1, uf.vector)
    assert diff.norm() < 1.0e-12
Exemple #2
0
def test_vector_p1_3d():
    meshc = UnitCubeMesh(MPI.comm_world, 2, 3, 4)
    meshf = UnitCubeMesh(MPI.comm_world, 3, 4, 5)

    Vc = VectorFunctionSpace(meshc, ("CG", 1))
    Vf = VectorFunctionSpace(meshf, ("CG", 1))

    @function.expression.numba_eval
    def expr_eval(values, x, cell_idx):
        values[:, 0] = x[:, 0] + 2.0 * x[:, 1]
        values[:, 1] = 4.0 * x[:, 0]
        values[:, 2] = 3.0 * x[:, 2] + x[:, 0]

    u = Expression(expr_eval, shape=(3, ))
    uc = interpolate(u, Vc)
    uf = interpolate(u, Vf)

    mat = PETScDMCollection.create_transfer_matrix(Vc._cpp_object,
                                                   Vf._cpp_object)
    Vuc = Function(Vf)
    mat.mult(uc.vector(), Vuc.vector())

    diff = Vuc.vector()
    diff.axpy(-1, uf.vector())
    assert diff.norm() < 1.0e-12
Exemple #3
0
def get_spaces(mesh):
    """
    Return an object of dolfin FunctionSpace, to 
    be used in the optimization pipeline

    :param mesh: The mesh
    :type mesh: :py:class:`dolfin.Mesh`
    :returns: An object of functionspaces
    :rtype: object

    """

    from dolfin import FunctionSpace, VectorFunctionSpace, TensorFunctionSpace

    # Make a dummy object
    spaces = Object()

    # A real space with scalars used for dolfin adjoint
    spaces.r_space = FunctionSpace(mesh, "R", 0)

    # A space for the strain fields
    spaces.strainfieldspace = VectorFunctionSpace(mesh, "CG", 1, dim=3)

    # A space used for scalar strains
    spaces.strainspace = VectorFunctionSpace(mesh, "R", 0, dim=3)

    # Spaces for the strain weights
    spaces.strain_weight_space = TensorFunctionSpace(mesh, "R", 0)

    return spaces
Exemple #4
0
def test_raises(meshes_p1):
    mesh1, mesh2 = meshes_p1[:2]

    # Wrong FE family
    V = VectorFunctionSpace(mesh2, "Discontinuous Lagrange", 1)
    c = Function(V)
    with pytest.raises(RuntimeError):
        get_coordinates(c, mesh2.geometry())
    with pytest.raises(RuntimeError):
        set_coordinates(mesh2.geometry(), c)

    # Wrong value rank
    V = FunctionSpace(mesh2, "Lagrange", 1)
    c = Function(V)
    with pytest.raises(RuntimeError):
        get_coordinates(c, mesh2.geometry())
    with pytest.raises(RuntimeError):
        set_coordinates(mesh2.geometry(), c)

    # Wrong value shape
    V = VectorFunctionSpace(mesh2, "Lagrange", mesh2.geometry().degree(),
            dim=mesh2.geometry().dim() - 1)
    c = Function(V)
    with pytest.raises(RuntimeError):
        get_coordinates(c, mesh2.geometry())
    with pytest.raises(RuntimeError):
        set_coordinates(mesh2.geometry(), c)

    # Non-matching degree
    V = VectorFunctionSpace(mesh2, "Lagrange", mesh2.geometry().degree() + 1)
    c = Function(V)
    with pytest.raises(RuntimeError):
        get_coordinates(c, mesh2.geometry())
    with pytest.raises(RuntimeError):
        set_coordinates(mesh2.geometry(), c)
Exemple #5
0
def cg1_cr_interpolation_matrix(mesh, constrained_domain=None):
    '''
    Compute matrix that allows fast interpolation of CG1 function to
    Couzeix-Raviart space.
    '''

    CG1 = VectorFunctionSpace(mesh,
                              'CG',
                              1,
                              constrained_domain=constrained_domain)
    CR = VectorFunctionSpace(mesh,
                             'CR',
                             1,
                             constrained_domain=constrained_domain)

    # Get the matrix with approximate sparsity as the interpolation matrix
    u = TrialFunction(CG1)
    v = TestFunction(CR)
    I = PETScMatrix()
    assemble(dot(u, v) * dx, tensor=I)

    # Fill the interpolation matrix
    d = mesh.geometry().dim()
    compiled_i_module.compute_cg1_cr_interpolation_matrix(I, d)

    return I
def gauss_divergence(u, mesh=None):
    '''
    This function uses Gauss divergence theorem to compute divergence of u
    inside the cell by integrating normal fluxes across the cell boundary.
    If u is a vector or tensor field the result of computation is diverence
    of u in the cell center = DG0 scalar/vector function. For scalar fields,
    the result is grad(u) = DG0 vector function. The fluxes are computed by
    midpoint rule and as such the computed divergence is exact for linear
    fields.
    '''

    # Require u to be GenericFunction
    assert isinstance(u, GenericFunction)

    # Require u to be scalar/vector/rank 2 tensor
    rank = u.value_rank()
    assert rank in [0, 1, 2]

    # For now, there is no support for manifolds
    if mesh is None:
        _mesh = u.function_space().mesh()
    else:
        _mesh = mesh

    tdim = _mesh.topology().dim()
    gdim = _mesh.geometry().dim()
    assert tdim == gdim

    for i in range(rank):
        assert u.value_dimension(i) == gdim

    # Based on rank choose the type of CR1 space where u should be interpolated
    # to to get the midpoint values + choose the type of DG0 space for
    # divergence
    if rank == 1:
        DG = FunctionSpace(_mesh, 'DG', 0)
        CR = VectorFunctionSpace(_mesh, 'CR', 1)
    else:
        DG = VectorFunctionSpace(_mesh, 'DG', 0)
        if rank == 0:
            CR = FunctionSpace(_mesh, 'CR', 1)
        else:
            CR = TensorFunctionSpace(_mesh, 'CR', 1)

    divu = Function(DG)
    _u = interpolate(u, CR)

    # Use Gauss theorem cell by cell to get the divergence. The implementation
    # is based on divergence(vector) = scalar and so the spaces for these
    # two need to be provided
    if rank == 1:
        pass  # CR, DG are correct already
    else:
        DG = FunctionSpace(_mesh, 'DG', 0)
        CR = VectorFunctionSpace(_mesh, 'CR', 1)
    compiled_cr_module.cr_divergence(divu, _u, DG, CR)

    return divu
Exemple #7
0
def get_function_spaces_1():
    return (
        lambda mesh: FunctionSpace(mesh, "Lagrange", 1),
        pytest.mark.slow(lambda mesh: FunctionSpace(mesh, "Lagrange", 2)),
        lambda mesh: VectorFunctionSpace(mesh, "Lagrange", 1),
        pytest.mark.slow(lambda mesh: VectorFunctionSpace(mesh, "Lagrange", 2)),
        pytest.mark.slow(lambda mesh: TensorFunctionSpace(mesh, "Lagrange", 1)),
        pytest.mark.slow(lambda mesh: TensorFunctionSpace(mesh, "Lagrange", 2)),
        lambda mesh: StokesFunctionSpace(mesh, "Lagrange", 1),
        pytest.mark.slow(lambda mesh: StokesFunctionSpace(mesh, "Lagrange", 2)),
        lambda mesh: FunctionSpace(mesh, "Real", 0),
        pytest.mark.slow(lambda mesh: VectorFunctionSpace(mesh, "Real", 0)),
        pytest.mark.slow(lambda mesh: FunctionAndRealSpace(mesh, "Lagrange", 1)),
        pytest.mark.slow(lambda mesh: FunctionAndRealSpace(mesh, "Lagrange", 2))
    )
Exemple #8
0
def test_save_1d_vector(tempfile, file_options):
    mesh = UnitIntervalMesh(MPI.comm_world, 32)
    u = Function(VectorFunctionSpace(mesh, "Lagrange", 2))
    u.vector()[:] = 1.0
    VTKFile(tempfile + "u.pvd", "ascii").write(u)
    for file_option in file_options:
        VTKFile(tempfile + "u.pvd", file_option).write(u)
Exemple #9
0
def increase_order(V):
    """
    For a given function space, return the same space, but with a
    higher polynomial degree
    """

    n = V.num_sub_spaces()
    if n > 0:
        spaces = []
        for i in range(n):
            V_i = V.sub(i)
            element = V_i.ufl_element()
            # Handle VectorFunctionSpaces specially
            if isinstance(element, ufl.VectorElement):
                spaces += [
                    VectorFunctionSpace(V_i.mesh(),
                                        element.family(),
                                        element.degree() + 1,
                                        dim=element.num_sub_elements())
                ]
            # Handle all else as MixedFunctionSpaces
            else:
                spaces += [increase_order(V_i)]

        return MixedFunctionSpace(spaces)

    if V.ufl_element().family() == "Real":
        return FunctionSpace(V.mesh(), "Real", 0)

    return FunctionSpace(V.mesh(),
                         V.ufl_element().family(),
                         V.ufl_element().degree() + 1)
Exemple #10
0
def test_pointsource_vector_fs(mesh, point):
    """Tests point source when given constructor PointSource(V, point,
    mag) with a vector for a vector function space that isn't placed
    at a node for 1D, 2D and 3D. Global points given to constructor
    from rank 0 processor.

    """

    rank = MPI.rank(mesh.mpi_comm())
    V = VectorFunctionSpace(mesh, "CG", 1)
    v = TestFunction(V)
    b = assemble(dot(Constant([0.0] * mesh.geometry().dim()), v) * dx)
    if rank == 0:
        ps = PointSource(V, point, 10.0)
    else:
        ps = PointSource(V, [])
    ps.apply(b)

    # Checks array sums to correct value
    b_sum = b.sum()
    assert round(b_sum - 10.0 * V.num_sub_spaces()) == 0

    # Checks point source is added to correct part of the array
    v2d = vertex_to_dof_map(V)
    for v in vertices(mesh):
        if near(v.midpoint().distance(point), 0.0):
            for spc_idx in range(V.num_sub_spaces()):
                ind = v2d[v.index() * V.num_sub_spaces() + spc_idx]
                if ind < len(b.get_local()):
                    assert np.round(b.get_local()[ind] - 10.0) == 0
Exemple #11
0
def test_multi_ps_matrix(mesh):
    """Tests point source PointSource(V, source) for mulitple point
    sources applied to a matrix for 1D, 2D and 3D. Global points given
    to constructor from rank 0 processor.

    """

    c_ids = [0, 1, 2]
    rank = MPI.rank(mesh.mpi_comm())
    V = VectorFunctionSpace(mesh, "CG", 1, dim=2)
    u, v = TrialFunction(V), TestFunction(V)
    A = assemble(Constant(0.0) * dot(u, v) * dx)

    source = []
    if rank == 0:
        for c_id in c_ids:
            cell = Cell(mesh, c_id)
            point = cell.midpoint()
            source.append((point, 10.0))
    ps = PointSource(V, source)
    ps.apply(A)

    # Checks b sums to correct value
    a_sum = MPI.sum(mesh.mpi_comm(), np.sum(A.array()))
    assert round(a_sum - 2 * len(c_ids) * 10) == 0
def test_p4_scalar_vector():

    perms = itertools.permutations([1, 2, 3, 4])

    for p in perms:
        cells = numpy.array([[0, 1, 2, 3], p], dtype=numpy.int64)
        points = numpy.array(
            [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0],
             [0.0, 0.0, 1.0], [1.0, 1.0, 1.0]],
            dtype=numpy.float64)

        mesh = Mesh(MPI.comm_world, CellType.Type.tetrahedron, points, cells,
                    [], GhostMode.none)
        mesh.geometry.coord_mapping = fem.create_coordinate_map(mesh)

        Q = FunctionSpace(mesh, ("CG", 4))
        F0 = interpolate(Expression("x[0]", degree=4), Q)
        F1 = interpolate(Expression("x[1]", degree=4), Q)
        F2 = interpolate(Expression("x[2]", degree=4), Q)

        pts = numpy.array([[0.4, 0.4, 0.1], [0.4, 0.1, 0.4], [0.1, 0.4, 0.4]])
        for pt in pts:
            assert numpy.isclose(pt[0], F0(pt)[0])
            assert numpy.isclose(pt[1], F1(pt)[0])
            assert numpy.isclose(pt[2], F2(pt)[0])

        V = VectorFunctionSpace(mesh, ("CG", 4))
        F = interpolate(Expression(("x[0]", "x[1]", "0.0"), degree=4), V)
        for pt in pts:
            result = F(pt)
            assert numpy.isclose(pt[0], result[0])
            assert numpy.isclose(pt[1], result[1])
            assert numpy.isclose(0.0, result[2])
Exemple #13
0
   def __init__(self, mesh, mf, bc_dict, move_dict):
       """
       Inititalize Stokes solver with a mesh, its corresponding facet function,
       a dictionary describing boundary conditions and 
       a dictionary describing which boundaries are fixed in the shape optimization setting
       """
       self.mesh = mesh
       self.backup = mesh.coordinates().copy()
       self.mf = mf
       V2 = VectorElement("CG", mesh.ufl_cell(), 2)
       S1 = FiniteElement("CG", mesh.ufl_cell(), 1)
       TH = V2 * S1
       self.VQ = FunctionSpace(self.mesh, TH)
       self.w = Function(self.VQ)
       self.f = Constant([0.]*mesh.geometric_dimension())
       self.S = VectorFunctionSpace(self.mesh, "CG", 1)
       self.move_dict = move_dict
       self.J = 0
       self._init_bcs(bc_dict)
       self.solve()
       self.vfac = 1e4
       self.bfac = 1e2
       self._init_geometric_functions()
       self.eval_current_J()
       self.eval_current_dJ()
       self.outfile = File("output/u_singlemesh.pvd")
       self.outfile << self.u
       self.gradient_scale = 1
 
       self.iteration_counter = 1
       self.create_mapping_for_moving_boundary()
def test_l2projection(polynomial_order, in_expression):
    # Test l2 projection for scalar and vector valued expression
    interpolate_expression = Expression(in_expression, degree=3)

    xmin, xmax = 0., 1.
    ymin, ymax = 0., 1.

    property_idx = 5

    mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 40, 40)

    if len(interpolate_expression.ufl_shape) == 0:
        V = FunctionSpace(mesh, "DG", polynomial_order)
    elif len(interpolate_expression.ufl_shape) == 1:
        V = VectorFunctionSpace(mesh, "DG", polynomial_order)

    v_exact = Function(V)
    v_exact.interpolate(interpolate_expression)

    x = RandomRectangle(Point(xmin, ymin), Point(xmax,
                                                 ymax)).generate([500, 500])
    s = assign_particle_values(x, interpolate_expression)

    # Just make a complicated particle, possibly with scalars and vectors mixed
    p = particles(x, [x, s, x, x, s], mesh)

    vh = Function(V)
    lstsq_rho = l2projection(p, V, property_idx)
    lstsq_rho.project(vh)

    error_sq = abs(assemble(dot(v_exact - vh, v_exact - vh) * dx))
    assert error_sq < 1e-15
    def amg_solve(N, method):
        # Elasticity parameters
        E = 1.0e9
        nu = 0.3
        mu = E / (2.0 * (1.0 + nu))
        lmbda = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu))

        # Stress computation
        def sigma(v):
            return 2.0 * mu * sym(grad(v)) + lmbda * tr(sym(
                grad(v))) * Identity(2)

        # Define problem
        mesh = UnitSquareMesh(MPI.comm_world, N, N)
        V = VectorFunctionSpace(mesh, 'Lagrange', 1)
        bc0 = Function(V)
        with bc0.vector().localForm() as bc_local:
            bc_local.set(0.0)

        def boundary(x, only_boundary):
            return [only_boundary] * x.shape(0)

        bc = DirichletBC(V.sub(0), bc0, boundary)
        u = TrialFunction(V)
        v = TestFunction(V)

        # Forms
        a, L = inner(sigma(u), grad(v)) * dx, dot(ufl.as_vector(
            (1.0, 1.0)), v) * dx

        # Assemble linear algebra objects
        A = assemble_matrix(a, [bc])
        A.assemble()
        b = assemble_vector(L)
        apply_lifting(b, [a], [[bc]])
        b.ghostUpdate(addv=PETSc.InsertMode.ADD,
                      mode=PETSc.ScatterMode.REVERSE)
        set_bc(b, [bc])

        # Create solution function
        u = Function(V)

        # Create near null space basis and orthonormalize
        null_space = build_nullspace(V, u.vector())

        # Attached near-null space to matrix
        A.set_near_nullspace(null_space)

        # Test that basis is orthonormal
        assert null_space.is_orthonormal()

        # Create PETSC smoothed aggregation AMG preconditioner, and
        # create CG solver
        solver = PETScKrylovSolver("cg", method)

        # Set matrix operator
        solver.set_operator(A)

        # Compute solution and return number of iterations
        return solver.solve(u.vector(), b)
Exemple #16
0
def test_read_write_p2_function(tempdir):
    mesh = cpp.generation.UnitDiscMesh.create(MPI.comm_world, 3,
                                              cpp.mesh.GhostMode.none)
    cmap = fem.create_coordinate_map(mesh.ufl_domain())
    mesh.geometry.coord_mapping = cmap
    Q = FunctionSpace(mesh, ("Lagrange", 2))

    F = Function(Q)
    if has_petsc_complex:
        F.interpolate(Expression("x[0] + j*x[0]", degree=1))
    else:
        F.interpolate(Expression("x[0]", degree=1))

    filename = os.path.join(tempdir, "tri6_function.xdmf")
    with XDMFFile(mesh.mpi_comm(), filename,
                  encoding=XDMFFile.Encoding.HDF5) as xdmf:
        xdmf.write(F)

    Q = VectorFunctionSpace(mesh, ("Lagrange", 1))
    F = Function(Q)
    if has_petsc_complex:
        F.interpolate(Expression(("x[0] + j*x[0]", "x[1] + j*x[1]"), degree=1))
    else:
        F.interpolate(Expression(("x[0]", "x[1]"), degree=1))

    filename = os.path.join(tempdir, "tri6_vector_function.xdmf")
    with XDMFFile(mesh.mpi_comm(), filename,
                  encoding=XDMFFile.Encoding.HDF5) as xdmf:
        xdmf.write(F)
Exemple #17
0
def _generate_space(expression: Operator):
    # Extract mesh from expression (from dolfin/fem/projection.py, _extract_function_space function)
    meshes = set(
        [ufl_domain.ufl_cargo() for ufl_domain in extract_domains(expression)])
    for t in traverse_unique_terminals(
            expression):  # from ufl/domain.py, extract_domains
        if hasattr(t, "_mesh"):
            meshes.add(t._mesh)
    assert len(meshes) == 1
    mesh = meshes.pop()
    # The EIM algorithm will evaluate the expression at vertices. However, since the Operator expression may
    # contain e.g. a gradient of a solution defined in a C^0 space, we resort to DG1 spaces.
    shape = expression.ufl_shape
    assert len(shape) in (0, 1, 2)
    if len(shape) == 0:
        space = FunctionSpace(mesh, "Discontinuous Lagrange", 1)
    elif len(shape) == 1:
        space = VectorFunctionSpace(mesh,
                                    "Discontinuous Lagrange",
                                    1,
                                    dim=shape[0])
    elif len(shape) == 2:
        space = TensorFunctionSpace(mesh,
                                    "Discontinuous Lagrange",
                                    1,
                                    shape=shape)
    else:
        raise ValueError(
            "Invalid expression in ParametrizedExpressionFactory.__init__().")
    return space
Exemple #18
0
    def __init__(self, U_m, mesh):
        """Function spaces and BCs"""
        V = VectorFunctionSpace(mesh, 'P', 2)
        Q = FunctionSpace(mesh, 'P', 1)
        self.mesh = mesh
        self.vu, self.vp = TestFunction(V), TestFunction(Q)  # for integration
        self.u_, self.p_ = Function(V), Function(Q)  # for the solution
        self.u_1, self.p_1 = Function(V), Function(Q)  # for the prev. solution
        self.u_k, self.p_k = Function(V), Function(Q)  # for the prev. solution
        self.u, self.p = TrialFunction(V), TrialFunction(Q)  # unknown!

        U0_str = "4.*U_m*x[1]*(.41-x[1])/(.41*.41)"
        x = [0,
             .41 / 2]  # evaluate the Expression at the center of the channel
        self.U_mean = np.mean(2 / 3 * eval(U0_str))

        U0 = Expression((U0_str, "0"), U_m=U_m, degree=2)
        bc0 = DirichletBC(V, Constant((0, 0)), cylinderwall)
        bc1 = DirichletBC(V, Constant((0, 0)), topandbottom)
        bc2 = DirichletBC(V, U0, inlet)
        bc3 = DirichletBC(Q, Constant(0), outlet)
        self.bcu = [bc0, bc1, bc2]
        self.bcp = [bc3]
        # ds is needed to compute drag and lift.
        ASD1 = AutoSubDomain(topandbottom)
        ASD2 = AutoSubDomain(cylinderwall)
        mf = MeshFunction("size_t", mesh, 1)
        mf.set_all(0)
        ASD1.mark(mf, 1)
        ASD2.mark(mf, 2)
        self.ds_ = ds(subdomain_data=mf, domain=mesh)
        return
Exemple #19
0
    def get_custom_space(self, family, degree, shape, boundary=False):
        """Get a custom function space. """

        if boundary:
            mesh = self.BoundaryMesh
            key = (family, degree, shape, boundary)
        else:
            mesh = self.mesh
            key = (family, degree, shape)
        space = self._spaces.get(key)

        if space is None:
            rank = len(shape)
            if rank == 0:
                space = FunctionSpace(mesh, family, degree)
            elif rank == 1:
                space = VectorFunctionSpace(mesh, family, degree, shape[0])
            else:
                space = TensorFunctionSpace(mesh,
                                            family,
                                            degree,
                                            shape,
                                            symmetry={})
            self._spaces[key] = space

        return space
    def initial_conditions(self):
        "Return initial conditions for v and s as a dolfin.GenericFunction."

        n = self.num_states() # (Maximal) Number of states in MultiCellModel
        VS = VectorFunctionSpace(self.mesh(), "DG", 0, n+1)
        vs = Function(VS)

        markers = self.markers()
        u = TrialFunction(VS)
        v = TestFunction(VS)

        dy = Measure("dx", domain=self.mesh(), subdomain_data=markers)

        # Define projection into multiverse
        a = inner(u, v)*dy()

        Ls = list()
        for (k, model) in enumerate(self.models()):
            ic = model.initial_conditions() # Extract initial conditions
            n_k = model.num_states() # Extract number of local states
            i_k = self.keys()[k] # Extract domain index of cell model k
            L_k = sum(ic[j]*v[j]*dy(i_k) for j in range(n_k))
            Ls.append(L_k)
        L = sum(Ls)
        solve(a == L, vs)
        return vs
Exemple #21
0
def test_save_3d_vector(tempdir, encoding):
    filename = os.path.join(tempdir, "u_3Dv.xdmf")
    mesh = UnitCubeMesh(MPI.comm_world, 2, 2, 2)
    u = Function(VectorFunctionSpace(mesh, ("Lagrange", 1)))
    u.vector.set(1.0 + (1j if has_petsc_complex else 0))
    with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file:
        file.write(u)
Exemple #22
0
def test_closed_boundary(advection_scheme):
    # FIXME: rk3 scheme does not bounces off the wall properly
    xmin, xmax = 0., 1.
    ymin, ymax = 0., 1.

    mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10)

    # Particle
    x = np.array([[0.975, 0.475]])

    # Given velocity field:
    vexpr = Constant((1., 0.))
    # Given time do_step:
    dt = 0.05
    # Then bounced position is
    x_bounced = np.array([[0.975, 0.475]])

    p = particles(x, [x, x], mesh)

    V = VectorFunctionSpace(mesh, "CG", 1)
    v = Function(V)
    v.assign(vexpr)

    # Different boundary parts
    bound_left = UnitSquareLeft()
    bound_right = UnitSquareRight()
    bound_top = UnitSquareTop()
    bound_bottom = UnitSquareBottom()

    # Mark all facets
    facet_marker = MeshFunction('size_t', mesh, mesh.topology().dim() - 1)
    facet_marker.set_all(0)

    # Mark as closed
    bound_right.mark(facet_marker, 1)

    # Mark other boundaries as open
    bound_left.mark(facet_marker, 2)
    bound_top.mark(facet_marker, 2)
    bound_bottom.mark(facet_marker, 2)

    if advection_scheme == 'euler':
        ap = advect_particles(p, V, v, facet_marker)
    elif advection_scheme == 'rk2':
        ap = advect_rk2(p, V, v, facet_marker)
    elif advection_scheme == 'rk3':
        ap = advect_rk3(p, V, v, facet_marker)
    else:
        assert False

    # Do one timestep, particle must bounce from wall of
    ap.do_step(dt)
    xpE = p.positions()

    # Check if particle correctly bounced off from closed wall
    xpE_root = comm.gather(xpE, root=0)
    if comm.rank == 0:
        xpE_root = np.float64(np.vstack(xpE_root))
        error = np.linalg.norm(x_bounced - xpE_root)
        assert(error < 1e-10)
def divergence_matrix(mesh):
    CR = VectorFunctionSpace(mesh, 'CR', 1)
    DG = FunctionSpace(mesh, 'DG', 0)
    A = cg1_cr_interpolation_matrix(mesh)
    M = assemble(dot(div(TrialFunction(CR)), TestFunction(DG)) * dx())
    C = compiled_cr_module.cr_divergence_matrix(M, A, DG, CR)
    return C
Exemple #24
0
def test_nullspace_check(mesh, degree):
    V = VectorFunctionSpace(mesh, ('Lagrange', degree))
    u, v = TrialFunction(V), TestFunction(V)

    mesh.geometry.coord_mapping = fem.create_coordinate_map(mesh)

    E, nu = 2.0e2, 0.3
    mu = E / (2.0 * (1.0 + nu))
    lmbda = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu))

    def sigma(w, gdim):
        return 2.0 * mu * ufl.sym(grad(w)) + lmbda * ufl.tr(
            grad(w)) * ufl.Identity(gdim)

    a = inner(sigma(u, mesh.geometry.dim), grad(v)) * dx
    zero = Function(V)
    L = inner(zero, v) * dx

    # Assemble matrix and create compatible vector
    A, L = assembling.assemble_system(a, L, [])

    # Create null space basis and test
    null_space = build_elastic_nullspace(V)
    assert null_space.in_nullspace(A, tol=1.0e-8)
    null_space.orthonormalize()
    assert null_space.in_nullspace(A, tol=1.0e-8)

    # Create incorrect null space basis and test
    null_space = build_broken_elastic_nullspace(V)
    assert not null_space.in_nullspace(A, tol=1.0e-8)
    null_space.orthonormalize()
    assert not null_space.in_nullspace(A, tol=1.0e-8)
Exemple #25
0
def test_advect_periodic(advection_scheme):
    # FIXME: this unit test is sensitive to the ordering of the particle
    # array, i.e. xp0_root and xpE_root may contain exactly the same entries
    # but only in a different order. This will return an error right now

    xmin, xmax = 0., 1.
    ymin, ymax = 0., 1.
    pres = 3

    mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10)

    lims = np.array([[xmin, xmin, ymin, ymax], [xmax, xmax, ymin, ymax],
                     [xmin, xmax, ymin, ymin], [xmin, xmax, ymax, ymax]])

    vexpr = Constant((1., 1.))
    V = VectorFunctionSpace(mesh, "CG", 1)

    x = RandomRectangle(Point(0.05, 0.05), Point(0.15, 0.15)).generate([pres, pres])
    x = comm.bcast(x, root=0)
    dt = 0.05

    v = Function(V)
    v.assign(vexpr)

    p = particles(x, [x*0, x**2], mesh)

    if advection_scheme == 'euler':
        ap = advect_particles(p, V, v, 'periodic', lims.flatten())
    elif advection_scheme == 'rk2':
        ap = advect_rk2(p, V, v, 'periodic', lims.flatten())
    elif advection_scheme == 'rk3':
        ap = advect_rk3(p, V, v, 'periodic', lims.flatten())
    else:
        assert False

    xp0 = p.positions()
    t = 0.
    while t < 1.-1e-12:
        ap.do_step(dt)
        t += dt
    xpE = p.positions()

    # Check if position correct
    xp0_root = comm.gather(xp0, root=0)
    xpE_root = comm.gather(xpE, root=0)

    num_particles = p.number_of_particles()

    if comm.Get_rank() == 0:
        xp0_root = np.float32(np.vstack(xp0_root))
        xpE_root = np.float32(np.vstack(xpE_root))

        # Sort on x positions
        xp0_root = xp0_root[xp0_root[:, 0].argsort(), :]
        xpE_root = xpE_root[xpE_root[:, 0].argsort(), :]

        error = np.linalg.norm(xp0_root - xpE_root)
        assert error < 1e-10
        assert num_particles - pres**2 == 0
def test_advect_periodic(advection_scheme):
    xmin, ymin, zmin = 0., 0., 0.
    xmax, ymax, zmax = 1., 1., 1.
    pres = 10

    mesh = UnitCubeMesh(10, 10, 10)

    lims = np.array([[xmin, xmin, ymin, ymax, zmin, zmax],
                     [xmax, xmax, ymin, ymax, zmin, zmax],
                     [xmin, xmax, ymin, ymin, zmin, zmax],
                     [xmin, xmax, ymax, ymax, zmin, zmax],
                     [xmin, xmax, ymin, ymax, zmin, zmin],
                     [xmin, xmax, ymin, ymax, zmax, zmax]])

    vexpr = Constant((1., 1., 1.))
    V = VectorFunctionSpace(mesh, "CG", 1)
    v = Function(V)
    v.assign(vexpr)

    x = RandomBox(Point(0., 0., 0.), Point(1., 1.,
                                           1.)).generate([pres, pres, pres])
    x = comm.bcast(x, root=0)
    dt = 0.05

    p = particles(x, [x * 0, x**2], mesh)

    if advection_scheme == 'euler':
        ap = advect_particles(p, V, v, 'periodic', lims.flatten())
    elif advection_scheme == 'rk2':
        ap = advect_rk2(p, V, v, 'periodic', lims.flatten())
    elif advection_scheme == 'rk3':
        ap = advect_rk3(p, V, v, 'periodic', lims.flatten())
    else:
        assert False

    xp0 = p.positions()
    t = 0.
    while t < 1. - 1e-12:
        ap.do_step(dt)
        t += dt
    xpE = p.positions()

    xp0_root = comm.gather(xp0, root=0)
    xpE_root = comm.gather(xpE, root=0)

    assert len(xp0) == len(xpE)
    num_particles = p.number_of_particles()

    if comm.Get_rank() == 0:
        xp0_root = np.float32(np.vstack(xp0_root))
        xpE_root = np.float32(np.vstack(xpE_root))

        # Sort on x positions
        xp0_root = xp0_root[xp0_root[:, 0].argsort(), :]
        xpE_root = xpE_root[xpE_root[:, 0].argsort(), :]

        error = np.linalg.norm(xp0_root - xpE_root)
        assert error < 1e-10
        assert num_particles - pres**3 == 0
Exemple #27
0
def make_function_spaces(mesh, element):
    'Create mixed function space on the mesh.'
    assert hasattr(element, 'V') and hasattr(element, 'Q')

    # Create velocity space
    n = len(element.V)
    assert n > 0
    V = VectorFunctionSpace(mesh, *element.V[0])
    for i in range(1, n):
        V += VectorFunctionSpace(mesh, *element.V[i])

    # Create pressure space
    assert len(element.Q) == 1
    Q = FunctionSpace(mesh, *element.Q[0])

    M = MixedFunctionSpace([V, Q])
    return V, Q, M
Exemple #28
0
def divergence_matrix(mesh):
    CR = VectorFunctionSpace(mesh, 'CR', 1)
    DG = FunctionSpace(mesh, 'DG', 0)
    A = cg1_cr_interpolation_matrix(mesh)
    M  = assemble(dot(div(TrialFunction(CR)), TestFunction(DG))*dx())
    compiled_cr_module.cr_divergence_matrix(M, A, DG, CR)
    M_mat = as_backend_type(M).mat()
    M_mat.matMult(A.mat())
    return M
Exemple #29
0
def test_save_2d_vector(tempdir, encoding):
    filename = os.path.join(tempdir, "u_2dv.xdmf")
    mesh = UnitSquareMesh(MPI.comm_world, 16, 16)
    V = VectorFunctionSpace(mesh, ("Lagrange", 2))
    u = Function(V)
    c = Constant((1.0 + (1j if has_petsc_complex else 0), 2.0))
    u.interpolate(c)
    with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file:
        file.write(u)
Exemple #30
0
def test_save_3d_vector(tempdir, encoding):
    filename = os.path.join(tempdir, "u_3Dv.xdmf")
    mesh = UnitCubeMesh(MPI.comm_world, 2, 2, 2)
    u = Function(VectorFunctionSpace(mesh, ("Lagrange", 1)))
    A = 1.0 + (1j if has_petsc_complex else 0)
    c = Constant((1.0 + A, 2.0 + 2 * A, 3.0 + 3 * A))
    u.interpolate(c)
    with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file:
        file.write(u)