Exemple #1
0
def coarsen_form(form):
    """Return a coarse mesh version of a form

    :arg form: The :class:`~ufl.classes.Form` to coarsen.

    This maps over the form and replaces coefficients and arguments
    with their coarse mesh equivalents."""
    if form is None:
        return None
    assert isinstance(form, ufl.Form), \
        "Don't know how to coarsen %r" % type(form)

    mapper = CoarsenIntegrand()
    forms = []
    # Ugh, visitors can't deal with measures (they're not actual
    # Exprs) so we need to map the transformer over the integrand and
    # reconstruct the integral by building the measure by hand.
    for it in form.integrals():
        integrand = map_expr_dag(mapper, it.integrand())
        mesh = it.ufl_domain()
        hierarchy, level = utils.get_level(mesh)
        new_mesh = hierarchy[level - 1]

        measure = ufl.Measure(it.integral_type(),
                              domain=new_mesh,
                              subdomain_id=it.subdomain_id(),
                              subdomain_data=it.subdomain_data(),
                              metadata=it.metadata())

        forms.append(integrand * measure)
    return reduce(add, forms)
Exemple #2
0
def test_interpolate_subset(order, dim, affine):
    if dim == 2:
        ct = CellType.triangle if affine else CellType.quadrilateral
        mesh = create_unit_square(MPI.COMM_WORLD, 3, 4, ct)
    elif dim == 3:
        ct = CellType.tetrahedron if affine else CellType.hexahedron
        mesh = create_unit_cube(MPI.COMM_WORLD, 3, 2, 2, ct)

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

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

    x = ufl.SpatialCoordinate(mesh)
    f = x[1]**order
    expr = Expression(f, V.element.interpolation_points)
    u.interpolate(expr, cells_local)
    mt = MeshTags(mesh, mesh.topology.dim, cells_local,
                  np.ones(cells_local.size, dtype=np.int32))
    dx = ufl.Measure("dx", domain=mesh, subdomain_data=mt)
    assert np.isclose(
        np.abs(form(assemble_scalar(form(ufl.inner(u - f, u - f) * dx(1))))),
        0)
    integral = mesh.comm.allreduce(assemble_scalar(form(u * dx)), op=MPI.SUM)
    assert np.isclose(integral, 1 / (order + 1) * 0.5**(order + 1), 0)
Exemple #3
0
def test_assembly_dx_domains(mode):
    mesh = dolfinx.generation.UnitSquareMesh(MPI.COMM_WORLD,
                                             10,
                                             10,
                                             ghost_mode=mode)
    V = dolfinx.FunctionSpace(mesh, ("CG", 1))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)

    # Prepare a marking structures
    # indices cover all cells
    # values are [1, 2, 3, 3, ...]
    cell_map = mesh.topology.index_map(mesh.topology.dim)
    num_cells = cell_map.size_local + cell_map.num_ghosts
    indices = numpy.arange(0, num_cells)
    values = numpy.full(indices.shape, 3, dtype=numpy.intc)
    values[0] = 1
    values[1] = 2
    marker = dolfinx.mesh.MeshTags(mesh, mesh.topology.dim, indices, values)
    dx = ufl.Measure('dx', subdomain_data=marker, domain=mesh)
    w = dolfinx.Function(V)
    with w.vector.localForm() as w_local:
        w_local.set(0.5)

    bc = dolfinx.fem.DirichletBC(dolfinx.Function(V), range(30))

    # Assemble matrix
    a = w * ufl.inner(u, v) * (dx(1) + dx(2) + dx(3))
    A = dolfinx.fem.assemble_matrix(a)
    A.assemble()
    a2 = w * ufl.inner(u, v) * dx
    A2 = dolfinx.fem.assemble_matrix(a2)
    A2.assemble()
    assert (A - A2).norm() < 1.0e-12

    # Assemble vector
    L = ufl.inner(w, v) * (dx(1) + dx(2) + dx(3))
    b = dolfinx.fem.assemble_vector(L)

    dolfinx.fem.apply_lifting(b, [a], [[bc]])
    b.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES,
                  mode=PETSc.ScatterMode.REVERSE)
    dolfinx.fem.set_bc(b, [bc])

    L2 = ufl.inner(w, v) * dx
    b2 = dolfinx.fem.assemble_vector(L2)
    dolfinx.fem.apply_lifting(b2, [a], [[bc]])
    b2.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES,
                   mode=PETSc.ScatterMode.REVERSE)
    dolfinx.fem.set_bc(b2, [bc])
    assert (b - b2).norm() < 1.0e-12

    # Assemble scalar
    L = w * (dx(1) + dx(2) + dx(3))
    s = dolfinx.fem.assemble_scalar(L)
    s = mesh.mpi_comm().allreduce(s, op=MPI.SUM)
    assert s == pytest.approx(0.5, 1.0e-12)
    L2 = w * dx
    s2 = dolfinx.fem.assemble_scalar(L2)
    s2 = mesh.mpi_comm().allreduce(s2, op=MPI.SUM)
    assert s == pytest.approx(s2, 1.0e-12)
