I want to plot vector fields belonging to spaces other than Lagrange spaces. As far as I know, the way to do this is to interpolate to a Lagrange vector field, and plot the Lagrange vector field. I have tried to do this, but it results in some weird plots. What is going on? And is this the right way to plot vector fields that are not Lagrange?
import numpy as np
import gmsh
from dolfinx.io import gmshio
from dolfinx import plot
import basix
from mpi4py import MPI
import pyvista as pv
import dolfinx.mesh as mesh
import dolfinx.fem as fem
approximate_simplex_diameter = 0.25
deviation = 0.001
gmsh.initialize()
gmsh.option.setNumber("General.Terminal",0) # Turn off terminal output for gmsh
model = gmsh.model()
model.add("Sphere") # Adds a new model with the name "name"
model.setCurrent("Sphere") # Sets the model we are currently working on to the model called "name"
sphere = model.occ.addSphere(0,0,0,1) # Adds a sphere with radius 1 and center at (0,0,0) to the model
centre_of_earth = model.occ.addPoint(0,0,0) # Adds a point at the center of the sphere
point_close_to_point2 = model.occ.addPoint(np.cos(-np.pi/2 -approximate_simplex_diameter),0,np.sin(-np.pi/2 -approximate_simplex_diameter)) # Adds a point close to the south pole
equator = model.occ.addCircleArc(1,centre_of_earth,point_close_to_point2)
gmsh.model.occ.synchronize()
model.add_physical_group(dim=2, tags=[sphere]) # Adds a physical group to the model. The group is a 2D group with the tag "sphere"
gmsh.model.mesh.embed(1, [equator],2,1) # Embeds the 1D entities in the 2D entities
gmsh.option.setNumber("Mesh.Algorithm", 6)
gmsh.option.setNumber("Mesh.ElementOrder", 2)
#gmsh.option.setNumber("Mesh.HighOrderOptimize", 2)
gmsh.option.setNumber("Mesh.Smoothing", 100)
gmsh.option.setNumber("Mesh.CharacteristicLengthMin", approximate_simplex_diameter - deviation)
gmsh.option.setNumber("Mesh.CharacteristicLengthMax", approximate_simplex_diameter + deviation)
gmsh.model.mesh.generate(2)
msh, cell_tags,facet_tags= gmshio.model_to_mesh(model,MPI.COMM_WORLD, gdim = 3, rank = 0)
N1E = basix.ufl.element(basix.ElementFamily.N1E,basix.CellType.triangle,degree = 1)
BDM = basix.ufl.element(basix.ElementFamily.BDM,basix.CellType.triangle, degree = 1)
P = basix.ufl.element(basix.ElementFamily.P,basix.CellType.triangle, shape = (3,), degree = 2, discontinuous=False)
N1E = fem.functionspace(msh, N1E)
BDM = fem.functionspace(msh, BDM)
P = fem.functionspace(msh, P)
n1e = fem.Function(N1E)
bdm = fem.Function(BDM)
p = fem.Function(P)
n1e.interpolate(lambda x : np.array([-x[2], np.zeros_like(x[1]), x[0]]))
bdm.interpolate(lambda x : np.array([ -x[2], np.zeros_like(x[1]), x[0]]))
p.interpolate(lambda x : np.array([ -x[2], np.zeros_like(x[1]), x[0]]))
cells, cell_types, x = plot.vtk_mesh(P)
grid = pv.UnstructuredGrid(cells, cell_types, x)
plotter = pv.Plotter(shape=(1, 3))
plotter.subplot(0, 0)
plotter.add_mesh(grid,style = "surface", color = "beige")
grid.point_data["v"] = p.x.array.reshape(-1, msh.geometry.dim)
plotter.add_text("Interpolate directly", font_size=12, position="upper_edge")
glyphs = grid.glyph(orient="v", factor=0.08)
plotter.add_mesh(glyphs, show_scalar_bar=False)
p.interpolate(n1e)
plotter.subplot(0, 1)
plotter.add_mesh(grid,style = "surface" ,color = "beige")
grid.point_data["v"] = p.x.array.reshape(-1, msh.geometry.dim)
plotter.add_text("Interpolate via N1E", font_size=12, position="upper_edge")
glyphs = grid.glyph(orient="v", factor=0.08)
plotter.add_mesh(glyphs, show_scalar_bar=False)
p.interpolate(bdm)
plotter.subplot(0, 2)
plotter.add_mesh(grid,style = "surface" ,color = "beige")
grid.point_data["v"] = p.x.array.reshape(-1, msh.geometry.dim)
plotter.add_text("Interpolate via BDM", font_size=12, position="upper_edge")
glyphs = grid.glyph(orient="v", factor=0.08)
plotter.add_mesh(glyphs, show_scalar_bar=False)
plotter.show()