Exemplo n.º 1
0
def test_b_mesh_mapping(celltype):
    """
    Creates a boundary mesh and checks that the geometrical entities
    are mapped to the correct cells.
    """
    mesh = dolfinx.UnitCubeMesh(MPI.COMM_WORLD, 2, 2, 2, cell_type=celltype)

    b_mesh, bndry_to_mesh = dolfinx.plotting.create_boundary_mesh(
        mesh, MPI.COMM_SELF)

    # Compute map from boundary mesh topology to boundary mesh geometry
    b_mesh.topology.create_connectivity(b_mesh.topology.dim,
                                        b_mesh.topology.dim)
    b_imap = b_mesh.topology.index_map(b_mesh.topology.dim)
    tdim_entities = np.arange(b_imap.size_local, dtype=np.int32)
    boundary_geometry = cmesh.entities_to_geometry(b_mesh, b_mesh.topology.dim,
                                                   tdim_entities, False)

    # Compare geometry maps
    for i in range(boundary_geometry.shape[0]):
        assert (np.allclose(b_mesh.geometry.x[boundary_geometry[i]],
                            mesh.geometry.x[bndry_to_mesh[i]]))

    # Check that boundary mesh integrated has the correct area
    b_volume = mesh.mpi_comm().allreduce(dolfinx.fem.assemble_scalar(
        dolfinx.Constant(b_mesh, 1) * ufl.dx),
                                         op=MPI.SUM)
    mesh_surface = mesh.mpi_comm().allreduce(dolfinx.fem.assemble_scalar(
        dolfinx.Constant(mesh, 1) * ufl.ds),
                                             op=MPI.SUM)
    assert (np.isclose(b_volume, mesh_surface))
Exemplo n.º 2
0
def xtest_assembly_dS_domains(mode):
    N = 10
    mesh = dolfinx.UnitSquareMesh(MPI.COMM_WORLD, N, N, ghost_mode=mode)
    one = dolfinx.Constant(mesh, 1)
    val = dolfinx.fem.assemble_scalar(one * ufl.dS)
    val = mesh.mpi_comm().allreduce(val, op=MPI.SUM)
    assert val == pytest.approx(2 * (N - 1) + N * numpy.sqrt(2), 1.0e-7)
Exemplo n.º 3
0
def xtest_assembly_dS_domains(mode):
    N = 10
    mesh = dolfinx.UnitSquareMesh(dolfinx.MPI.comm_world,
                                  N,
                                  N,
                                  ghost_mode=mode)
    one = dolfinx.Constant(mesh, 1)
    val = dolfinx.fem.assemble_scalar(one * ufl.dS)
    val = dolfinx.MPI.sum(mesh.mpi_comm(), val)
    assert val == pytest.approx(2 * (N - 1) + N * numpy.sqrt(2), 1.0e-7)
Exemplo n.º 4
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")
Exemplo n.º 5
0
lid_velocity = Function(V)
lid_velocity.interpolate(lid_velocity_expression)

facets = locate_entities_boundary(mesh, 1, lid)
bc1 = DirichletBC(lid_velocity, locate_dofs_topological(V, 1, facets))

# Collect Dirichlet boundary conditions
bcs = [bc0, bc1]

# We now define the bilinear and linear forms corresponding to the weak
# mixed formulation of the Stokes equations in a blocked structure::

# Define variational problem
(u, p) = ufl.TrialFunction(V), ufl.TrialFunction(Q)
(v, q) = ufl.TestFunction(V), ufl.TestFunction(Q)
f = dolfinx.Constant(mesh, (0, 0))

a = [[inner(grad(u), grad(v)) * dx,
      inner(p, div(v)) * dx], [inner(div(u), q) * dx, None]]

L = [inner(f, v) * dx, inner(dolfinx.Constant(mesh, 0), q) * dx]

# We will use a block-diagonal preconditioner to solve this problem::

a_p11 = inner(p, q) * dx
a_p = [[a[0][0], None], [None, a_p11]]

