Exemple #1
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)
    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)
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 #4
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
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 #6
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 #7
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
Exemple #8
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
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 #10
0
 def __init__(self, u, name="Assigned Vector Function"):
     
     self.u = u
     assert isinstance(u, ListTensor)
     V = u[0].function_space()
     mesh = V.mesh()
     family = V.ufl_element().family()
     degree = V.ufl_element().degree()
     constrained_domain = V.dofmap().constrained_domain            
     Vv = VectorFunctionSpace(mesh, family, degree, constrained_domain=constrained_domain)
     
     Function.__init__(self, Vv, name=name)
     self.fa = [FunctionAssigner(Vv.sub(i), V) for i, _u in enumerate(u)]
Exemple #11
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 #12
0
    def __init__(self, V, subdomains, shape_parametrization_expression):
        # Store dolfin data structure related to the geometrical parametrization
        self.mesh = subdomains.mesh()
        self.subdomains = subdomains
        self.reference_coordinates = self.mesh.coordinates().copy()
        self.deformation_V = VectorFunctionSpace(self.mesh, "Lagrange", 1)
        self.subdomain_id_to_deformation_dofs = dict()  # from int to list
        for cell in cells(self.mesh):
            subdomain_id = int(
                self.subdomains[cell]
            ) - 1  # tuple start from 0, while subdomains from 1
            if subdomain_id not in self.subdomain_id_to_deformation_dofs:
                self.subdomain_id_to_deformation_dofs[subdomain_id] = list()
            dofs = self.deformation_V.dofmap().cell_dofs(cell.index())
            for dof in dofs:
                global_dof = self.deformation_V.dofmap().local_to_global_index(
                    dof)
                if (self.deformation_V.dofmap().ownership_range()[0] <=
                        global_dof and global_dof <
                        self.deformation_V.dofmap().ownership_range()[1]):
                    self.subdomain_id_to_deformation_dofs[subdomain_id].append(
                        dof)
        # In parallel some subdomains may not be present on all processors. Fill in
        # the dict with empty lists if that is the case
        mpi_comm = self.mesh.mpi_comm()
        if not has_pybind11():
            mpi_comm = mpi_comm.tompi4py()
        min_subdomain_id = mpi_comm.allreduce(min(
            self.subdomain_id_to_deformation_dofs.keys()),
                                              op=MIN)
        max_subdomain_id = mpi_comm.allreduce(max(
            self.subdomain_id_to_deformation_dofs.keys()),
                                              op=MAX)
        for subdomain_id in range(min_subdomain_id, max_subdomain_id + 1):
            if subdomain_id not in self.subdomain_id_to_deformation_dofs:
                self.subdomain_id_to_deformation_dofs[subdomain_id] = list()
        # Subdomain numbering is contiguous
        assert min(self.subdomain_id_to_deformation_dofs.keys()) == 0
        assert len(self.subdomain_id_to_deformation_dofs.keys()) == max(
            self.subdomain_id_to_deformation_dofs.keys()) + 1

        # Store the shape parametrization expression
        self.shape_parametrization_expression = shape_parametrization_expression
        assert len(self.shape_parametrization_expression) == len(
            self.subdomain_id_to_deformation_dofs.keys())

        # Prepare storage for displacement expression, computed by init()
        self.displacement_expression = list()