Exemple #4
0
def test_assembly_dx_domains(mesh):
    V = dolfinx.FunctionSpace(mesh, ("CG", 1))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)

    # Prepare a marking structures
    # indices cover all cells
    # values are [1, 2, 3, 3, ...]
    imap = mesh.topology.index_map(mesh.topology.dim)
    num_cells = imap.size_local + imap.num_ghosts
    indices = numpy.arange(0, num_cells)
    values = numpy.full(indices.shape, 3, dtype=numpy.intc)
    values[0] = 1
    values[1] = 2
    marker = dolfinx.mesh.MeshTags(mesh, mesh.topology.dim, indices, values)
    dx = ufl.Measure('dx', subdomain_data=marker, domain=mesh)
    w = dolfinx.Function(V)
    with w.vector.localForm() as w_local:
        w_local.set(0.5)

    # Assemble matrix

    a = w * ufl.inner(u, v) * (dx(1) + dx(2) + dx(3))

    A = dolfinx.fem.assemble_matrix(a)
    A.assemble()
    norm1 = A.norm()

    a2 = w * ufl.inner(u, v) * dx

    A2 = dolfinx.fem.assemble_matrix(a2)
    A2.assemble()
    norm2 = A2.norm()

    assert norm1 == pytest.approx(norm2, 1.0e-12)

    # Assemble vector

    L = ufl.inner(w, v) * (dx(1) + dx(2) + dx(3))
    b = dolfinx.fem.assemble_vector(L)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)

    L2 = ufl.inner(w, v) * dx
    b2 = dolfinx.fem.assemble_vector(L2)
    b2.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)

    assert b.norm() == pytest.approx(b2.norm(), 1.0e-12)

    # Assemble scalar

    L = w * (dx(1) + dx(2) + dx(3))
    s = dolfinx.fem.assemble_scalar(L)
    s = mesh.mpi_comm().allreduce(s, op=MPI.SUM)

    L2 = w * dx
    s2 = dolfinx.fem.assemble_scalar(L2)
    s2 = mesh.mpi_comm().allreduce(s2, op=MPI.SUM)
    assert (s == pytest.approx(s2, 1.0e-12)
            and 0.5 == pytest.approx(s, 1.0e-12))
Exemple #5
0
def test_assembly_ds_domains(mesh):
    V = dolfinx.FunctionSpace(mesh, ("CG", 1))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)

    marker = dolfinx.MeshFunction("size_t", mesh, mesh.topology.dim - 1, 0)

    def bottom(x):
        return numpy.isclose(x[1], 0.0)

    def top(x):
        return numpy.isclose(x[1], 1.0)

    def left(x):
        return numpy.isclose(x[0], 0.0)

    def right(x):
        return numpy.isclose(x[0], 1.0)

    marker.mark(bottom, 111)
    marker.mark(top, 222)
    marker.mark(left, 333)
    marker.mark(right, 444)

    ds = ufl.Measure('ds', subdomain_data=marker, domain=mesh)

    w = dolfinx.Function(V)
    with w.vector.localForm() as w_local:
        w_local.set(0.5)

    # Assemble matrix
    a = w * ufl.inner(u, v) * (ds(111) + ds(222) + ds(333) + ds(444))
    A = dolfinx.fem.assemble_matrix(a)
    A.assemble()
    norm1 = A.norm()
    a2 = w * ufl.inner(u, v) * ds
    A2 = dolfinx.fem.assemble_matrix(a2)
    A2.assemble()
    norm2 = A2.norm()
    assert norm1 == pytest.approx(norm2, 1.0e-12)

    # Assemble vector
    L = ufl.inner(w, v) * (ds(111) + ds(222) + ds(333) + ds(444))
    b = dolfinx.fem.assemble_vector(L)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    L2 = ufl.inner(w, v) * ds
    b2 = dolfinx.fem.assemble_vector(L2)
    b2.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    assert b.norm() == pytest.approx(b2.norm(), 1.0e-12)

    # Assemble scalar
    L = w * (ds(111) + ds(222) + ds(333) + ds(444))
    s = dolfinx.fem.assemble_scalar(L)
    s = dolfinx.MPI.sum(mesh.mpi_comm(), s)
    L2 = w * ds
    s2 = dolfinx.fem.assemble_scalar(L2)
    s2 = dolfinx.MPI.sum(mesh.mpi_comm(), s2)
    assert (s == pytest.approx(s2, 1.0e-12)
            and 2.0 == pytest.approx(s, 1.0e-12))
Exemple #6
0
def test_assembly_dx_domains(mode, meshtags_factory):
    mesh = create_unit_square(MPI.COMM_WORLD, 10, 10, ghost_mode=mode)
    V = FunctionSpace(mesh, ("Lagrange", 1))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)

    # Prepare a marking structures
    # indices cover all cells
    # values are [1, 2, 3, 3, ...]
    cell_map = mesh.topology.index_map(mesh.topology.dim)
    num_cells = cell_map.size_local + cell_map.num_ghosts
    indices = np.arange(0, num_cells)
    values = np.full(indices.shape, 3, dtype=np.intc)
    values[0] = 1
    values[1] = 2
    marker = meshtags_factory(mesh, mesh.topology.dim, indices, values)
    dx = ufl.Measure('dx', subdomain_data=marker, domain=mesh)
    w = Function(V)
    w.x.array[:] = 0.5

    # Assemble matrix
    a = form(w * ufl.inner(u, v) * (dx(1) + dx(2) + dx(3)))
    A = assemble_matrix(a)
    A.assemble()
    a2 = form(w * ufl.inner(u, v) * dx)
    A2 = assemble_matrix(a2)
    A2.assemble()
    assert (A - A2).norm() < 1.0e-12

    bc = dirichletbc(Function(V), range(30))

    # Assemble vector
    L = form(ufl.inner(w, v) * (dx(1) + dx(2) + dx(3)))
    b = assemble_vector(L)

    apply_lifting(b, [a], [[bc]])
    b.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES,
                  mode=PETSc.ScatterMode.REVERSE)
    set_bc(b, [bc])

    L2 = form(ufl.inner(w, v) * dx)
    b2 = assemble_vector(L2)
    apply_lifting(b2, [a], [[bc]])
    b2.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES,
                   mode=PETSc.ScatterMode.REVERSE)
    set_bc(b2, [bc])
    assert (b - b2).norm() < 1.0e-12

    # Assemble scalar
    L = form(w * (dx(1) + dx(2) + dx(3)))
    s = assemble_scalar(L)
    s = mesh.comm.allreduce(s, op=MPI.SUM)
    assert s == pytest.approx(0.5, 1.0e-12)
    L2 = form(w * dx)
    s2 = assemble_scalar(L2)
    s2 = mesh.comm.allreduce(s2, op=MPI.SUM)
    assert s == pytest.approx(s2, 1.0e-12)