# Nested matrix solver
# ^^^^^^^^^^^^^^^^^^^^
#
# We now assemble the bilinear form into a nested matrix `A`, and call
def test_assembly_into_quadrature_function():
    """Test assembly into a Quadrature function.

    This test evaluates a UFL Expression into a Quadrature function space by
    evaluating the Expression on all cells of the mesh, and then inserting the
    evaluated values into a PETSc Vector constructed from a matching Quadrature
    function space.

    Concretely, we consider the evaluation of:

        e = B*(K(T)))**2 * grad(T)

    where

        K = 1/(A + B*T)

    where A and B are Constants and T is a Coefficient on a P2 finite element
    space with T = x + 2*y.

    The result is compared with interpolating the analytical expression of e
    directly into the Quadrature space.

    In parallel, each process evaluates the Expression on both local cells and
    ghost cells so that no parallel communication is required after insertion
    into the vector.
    """
    mesh = dolfinx.UnitSquareMesh(MPI.COMM_WORLD, 3, 6)

    quadrature_degree = 2
    quadrature_points = basix.make_quadrature(basix.CellType.triangle, quadrature_degree)
    Q_element = ufl.VectorElement("Quadrature", ufl.triangle, quadrature_degree, quad_scheme="default")
    Q = dolfinx.FunctionSpace(mesh, Q_element)

    def T_exact(x):
        return x[0] + 2.0 * x[1]

    P2 = dolfinx.FunctionSpace(mesh, ("P", 2))
    T = dolfinx.Function(P2)
    T.interpolate(T_exact)
    A = dolfinx.Constant(mesh, 1.0)
    B = dolfinx.Constant(mesh, 2.0)

    K = 1.0 / (A + B * T)
    e = B * K**2 * ufl.grad(T)

    e_expr = dolfinx.Expression(e, quadrature_points)

    map_c = mesh.topology.index_map(mesh.topology.dim)
    num_cells = map_c.size_local + map_c.num_ghosts
    cells = np.arange(0, num_cells, dtype=np.int32)

    e_eval = e_expr.eval(cells)

    # Assemble into Function
    e_Q = dolfinx.Function(Q)
    with e_Q.vector.localForm() as e_Q_local:
        e_Q_local.setBlockSize(e_Q.function_space.dofmap.bs)
        e_Q_local.setValuesBlocked(Q.dofmap.list.array, e_eval, addv=PETSc.InsertMode.INSERT)

    def e_exact(x):
        T = x[0] + 2.0 * x[1]
        K = 1.0 / (A.value + B.value * T)

        grad_T = np.zeros((2, x.shape[1]))
        grad_T[0, :] = 1.0
        grad_T[1, :] = 2.0

        e = B.value * K**2 * grad_T
        return e

    e_exact_Q = dolfinx.Function(Q)
    e_exact_Q.interpolate(e_exact)

    assert np.isclose((e_exact_Q.vector - e_Q.vector).norm(), 0.0)