Exemple #13
0
    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)
        bc = DirichletBC(V.sub(0), bc0, lambda x, on_boundary: on_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, b = assemble_system(a, L, 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 #14
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 #15
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 #16
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
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 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 #19
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_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 #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 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)
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 __init__(self, u, name="Assigned Vector Function"):

        self.u = u
        assert isinstance(u, ListTensor)
        V = u[0].function_space()
        mesh = V.mesh()
        family = V.ufl_element().family()
        degree = V.ufl_element().degree()
        constrained_domain = V.dofmap().constrained_domain
        Vv = VectorFunctionSpace(mesh,
                                 family,
                                 degree,
                                 constrained_domain=constrained_domain)

        Function.__init__(self, Vv, name=name)
        self.fa = [FunctionAssigner(Vv.sub(i), V) for i, _u in enumerate(u)]
Exemple #25
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)
Exemple #26
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
Exemple #27
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
Exemple #28
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 #29
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)
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 #31
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
Exemple #32
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 #33
0
class SNDiscretization(Discretization):
  def __init__(self, problem, SN_order, verbosity=0):
    super(SNDiscretization, self).__init__(problem, verbosity)

    if self.verb > 1: print0("Obtaining angular discretization data")
    t_ordinates = Timer("Angular discretization data")

    from transport_data import ordinates_ext_module, quadrature_file
    from common import check_sn_order

    self.angular_quad = ordinates_ext_module.OrdinatesData(SN_order, self.mesh.topology().dim(), quadrature_file)
    self.M = self.angular_quad.get_M()
    self.N = check_sn_order(SN_order)

    ord_mat = [self.angular_quad.get_xi().tolist(), self.angular_quad.get_eta().tolist()]
    if self.angular_quad.get_D() == 3: ord_mat.append(self.angular_quad.get_mu().tolist())
    self.ordinates_matrix = as_matrix(ord_mat)

    if self.verb > 2:
      self.angular_quad.print_info()

  def init_solution_spaces(self, group_GS=False):
    if self.verb > 1: print0("Defining function spaces" )

    self.t_spaces.start()

    self.Vpsi1 = VectorFunctionSpace(self.mesh, "CG", self.parameters["p"], self.M)

    if not group_GS:
      self.V = MixedFunctionSpace([self.Vpsi1]*self.G)
    else:
      # Alias the solution space as Vpsi1
      self.V = self.Vpsi1

    self.Vphi1 = FunctionSpace(self.mesh, "CG", self.parameters["p"])

    self.ndof1 = self.Vpsi1.dim()
    self.ndof = self.V.dim()

    if self.verb > 1:
      print0("  {0} direction(s), {1} group(s), {2}".format(self.M, self.G, "group GS" if group_GS else "full system"))
      print0("    NDOF (solution): {0}".format(self.ndof) )
      print0("    NDOF (1gr): {0}".format(self.ndof1) )
      print0("    NDOF (1dir, 1gr): {0}".format(self.Vpsi1.sub(0).dim()) )
      print0("    NDOF (XS): {0}".format(self.ndof0) )