Exemple #7
0
def norm_L2(u):
    """
    Returns the L2 norm of the function u
    """
    comm = u.function_space.mesh.comm
    dx = ufl.Measure("dx", u.function_space.mesh)
    norm_form = form(ufl.inner(u, u) * dx)
    norm = np.sqrt(
        comm.allreduce(assemble_scalar(norm_form), op=mpi4py.MPI.SUM))
    return norm
Exemple #8
0
def assemble(mesh, space, k):
    V = fem.FunctionSpace(mesh, (space, k))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)
    dx = ufl.Measure("dx", domain=mesh)
    a = fem.form(ufl.inner(u, v) * dx)

    A = fem.petsc.assemble_matrix(a)
    A.assemble()

    return A
Exemple #9
0
def translate_facetarea(terminal, mt, ctx):
    assert ctx.integral_type != 'cell'
    domain = terminal.ufl_domain()
    integrand, degree = one_times(ufl.Measure(ctx.integral_type, domain=domain))

    config = {name: getattr(ctx, name)
              for name in ["ufl_cell", "integration_dim",
                           "entity_ids", "precision", "index_cache"]}
    config.update(interface=ctx, quadrature_degree=degree)
    expr, = compile_ufl(integrand, point_sum=True, **config)
    return expr
def test_facet_area1D():
    mesh = create_unit_interval(MPI.COMM_WORLD, 10)

    # NOTE: Area of a vertex is defined to 1 in ufl
    c0 = ufl.FacetArea(mesh)
    c = Constant(mesh, ScalarType(1))

    ds = ufl.Measure("ds", domain=mesh)
    a0 = mesh.comm.allreduce(assemble_scalar(form(c * ds)), op=MPI.SUM)
    a = mesh.comm.allreduce(assemble_scalar(form(c0 * ds)), op=MPI.SUM)
    assert numpy.isclose(a.real, 2)
    assert numpy.isclose(a0.real, 2)
Exemple #11
0
    def initialize_geometry(self, mesh, facet_domains=None, cell_domains=None):
        """Stores mesh, domains and related quantities in a canonical member naming.

        Creates attributes on self:

            - mesh
            - facet_domains
            - cell_domains
            - ds
            - dS
            - dx

        """
        # Store geometry properties
        self.mesh = mesh
        self.facet_domains = facet_domains
        self.cell_domains = cell_domains

        # Fetch domains from mesh if necessary and avaiable
        domains = mesh.domains()
        if domains is not None:
            dim = mesh.geometry().dim()
            if self.facet_domains is None:
                self.facet_domains = MeshFunction("size_t", mesh, dim - 1,
                                                  domains)
            if self.cell_domains is None:
                self.cell_domains = MeshFunction("size_t", mesh, dim, domains)

        # Attach domains to measures for convenience
        self.ds = ufl.Measure("ds",
                              domain=self.mesh,
                              subdomain_data=self.facet_domains)
        self.dS = ufl.Measure("dS",
                              domain=self.mesh,
                              subdomain_data=self.facet_domains)
        self.dx = ufl.Measure("dx",
                              domain=self.mesh,
                              subdomain_data=self.cell_domains)
Exemple #12
0
    def facet_avg(self, o):
        if self.context.integral_type == "cell":
            raise ValueError("Can't take FacetAvg in cell integral")
        integrand, = o.ufl_operands
        domain = o.ufl_domain()
        measure = ufl.Measure(self.context.integral_type, domain=domain)
        integrand, degree, argument_multiindices = entity_avg(integrand / CellVolume(domain), measure, self.context.argument_multiindices)

        config = {name: getattr(self.context, name)
                  for name in ["ufl_cell", "precision", "index_cache"]},
        config.update(quadrature_degree=degree, interface=self.context,
                      argument_multiindices=argument_multiindices)
        expr, = compile_ufl(integrand, point_sum=True, **config)
        return expr
    def blocks(self):
        dx = ufl.Measure("dx", self.mesh)

        u, p = self.uu_[0:2]
        v, q = self.vv_[0:2]

        aa = [[
            ufl.inner(self.sigma(u), symgrad(v)) * dx,
            ufl.inner(p, v) * dx
        ], [ufl.inner(q, u) * dx, 0]]

        # Notice that dot(sigma(Eps), symgrad(v)) = dot(Eps, sigma(symgrad(v)))
        ff = [-ufl.inner(self.Eps, self.sigma(v)) * dx, 0]

        return [aa, ff]
Exemple #14
0
    def blocks(self):
        aa, ff = super(FormulationMinimallyConstrained, self).blocks()

        n = ufl.FacetNormal(self.mesh)
        ds = ufl.Measure("ds", self.mesh)

        u, P = self.uu_[0], self.uu_[2]
        v, Q = self.vv_[0], self.vv_[2]

        aa[0].append(-ufl.inner(P, ufl.outer(v, n)) * ds)
        aa[1].append(0)
        aa.append([-ufl.inner(Q, ufl.outer(u, n)) * ds, 0, 0])

        ff.append(0)

        return [aa, ff]