def test_simple_evaluation():
    """Test evaluation of UFL Expression.

    This test evaluates a UFL Expression on cells of the mesh and compares the
    result with an analytical expression.

    For a function f(x, y) = 3*(x^2 + 2*y^2) the result is compared with the
    exact gradient:

        grad f(x, y) = 3*[2*x, 4*y].

    (x^2 + 2*y^2) is first interpolated into a P2 finite element space. The
    scaling by a constant factor of 3 and the gradient is calculated using code
    generated by FFCX. The analytical solution is found by evaluating the
    spatial coordinates as an Expression using UFL/FFCX and passing the result
    to a numpy function that calculates the exact gradient.
    """
    mesh = dolfinx.generation.UnitSquareMesh(MPI.COMM_WORLD, 3, 3)
    P2 = dolfinx.FunctionSpace(mesh, ("P", 2))

    # NOTE: The scaling by a constant factor of 3.0 to get f(x, y) is
    # implemented within the UFL Expression. This is to check that the
    # Constants are being set up correctly.
    def exact_expr(x):
        return x[0] ** 2 + 2.0 * x[1] ** 2

    # Unused, but remains for clarity.
    def f(x):
        return 3 * (x[0] ** 2 + 2.0 * x[1] ** 2)

    def exact_grad_f(x):
        values = np.zeros_like(x)
        values[:, 0::2] = 2 * x[:, 0::2]
        values[:, 1::2] = 4 * x[:, 1::2]
        values *= 3.0
        return values

    expr = dolfinx.Function(P2)
    expr.interpolate(exact_expr)

    ufl_grad_f = dolfinx.Constant(mesh, 3.0) * ufl.grad(expr)
    points = np.array([[0.0, 0.0], [1.0, 0.0], [0.0, 1.0]])
    grad_f_expr = dolfinx.Expression(ufl_grad_f, points)
    assert grad_f_expr.num_points == points.shape[0]
    assert grad_f_expr.value_size == 2

    # NOTE: Cell numbering is process local.
    map_c = mesh.topology.index_map(mesh.topology.dim)
    num_cells = map_c.size_local + map_c.num_ghosts
    cells = np.arange(0, num_cells, dtype=np.int32)

    grad_f_evaluated = grad_f_expr.eval(cells)
    assert grad_f_evaluated.shape[0] == cells.shape[0]
    assert grad_f_evaluated.shape[1] == grad_f_expr.value_size * grad_f_expr.num_points

    # Evaluate points in global space
    ufl_x = ufl.SpatialCoordinate(mesh)
    x_expr = dolfinx.Expression(ufl_x, points)
    assert x_expr.num_points == points.shape[0]
    assert x_expr.value_size == 2
    x_evaluated = x_expr.eval(cells)
    assert x_evaluated.shape[0] == cells.shape[0]
    assert x_evaluated.shape[1] == x_expr.num_points * x_expr.value_size

    # Evaluate exact gradient using global points
    grad_f_exact = exact_grad_f(x_evaluated)

    assert np.allclose(grad_f_evaluated, grad_f_exact)
# Structure: shear correction factor, see Cowper (1966)
sc_fac = 10 * (1 + n) / (12 + 11 * n)


def s(e):
    """
    Stress as function of strain from strain energy function
    """
    e = ufl.variable(e)
    W = lamé_μ * e * e + lamé_λ / 2 * e**2  # Saint-Venant Kirchhoff
    s = ufl.diff(W, e)
    return s


# Structure: load parameters
μ = dolfinx.Constant(mesh, 1.0)  # load factor

p_x = μ * dolfinx.Constant(mesh, 1.0 * 0)
p_z = μ * dolfinx.Constant(mesh, 1.0 * 0)
m_y = μ * dolfinx.Constant(mesh, 1.0 * 0)

F_x = μ * dolfinx.Constant(
    mesh, (2.0 * np.pi / L)**2 * E * I * 0)  # prescribed F_x: 2, 4
F_z = μ * dolfinx.Constant(
    mesh, (0.5 * np.pi / L)**2 * E * I * 0)  # prescribed F_z: 4, 8
M_y = μ * dolfinx.Constant(
    mesh, (2.0 * np.pi / L)**1 * E * I * 1)  # prescribed M_y: 1, 2

