import underworld3 as uw
import numpy as np
import sympy
Notebook 2: Variables
We can add discrete variables (unknowns associated with the mesh points).
= uw.meshing.uw.meshing.CubedSphere(
mesh =1.0,
radiusOuter=0.547,
radiusInner=8,
numElements=False,
simplex=False,
verbose
)
= mesh.CoordinateSystem.X
x,y,z = mesh.CoordinateSystem.R
r,th,phi = mesh.CoordinateSystem.unit_e_0
r_vec = mesh.CoordinateSystem.unit_e_1
th_vec = mesh.CoordinateSystem.unit_e_2 phi_vec
This example shows how we can add a scalar field with a single value associated with each mesh node, and a vector field which has quadratic interpolation (points at the nodes plus interpolating points along mesh edges).
# mesh variable example / test
= uw.discretisation.MeshVariable(
scalar_var ="Radius",
varname=mesh,
mesh= uw.VarType.SCALAR,
vtype =r"r"
varsymbol
)
= uw.discretisation.MeshVariable(
vector_var ="Vertical_Vec",
varname=mesh,
mesh=2,
degree= uw.VarType.VECTOR,
vtype =r"\mathbf{v}",
varsymbol
)
To set values of the variable, we first have to unlock it using the access
context manager, and then we can evaluate
a function at the coordinates appropriate to fill up each variable:
with mesh.access(scalar_var, vector_var):
0] = uw.function.evaluate(r, scalar_var.coords)
scalar_var.data[:,= uw.function.evaluate(r_vec, vector_var.coords) vector_var.data[:,:]
Variables are like most underworld
and PETSc
objects - they can be examined using their view()
method. The information that you will see is split into the underworld representation (listed under MeshVariable) and the PETSc representation (listed under FE Data which also includes the numerical values).
scalar_var.view()
Class: <class ‘underworld3.discretisation._MeshVariable’>
MeshVariable:
symbol: \({ \hspace{ 0.03pt } {r} }\)
shape: \((1, 1)\)
degree: \(1\)
continuous:
True
type:
SCALAR
FE Data:
PETSc field id: \(0\)
PETSc field name:
Radius
array([[1. ],
[1. ],
[1. ],
...,
[0.830125],
[0.88675 ],
[0.943375]])
# Visualise it / them
import pyvista as pv
import underworld3.visualisation as vis
= vis.mesh_to_pv_mesh(mesh)
pvmesh "z"] = vis.scalar_fn_to_pv_points(pvmesh, mesh.CoordinateSystem.X[2])
pvmesh.point_data["r"] = vis.scalar_fn_to_pv_points(pvmesh, scalar_var.sym[0])
pvmesh.point_data["V"] = vis.vector_fn_to_pv_points(pvmesh, (1-scalar_var.sym[0]) * vector_var.sym)
pvmesh.point_data[
if mesh.dim==3:
= pvmesh.clip( normal='z', crinkle=True,origin=(0.0,0.0,0.01))
pvmesh_clipped
# pvmesh.plot(show_edges=True, show_scalar_bar=False)
= pv.Plotter(window_size=(750, 750))
pl
pl.add_mesh(pvmesh_clipped, =True,
show_edges="z",
scalars=0.6,
opacity=False)
show_scalar_bar
pl.add_arrows(pvmesh.points, "V"],
pvmesh.point_data[=0.25,
mag=0.6,
opacity="Black",
color=False)
show_scalar_bar
"html5/echidna_plot.html") pl.export_html(
from IPython.display import IFrame
="html5/echidna_plot.html", width=600, height=400) IFrame(src
Interactive Image: Spherical shell mesh cut away to show radial arrows with length decreasing away from the centre.
More information
The meshVariable code is described in the API docs: https://underworldcode.github.io/underworld3/main_api/underworld3/meshing.html