def test_facet_area(mesh_factory):
    """
    Compute facet area of cell. UFL currently only supports affine cells for this computation
    """
    # NOTE: UFL only supports facet area calculations of affine cells
    func, args, exact_area = mesh_factory
    mesh = func(*args)
    c0 = ufl.FacetArea(mesh)
    c = Constant(mesh, ScalarType(1))
    tdim = mesh.topology.dim
    num_faces = 4 if tdim == 2 else 6

    ds = ufl.Measure("ds", domain=mesh)
    a = mesh.comm.allreduce(assemble_scalar(form(c * ds)), op=MPI.SUM)
    a0 = mesh.comm.allreduce(assemble_scalar(form(c0 * ds)), op=MPI.SUM)
    assert numpy.isclose(a.real, num_faces)
    assert numpy.isclose(a0.real, num_faces * exact_area)
Exemple #16
0
    def cell_avg(self, o):
        if self.context.integral_type != "cell":
            # Need to create a cell-based quadrature rule and
            # translate the expression using that (c.f. CellVolume
            # below).
            raise NotImplementedError("CellAvg on non-cell integrals not yet implemented")
        integrand, = o.ufl_operands
        domain = o.ufl_domain()
        measure = ufl.Measure(self.context.integral_type, domain=domain)
        integrand, degree, argument_multiindices = entity_avg(integrand / CellVolume(domain), measure, self.context.argument_multiindices)

        config = {name: getattr(self.context, name)
                  for name in ["ufl_cell", "precision", "index_cache"]}
        config.update(quadrature_degree=degree, interface=self.context,
                      argument_multiindices=argument_multiindices)
        expr, = compile_ufl(integrand, point_sum=True, **config)
        return expr
Exemple #17
0
    def blocks(self):
        aa, ff = super(FormulationDirichletLagrange, self).blocks()

        uD = self.others["uD"] if "uD" in self.others else df.Constant((0, 0))

        ds = ufl.Measure("ds", self.mesh)

        u, p = self.uu_[0], self.uu_[2]
        v, q = self.vv_[0], self.vv_[2]

        aa[0].append(ufl.inner(p, v) * ds)
        aa[1].append(0)
        aa.append([ufl.inner(q, u) * ds, 0, 0])

        ff.append(ufl.inner(q, uD) * ds)

        return [aa, ff]
Exemple #18
0
    def get_tangent(self):
        if self.Chom_ is None:
            self.Chom_ = np.zeros((self.nvoigt, self.nvoigt))

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

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

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

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

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

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

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

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

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

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

        return self.Chom_
Exemple #19
0
                          window_size=[2 * figsize, figsize])
else:
    subplotter.show()

# Plotting a dolfinx.Function
# ===========================

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

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

        # GEOMETRY: rectangular domain with 5mm radius piston on left wall
        #  |------------------------------------------------------------|
        #  |                                                            |
        #  |                                                            |
        #  ||                                                           |
        #  ||                                                           |
        #  || <-- 5mm radius piston                                     |
        #  ||                                                           |
        #  ||                                                           |
        #  |                                                            |
        #  |                                                            |
        #  |----------------------------------------------------------- |
        # Locate boundary facets
        tdim = mesh.topology.dim
        # facets0 belong to 5mm radius piston at x=0
        facets0 = locate_entities_boundary(mesh, tdim - 1,
                                           lambda x: (x[0] < 1.0e-6) *
                                           (np.abs(x[1]) < 5e-3))
        # facets1 belong to right hand wall, at x=wx
        facets1 = locate_entities_boundary(mesh, tdim - 1,
                                           lambda x: x[0] > (wx - 1.0e-6))
        # facets2 belong to top and bottom walls, at y=+wy/2 and y=-wy/2
        facets2 = locate_entities_boundary(mesh, tdim - 1,
                                           lambda x:
                                           np.abs(x[1]) > (wy / 2 - 1.0e-6))

        indices, pos = np.unique(np.hstack((facets0, facets1, facets2)),
                                 return_index=True)
        values = np.hstack((np.full(facets0.shape, 1, np.intc),
                            np.full(facets1.shape, 2, np.intc),
                            np.full(facets2.shape, 3, np.intc)))
        marker = dolfinx.mesh.MeshTags(mesh, tdim - 1, indices, values[pos])
        ds = ufl.Measure('ds', subdomain_data=marker, domain=mesh)

        # dv, p = TrialFunction(self.V), TestFunction(self.V)
        p = TestFunction(self.V)
        beta = 3.5
        delta0 = 3.0e-6
        delta = delta0

        # # EXPERIMENT: add absorbing layers to top and bottom ("PMLs")
        # def delta_fun(x):
        #     lam = 2 * np.pi / k
        #     depth = 2 * lam
        #     dist = np.abs(x[1]) - (wy/2 - depth)
        #     inside = (dist >= 0)
        #     # outside = (dist < 0)
        #     return delta0 + inside * (dist**2) * 1e3

        # delta = Function(self.V)
        # delta.interpolate(delta_fun)
        # delta.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
        #                          mode=PETSc.ScatterMode.FORWARD)

        # with XDMFFile(mesh.mpi_comm(), "delta.xdmf", "w",
        #               encoding=XDMFFile.Encoding.HDF5) as file:
        #     file.write_mesh(mesh)
        #     file.write_function(delta)

        # Westervelt equation
        self.L1 = - inner(grad(self.u), grad(p)) * dx \
            - (delta / c**2) * inner(grad(self.v), grad(p)) * dx \
            + (2 * beta / (rho * c**4)) * inner(self.v * self.v, p) * dx \
            - (1 / c) * inner(self.v, p) * ds \
            + inner(self.g, p) * ds(1) \
            + (delta / c**2) * inner(self.g_deriv, p) * ds(1)

        self.lumped = True
        # Vector to be re-used for assembly
        self.b = None

        # TODO: precompile/pre-process Form L

        if self.lumped:
            # Westervelt equation
            a = (1 / c**2) * \
                (1 - 2 * beta * self.u / (rho * c**2)) * p * dx(degree=k) \
                + (delta / c**3) * p * ds

            self.M = dolfinx.fem.assemble_vector(a)
            self.M.ghostUpdate(addv=PETSc.InsertMode.ADD,
                               mode=PETSc.ScatterMode.REVERSE)
        else:
            # TODO: non-lumped version of Westervelt
            # a = (1 / self.c**2) * inner(dv, p) * dx(degree=k * k)
            M = dolfinx.fem.assemble_matrix(a)
            M.assemble()
            self.solver = PETSc.KSP().create(mesh.mpi_comm())
            opts = PETSc.Options()
            opts["ksp_type"] = "cg"
            opts["ksp_rtol"] = 1.0e-8
            self.solver.setFromOptions()
            self.solver.setOperators(M)