# Define integration measures
dx = ufl.Measure("dx", domain=mesh, subdomain_data=subdomains)
ds = ufl.Measure("ds", domain=mesh, subdomain_data=interfaces)
Exemplo n.º 9
0
def ode_1st_linear_odeint(a=1.0, b=0.5, u_0=1.0, nT=10, dt=0.1, **kwargs):
    """
    Create 1st order ODE problem and solve with `ODEInt` time integrator.

    First order linear ODE:
    dot u + a * u - b = 0 with initial condition u(t=0) = u_0
    """

    mesh = UnitCubeMesh(MPI.COMM_WORLD, 1, 1, 1)
    U = FunctionSpace(mesh, ("DG", 0))

    u = Function(U, name="u")
    ut = Function(U, name="ut")

    u.vector.set(u_0)  # initial condition
    ut.vector.set(
        b - a * u_0)  # exact initial rate of this ODE for generalised alpha

    u.vector.ghostUpdate()
    ut.vector.ghostUpdate()

    δu = ufl.TestFunction(U)

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

    # Global time
    time = dolfinx.Constant(mesh, 0.0)

    # Time step size
    dt = dolfinx.Constant(mesh, dt)

    # Time integrator
    odeint = dolfiny.odeint.ODEInt(t=time, dt=dt, x=u, xt=ut, **kwargs)

    # Weak form (as one-form)
    f = δu * (ut + a * u - b) * dx

    # Overall form (as one-form)
    F = odeint.discretise_in_time(f)
    # Overall form (as list of forms)
    F = dolfiny.function.extract_blocks(F, [δu])

    # Silence SNES monitoring during test
    dolfiny.snesblockproblem.SNESBlockProblem.print_norms = lambda self, it: 1

    # Create problem (although having a linear ODE we use the dolfiny.snesblockproblem API)
    problem = dolfiny.snesblockproblem.SNESBlockProblem(F, [u])

    # Book-keeping of results
    u_avg = numpy.zeros(nT + 1)
    u_avg[0] = u.vector.sum() / u.vector.getSize()

    dolfiny.utils.pprint(f"+++ Processing time steps = {nT}")

    # Process time steps
    for time_step in range(1, nT + 1):

        # Stage next time step
        odeint.stage()

        # Solve (linear) problem
        u, = problem.solve()

        # Update solution states for time integration
        odeint.update()

        # Store result
        u_avg[time_step] = u.vector.sum() / u.vector.getSize()

    return u_avg
Exemplo n.º 10
0
    def __init__(self, t, dt, x, xt, **kwargs):
        """Initialises the ODE integrator (single-step-method).
        Uses underneath the generalised alpha method and its limits:

        Euler forward:
            alpha_f = 0, alpha_m = 1/2, gamma = 1/2
        Euler backward:
            alpha_f = 1, alpha_m = 1/2, gamma = 1/2
        Crank-Nicolson:
            alpha_f = 1/2, alpha_m = 1/2, gamma = 1/2
        Theta:
            alpha_f = theta, alpha_m = 1/2, gamma = 1/2
        Generalised alpha:
            The value of rho can be used to determine the values
            alpha_f = 1 / (1 + rho),
            alpha_m = 1 / 2 * (3 - rho) / (1 + rho),
            gamma = 1 / 2 + alpha_m - alpha_f

        Parameters
        ----------
        t: Stage time.
        dt: Time step size.
        x: Pointer to function describing the state.
        xt: Pointer to function describing the rate of the state.

        rho: Spectral radius rho_infinity for generalised alpha.
        alpha_f: Specific value for alpha_f.
        alpha_m: Specific value for alpha_m.
        gamma: Specific value for gamma.
        """

        # Set stage time and time step
        self.t = t
        self.dt = dt

        if not isinstance(self.t, dolfinx.Constant):
            raise RuntimeError("No stage time t as dolfinx.Constant provied.")

        if not isinstance(self.dt, dolfinx.Constant):
            raise RuntimeError("No time step dt as dolfinx.Constant provied.")

        # Pointers to state x and rate xt (as function or list of functions)
        self.x = x
        self.xt = xt

        if isinstance(self.x, list):
            self.x0 = []
            for x, xt in zip(self.x, self.xt):
                if x.function_space is not xt.function_space:
                    raise RuntimeError(
                        "Incompatible function spaces for state and rate.")
        else:
            if self.x.function_space is not self.xt.function_space:
                raise RuntimeError(
                    "Incompatible function spaces for state and rate.")

        # Set state x0
        if isinstance(self.x, list):
            self.x0 = []
            for xi in self.x:
                self.x0.append(dolfinx.function.Function(xi.function_space))
        else:
            self.x0 = dolfinx.function.Function(self.x.function_space)

        # Set rate of state x0t
        if isinstance(self.xt, list):
            self.x0t = []
            for xti in self.xt:
                self.x0t.append(dolfinx.function.Function(xti.function_space))
        else:
            self.x0t = dolfinx.function.Function(self.xt.function_space)

        # Expression: derivative in time
        self.derivative_dt = lambda x, x0, x0t: \
            1.0 / (self.gamma * self.dt) * (x - x0) + (self.gamma - 1.0) / self.gamma * x0t

        # Expression: integral in time
        self.integral_dt = lambda x, xt, x0, x0t: \
            self.dt / 2 * (x0 + x) + self.dt**2 / 12 * (x0t - xt)

        # Expression: state at collocation point in time interval
        self.state = lambda x0, x1: \
            self.alpha_f * x1 + (1.0 - self.alpha_f) * x0

        # Expression: rate of state at collocation point in time interval
        self.rate = lambda x0t, x1t: \
            self.alpha_m * x1t + (1.0 - self.alpha_m) * x0t

        # Default values: Backward Euler
        self.alpha_f = dolfinx.Constant(self.t.ufl_domain(), 1.0)
        self.alpha_m = dolfinx.Constant(self.t.ufl_domain(), 0.5)
        self.gamma = dolfinx.Constant(self.t.ufl_domain(), 0.5)

        # Parameters from given rho
        if "rho" in kwargs:
            self.alpha_f.value = 1.0 / (1.0 + kwargs["rho"])
            self.alpha_m.value = 0.5 * (3.0 -
                                        kwargs["rho"]) * self.alpha_f.value
            self.gamma.value = 0.5 + self.alpha_m.value - self.alpha_f.value

        # Parameters directly
        if "alpha_f" in kwargs and "alpha_m" in kwargs and "gamma" in kwargs:
            self.alpha_f.value = kwargs["alpha_f"]
            self.alpha_m.value = kwargs["alpha_m"]
            self.gamma.value = kwargs["gamma"]