def test_multi_ps_matrix_node_vector_fs(mesh):
    """Tests point source applied to a matrix with given constructor
    PointSource(V, source) and a vector function space when points
    placed at 3 vertices for 1D, 2D and 3D. Global points given to
    constructor from rank 0 processor.

    """

    point = [0.0, 0.5, 1.0]
    rank = MPI.rank(mesh.mpi_comm())
    V = VectorFunctionSpace(mesh, "CG", 1, dim=2)
    u, v = TrialFunction(V), TestFunction(V)
    w = Function(V)
    A = assemble(Constant(0.0)*dot(u, v)*dx)
    dim = mesh.geometry().dim()

    source = []
    point_coords = np.zeros(dim)
    for p in point:
        for i in range(dim):
            point_coords[i - 1] = p
        if rank == 0:
            source.append((Point(point_coords), 10.0))
    ps = PointSource(V, source)
    ps.apply(A)

    # Checks array sums to correct value
    A.get_diagonal(w.vector())
    a_sum = MPI.sum(mesh.mpi_comm(), np.sum(A.array()))
    assert round(a_sum - 2*len(point)*10) == 0

    # Check if coordinates are in portion of mesh and if so check that
    # diagonal components sum to the correct value.
    mesh_coords = V.tabulate_dof_coordinates()
    for p in point:
        for i in range(dim):
            point_coords[i] = p

        j = 0
        for i in range(len(mesh_coords)//(dim)):
            mesh_coords_check = mesh_coords[j:j+dim-1]
            if np.array_equal(point_coords, mesh_coords_check) is True:
                assert np.round(w.vector()[j//(dim)] - 10.0) == 0.0
            j += dim
Exemple #35
0
def save_tstep_solution_h5(tstep, q_, u_, newfolder, tstepfiles, constrained_domain,
                           output_timeseries_as_vector, u_components, 
                           scalar_components, NS_parameters):
    """Store solution on current timestep to XDMF file."""
    timefolder = path.join(newfolder, 'Timeseries')
    if output_timeseries_as_vector:
        # project or store velocity to vector function space
        for comp, tstepfile in tstepfiles.iteritems():
            if comp == "u":
                if not hasattr(tstepfile, 'uv'): # First time around only
                    V = q_['u0'].function_space()
                    Vv = VectorFunctionSpace(V.mesh(), V.ufl_element().family(), V.ufl_element().degree(),
                                            constrained_domain=constrained_domain)
                    tstepfile.uv = Function(Vv)
                    tstepfile.d = dict((ui, Vv.sub(i).dofmap().collapse(Vv.mesh())[1]) 
                                       for i, ui in enumerate(u_components))

                # The short but timeconsuming way:
                #tstepfile.uv.assign(project(u_, Vv))
                
                # Or the faster, but more comprehensive way:
                for ui in u_components:
                    q_[ui].update()    
                    vals = tstepfile.d[ui].values()
                    keys = tstepfile.d[ui].keys()
                    tstepfile.uv.vector()[vals] = q_[ui].vector()[keys]
                tstepfile << (tstepfile.uv, float(tstep))
            
            elif comp in q_:                
                tstepfile << (q_[comp], float(tstep))
            
            else:
                tstepfile << (tstepfile.function, float(tstep))
            
    else:
        for comp, tstepfile in tstepfiles.iteritems():
            tstepfile << (q_[comp], float(tstep))
        
    if MPI.rank(mpi_comm_world()) == 0:
        if not path.exists(path.join(timefolder, "params.dat")):
            f = open(path.join(timefolder, 'params.dat'), 'w')
            cPickle.dump(NS_parameters,  f)
Exemple #36
0
def pot():
    # Define mesh and boundaries.
    mesh = RectangleMesh(0.0, 0.0, 0.4, 0.1, 120, 30, "left/right")

    V = VectorFunctionSpace(mesh, "CG", 2)
    Q = FunctionSpace(mesh, "CG", 1)

    class LeftBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[0] < GMSH_EPS

    left_boundary = LeftBoundary()

    class RightBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[0] > 0.4 - GMSH_EPS

    right_boundary = RightBoundary()

    class LowerBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[1] < GMSH_EPS

    lower_boundary = LowerBoundary()

    class UpperBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[1] > 0.1 - GMSH_EPS

    upper_boundary = UpperBoundary()

    # Boundary conditions for the velocity.
    u_bcs = [
        DirichletBC(V, (0.0, 0.0), lower_boundary),
        DirichletBC(V.sub(1), 0.0, upper_boundary),
        DirichletBC(V.sub(0), 0.0, right_boundary),
        DirichletBC(V.sub(0), 0.0, left_boundary),
    ]
    p_bcs = []
    return mesh, V, Q, u_bcs, p_bcs, [lower_boundary], [right_boundary, left_boundary]
Exemple #37
0
def save_tstep_solution_h5(tstep, q_, u_, newfolder, tstepfiles, constrained_domain,
                           output_timeseries_as_vector, u_components,
                           scalar_components, NS_parameters):
    """Store solution on current timestep to XDMF file."""
    timefolder = path.join(newfolder, 'Timeseries')
    if output_timeseries_as_vector:
        # project or store velocity to vector function space
        for comp, tstepfile in tstepfiles.iteritems():
            if comp == "u":
                V = q_['u0'].function_space()
                # First time around create vector function and assigners
                if not hasattr(tstepfile, 'uv'):
                    Vv = VectorFunctionSpace(V.mesh(), V.ufl_element().family(), V.ufl_element().degree(),
                                            constrained_domain=constrained_domain)
                    tstepfile.uv = Function(Vv)
                    tstepfile.fa = [FunctionAssigner(Vv.sub(i), V) for i, ui in enumerate(u_components)]

                # Assign solution to vector
                for i, ui in enumerate(u_components):
                    tstepfile.fa[i].assign(tstepfile.uv.sub(i), q_[ui])
                    
                # Store solution vector
                tstepfile << (tstepfile.uv, float(tstep))
            
            elif comp in q_:                
                tstepfile << (q_[comp], float(tstep))
            
            else:
                tstepfile << (tstepfile.function, float(tstep))
            
    else:
        for comp, tstepfile in tstepfiles.iteritems():
            tstepfile << (q_[comp], float(tstep))
        
    if MPI.rank(mpi_comm_world()) == 0:
        if not path.exists(path.join(timefolder, "params.dat")):
            f = open(path.join(timefolder, 'params.dat'), 'w')
            cPickle.dump(NS_parameters,  f)
Exemple #38
0
  def init_solution_spaces(self, group_GS=False):
    if self.verb > 1: print0("Defining function spaces" )

    self.t_spaces.start()

    self.Vpsi1 = VectorFunctionSpace(self.mesh, "CG", self.parameters["p"], self.M)

    if not group_GS:
      self.V = MixedFunctionSpace([self.Vpsi1]*self.G)
    else:
      # Alias the solution space as Vpsi1
      self.V = self.Vpsi1

    self.Vphi1 = FunctionSpace(self.mesh, "CG", self.parameters["p"])

    self.ndof1 = self.Vpsi1.dim()
    self.ndof = self.V.dim()

    if self.verb > 1:
      print0("  {0} direction(s), {1} group(s), {2}".format(self.M, self.G, "group GS" if group_GS else "full system"))
      print0("    NDOF (solution): {0}".format(self.ndof) )
      print0("    NDOF (1gr): {0}".format(self.ndof1) )
      print0("    NDOF (1dir, 1gr): {0}".format(self.Vpsi1.sub(0).dim()) )
      print0("    NDOF (XS): {0}".format(self.ndof0) )
    def _evaluateLocalEstimator(cls, mu, w, coeff_field, pde, f, quadrature_degree, epsilon=1e-5):
        """Evaluation of patch local equilibrated estimator."""

        # prepare numerical flux and f
        sigma_mu, f_mu = evaluate_numerical_flux(w, mu, coeff_field, f)

        # ###################
        # ## MIXED PROBLEM ##
        # ###################

        # get setup data for mixed problem
        V = w[mu]._fefunc.function_space()
        mesh = V.mesh()
        mesh.init()
        degree = element_degree(w[mu]._fefunc)

        # data for nodal bases
        V_dm = V.dofmap()
        V_dofs = dict([(i, V_dm.cell_dofs(i)) for i in range(mesh.num_cells())])
        V1 = FunctionSpace(mesh, 'CG', 1)   # V1 is to define nodal base functions
        phi_z = Function(V1)
        phi_coeffs = np.ndarray(V1.dim())
        vertex_dof_map = V1.dofmap().vertex_to_dof_map(mesh)
        # vertex_dof_map = vertex_to_dof_map(V1)
        dof_list = vertex_dof_map.tolist()
        # DG0 localisation
        DG0 = FunctionSpace(mesh, 'DG', 0)
        DG0_dofs = dict([(c.index(),DG0.dofmap().cell_dofs(c.index())[0]) for c in cells(mesh)])
        dg0 = TestFunction(DG0)
        # characteristic function of patch
        xi_z = Function(DG0)
        xi_coeffs = np.ndarray(DG0.dim())
        # mesh data
        h = CellSize(mesh)
        n = FacetNormal(mesh)
        cf = CellFunction('size_t', mesh)
        # setup error estimator vector
        eq_est = np.zeros(DG0.dim())

        # setup global equilibrated flux vector
        DG = VectorFunctionSpace(mesh, "DG", degree)
        DG_dofmap = DG.dofmap()

        # define form functions
        tau = TrialFunction(DG)
        v = TestFunction(DG)

        # define global tau
        tau_global = Function(DG)
        tau_global.vector()[:] = 0.0

        # iterate vertices
        for vertex in vertices(mesh):
            # get patch cell indices
            vid = vertex.index()
            patch_cid, FF_inner, FF_boundary = get_vertex_patch(vid, mesh, layers=1)

            # set nodal base function
            phi_coeffs[:] = 0
            phi_coeffs[dof_list.index(vid)] = 1
            phi_z.vector()[:] = phi_coeffs

            # set characteristic function and mark patch
            cf.set_all(0)
            xi_coeffs[:] = 0
            for cid in patch_cid:
                xi_coeffs[DG0_dofs[int(cid)]] = 1
                cf[int(cid)] = 1
            xi_z.vector()[:] = xi_coeffs

            # determine local dofs
            lDG_cell_dofs = dict([(cid, DG_dofmap.cell_dofs(cid)) for cid in patch_cid])
            lDG_dofs = [cd.tolist() for cd in lDG_cell_dofs.values()]
            lDG_dofs = list(iter.chain(*lDG_dofs))

            # print "\nlocal DG subspace has dimension", len(lDG_dofs), "degree", degree, "cells", len(patch_cid), patch_cid
            # print "local DG_cell_dofs", lDG_cell_dofs
            # print "local DG_dofs", lDG_dofs

            # create patch measures
            dx = Measure('dx')[cf]
            dS = Measure('dS')[FF_inner]

            # define forms
            alpha = Constant(1 / epsilon) / h
            a = inner(tau,v) * phi_z * dx(1) + alpha * div(tau) * div(v) * dx(1) + avg(alpha) * jump(tau,n) * jump(v,n) * dS(1)\
                + avg(alpha) * jump(xi_z * tau,n) * jump(v,n) * dS(2)
            L = -alpha * (div(sigma_mu) + f) * div(v) * phi_z * dx(1)\
                - avg(alpha) * jump(sigma_mu,n) * jump(v,n) * avg(phi_z)*dS(1)

    #        print "L2 f + div(sigma)", assemble((f + div(sigma)) * (f + div(sigma)) * dx(0))

            # assemble forms
            lhs = assemble(a, form_compiler_parameters={'quadrature_degree': quadrature_degree})
            rhs = assemble(L, form_compiler_parameters={'quadrature_degree': quadrature_degree})

            # convert DOLFIN representation to scipy sparse arrays
            rows, cols, values = lhs.data()
            lhsA = sps.csr_matrix((values, cols, rows)).tocoo()

            # slice sparse matrix and solve linear problem
            lhsA = coo_submatrix_pull(lhsA, lDG_dofs, lDG_dofs)
            lx = spsolve(lhsA, rhs.array()[lDG_dofs])
            # print ">>> local solution lx", type(lx), lx
            local_tau = Function(DG)
            local_tau.vector()[lDG_dofs] = lx
            # print "div(tau)", assemble(inner(div(local_tau),div(local_tau))*dx(1))

            # add up local fluxes
            tau_global.vector()[lDG_dofs] += lx

        # evaluate estimator
        # maybe TODO: re-define measure dx
        eq_est = assemble( inner(tau_global, tau_global) * dg0 * (dx(0)+dx(1)),\
                           form_compiler_parameters={'quadrature_degree': quadrature_degree})

        # reorder according to cell ids
        eq_est = eq_est[DG0_dofs.values()].array()
        global_est = np.sqrt(np.sum(eq_est))
        # eq_est_global = assemble( inner(tau_global, tau_global) * (dx(0)+dx(1)), form_compiler_parameters={'quadrature_degree': quadrature_degree} )
        # global_est2 = np.sqrt(np.sum(eq_est_global))
        return global_est, FlatVector(np.sqrt(eq_est))#, tau_global
Exemple #40
0
def karman():
    #mesh = Mesh('../meshes/2d/karman.xml')
    mesh = Mesh('../meshes/2d/karman-coarse2.xml')

    V = VectorFunctionSpace(mesh, 'CG', 2)
    Q = FunctionSpace(mesh, 'CG', 1)

    # Define mesh and boundaries.
    class LeftBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[0] < DOLFIN_EPS
    left_boundary = LeftBoundary()

    class RightBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[0] > 2.5 - DOLFIN_EPS

    class LowerBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[1] < DOLFIN_EPS
    lower_boundary = LowerBoundary()

    class UpperBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[1] > 0.4-DOLFIN_EPS
    upper_boundary = UpperBoundary()

    class ObstacleBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary \
                and x[0] > DOLFIN_EPS and x[0] < 2.5-DOLFIN_EPS \
                and x[1] > DOLFIN_EPS and x[1] < 0.4-DOLFIN_EPS
    obstacle_boundary = ObstacleBoundary()

    # Boundary conditions for the velocity.
    # Proper inflow and outflow conditions are a matter of voodoo. See for
    # example Gresho/Sani, or
    #
    #     Boundary conditions for open boundaries
    #     for the incompressible Navier-Stokes equation;
    #     B.C.V. Johansson;
    #     J. Comp. Phys. 105, 233-251 (1993).
    #
    # The latter in particularly suggest for the inflow:
    #
    #     u = u0,
    #     d^r v / dx^r = v_r,
    #     div(u) = 0,
    #
    # where u and v are the velocities in normal and tangential directions,
    # respectively, and r\in{0,1,2}. The setting r=0 essentially means to set
    # (u,v) statically at the left boundary, r=1 means to set u and control
    # dv/dn, which is what we do here (namely implicitly by dv/dn=0).
    # At the outflow,
    #
    #     d^j u / dx^j = 0,
    #     d^q v / dx^q = 0,
    #     p = p0,
    #
    # is suggested with j=q+1. Choosing q=0, j=1 means setting the tangential
    # component of the outflow to 0, and letting the normal component du/dn=0
    # (again, this is achieved implicitly by the weak formulation).
    #
    inflow = Expression('100*x[1]*(0.4-x[1])', degree=2)
    u_bcs = [DirichletBC(V, (0.0, 0.0), upper_boundary),
             DirichletBC(V, (0.0, 0.0), lower_boundary),
             DirichletBC(V, (0.0, 0.0), obstacle_boundary),
             DirichletBC(V.sub(0), inflow, left_boundary),
             #DirichletBC(V.sub(1), 0.0, right_boundary),
             ]
    dudt_bcs = [DirichletBC(V, (0.0, 0.0), upper_boundary),
                DirichletBC(V, (0.0, 0.0), lower_boundary),
                DirichletBC(V, (0.0, 0.0), obstacle_boundary),
                DirichletBC(V.sub(0), 0.0, left_boundary),
                #DirichletBC(V.sub(1), 0.0, right_boundary),
                ]
    # If there is a penetration boundary (i.e., n.u!=0), then the pressure must
    # be set at the boundary to make sure that the Navier-Stokes problem
    # remains consistent.
    # It is not quite clear now where exactly to set the pressure to 0. Inlet,
    # outlet, some other place? The PPE system is consistent in all cases.
    # TODO find out more about it
    #p_bcs = [DirichletBC(Q, 0.0, right_boundary)]
    p_bcs = []
    return mesh, V, Q, u_bcs, dudt_bcs, p_bcs
Exemple #41
0
def peter():
    base = '../meshes/2d/peter'
    #base = '../meshes/2d/peter-fine'
    mesh = Mesh(base + '.xml')

    subdomains = MeshFunction('size_t', mesh, base+'_physical_region.xml')

    workpiece_index = 3
    subdomain_materials = {1: 'SiC',
                           2: 'carbon steel',
                           3: 'GaAs (liquid)'}

    submesh_workpiece = SubMesh(mesh, subdomains, workpiece_index)
    W = VectorFunctionSpace(submesh_workpiece, 'CG', 2)
    Q = FunctionSpace(submesh_workpiece, 'CG', 2)

    # Define melt boundaries.
    class LeftBoundary(SubDomain):
        def inside(self, x, on_boundary):
            # Be especially careful in the corners when defining the r=0 axis:
            # For the PPE to be consistent, we need to have n.u=0 *everywhere*
            # on the non-(r=0) boundaries.
            return on_boundary \
                and x[0] < GMSH_EPS \
                and 0.005+GMSH_EPS < x[1] and x[1] < 0.050-GMSH_EPS

    class SurfaceBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary \
                and 0.055-GMSH_EPS < x[1] \
                and 0.030-GMSH_EPS < x[0] and x[0] < 0.075+GMSH_EPS

    class StampBoundary(SubDomain):
        def inside(self, x, on_boundary):
            # Well well. If we don't include the endpoints here, the PPE turns
            # out inconsistent. This is weird since the endpoints should be
            # picked up by RightBoundary and StampBoundary.
            return on_boundary \
                and 0.050-GMSH_EPS < x[1] and x[1] < 0.055+GMSH_EPS \
                and x[0] < 0.030+GMSH_EPS

    class LowerBoundary(SubDomain):
        def inside(self, x, on_boundary):
            # Danger, danger.
            # If the rightmost point (0.075, 0.010) is excluded, the PPE will
            # end up inconsistent.
            # This is actually weird since it should be picked up by
            # RightBoundary.
            return on_boundary \
                and (x[1] < 0.005+GMSH_EPS
                     or (x[0] > 0.070-GMSH_EPS and x[1] < 0.010+GMSH_EPS)
                     )

    class RightBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary \
                and x[0] > 0.075-GMSH_EPS

    left_boundary = LeftBoundary()
    lower_boundary = LowerBoundary()
    right_boundary = RightBoundary()
    surface_boundary = SurfaceBoundary()
    stamp_boundary = StampBoundary()

    # Define workpiece boundaries.
    wp_boundaries = FacetFunction('size_t', submesh_workpiece)
    wp_boundaries.set_all(0)
    left_boundary.mark(wp_boundaries, 1)
    lower_boundary.mark(wp_boundaries, 2)
    right_boundary.mark(wp_boundaries, 3)
    surface_boundary.mark(wp_boundaries, 4)
    stamp_boundary.mark(wp_boundaries, 5)

    # For local use only:
    wp_boundary_indices = {'left': 1,
                           'lower': 2,
                           'right': 3,
                           'surface': 4,
                           'stamp': 5}

    # Boundary conditions for the velocity.
    u_bcs = [DirichletBC(W, (0.0, 0.0), stamp_boundary),
             DirichletBC(W, (0.0, 0.0), right_boundary),
             DirichletBC(W, (0.0, 0.0), lower_boundary),
             DirichletBC(W.sub(0), 0.0, left_boundary),
             DirichletBC(W.sub(1), 0.0, surface_boundary),
             ]
    p_bcs = []

    # Boundary conditions for the heat equation.
    # Dirichlet
    theta_bcs_d = []
    # Neumann
    theta_bcs_n = {}
    # Robin, i.e.,
    #
    #    -dtheta/dn = alpha (theta - theta0)
    #
    # (with alpha>0 to preserve coercivity of the scheme).
    #
    theta_bcs_r = {
        wp_boundary_indices['stamp']: (100.0, 1500.0),
        wp_boundary_indices['surface']: (100.0, 1550.0),
        wp_boundary_indices['right']: (300.0, Expression('200*x[0] + 1600', degree=1)),
        wp_boundary_indices['lower']: (300.0, Expression('-1200*x[1] + 1614', degree=1)),
        }
    return mesh, subdomains, subdomain_materials, workpiece_index, \
        wp_boundaries, W, u_bcs, p_bcs, \
        Q, theta_bcs_d, theta_bcs_n, theta_bcs_r
Exemple #42
0
def crucible_without_coils():
    base = '../meshes/2d/crucible'
    mesh = Mesh(base + '.xml')
    subdomains = MeshFunction('size_t', mesh, base+'_physical_region.xml')
    workpiece_index = 4
    subdomain_materials = {1: 'SiC',
                           2: 'boron trioxide',
                           3: 'GaAs (solid)',
                           4: 'GaAs (liquid)'}

    submesh_workpiece = SubMesh(mesh, subdomains, workpiece_index)
    V = VectorFunctionSpace(submesh_workpiece, 'CG', 2)
    P = FunctionSpace(submesh_workpiece, 'CG', 1)

    Q = FunctionSpace(mesh, 'CG', 2)

    # Define mesh and boundaries.
    class LeftBoundary(SubDomain):
        def inside(self, x, on_boundary):
            # Be especially careful in the corners when defining the r=0 axis:
            # For the PPE to be consistent, we need to have n.u=0 *everywhere*
            # on the non-r=0 boundaries.
            return on_boundary \
                and x[0] < GMSH_EPS and 0.366 + GMSH_EPS < x[1] \
                and x[1] < 0.411 - GMSH_EPS
    left_boundary = LeftBoundary()

    class SurfaceBoundary(SubDomain):
        def inside(self, x, on_boundary):
            # Make sure to catch the entire surface, so don't be too
            # restrictive about x[0].
            return on_boundary \
                and x[1] > 0.38-GMSH_EPS \
                and x[0] > 0.04-GMSH_EPS and x[0] < 0.07+GMSH_EPS

    class OtherBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary \
                and not left_boundary.inside(x, on_boundary)  # \
                #and not surface_boundary.inside(x, on_boundary)
    other_boundary = OtherBoundary()

    # Boundary conditions for the velocity.
    u_bcs = [DirichletBC(V, (0.0, 0.0), other_boundary),
             DirichletBC(V.sub(0), 0.0, left_boundary),
             #DirichletBC(V.sub(1), 0.0, surface_boundary),
             ]
    #u_bcs = [DirichletBC(V, (0.0, 0.0), 'on_boundary')]
    p_bcs = []

    class HeaterBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary \
                and ((x[1] < 0.38 and GMSH_EPS < x[0]
                      and x[0] < 0.075+GMSH_EPS)
                     or x[0] < GMSH_EPS and x[1] < 0.365+GMSH_EPS)
    heater_boundary = HeaterBoundary()

    background_temp = 1400.0

    # Heat with 1580K at r=0, 1590K at r=0.075.
    heater_bcs = [(heater_boundary, '1580.0 + 133.0 * x[0]')]

    return mesh, subdomains, subdomain_materials, workpiece_index, \
        V, Q, P, u_bcs, p_bcs, background_temp, heater_bcs