# u_t = (b.value[1] * rho.value * dz * dy * dx**4) / (8 * 2 * mu.value * dz * dy**3 / 12)
# print(f"u_t = {u_t} [m]")
# ω_0 = numpy.sqrt((2 * mu.value * dz * dy**3 / 12) / (rho.value * dz * dy * dx**4)) * numpy.array([1.875**2, 4.694**2])
# T_0 = 2 * numpy.pi / ω_0
# print(f"ω_0 = {ω_0} [rad/s]")
# print(f"T_0 = {T_0} [s]")

# Global time
time = dolfinx.fem.Constant(mesh, 0.0)  # [s]
# Time step size
dt = dolfinx.fem.Constant(mesh, 1e-2)  # [s]
# Number of time steps
nT = 200

# Define integration measures
dx = ufl.Measure("dx", domain=mesh, subdomain_data=subdomains)
ds = ufl.Measure("ds", domain=mesh, subdomain_data=interfaces)

# Function spaces
Ue = ufl.VectorElement("CG", mesh.ufl_cell(), 2)

Uf = dolfinx.fem.FunctionSpace(mesh, Ue)

# Define functions
u = dolfinx.fem.Function(Uf, name="u")
ut = dolfinx.fem.Function(Uf, name="ut")
utt = dolfinx.fem.Function(Uf, name="utt")

u_ = dolfinx.fem.Function(Uf, name="u_")  # boundary conditions

δu = ufl.TestFunction(Uf)
Exemple #22
0
    file.write_mesh(mesh)

# Function spaces
element_u = ufl.VectorElement("Lagrange", mesh.ufl_cell(), degree=1, dim=tdim)
V_u = dolfinx.fem.FunctionSpace(mesh, element_u)

# Define the state
u = dolfinx.fem.Function(V_u, name="Displacement")
u_ = dolfinx.fem.Function(V_u, name="Boundary Displacement")
ux_ = dolfinx.fem.Function(V_u.sub(0).collapse(), name="Boundary Displacement")
zero_u = dolfinx.fem.Function(V_u, name="   Boundary Displacement")

state = {"u": u}

# Measures
dx = ufl.Measure("dx", domain=mesh)
ds = ufl.Measure("ds", domain=mesh)

dofs_u_left = dolfinx.fem.locate_dofs_geometrical(
    V_u, lambda x: np.isclose(x[0], 0.0))
dofs_u_right = dolfinx.fem.locate_dofs_geometrical(
    V_u, lambda x: np.isclose(x[0], Lx))
dofs_ux_right = dolfinx.fem.locate_dofs_geometrical(
    (V_u.sub(0), V_u.sub(0).collapse()), lambda x: np.isclose(x[0], Lx))

# Set Bcs Function
zero_u.interpolate(lambda x: (np.zeros_like(x[0]), np.zeros_like(x[1])))
u_.interpolate(lambda x: (np.ones_like(x[0]), 0 * np.ones_like(x[1])))
ux_.interpolate(lambda x: np.ones_like(x[0]))

for f in [zero_u, ux_]:
def test_assembly_dx_domains(mesh):
    V = dolfin.FunctionSpace(mesh, ("CG", 1))
    u, v = dolfin.TrialFunction(V), dolfin.TestFunction(V)

    marker = dolfin.MeshFunction("size_t", mesh, mesh.topology.dim, 0)
    values = marker.values
    # Mark first, second and all other
    # Their union is the whole domain
    values[0] = 111
    values[1] = 222
    values[2:] = 333

    dx = ufl.Measure('dx', subdomain_data=marker, domain=mesh)

    w = dolfin.Function(V)
    with w.vector.localForm() as w_local:
        w_local.set(0.5)

    #
    # Assemble matrix
    #

    a = w * ufl.inner(u, v) * (dx(111) + dx(222) + dx(333))

    A = dolfin.fem.assemble_matrix(a)
    A.assemble()
    norm1 = A.norm()

    a2 = w * ufl.inner(u, v) * dx

    A2 = dolfin.fem.assemble_matrix(a2)
    A2.assemble()
    norm2 = A2.norm()

    assert norm1 == pytest.approx(norm2, 1.0e-12)

    #
    # Assemble vector
    #

    L = ufl.inner(w, v) * (dx(111) + dx(222) + dx(333))
    b = dolfin.fem.assemble_vector(L)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)

    L2 = ufl.inner(w, v) * dx
    b2 = dolfin.fem.assemble_vector(L2)
    b2.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)

    assert b.norm() == pytest.approx(b2.norm(), 1.0e-12)

    #
    # Assemble scalar
    #

    L = w * (dx(111) + dx(222) + dx(333))
    s = dolfin.fem.assemble_scalar(L)
    s = dolfin.MPI.sum(mesh.mpi_comm(), s)

    L2 = w * dx
    s2 = dolfin.fem.assemble_scalar(L2)
    s2 = dolfin.MPI.sum(mesh.mpi_comm(), s2)

    assert (s == pytest.approx(s2, 1.0e-12)
            and 0.5 == pytest.approx(s, 1.0e-12))
Exemple #24
0
def test_simple_triangle():

    if MPI.COMM_WORLD.rank == 0:

        import gmsh

        gmsh.initialize()
        gmsh.model.add("test")

        p0 = gmsh.model.geo.addPoint(0.0, 0.0, 0.0)
        p1 = gmsh.model.geo.addPoint(1.0, 0.0, 0.0)
        p2 = gmsh.model.geo.addPoint(1.0, 1.0, 0.0)
        p3 = gmsh.model.geo.addPoint(0.0, 1.0, 0.0)
        p4 = gmsh.model.geo.addPoint(1.0, 0.5, 0.0)

        l0 = gmsh.model.geo.addLine(p0, p1)
        l1 = gmsh.model.geo.addCircleArc(p1, p4, p2)
        l2 = gmsh.model.geo.addLine(p2, p3)
        l3 = gmsh.model.geo.addLine(p3, p0)

        cl0 = gmsh.model.geo.addCurveLoop([l0, l1, l2, l3])
        s0 = gmsh.model.geo.addPlaneSurface([cl0])

        gmsh.model.addPhysicalGroup(1, [l0, l2], 2)
        gmsh.model.setPhysicalName(1, 2, "sides")

        gmsh.model.addPhysicalGroup(1, [l1], 3)
        gmsh.model.setPhysicalName(1, 3, "arc")

        gmsh.model.addPhysicalGroup(2, [s0], 4)
        gmsh.model.setPhysicalName(2, 4, "surface")

        gmsh.model.geo.synchronize()
        gmsh.model.mesh.generate()
        gmsh.model.mesh.setOrder(2)

        gmsh_model = gmsh.model

    else:

        gmsh_model = None

    mesh, mts = dolfiny.mesh.gmsh_to_dolfin(gmsh_model, 2, prune_z=True)
    mt1, keys1 = dolfiny.mesh.merge_meshtags(mts, 1)
    mt2, keys2 = dolfiny.mesh.merge_meshtags(mts, 2)

    assert mesh.geometry.dim == 2
    assert mesh.topology.dim == 2
    assert mts["arc"].dim == 1

    with dolfinx.io.XDMFFile(MPI.COMM_WORLD, "mesh.xdmf", "w") as file:
        file.write_mesh(mesh)
        mesh.topology.create_connectivity(1, 2)
        file.write_meshtags(mts["arc"])

    ds = ufl.Measure("ds", subdomain_data=mt1, domain=mesh)

    form = dolfinx.fem.form(1.0 * ds(keys1["sides"]) + 1.0 * ds(keys1["arc"]))
    val = dolfinx.fem.assemble_scalar(form)

    val = mesh.comm.allreduce(val, op=MPI.SUM)
    assert numpy.isclose(val, 2.0 + 2.0 * numpy.pi * 0.5 / 2.0, rtol=1.0e-3)

    dx = ufl.Measure("dx", subdomain_data=mt2, domain=mesh)

    form = dolfinx.fem.form(1.0 * dx(keys2["surface"]))
    val = dolfinx.fem.assemble_scalar(form)

    val = mesh.comm.allreduce(val, op=MPI.SUM)
    assert numpy.isclose(val, 1.0 + numpy.pi * 0.5**2 / 2.0, rtol=1.0e-3)
Exemple #25
0
# Max inner ring velocity
v_inner_max = 0.1  # [m/s]
# Normal and tangential velocity at inner ring
v_n = dolfinx.fem.Constant(mesh, 0.0)  # [m/s]
v_t = dolfinx.fem.Constant(mesh, 0.0)  # [m/s] -- value set/updated in analysis

# Global time
time = dolfinx.fem.Constant(mesh, 0.0)  # [s]
# Time step size
dt = dolfinx.fem.Constant(mesh, 0.05)  # [s]
# Number of time steps
nT = 80

# Define integration measures
dx = ufl.Measure("dx",
                 domain=mesh,
                 subdomain_data=subdomains,
                 metadata={"quadrature_degree": 4})
ds = ufl.Measure("ds",
                 domain=mesh,
                 subdomain_data=interfaces,
                 metadata={"quadrature_degree": 4})


# Inner ring velocity
def v_inner_(t=0.0, vt=v_inner_max, g=5, a=1, b=3):
    return vt * 0.25 * (np.tanh(g * (t - a)) + 1) * (np.tanh(-g * (t - b)) + 1)