Exemplo n.º 11
0
# # Read mesh and meshtags from file
# with dolfiny.io.XDMFFile(comm, f"{name}.xdmf", "r") as ifile:
#     mesh, mts = ifile.read_mesh_meshtags()

# Get merged MeshTags for each codimension
subdomains, subdomains_keys = dolfiny.mesh.merge_meshtags(mts, tdim - 0)
interfaces, interfaces_keys = dolfiny.mesh.merge_meshtags(mts, tdim - 1)

# Define shorthands for labelled tags
ring_inner = interfaces_keys["ring_inner"]
ring_outer = interfaces_keys["ring_outer"]
domain = subdomains_keys["domain"]

# Fluid material parameters
rho = dolfinx.Constant(mesh, 2.0)  # [kg/m^3]
mu = dolfinx.Constant(mesh, 1.0)  # [kg/m/s]
tau_zero = dolfinx.Constant(mesh, 0.2)  # [kg/m/s^2]
tau_zero_regularisation = dolfinx.Constant(mesh, 1.e-3)  # [-]

# Max inner ring velocity
v_inner_max = 0.1  # [m/s]
# Normal and tangential velocity at inner ring
v_n = dolfinx.Constant(mesh, 0.0)  # [m/s]
v_t = dolfinx.Constant(mesh, 0.0)  # [m/s] -- value set/updated in analysis

# Global time
time = dolfinx.Constant(mesh, 0.0)  # [s]
# Time step size
dt = dolfinx.Constant(mesh, 0.05)  # [s]
# Number of time steps
Exemplo n.º 12
0
def test_assembly_into_quadrature_function():
    """Test assembly into a Quadrature function.

    This test evaluates a UFL Expression into a Quadrature function space by
    evaluating the Expression on all cells of the mesh, and then inserting the
    evaluated values into a PETSc Vector constructed from a matching Quadrature
    function space.

    Concretely, we consider the evaluation of:

        e = B*(K(T)))**2 * grad(T)

    where

        K = 1/(A + B*T)

    where A and B are Constants and T is a Coefficient on a P2 finite element
    space with T = x + 2*y.

    The result is compared with interpolating the analytical expression of e
    directly into the Quadrature space.

    In parallel, each process evaluates the Expression on both local cells and
    ghost cells so that no parallel communication is required after insertion
    into the vector.
    """
    mesh = dolfinx.UnitSquareMesh(MPI.COMM_WORLD, 3, 6)

    quadrature_degree = 2
    quadrature_points, wts = basix.make_quadrature("default",
                                                   basix.CellType.triangle,
                                                   quadrature_degree)
    Q_element = ufl.VectorElement("Quadrature",
                                  ufl.triangle,
                                  quadrature_degree,
                                  quad_scheme="default")
    Q = dolfinx.FunctionSpace(mesh, Q_element)

    def T_exact(x):
        return x[0] + 2.0 * x[1]

    P2 = dolfinx.FunctionSpace(mesh, ("P", 2))
    T = dolfinx.Function(P2)
    T.interpolate(T_exact)
    A = dolfinx.Constant(mesh, 1.0)
    B = dolfinx.Constant(mesh, 2.0)

    K = 1.0 / (A + B * T)
    e = B * K**2 * ufl.grad(T)

    e_expr = dolfinx.Expression(e, quadrature_points)

    map_c = mesh.topology.index_map(mesh.topology.dim)
    num_cells = map_c.size_local + map_c.num_ghosts
    cells = np.arange(0, num_cells, dtype=np.int32)

    e_eval = e_expr.eval(cells)

    # Assemble into Function
    e_Q = dolfinx.Function(Q)
    with e_Q.vector.localForm() as e_Q_local:
        e_Q_local.setBlockSize(e_Q.function_space.dofmap.bs)
        e_Q_local.setValuesBlocked(Q.dofmap.list.array,
                                   e_eval,
                                   addv=PETSc.InsertMode.INSERT)

    def e_exact(x):
        T = x[0] + 2.0 * x[1]
        K = 1.0 / (A.value + B.value * T)

        grad_T = np.zeros((2, x.shape[1]))
        grad_T[0, :] = 1.0
        grad_T[1, :] = 2.0

        e = B.value * K**2 * grad_T
        return e

    # FIXME: Below is only for testing purposes,
    # never to be used in user code!
    #
    # Replace when interpolation into Quadrature element works.
    coord_dofs = mesh.geometry.dofmap
    x_g = mesh.geometry.x
    tdim = mesh.topology.dim
    Q_dofs = Q.dofmap.list.array.reshape(num_cells, quadrature_points.shape[0])
    bs = Q.dofmap.bs

    Q_dofs_unrolled = bs * np.repeat(Q_dofs, bs).reshape(-1,
                                                         bs) + np.arange(bs)
    Q_dofs_unrolled = Q_dofs_unrolled.reshape(
        -1, bs * quadrature_points.shape[0]).astype(Q_dofs.dtype)

    with e_Q.vector.localForm() as local:
        e_exact_eval = np.zeros_like(local.array)

        for cell in range(num_cells):
            xg = x_g[coord_dofs.links(cell), :tdim]
            x = mesh.geometry.cmap.push_forward(quadrature_points, xg)
            e_exact_eval[Q_dofs_unrolled[cell]] = e_exact(x.T).T.flatten()

        assert np.allclose(local.array, e_exact_eval)
Exemplo n.º 13
0
boundary_facets_fine = np.where(
    np.array(dolfinx.cpp.mesh.compute_boundary_facets(mesh_fine.topology)) ==
    1)[0]
boundary_facets_coarse = np.where(
    np.array(dolfinx.cpp.mesh.compute_boundary_facets(mesh_coarse.topology)) ==
    1)[0]

boundary_dofs_fine = dolfinx.fem.locate_dofs_topological(
    V_fine, fdim_fine, boundary_facets_fine)
boundary_dofs_coarse = dolfinx.fem.locate_dofs_topological(
    V_coarse, fdim_coarse, boundary_facets_coarse)

bc_fine = dolfinx.DirichletBC(u_fine, boundary_dofs_fine)
u_D_fine = ufl.TrialFunction(V_fine)
v_D_fine = ufl.TestFunction(V_fine)
f_fine = dolfinx.Constant(mesh_fine, -6)
a_fine = ufl.dot(ufl.grad(u_D_fine), ufl.grad(v_D_fine)) * ufl.dx
#A_fine = dolfinx.fem.assemble_matrix(a_fine, bcs=[bc_fine])
# A_fine.assemble()

