Skip to content

Add manifold example with real spaces #118

@jorgensd

Description

@jorgensd

Code based on @meg-simula's paper, now using GMSH to generate higher order grids:

from mpi4py import MPI
import gmsh
import numpy as np
import ufl
import dolfinx
import scifem

order = 3
exact_case = 2
res = 0.2

gmsh.initialize()
outer_sphere = gmsh.model.occ.addSphere(0, 0, 0, 1)
gmsh.model.occ.synchronize()
boundary = gmsh.model.getBoundary([(3, outer_sphere)], recursive=False)
gmsh.model.addPhysicalGroup(boundary[0][0], [boundary[0][1]], tag=1)
gmsh.option.setNumber("Mesh.CharacteristicLengthFactor", res)
gmsh.model.mesh.generate(2)
gmsh.model.mesh.setOrder(order)

mesh_data = dolfinx.io.gmshio.model_to_mesh(gmsh.model, MPI.COMM_WORLD, 0, gdim=3)


mesh = mesh_data.mesh


# Define global normal
x = ufl.SpatialCoordinate(mesh)
global_normal = x


V = dolfinx.fem.functionspace(mesh, ("RT", order))
Q = dolfinx.fem.functionspace(mesh, ("DG", order - 1))
R = scifem.create_real_functionspace(mesh)
W = ufl.MixedFunctionSpace(*(V, Q, R))

(sigma, u, r) = ufl.TrialFunctions(W)
(tau, v, t) = ufl.TestFunctions(W)

global_orientation = ufl.sign(ufl.dot(x, ufl.CellNormal(mesh)))
sigma_ = global_orientation * sigma
tau_ = global_orientation * tau
# Choose exact solution based on user preference
if exact_case == 1:
    g = x[2]
    u_exact = -0.5 * x[2]
elif exact_case == 2:
    g = x[0] * x[1] * x[2]
    u_exact = -x[0] * x[1] * x[2] / 12
    sigma_exact = ufl.as_vector(
        (
            -(
                x[1] * x[2]
                - 3
                * x[0]
                * x[0]
                * x[1]
                * x[2]
                / (x[0] * x[0] + x[1] * x[1] + x[2] * x[2])
            )
            / 12,
            -(
                x[0] * x[2]
                - 3
                * x[0]
                * x[1]
                * x[1]
                * x[2]
                / (x[0] * x[0] + x[1] * x[1] + x[2] * x[2])
            )
            / 12,
            -(
                x[0] * x[1]
                - 3
                * x[0]
                * x[1]
                * x[2]
                * x[2]
                / (x[0] * x[0] + x[1] * x[1] + x[2] * x[2])
            )
            / 12,
        )
    )
elif exact_case == 3:
    g = 3 * x[2] * x[2] - 1
    u_exact = -(3 * x[2] * x[2] - 1) / 6
else:
    raise Exception("Unrecognized exact case (%d)" % exact_case)

a = (
    ufl.inner(sigma_, tau_) + ufl.div(sigma_) * v + ufl.div(tau_) * u + r * v + t * u
) * ufl.dx
L = [ufl.ZeroBaseForm((tau,)), g * v * ufl.dx, ufl.ZeroBaseForm((t,))]

petsc_options = {
    "ksp_type": "preonly",
    "pc_type": "lu",
    "pc_factor_mat_solver_type": "mumps",
    "ksp_error_if_not_converged": True,
}
problem = dolfinx.fem.petsc.LinearProblem(
    ufl.extract_blocks(a),
    L,
    bcs=[],
    petsc_options=petsc_options,
    petsc_options_prefix="mixed_poisson_",
    kind="mpi",
)
sigma_h, u_h, r_h = problem.solve()

V_out = dolfinx.fem.functionspace(mesh, ("DG", order))
v_out = dolfinx.fem.Function(V_out)
v_out.interpolate(u_h)
v_out.name = "u_h"
with dolfinx.io.VTXWriter(mesh.comm, "u.bp", [v_out]) as vtx_writer:
    vtx_writer.write(0.0)

L2_error_u = dolfinx.fem.form(ufl.inner(u_h - u_exact, u_h - u_exact) * ufl.dx)
sigma_approx = global_orientation * sigma_h
L2_error_sigma = dolfinx.fem.form(
    ufl.inner(sigma_approx - sigma_exact, sigma_approx - sigma_exact) * ufl.dx
)
Hdiv_error_sigma = dolfinx.fem.form(
    ufl.inner(ufl.div(sigma_approx) - g, ufl.div(sigma_approx) - g) * ufl.dx
    + ufl.inner(sigma_approx - sigma_exact, sigma_approx - sigma_exact) * ufl.dx
)

E_u = np.sqrt(mesh.comm.allreduce(dolfinx.fem.assemble_scalar(L2_error_u), op=MPI.SUM))
E_sigma = np.sqrt(
    mesh.comm.allreduce(dolfinx.fem.assemble_scalar(L2_error_sigma), op=MPI.SUM)
)
E_sigma_hdiv = np.sqrt(
    mesh.comm.allreduce(dolfinx.fem.assemble_scalar(Hdiv_error_sigma), op=MPI.SUM)
)
print("L2 error in u:", E_u)
print("L2 error in sigma:", E_sigma)
print("H(div) error in sigma:", E_sigma_hdiv)

Output:

L2 error in u: 6.449031074513135e-07
L2 error in sigma: 1.8679131149781764e-06
H(div) error in sigma: 1.408483169816556e-05

Solution visualized in Paraview:

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions