Пример #1
0
def test_additivity(mode):
    mesh = dolfinx.UnitSquareMesh(MPI.COMM_WORLD, 12, 12, ghost_mode=mode)
    V = dolfinx.FunctionSpace(mesh, ("CG", 1))

    f1 = dolfinx.Function(V)
    f2 = dolfinx.Function(V)
    f3 = dolfinx.Function(V)
    with f1.vector.localForm() as f1_local:
        f1_local.set(1.0)
    with f2.vector.localForm() as f2_local:
        f2_local.set(2.0)
    with f3.vector.localForm() as f3_local:
        f3_local.set(3.0)
    j1 = ufl.inner(f1, f1) * ufl.dx(mesh)
    j2 = ufl.inner(f2, f2) * ufl.ds(mesh)
    j3 = ufl.inner(ufl.avg(f3), ufl.avg(f3)) * ufl.dS(mesh)

    # Assemble each scalar form separately
    J1 = mesh.mpi_comm().allreduce(dolfinx.fem.assemble_scalar(j1), op=MPI.SUM)
    J2 = mesh.mpi_comm().allreduce(dolfinx.fem.assemble_scalar(j2), op=MPI.SUM)
    J3 = mesh.mpi_comm().allreduce(dolfinx.fem.assemble_scalar(j3), op=MPI.SUM)

    # Sum forms and assemble the result
    J12 = mesh.mpi_comm().allreduce(dolfinx.fem.assemble_scalar(j1 + j2), op=MPI.SUM)
    J13 = mesh.mpi_comm().allreduce(dolfinx.fem.assemble_scalar(j1 + j3), op=MPI.SUM)
    J23 = mesh.mpi_comm().allreduce(dolfinx.fem.assemble_scalar(j2 + j3), op=MPI.SUM)
    J123 = mesh.mpi_comm().allreduce(dolfinx.fem.assemble_scalar(j1 + j2 + j3), op=MPI.SUM)

    # Compare assembled values
    assert (J1 + J2) == pytest.approx(J12)
    assert (J1 + J3) == pytest.approx(J13)
    assert (J2 + J3) == pytest.approx(J23)
    assert (J1 + J2 + J3) == pytest.approx(J123)
Пример #2
0
def test_additivity(mode):
    mesh = create_unit_square(MPI.COMM_WORLD, 12, 12, ghost_mode=mode)
    V = FunctionSpace(mesh, ("Lagrange", 1))

    f1 = Function(V)
    f2 = Function(V)
    f3 = Function(V)
    f1.x.array[:] = 1.0
    f2.x.array[:] = 2.0
    f3.x.array[:] = 3.0
    j1 = ufl.inner(f1, f1) * ufl.dx(mesh)
    j2 = ufl.inner(f2, f2) * ufl.ds(mesh)
    j3 = ufl.inner(ufl.avg(f3), ufl.avg(f3)) * ufl.dS(mesh)

    # Assemble each scalar form separately
    J1 = mesh.comm.allreduce(assemble_scalar(form(j1)), op=MPI.SUM)
    J2 = mesh.comm.allreduce(assemble_scalar(form(j2)), op=MPI.SUM)
    J3 = mesh.comm.allreduce(assemble_scalar(form(j3)), op=MPI.SUM)

    # Sum forms and assemble the result
    J12 = mesh.comm.allreduce(assemble_scalar(form(j1 + j2)), op=MPI.SUM)
    J13 = mesh.comm.allreduce(assemble_scalar(form(j1 + j3)), op=MPI.SUM)
    J23 = mesh.comm.allreduce(assemble_scalar(form(j2 + j3)), op=MPI.SUM)
    J123 = mesh.comm.allreduce(assemble_scalar(form(j1 + j2 + j3)), op=MPI.SUM)

    # Compare assembled values
    assert (J1 + J2) == pytest.approx(J12)
    assert (J1 + J3) == pytest.approx(J13)
    assert (J2 + J3) == pytest.approx(J23)
    assert (J1 + J2 + J3) == pytest.approx(J123)
Пример #3
0
    def error_indicators(self):
        """
        Generate and return linear form defining error indicators
        """
        # Extract these to increase readability
        R_T = self._R_T
        R_dT = self._R_dT
        z = self._Ez_h
        z_h = self._z_h

        # Define linear form for computing error indicators
        v = self.module.TestFunction(self._DG0)
        eta_T = (v * inner(R_T, z - z_h) * dx(self.domain) +
                 avg(v)*(inner(R_dT('+'), (z - z_h)('+')) +
                         inner(R_dT('-'), (z - z_h)('-'))) * dS(self.domain) +
                 v * inner(R_dT, z - z_h) * ds(self.domain))

        return eta_T
