Unit Cube#

Here we demonstrate how to plot different FEniCSx object for a unit square geometry

First we make the necessary imports

import dolfinx
from mpi4py import MPI
import ufl
import numpy as np
from fenicsx_plotly import plot

First we create the unit cube geometry

mesh = dolfinx.mesh.create_unit_cube(MPI.COMM_WORLD, 3, 3, 3)

Now we can plot the mesh. By default it will plot the mesh in wireframe

plot(mesh)
<fenicsx_plotly._fenicsx_plotly.FEniCSPlotFig at 0x7efbcf0373d0>

We can also turn off wireframe mode

plot(mesh, wireframe=False)
<fenicsx_plotly._fenicsx_plotly.FEniCSPlotFig at 0x7efbc67ba0b0>

Now we can try to create a function space and plot the degrees of freedom

V = dolfinx.fem.FunctionSpace(mesh, ("P",  2))
plot(V)
<fenicsx_plotly._fenicsx_plotly.FEniCSPlotFig at 0x7efbc51dafe0>

This is a scalar function space, but we could also try to create a vector function spaces

W = dolfinx.fem.FunctionSpace(mesh, ufl.VectorElement("P", mesh.ufl_cell(), 2))
plot(W)
<fenicsx_plotly._fenicsx_plotly.FEniCSPlotFig at 0x7efbc4d33430>

We can also plot a function in the scalar function space

p = dolfinx.fem.Function(V)
p.interpolate(lambda x: np.sin(x[0]))
plot(p, scatter=True, wireframe=False)
<fenicsx_plotly._fenicsx_plotly.FEniCSPlotFig at 0x7efc08796f50>

Or we can use a surface plot

p = dolfinx.fem.Function(V)
p.interpolate(lambda x: np.sin(x[0]))
plot(p, scatter=False, wireframe=False, show_grid=True)
<fenicsx_plotly._fenicsx_plotly.FEniCSPlotFig at 0x7efbc4dea0b0>

Now let us create a function in the vector function space and plot it

u = dolfinx.fem.Function(W)
# Just create create some non-trivial function
x = ufl.SpatialCoordinate(mesh)
expr = dolfinx.fem.Expression(
    ufl.as_vector((1 + x[0], x[1], x[2])), W.element.interpolation_points()
)

u.interpolate(expr)

plot(u, size=1)
plot(u, normalize=True, size=1)
<fenicsx_plotly._fenicsx_plotly.FEniCSPlotFig at 0x7efbc4de9000>
for component in ["magnitude", "x", "y", "z"]:
    plot(u, component=component)

We can also plot MeshTags

locator_x0 = lambda x: np.isclose(x[0], 0)
entities_x0 = dolfinx.mesh.locate_entities(mesh, 2, locator_x0)
marker_x0 = 1
values_x0 = np.full_like(entities_x0, marker_x0)

locator_x1 = lambda x: np.isclose(x[0], 1)
entities_x1 = dolfinx.mesh.locate_entities(mesh, 2, locator_x1)
marker_x1 = 2
values_x1 = np.full_like(entities_x0, marker_x1)

entities = np.hstack([entities_x0, entities_x1])
values = np.hstack([values_x0, values_x1])

facet_tags = dolfinx.mesh.meshtags(mesh, 2, entities, values)
plot(facet_tags, show_grid=True, mesh=mesh)
<fenicsx_plotly._fenicsx_plotly.FEniCSPlotFig at 0x7efbc4938be0>

And we can plot dirichlet BC (currently only scalar values)

boundary = lambda x: np.isclose(x[0], 0)

el = ufl.FiniteElement("P", mesh.ufl_cell(), 2)
V = dolfinx.fem.FunctionSpace(mesh, el)

dofs_D = dolfinx.fem.locate_dofs_geometrical(V, boundary)
u_exact = lambda x: 1 + x[1] + x[2] 

u_bc = dolfinx.fem.Function(V)
u_bc.interpolate(u_exact)
bc = dolfinx.fem.dirichletbc(u_bc, dofs_D)
plot(bc, show_grid=True)
<fenicsx_plotly._fenicsx_plotly.FEniCSPlotFig at 0x7efbc4d32bc0>