# Function spaces
Ve = ufl.VectorElement("CG", mesh.ufl_cell(), 2)
Pe = ufl.FiniteElement("CG", mesh.ufl_cell(), 1)
Exemple #26
0
    def solve(self, f, filename):
        # redifine constans for specific frequency
        self.f = f
        self.omega = 2 * np.pi * f
        self.lmda = self.c / f
        self.k0 = self.omega / self.c

        # Load mesh
        mesh, cell_tags, facet_tags = read_from_msh(filename,
                                                    cell_data=True,
                                                    facet_data=True,
                                                    gdim=2)

        # Define function space
        V = dolfinx.FunctionSpace(mesh, ("Lagrange", self.degree))

        # Interpolate wavenumber k onto V
        k = dolfinx.Constant(V, self.k0)

        # Interpolate absorbing layer piece of wavenumber k_absorb onto V
        k_absorb = dolfinx.Function(V)
        adiabatic_layer = AdiabaticLayer(self.deg_absorber, self.k0, self.lmda)
        k_absorb.interpolate(adiabatic_layer.eval)

        # Interpolate incident wave field onto V
        ui = dolfinx.Function(V)
        ui_expr = IncidentWave(self.k0)
        ui.interpolate(ui_expr.eval)

        # Define variational problem
        u = ufl.TrialFunction(V)
        v = ufl.TestFunction(V)

        ds_exited = ufl.Measure("ds",
                                domain=mesh,
                                subdomain_data=facet_tags,
                                subdomain_id=1)

        a = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx \
            - k ** 2 * ufl.inner(u, v) * ufl.dx \
            - k_absorb * ufl.inner(u, v) * ufl.dx

        L = -1j * self.omega * self.rho_0 * ufl.inner(ui, v) * ufl.dx

        # Assemble matrix and vector and set up direct solver
        A = dolfinx.fem.assemble_matrix(a)
        A.assemble()
        b = dolfinx.fem.assemble_vector(L)
        b.ghostUpdate(addv=PETSc.InsertMode.ADD,
                      mode=PETSc.ScatterMode.REVERSE)

        solver = PETSc.KSP().create(mesh.mpi_comm())
        opts = PETSc.Options()
        opts["ksp_type"] = "preonly"
        opts["pc_type"] = "lu"
        opts["pc_factor_mat_solver_type"] = "mumps"
        solver.setFromOptions()
        solver.setOperators(A)

        # Solve linear system
        u = dolfinx.Function(V)
        start = time.time()
        solver.solve(b, u.vector)
        end = time.time()
        time_elapsed = end - start
        print('Solve time: ', time_elapsed)
        u.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                             mode=PETSc.ScatterMode.FORWARD)
        save(mesh, u, f"../Solution/sol_{f}Hz.xdmf")
Exemple #27
0
def test_assembly_ds_domains(mesh):
    V = dolfinx.FunctionSpace(mesh, ("CG", 1))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)

    def bottom(x):
        return numpy.isclose(x[1], 0.0)

    def top(x):
        return numpy.isclose(x[1], 1.0)

    def left(x):
        return numpy.isclose(x[0], 0.0)

    def right(x):
        return numpy.isclose(x[0], 1.0)

    bottom_facets = locate_entities_geometrical(mesh,
                                                mesh.topology.dim - 1,
                                                bottom,
                                                boundary_only=True)
    bottom_vals = numpy.full(bottom_facets.shape, 1, numpy.intc)

    top_facets = locate_entities_geometrical(mesh,
                                             mesh.topology.dim - 1,
                                             top,
                                             boundary_only=True)
    top_vals = numpy.full(top_facets.shape, 2, numpy.intc)

    left_facets = locate_entities_geometrical(mesh,
                                              mesh.topology.dim - 1,
                                              left,
                                              boundary_only=True)
    left_vals = numpy.full(left_facets.shape, 3, numpy.intc)

    right_facets = locate_entities_geometrical(mesh,
                                               mesh.topology.dim - 1,
                                               right,
                                               boundary_only=True)
    right_vals = numpy.full(right_facets.shape, 6, numpy.intc)

    indices = numpy.hstack(
        (bottom_facets, top_facets, left_facets, right_facets))
    values = numpy.hstack((bottom_vals, top_vals, left_vals, right_vals))

    indices, pos = numpy.unique(indices, return_index=True)
    marker = dolfinx.mesh.MeshTags(mesh, mesh.topology.dim - 1, indices,
                                   values[pos])

    ds = ufl.Measure('ds', subdomain_data=marker, domain=mesh)

    w = dolfinx.Function(V)
    with w.vector.localForm() as w_local:
        w_local.set(0.5)

    # Assemble matrix
    a = w * ufl.inner(u, v) * (ds(1) + ds(2) + ds(3) + ds(6))
    A = dolfinx.fem.assemble_matrix(a)
    A.assemble()
    norm1 = A.norm()
    a2 = w * ufl.inner(u, v) * ds
    A2 = dolfinx.fem.assemble_matrix(a2)
    A2.assemble()
    norm2 = A2.norm()
    assert norm1 == pytest.approx(norm2, 1.0e-12)

    # Assemble vector
    L = ufl.inner(w, v) * (ds(1) + ds(2) + ds(3) + ds(6))
    b = dolfinx.fem.assemble_vector(L)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    L2 = ufl.inner(w, v) * ds
    b2 = dolfinx.fem.assemble_vector(L2)
    b2.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    assert b.norm() == pytest.approx(b2.norm(), 1.0e-12)

    # Assemble scalar
    L = w * (ds(1) + ds(2) + ds(3) + ds(6))
    s = dolfinx.fem.assemble_scalar(L)
    s = mesh.mpi_comm().allreduce(s, op=MPI.SUM)
    L2 = w * ds
    s2 = dolfinx.fem.assemble_scalar(L2)
    s2 = mesh.mpi_comm().allreduce(s2, op=MPI.SUM)
    assert (s == pytest.approx(s2, 1.0e-12)
            and 2.0 == pytest.approx(s, 1.0e-12))