Пример #4
0
    def facet_residual(self):
        """
        Generate and return (bilinear, linear) forms defining linear
        variational problem for the strong facet residual(s)
        """
        # Define trial and test functions for the facet residuals on
        # discontinuous version of primal trial space
        R_e = self.module.TrialFunction(self._dV)
        v = self.module.TestFunction(self._dV)

        # Extract original test function in the weak residual
        v_h = self.weak_residual.arguments()[0]

        # Define forms defining linear variational problem for facet
        # residual
        v_e = self._b_e * v
        a_R_dT = ((inner(v_e('+'), R_e('+')) + inner(v_e('-'), R_e('-'))) *
                  dS(self.domain) + inner(v_e, R_e) * ds(self.domain))
        L_R_dT = (replace(self.weak_residual, {v_h: v_e}) -
                  inner(v_e, self._R_T) * dx(self.domain))

        return (a_R_dT, L_R_dT)
Пример #5
0
    def facet_residual(self):
        """
        Generate and return (bilinear, linear) forms defining linear
        variational problem for the strong facet residual(s)
        """
        # Define trial and test functions for the facet residuals on
        # discontinuous version of primal trial space
        R_e = self.module.TrialFunction(self._dV)
        v = self.module.TestFunction(self._dV)

        # Extract original test function in the weak residual
        v_h = self.weak_residual.arguments()[0]

        # Define forms defining linear variational problem for facet
        # residual
        v_e = self._b_e*v
        a_R_dT = ((inner(v_e('+'), R_e('+')) + inner(v_e('-'), R_e('-')))*dS(self.domain)
                  + inner(v_e, R_e)*ds(self.domain))
        L_R_dT = (replace(self.weak_residual, {v_h: v_e})
                  - inner(v_e, self._R_T)*dx(self.domain))

        return (a_R_dT, L_R_dT)
Пример #6
0
def test_manufactured_poisson_dg(degree, filename, datadir):
    """ Manufactured Poisson problem, solving u = x[component]**n, where n is the
    degree of the Lagrange function space.

    """
    with XDMFFile(MPI.COMM_WORLD,
                  os.path.join(datadir, filename),
                  "r",
                  encoding=XDMFFile.Encoding.ASCII) as xdmf:
        mesh = xdmf.read_mesh(name="Grid")

    V = FunctionSpace(mesh, ("DG", degree))
    u, v = TrialFunction(V), TestFunction(V)

    # Exact solution
    x = SpatialCoordinate(mesh)
    u_exact = x[1]**degree

    # Coefficient
    k = Function(V)
    k.vector.set(2.0)
    k.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                         mode=PETSc.ScatterMode.FORWARD)

    # Source term
    f = -div(k * grad(u_exact))

    # Mesh normals and element size
    n = FacetNormal(mesh)
    h = CellDiameter(mesh)
    h_avg = (h("+") + h("-")) / 2.0

    # Penalty parameter
    alpha = 32

    dx_ = dx(metadata={"quadrature_degree": -1})
    ds_ = ds(metadata={"quadrature_degree": -1})
    dS_ = dS(metadata={"quadrature_degree": -1})

    a = inner(k * grad(u), grad(v)) * dx_ \
        - k("+") * inner(avg(grad(u)), jump(v, n)) * dS_ \
        - k("+") * inner(jump(u, n), avg(grad(v))) * dS_ \
        + k("+") * (alpha / h_avg) * inner(jump(u, n), jump(v, n)) * dS_ \
        - inner(k * grad(u), v * n) * ds_ \
        - inner(u * n, k * grad(v)) * ds_ \
        + (alpha / h) * inner(k * u, v) * ds_
    L = inner(f, v) * dx_ - inner(k * u_exact * n, grad(v)) * ds_ \
        + (alpha / h) * inner(k * u_exact, v) * ds_

    for integral in a.integrals():
        integral.metadata(
        )["quadrature_degree"] = ufl.algorithms.estimate_total_polynomial_degree(
            a)
    for integral in L.integrals():
        integral.metadata(
        )["quadrature_degree"] = ufl.algorithms.estimate_total_polynomial_degree(
            L)

    b = assemble_vector(L)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)

    A = assemble_matrix(a, [])
    A.assemble()

    # Create LU linear solver
    solver = PETSc.KSP().create(MPI.COMM_WORLD)
    solver.setType(PETSc.KSP.Type.PREONLY)
    solver.getPC().setType(PETSc.PC.Type.LU)
    solver.setOperators(A)

    # Solve
    uh = Function(V)
    solver.solve(b, uh.vector)
    uh.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                          mode=PETSc.ScatterMode.FORWARD)
    error = mesh.mpi_comm().allreduce(assemble_scalar((u_exact - uh)**2 * dx),
                                      op=MPI.SUM)
    assert np.absolute(error) < 1.0e-14