bc_coarse = dolfinx.DirichletBC(u_coarse, boundary_dofs_coarse)
u_D_coarse = ufl.TrialFunction(V_coarse)
v_D_coarse = ufl.TestFunction(V_coarse)
f_coarse = dolfinx.Constant(mesh_coarse, -6)
a_coarse = ufl.dot(ufl.grad(u_D_coarse), ufl.grad(v_D_coarse)) * ufl.dx
#A_coarse = dolfinx.fem.assemble_matrix(a_coarse, bcs=[bc_coarse])
# A_coarse.assemble()
"""ai1, aj1, av1 = A_fine.getValuesCSR()
A_sp_fine = scp.sparse.csr_matrix((av1, aj1, ai1))

ai2, aj2, av2 = A_coarse.getValuesCSR()
Exemplo n.º 14
0
def ode_1st_nonlinear_odeint(a=1.0, b=1.0, c=1.0, nT=10, dt=0.1, **kwargs):
    """
    Create 1st order ODE problem and solve with `ODEInt` time integrator.

    First order nonlinear non-autonomous ODE:
    t * dot u - a * cos(c*t) * u^2 - 2 * u - a * b^2 * t^4 * cos(c*t) = 0 with initial condition u(t=1) = 0
    """

    mesh = UnitCubeMesh(MPI.COMM_WORLD, 1, 1, 1)
    U = FunctionSpace(mesh, ("DG", 0))

    u = Function(U, name="u")
    ut = Function(U, name="ut")

    u.vector.set(0.0)  # initial condition
    ut.vector.set(
        a * b**2 *
        numpy.cos(c))  # exact initial rate of this ODE for generalised alpha

    u.vector.ghostUpdate()
    ut.vector.ghostUpdate()

    δu = ufl.TestFunction(U)

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

    # Global time
    t = dolfinx.Constant(mesh, 1.0)

    # Time step size
    dt = dolfinx.Constant(mesh, dt)

    # Time integrator
    odeint = dolfiny.odeint.ODEInt(t=t, dt=dt, x=u, xt=ut, **kwargs)

    # Weak form (as one-form)
    f = δu * (t * ut - a * ufl.cos(c * t) * u**2 - 2 * u -
              a * b**2 * t**4 * ufl.cos(c * t)) * dx

    # Overall form (as one-form)
    F = odeint.discretise_in_time(f)
    # Overall form (as list of forms)
    F = dolfiny.function.extract_blocks(F, [δu])

    # # Options for PETSc backend
    from petsc4py import PETSc
    opts = PETSc.Options()
    opts["snes_type"] = "newtonls"
    opts["snes_linesearch_type"] = "basic"
    opts["snes_atol"] = 1.0e-10
    opts["snes_rtol"] = 1.0e-12

    # Silence SNES monitoring during test
    dolfiny.snesblockproblem.SNESBlockProblem.print_norms = lambda self, it: 1

    # Create nonlinear problem
    problem = dolfiny.snesblockproblem.SNESBlockProblem(F, [u])

    # Book-keeping of results
    u_avg = numpy.zeros(nT + 1)
    u_avg[0] = u.vector.sum() / u.vector.getSize()

    dolfiny.utils.pprint(f"+++ Processing time steps = {nT}")

    # Process time steps
    for time_step in range(1, nT + 1):

        # Stage next time step
        odeint.stage()

        # Solve nonlinear problem
        u, = problem.solve()

        # Assert convergence of nonlinear solver
        assert problem.snes.getConvergedReason(
        ) > 0, "Nonlinear solver did not converge!"

        # Update solution states for time integration
        odeint.update()

        # Store result
        u_avg[time_step] = u.vector.sum() / u.vector.getSize()

    return u_avg
Exemplo n.º 15
0
# Driving velocity condition u = (1, 0) on top boundary (y = 1)
lid_velocity = Function(V)
lid_velocity.interpolate(lid_velocity_expression)
facets = locate_entities_boundary(mesh, 1, lid)
bc1 = DirichletBC(lid_velocity, locate_dofs_topological(V, 1, facets))

# Collect Dirichlet boundary conditions
bcs = [bc0, bc1]

# We now define the bilinear and linear forms corresponding to the weak
# mixed formulation of the Stokes equations in a blocked structure::

# Define variational problem
(u, p) = ufl.TrialFunction(V), ufl.TrialFunction(Q)
(v, q) = ufl.TestFunction(V), ufl.TestFunction(Q)
f = dolfinx.Constant(mesh, (0, 0))

a = [[inner(grad(u), grad(v)) * dx, inner(p, div(v)) * dx],
     [inner(div(u), q) * dx, None]]

L = [inner(f, v) * dx,
     inner(dolfinx.Constant(mesh, 0), q) * dx]

# We will use a block-diagonal preconditioner to solve this problem::

a_p11 = inner(p, q) * dx
a_p = [[a[0][0], None],
       [None, a_p11]]

# Nested matrix solver
# ^^^^^^^^^^^^^^^^^^^^
Exemplo n.º 16
0
#     ofile.write_mesh_meshtags(mesh, mts)

# # Read mesh and meshtags from file
# with dolfiny.io.XDMFFile(comm, f"{name}.xdmf", "r") as ifile:
#     mesh, mts = ifile.read_mesh_meshtags()

# Get merged MeshTags for each codimension
subdomains, subdomains_keys = dolfiny.mesh.merge_meshtags(mts, tdim - 0)
interfaces, interfaces_keys = dolfiny.mesh.merge_meshtags(mts, tdim - 1)

# Define shorthands for labelled tags
ring_inner = interfaces_keys["ring_inner"]
ring_outer = interfaces_keys["ring_outer"]

# Fluid material parameters
rho = dolfinx.Constant(mesh, 2.0)  # [kg/m^3]
mu = dolfinx.Constant(mesh, 1.0)  # [kg/m/s]
tau_zero = dolfinx.Constant(mesh, 0.2)  # [kg/m/s^2]
tau_zero_regularisation = dolfinx.Constant(mesh, 1.e-3)  # [-]

# Max inner ring velocity
v_inner_max = 0.1  # [m/s]

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

# Define integration measures
Exemplo n.º 17
0
    uD_i = dolfinx.Function(V_i)
    uD_i.interpolate(lambda x: 1 + x[0]**2 + 2 * x[1]**2)
    uD_i.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                            mode=PETSc.ScatterMode.FORWARD)
    fdim_i = mesh_i.topology.dim - 1
    mesh_i.topology.create_connectivity(fdim_i, mesh_i.topology.dim)
    boundary_facets_i = np.where(
        np.array(dolfinx.cpp.mesh.compute_boundary_facets(mesh_i.topology)) ==
        1)[0]
    boundary_dofs_i = dolfinx.fem.locate_dofs_topological(
        V_i, fdim_i, boundary_facets_i)
    bc_i = dolfinx.DirichletBC(uD_i, boundary_dofs_i)
    u_i = ufl.TrialFunction(V_i)
    v_i = ufl.TestFunction(V_i)
    f_i = dolfinx.Constant(mesh_i, -6)
    a_i = ufl.dot(ufl.grad(u_i), ufl.grad(v_i)) * ufl.dx
    A_i = dolfinx.fem.assemble_matrix(a_i, bcs=[bc_i])
    A_i.assemble()
    assert isinstance(A_i, PETSc.Mat)
    ai, aj, av = A_i.getValuesCSR()
    A_sp_i = scp.sparse.csr_matrix((av, aj, ai))
    del A_i, av, ai, aj
    # Stores the Sparse version of the Stiffness Matrices
    A_sp_dict[i] = (A_sp_i, i)
    L_i = f_i * v_i * ufl.dx
    b_i = dolfinx.fem.create_vector(L_i)
    with b_i.localForm() as loc_b:
        loc_b.set(0)
    dolfinx.fem.assemble_vector(b_i, L_i)
    dolfinx.fem.apply_lifting(b_i, [a_i], [[bc_i]])