def test_assembly_ds_domains(mode):
    mesh = dolfinx.generation.UnitSquareMesh(MPI.COMM_WORLD, 10, 10, ghost_mode=mode)
    V = dolfinx.FunctionSpace(mesh, ("CG", 1))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)

    def bottom(x):
        return numpy.isclose(x[1], 0.0)

    def top(x):
        return numpy.isclose(x[1], 1.0)

    def left(x):
        return numpy.isclose(x[0], 0.0)

    def right(x):
        return numpy.isclose(x[0], 1.0)

    bottom_facets = locate_entities_boundary(mesh, mesh.topology.dim - 1, bottom)
    bottom_vals = numpy.full(bottom_facets.shape, 1, numpy.intc)

    top_facets = locate_entities_boundary(mesh, mesh.topology.dim - 1, top)
    top_vals = numpy.full(top_facets.shape, 2, numpy.intc)

    left_facets = locate_entities_boundary(mesh, mesh.topology.dim - 1, left)
    left_vals = numpy.full(left_facets.shape, 3, numpy.intc)

    right_facets = locate_entities_boundary(mesh, mesh.topology.dim - 1, right)
    right_vals = numpy.full(right_facets.shape, 6, numpy.intc)

    indices = numpy.hstack((bottom_facets, top_facets, left_facets, right_facets))
    values = numpy.hstack((bottom_vals, top_vals, left_vals, right_vals))

    indices, pos = numpy.unique(indices, return_index=True)
    marker = dolfinx.mesh.MeshTags(mesh, mesh.topology.dim - 1, indices, values[pos])

    ds = ufl.Measure('ds', subdomain_data=marker, domain=mesh)

    w = dolfinx.Function(V)
    with w.vector.localForm() as w_local:
        w_local.set(0.5)

    bc = dolfinx.fem.DirichletBC(dolfinx.Function(V), range(30))

    # Assemble matrix
    a = w * ufl.inner(u, v) * (ds(1) + ds(2) + ds(3) + ds(6))
    A = dolfinx.fem.assemble_matrix(a)
    A.assemble()
    norm1 = A.norm()
    a2 = w * ufl.inner(u, v) * ds
    A2 = dolfinx.fem.assemble_matrix(a2)
    A2.assemble()
    norm2 = A2.norm()
    assert norm1 == pytest.approx(norm2, 1.0e-12)

    # Assemble vector
    L = ufl.inner(w, v) * (ds(1) + ds(2) + ds(3) + ds(6))
    b = dolfinx.fem.assemble_vector(L)

    dolfinx.fem.apply_lifting(b, [a], [[bc]])
    b.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES,
                  mode=PETSc.ScatterMode.REVERSE)
    dolfinx.fem.set_bc(b, [bc])

    L2 = ufl.inner(w, v) * ds
    b2 = dolfinx.fem.assemble_vector(L2)
    dolfinx.fem.apply_lifting(b2, [a2], [[bc]])
    b2.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES,
                   mode=PETSc.ScatterMode.REVERSE)
    dolfinx.fem.set_bc(b2, [bc])

    assert b.norm() == pytest.approx(b2.norm(), 1.0e-12)

    # Assemble scalar
    L = w * (ds(1) + ds(2) + ds(3) + ds(6))
    s = dolfinx.fem.assemble_scalar(L)
    s = mesh.mpi_comm().allreduce(s, op=MPI.SUM)
    L2 = w * ds
    s2 = dolfinx.fem.assemble_scalar(L2)
    s2 = mesh.mpi_comm().allreduce(s2, op=MPI.SUM)
    assert (s == pytest.approx(s2, 1.0e-12) and 2.0 == pytest.approx(s, 1.0e-12))
def free_end(x):
    """Marks the leftmost points of the cantilever"""
    return numpy.isclose(x[0], 48.0)


def left(x):
    """Marks left part of boundary, where cantilever is attached to wall"""
    return numpy.isclose(x[0], 0.0)


# Locate all facets at the free end and assign them value 1
free_end_facets = locate_entities_boundary(mesh, 1, free_end)
mt = dolfinx.mesh.MeshTags(mesh, 1, free_end_facets, 1)

ds = ufl.Measure("ds", subdomain_data=mt)

# Homogeneous boundary condition in displacement
u_bc = dolfinx.Function(U)
with u_bc.vector.localForm() as loc:
    loc.set(0.0)

# Displacement BC is applied to the left side
left_facets = locate_entities_boundary(mesh, 1, left)
bdofs = locate_dofs_topological(U, 1, left_facets)
bc = dolfinx.fem.DirichletBC(u_bc, bdofs)

# Elastic stiffness tensor and Poisson ratio
E, nu = 1.0, 1.0 / 3.0

Exemple #30
0
alpha_ub.interpolate(lambda x: np.ones_like(x[0]))

#In order to defined a function in a specific subspace of the model, it must be
#specified in the model 'V_u.sub(i)', where i = 0 -> x, 1 -> y, 2-> z.
#Don't forget to collapse, to choose only the DOF associated with the subspace.

#I don't think  this part works to definy the body force applied in a geometry.
#It could be better to define it in the energy definition as constant. If not a
#constant, we might need to define as a space function.
# g = dolfinx.fem.Function(V_u, name="Body_pressure")
# with g.vector.localForm() as loc:
#   loc.set(-78500.0)

# Integral measures -> in order to define the energy lately, it's necessary to
#define the integral measures, as such one is a integral.
dx = ufl.Measure("dx", domain=mesh)  #-> volume measure
#We include here the subdomain data generated at the gmsh file.
ds = ufl.Measure("ds", subdomain_data=facet_tags,
                 domain=mesh)  #-> surface measure
#ds(<number of the facet tags>)
#dS = ufl.Measure("dS", domain = mesh) - inner boundaries of the mesh -> not usefull

import models
from models import DamageElasticityModel as Brittle

model = Brittle(parameters.get('model'))
state = {'u': u, 'alpha': alpha}
#The total energy density is calculated this time using a already written
#function of the "model". This return the elasticity energy (with the a(alpha))
#and the damage energy term. To count for externals forces, it need to substract it
#from the total energy