def run_dg_test(mesh, V, degree):
    """ Manufactured Poisson problem, solving u = x[component]**n, where n is the
    degree of the Lagrange function space.
    """
    u, v = TrialFunction(V), TestFunction(V)

    # Exact solution
    x = SpatialCoordinate(mesh)
    u_exact = x[1]**degree

    # Coefficient
    k = Function(V)
    k.vector.set(2.0)
    k.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                         mode=PETSc.ScatterMode.FORWARD)

    # Source term
    f = -div(k * grad(u_exact))

    # Mesh normals and element size
    n = FacetNormal(mesh)
    h = CellDiameter(mesh)
    h_avg = (h("+") + h("-")) / 2.0

    # Penalty parameter
    alpha = 32

    dx_ = dx(metadata={"quadrature_degree": -1})
    ds_ = ds(metadata={"quadrature_degree": -1})
    dS_ = dS(metadata={"quadrature_degree": -1})

    with common.Timer("Compile forms"):
        a = inner(k * grad(u), grad(v)) * dx_ \
            - k("+") * inner(avg(grad(u)), jump(v, n)) * dS_ \
            - k("+") * inner(jump(u, n), avg(grad(v))) * dS_ \
            + k("+") * (alpha / h_avg) * inner(jump(u, n), jump(v, n)) * dS_ \
            - inner(k * grad(u), v * n) * ds_ \
            - inner(u * n, k * grad(v)) * ds_ \
            + (alpha / h) * inner(k * u, v) * ds_
        L = inner(f, v) * dx_ - inner(k * u_exact * n, grad(v)) * ds_ \
            + (alpha / h) * inner(k * u_exact, v) * ds_

    for integral in a.integrals():
        integral.metadata(
        )["quadrature_degree"] = ufl.algorithms.estimate_total_polynomial_degree(
            a)
    for integral in L.integrals():
        integral.metadata(
        )["quadrature_degree"] = ufl.algorithms.estimate_total_polynomial_degree(
            L)

    with common.Timer("Assemble vector"):
        b = assemble_vector(L)
        b.ghostUpdate(addv=PETSc.InsertMode.ADD,
                      mode=PETSc.ScatterMode.REVERSE)

    with common.Timer("Assemble matrix"):
        A = assemble_matrix(a, [])
        A.assemble()

    with common.Timer("Solve"):
        # Create LU linear solver
        solver = PETSc.KSP().create(MPI.COMM_WORLD)
        solver.setType(PETSc.KSP.Type.PREONLY)
        solver.getPC().setType(PETSc.PC.Type.LU)
        solver.setOperators(A)

        # Solve
        uh = Function(V)
        solver.solve(b, uh.vector)
        uh.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                              mode=PETSc.ScatterMode.FORWARD)

    with common.Timer("Error functional compile"):
        # Calculate error
        M = (u_exact - uh)**2 * dx
        M = fem.Form(M)

    with common.Timer("Error assembly"):
        error = mesh.mpi_comm().allreduce(assemble_scalar(M), op=MPI.SUM)

    common.list_timings(MPI.COMM_WORLD, [common.TimingType.wall])
    assert np.absolute(error) < 1.0e-14
Пример #8
0
# Copyright (C) 2008 Anders Logg and Kristian B. Oelgaard
#
# This file is part of UFL.
#
# UFL is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# UFL is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with UFL. If not, see <http://www.gnu.org/licenses/>.
#
# This simple example illustrates how forms can be defined on different sub domains.
# It is supported for all three integral types.
from ufl import (FiniteElement, TestFunction, TrialFunction, ds, dS, dx,
                 tetrahedron)

element = FiniteElement("CG", tetrahedron, 1)

v = TestFunction(element)
u = TrialFunction(element)

a = v * u * dx(0) + 10.0 * v * u * dx(1) + v * u * ds(0) + 2.0 * v * u * ds(1)\
    + v('+') * u('+') * dS(0) + 4.3 * v('+') * u('+') * dS(1)