API – mesher¶
HOMER.mesher.MeshNode(loc, id=None, **kwargs)
¶
Bases: dict
A mesh node that stores a physical location and associated derivative data.
:class:MeshNode subclasses :class:dict so that derivative quantities
(du, dv, dw, dudv, …) required by higher-order basis
functions can be stored as named entries. All values must be
:class:numpy.ndarray objects of the same length as loc.
For a 2-D manifold mesh with cubic-Hermite basis in both directions
(H3Basis, H3Basis), each node must carry du, dv, and
dudv derivatives::
node = MeshNode(
loc=np.array([0.0, 0.0, 1.0]),
du=np.zeros(3),
dv=np.zeros(3),
dudv=np.zeros(3),
)
For a 3-D volume mesh with H3Basis in all three directions, the
additional derivatives dw, dudw, dvdw, and dudvdw are
also required::
node = MeshNode(
loc=np.array([0.0, 0.0, 1.0]),
du=np.zeros(3), dv=np.zeros(3), dw=np.zeros(3),
dudv=np.zeros(3), dudw=np.zeros(3), dvdw=np.zeros(3),
dudvdw=np.zeros(3),
)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
loc
|
Physical-space coordinates of the node, shape |
required | |
id
|
Optional unique identifier. When provided, nodes can be referenced
by ID rather than list index in a :class: |
None
|
|
**kwargs
|
Named derivative arrays, e.g. |
{}
|
Attributes:
| Name | Type | Description |
|---|---|---|
loc |
ndarray
|
Physical-space coordinates, shape |
id |
The node identifier (or |
|
fixed_params |
dict
|
Maps parameter name → array of fixed component indices. Populated
by :meth: |
Initialise a :class:MeshNode.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
loc
|
Physical-space coordinates, shape |
required | |
id
|
Optional unique identifier. |
None
|
|
**kwargs
|
Named derivative arrays ( |
{}
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If any keyword-argument value is not an array-like type. |
fix_parameter(param_names, values=None, inds=None)
¶
Mark one or more node parameters as fixed (non-optimisable).
Fixed parameters are excluded from the optimisable parameter vector
exposed by :class:MeshField. Optionally, the parameter can also be
set to a specified value at the same time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
param_names
|
list | str
|
Name or list of names of the parameters to fix, e.g.
|
required |
values
|
Optional[list[ndarray] | ndarray]
|
Optional value(s) to assign at the time of fixing. Must match
the shape implied by |
None
|
inds
|
Optional[list[int]]
|
Component indices to fix within the parameter array (e.g.
|
None
|
get_optimisability_arr()
¶
Returns the optimisable status of all data stored on the node.
plot(scene=None)
¶
Draws the node, and any quantities, to a pyvista plotter. :param scene: An existing pyvista scene to draw too - if given will not draw the plot.
HOMER.mesher.MeshElement(basis_functions, node_indexes=None, node_ids=None, BP_inds=None, id=None)
¶
A single high-order mesh element linking nodes through tensor-product basis functions.
A :class:MeshElement combines a list of :class:MeshNode references with
a group of 1-D basis functions (one per parametric direction) to define a
2-D manifold surface element or a 3-D volume element.
The number of nodes required per element equals the product of the numbers of 1-D basis nodes:
- H3Basis × H3Basis → 2 × 2 = 4 nodes (2-D)
- H3Basis × H3Basis × H3Basis → 2 × 2 × 2 = 8 nodes (3-D)
- L2Basis × L2Basis → 3 × 3 = 9 nodes (2-D)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
basis_functions
|
BasisGroup
|
A sequence of 1-D basis classes (length 2 or 3) defining the
parametric-direction interpolation. E.g.
|
required |
node_indexes
|
Optional[list[int]]
|
Zero-based integer indices into the parent mesh's |
None
|
node_ids
|
Optional[list]
|
User-supplied node identifiers (alternative to node_indexes). |
None
|
BP_inds
|
Optional
|
Pre-computed basis-product index pairs. Computed automatically
when |
None
|
id
|
Optional element identifier. |
None
|
Attributes:
| Name | Type | Description |
|---|---|---|
ndim |
int
|
Parametric dimensionality (2 or 3). |
nodes |
list
|
The ordered node references (indexes or ids). |
basis_functions |
BasisGroup
|
The sequence of 1-D basis classes. |
used_node_fields |
list[str]
|
Derivative field names ( |
BasisProductInds |
list[tuple[int, ...]]
|
Ordered index pairs/triplets defining the tensor-product weight computation. |
num_nodes |
int
|
Total number of nodes in this element. |
Initialise a :class:MeshElement.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
basis_functions
|
BasisGroup
|
A sequence of 1-D basis classes (length 2 or 3). |
required |
node_indexes
|
Optional[list[int]]
|
Zero-based indices into the parent mesh's node list. |
None
|
node_ids
|
Optional[list]
|
User-supplied node identifiers. |
None
|
BP_inds
|
Optional
|
Pre-computed basis-product index pairs (optional optimisation). |
None
|
id
|
Optional element identifier. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If neither node_indexes nor node_ids is provided, or if both are provided. |
get_used_fields()
¶
Calculates the used node fields for field objects. This represents the increasing derivative pattern du -> du, dw, dudw -> du ... dudvdw
argsort_derivs(derivs_struct, order_dict)
¶
Given a derivs struct defined iternally, returns the canonical ordering according to a given order dict.
:params derivs_struct: The calculated derivative pairs to evaluate. :params order_dict: The ordering to follow
HOMER.mesher.MeshField(nodes=None, elements=None, jax_compile=False)
¶
A collection of :class:MeshNode and :class:MeshElement objects representing a single field.
:class:MeshField is the base class for both the primary geometry of a
:class:Mesh and for any secondary fields (fibre directions, stresses,
velocities, etc.) created with :meth:Mesh.new_field.
A :class:MeshField owns:
- A node list storing the field's degrees of freedom (parameter values and, for Hermite bases, derivative vectors).
- An element list defining how nodes are connected and which basis functions to use for interpolation.
- Compiled JAX functions (built by :meth:
generate_mesh) for fast evaluation, differentiation, and optimisation.
The @expand_wide_evals decorator automatically adds
*_in_every_element and *_ele_xi_pair variants for every method
decorated with @wide_eval.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nodes
|
Optional[list[MeshNode]]
|
List of :class: |
None
|
elements
|
Union[list[MeshElement], MeshElement, NoneType]
|
List (or single instance) of :class: |
None
|
jax_compile
|
bool
|
When |
False
|
Attributes:
| Name | Type | Description |
|---|---|---|
nodes |
list[MeshNode]
|
All nodes belonging to this field. |
elements |
list[MeshElement]
|
All elements belonging to this field. |
fdim |
int
|
Physical dimensionality of the field values (e.g. 3 for XYZ). |
ndim |
int
|
Parametric dimensionality (2 or 3). |
true_param_array |
ndarray
|
Flat vector of all nodal parameters (free and fixed). |
optimisable_param_array |
ndarray
|
Subset of true_param_array that is not fixed. |
optimisable_param_bool |
ndarray
|
Boolean mask selecting optimisable parameters from true_param_array. |
ele_map |
ndarray
|
|
Initialise a :class:MeshField.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nodes
|
Optional[list[MeshNode]]
|
Node list (or |
None
|
elements
|
Union[list[MeshElement], MeshElement, NoneType]
|
Element or list of elements (or |
None
|
jax_compile
|
bool
|
If |
False
|
evaluate_embeddings(*a, **kw)
¶
Evaluate the field at parametric coordinates within one or more elements.
This is a placeholder that is replaced by a compiled JAX function when
:meth:generate_mesh is called. The full signature after
initialisation is::
evaluate_embeddings(element_ids, xis, fit_params=None) -> jnp.ndarray
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
element_ids
|
1-D array of integer element indices, shape |
required | |
xis
|
Parametric coordinates, shape |
required | |
fit_params
|
Override of the current :attr: |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Field values at the requested locations, shape |
Notes
The @expand_wide_evals class decorator automatically creates two
additional variants:
evaluate_embeddings_in_every_element(xis)– evaluates the same grid of xi points in every element and stacks the results.evaluate_embeddings_ele_xi_pair(element_ids, xis)– evaluates each(element, xi)pair independently (equivalent signature to the base function but without batching).
evaluate_deriv_embeddings(*a, **kw)
¶
Evaluate a specified partial derivative of the field.
This is a placeholder replaced at :meth:generate_mesh time. The
full signature is::
evaluate_deriv_embeddings(element_ids, xis, derivs, fit_params=None)
-> jnp.ndarray
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
element_ids
|
1-D integer array, shape |
required | |
xis
|
Parametric coordinates, shape |
required | |
derivs
|
Derivative order per parametric direction, e.g. |
required | |
fit_params
|
Optional override of :attr: |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Derivative field values, shape |
evaluate_element_embeddings(element_id, xis, fit_params=None)
¶
Evaluate the embedding for a single element identified by its ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
element_id
|
The user-assigned element ID (not the list index). |
required | |
xis
|
Parametric coordinates, shape |
required | |
fit_params
|
Optional parameter override. |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Field values, shape |
evaluate_normals(element_ids, xis, fit_params=None)
¶
Return the surface normal vectors at parametric coordinates.
Only valid for 2-D manifold meshes (ndim == 2). The normal is
computed as the cross product of the two surface tangent vectors.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
element_ids
|
ndarray
|
1-D integer array of element indices, shape |
required |
xis
|
ndarray
|
Parametric coordinates, shape |
required |
fit_params
|
Optional override of :attr: |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Normal vectors (not normalised), shape |
Raises:
| Type | Description |
|---|---|
ValueError
|
If called on a 3-D volume mesh. |
eval_numeric_jac(element_ids, xis, locals=None, step=0.2, fit_params=None)
¶
Evaluates the jacobian at a set of xis within an element Uses numeric derivatives, useful when the underlying mesh field has zero derivative boundaries.
evaluate_jacobians(element_ids, xis, fit_params=None)
¶
Evaluate the Jacobian matrix of the embedding at parametric coordinates.
Returns ∂x/∂ξ, the matrix mapping parametric-space tangent vectors to physical-space tangent vectors. Rows correspond to physical directions (x, y, z) and columns to parametric directions (u, v[, w]).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
element_ids
|
1-D integer array, shape |
required | |
xis
|
Parametric coordinates, shape |
required | |
fit_params
|
Optional override of :attr: |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Jacobian matrices, shape |
xi_grid(res, dim=None, surface=False, boundary_points=True, lattice=None)
¶
Return a regular grid of parametric (xi) coordinates.
Creates a uniform Cartesian grid of xi points for use with
:meth:evaluate_embeddings_in_every_element or for passing to
:meth:get_xi_weight_mat.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
res
|
int
|
Number of grid points along each parametric direction. The
total number of points is |
required |
dim
|
Dimensionality of the grid (2 or 3). Defaults to
:attr: |
None
|
|
surface
|
For a 3-D mesh, return only points on the six element faces rather than the full interior grid. |
False
|
|
boundary_points
|
When |
True
|
|
lattice
|
Optional |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Grid points, shape |
gauss_grid(ng)
¶
Return a tensor-product Gauss quadrature grid.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ng
|
|
required |
Returns:
| Name | Type | Description |
|---|---|---|
Xi |
ndarray
|
Gauss point locations, shape |
W |
ndarray
|
Corresponding quadrature weights, shape |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
get_element_params(ele_num)
¶
returns the flat vector of node parameters associated with this element.
update_from_params(inp_params, generate=True)
¶
Updates all nodes with data from an input param array.
:param inp_params: the input params to update the mesh with :param generate: whether to rebuild the mesh after updating.
generate_mesh()
¶
Builds the mesh representation on call.
This code is responsible for handling on-the-fly functions, and the generation of the 'fast' pathway jax.numpy array representation.
add_node(node)
¶
Add a node to the node list.
add_element(element)
¶
Adds an element to the element list.
get_element(element_ids)
¶
Returns the element with the associated id.
associated_node_index(index_list, nodes_to_gather=None, node_by_id=False)
¶
Given an index list, returns the associated indexes of features in that index in the input param array. Used to perform manipulations, and identify which features to fix
unfix_mesh()
¶
Removes all fixed parameters in the mesh, and regenerates the mesh structure.
get_surface(element_ids=None, res=20, just_faces=False, tiling=None)
¶
Returns a set of points evaluated over the mesh surface.
get_hex_surface(element_ids, tiling=(10, 6))
¶
Returns lines evaluating a hexagon tiling of the element surface
:params tiling: the repetitions of the underlying unit surface (5/3 ratio "looks good")
get_triangle_surface(element_ids=None, res=20)
¶
Returns a set of points evaluated over the mesh surface, and triangles to create the surface.
:returns surface pts: Surface points evaluated over the mesh. :returns tris: the triangles creatign the mesh surface.
get_lines(element_ids=None, res=20)
¶
Returns a pv.PolyData object containing lines defining the edges of the mesh surface.
get_faces(rounding_res=10)
¶
Returns all external faces of the current mesh. Faces are indicated as tuples (elem_id, dim, {0,1}). By definition, A manifold is a face, indicated as (elem_id, -1, -1). Faces are determined by spatial hashing of the face center i.e (0.5,0.5, {0,1})
plot(scene=None, node_colour='r', node_size=10, labels=False, tiling=(10, 6), mesh_colour='gray', mesh_opacity=0.1, mesh_width=2, mesh_col_scalar_name='Field', line_colour='black', line_opacity=1, line_width=2, line_col_scalar_name='Field', elem_labels=False, render_name=None)
¶
Draws the mesh as a pyvista scene.
:param scene: A pyvista scene, if provided will not call .show(). :param node_colour: The colour to draw the node values. :param node_size: The size of the node points. :param labels: Whether to label the node numbers. :param res: The resolution of the surface mesh. :param mesh_color: The mesh surface colour. :param mesh_opacity: The mesh surface opacity. :param elem_labels: Whether to label the mesh elements.
transform(tform)
¶
Apply a 4x4 3D homogenous transform to the mesh.
embed_points(points, verbose=0, init_elexi=None, fit_params=None, return_residual=False, surface_embed=False, iterations=3)
¶
Find the parametric coordinates (element, xi) for a set of physical-space points.
Uses an approximate nearest-neighbour search on a coarse xi grid to
obtain initial estimates, then refines with a JAX-accelerated RK4
fixed-iteration descent (see :meth:_xis_to_points). Topology
mapping (:meth:topomap) is applied at each iteration so that points
near element boundaries are correctly assigned to neighbouring
elements.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
points
|
Physical-space query points, shape |
required | |
verbose
|
Verbosity level. |
0
|
|
init_elexi
|
Pre-computed initial |
None
|
|
fit_params
|
Optional parameter override for the mesh geometry. |
None
|
|
return_residual
|
When |
False
|
|
surface_embed
|
Restrict the coarse search to the surface faces of a 3-D mesh. |
False
|
|
iterations
|
Number of RK4 refinement iterations. |
3
|
Returns:
| Name | Type | Description |
|---|---|---|
elem_num |
ndarray
|
Element index for each query point, shape |
embedded |
ndarray
|
Parametric coordinates, shape |
residual |
ndarray
|
(Only when return_residual is |
evaluate_sobolev(weights=None, fit_params=None)
¶
Works out and defines the Sobolev values associated with the derivatives of the input elements. Then calculates the appropriate gauss points, and returns the elements assessed with the appropriate weighting.
get_volume(fit_params=None)
¶
Calculates the mesh volume using a gauss point integration scheme.
:param fit_params: an overide of the standard mesh parameters to use for fitting. :returns vol: The estimated volume of the mesh.
evaluate_strain(element_ids, xis, othr, coord_function=None, return_F=False, fit_params=None)
¶
Evaluate the Green-Lagrange strain tensor between two mesh states.
Computes the deformation gradient F = J_ref⁻¹ · J_def where J_ref is the Jacobian of self (reference configuration) and J_def is the Jacobian of othr (deformed configuration), then returns the strain tensor E = (Fᵀ F − I) / 2.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
element_ids
|
1-D integer array, shape |
required | |
xis
|
Parametric coordinates, shape |
required | |
othr
|
Mesh
|
A :class: |
required |
coord_function
|
Optional[Callable]
|
Optional callable |
None
|
return_F
|
When |
False
|
|
fit_params
|
Optional parameter override for self. |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Green-Lagrange strain tensor |
Raises:
| Type | Description |
|---|---|
ValueError
|
If called on a 2-D manifold mesh without supplying coord_function. |
get_xi_weight_mat(eles, xis)
¶
Build the linear weight matrix for least-squares fitting.
For each query point (eles[i], xis[i]), evaluates the basis
function values and places them in the appropriate column positions of
a global weight matrix W, where W[i, j] is the contribution
of the j-th nodal degree of freedom to the i-th query point.
This matrix is used by :meth:linear_fit::
W * node_params = target_values (solved in a least-squares sense)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
eles
|
1-D integer array of element indices, shape |
required | |
xis
|
Parametric coordinates, shape |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Weight matrix, shape |
linear_fit(targets, weight_mat, target_empty=-1)
¶
Fit nodal parameters by solving a linear least-squares problem.
Solves weight_mat @ params ≈ targets via :func:numpy.linalg.lstsq
and updates the mesh's nodal parameters with the solution. This is
the fastest fitting approach when the xi embeddings are fixed (i.e. the
mesh topology does not change during fitting).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
targets
|
Target field values, shape |
required | |
weight_mat
|
Weight matrix from :meth: |
required | |
target_empty
|
Sentinel value used to mask out unused target rows. |
-1
|
Notes
Fixed parameters (set via :meth:MeshNode.fix_parameter) are
currently not respected by this method. Use the nonlinear
optimisation pathway (fitting.point_cloud_fit) if constraints
are required.
refine(refinement_factor=None, by_xi_refinement=None, clean_nodes=True)
¶
Subdivide every element, increasing the mesh resolution.
Each existing element is replaced by refinement_factor ** ndim
(or the equivalent for by_xi_refinement) smaller elements sharing
intermediate nodes. Derivative values at the new nodes are obtained
by evaluating the current basis functions.
Exactly one of refinement_factor or by_xi_refinement must be provided.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
refinement_factor
|
Optional[int]
|
Integer ≥ 2 that subdivides each parametric direction uniformly.
For example, |
None
|
by_xi_refinement
|
Optional[tuple[ndarray]]
|
Tuple of 1-D arrays, one per parametric direction, specifying the xi values at which to place the new element boundaries. Each array must start with 0 and end with 1. |
None
|
clean_nodes
|
When |
True
|
Raises:
| Type | Description |
|---|---|
AssertionError
|
If both refinement_factor and by_xi_refinement are given, or if refinement_factor < 2. |
save(loc)
¶
Saves the mesh to a .json formated file in the given location
dump_to_dict()
¶
Returns a dict structure representing the mesh object, for ease of saving
__deepcopy__(memo)
¶
Dumps the mesh to a dictionairy then rebuilds it to ensure that there is no shared memory between a mesh and it's deepcopy.
rebase(new_basis, in_place=False, res=10)
¶
Convert the mesh to a different set of basis functions.
Constructs a new :class:MeshField with new_basis, sampling the
current mesh on a dense xi grid and linearly fitting the new nodal
parameters to match the sampled geometry. This allows, for example,
converting a trilinear (L1Basis) mesh into a cubic-Hermite
(H3Basis) mesh without losing the shape.
The three-step algorithm is:
- Determine the new node locations by evaluating the current mesh at the basis node positions of new_basis.
- Sample a fine xi grid in the current basis to get dense geometry samples.
- Linearly fit the new nodal parameters to these samples.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
new_basis
|
tuple[type[AbstractBasis], type[AbstractBasis]] | tuple[type[AbstractBasis], type[AbstractBasis], type[AbstractBasis]] | list[type[AbstractBasis], type[AbstractBasis]]
|
Sequence of new 1-D basis classes, one per parametric direction. |
required |
in_place
|
Currently unused (future: modify self rather than returning a new object). |
False
|
|
res
|
Number of xi grid points per direction used for the linear fit. |
10
|
Returns:
| Type | Description |
|---|---|
MeshField
|
New mesh with the requested basis functions. |
HOMER.mesher.Mesh(nodes=None, elements=None, jax_compile=False)
¶
Bases: MeshField
A coordinate mesh that can also carry named secondary fields.
:class:Mesh extends :class:MeshField by adding a dictionary
fields that stores secondary :class:MeshField objects. The
primary geometry (XYZ world-space coordinates) is stored in the parent
:class:MeshField, while any secondary quantities such as fibre
directions, velocities, or material properties are stored as named
entries in fields.
Secondary fields are created with :meth:new_field and accessed via
dictionary-style indexing::
mesh = Mesh(nodes=[...], elements=[...])
mesh.new_field('fibre', field_dimension=3,
field_locs=data_pts, field_values=fibre_vectors,
new_basis=[H3Basis]*3)
fibre_field = mesh['fibre'] # MeshField
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nodes
|
Optional[list[MeshNode]]
|
Nodes defining the primary geometry. |
None
|
elements
|
Optional[list[MeshElement] | MeshElement]
|
Elements of the mesh. |
None
|
jax_compile
|
bool
|
Pre-compile JAX functions at construction time. |
False
|
Attributes:
| Name | Type | Description |
|---|---|---|
fields |
dict[str, MeshField]
|
Named secondary fields. |
Initialise a :class:Mesh.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nodes
|
Optional[list[MeshNode]]
|
Node list (may be |
None
|
elements
|
Optional[list[MeshElement] | MeshElement]
|
Element or element list. |
None
|
jax_compile
|
bool
|
If |
False
|
refine(refinement_factor=None, by_xi_refinement=None, clean_nodes=True)
¶
Refine the primary geometry and all secondary fields simultaneously.
Calls :meth:MeshField.refine on the coordinate mesh and on every
field in :attr:fields.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
refinement_factor
|
Optional[int]
|
Uniform refinement multiplier (≥ 2). |
None
|
by_xi_refinement
|
Optional[tuple[ndarray]]
|
Per-direction xi breakpoint arrays. |
None
|
clean_nodes
|
Remove unreferenced nodes after refinement. |
True
|
plot(scene=None, node_colour='r', node_size=10, labels=False, tiling=(10, 6), mesh_colour='gray', mesh_opacity=0.1, mesh_width=2, mesh_col_scalar_name='Field', line_colour='black', line_opacity=1, line_width=2, line_col_scalar_name='Field', elem_labels=False, render_name=None, field_to_draw=None, field_xi=None, draw_xyz_field=True, field_artist=None, default_field_point_size=25, default_xi_res=4)
¶
Draw the mesh and optionally overlay a secondary field.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scene
|
Optional[Plotter]
|
Existing :class: |
None
|
node_colour
|
Colour for node spheres. |
'r'
|
|
node_size
|
Node sphere size. |
10
|
|
labels
|
When |
False
|
|
tiling
|
|
(10, 6)
|
|
mesh_colour
|
str | ndarray
|
Surface mesh colour. Pass a :class: |
'gray'
|
mesh_opacity
|
Surface opacity (0–1). |
0.1
|
|
mesh_width
|
Line width for the hex wireframe. |
2
|
|
mesh_col_scalar_name
|
Scalar array name used when mesh_colour is an array. |
'Field'
|
|
line_colour
|
str | ndarray
|
Colour for the structural edge lines. |
'black'
|
line_opacity
|
Edge line opacity. |
1
|
|
line_width
|
Edge line width. |
2
|
|
line_col_scalar_name
|
Scalar name for colour-mapped edges. |
'Field'
|
|
elem_labels
|
When |
False
|
|
render_name
|
Optional[str]
|
Prefix for named actors (allows individual actor replacement in an interactive scene). |
None
|
field_to_draw
|
Name of a secondary field to visualise. When |
None
|
|
field_xi
|
Custom xi grid at which to evaluate the secondary field. Defaults to a uniform grid at default_xi_res. |
None
|
|
draw_xyz_field
|
When |
True
|
|
field_artist
|
Optional[Callable[[Plotter, ndarray, ndarray], None]]
|
Custom callable |
None
|
default_field_point_size
|
Point size used by the default scalar field artist. |
25
|
|
default_xi_res
|
Xi grid resolution for the secondary field visualisation. |
4
|
new_field(field_name, field_dimension, new_basis, field_locs=None, field_values=None, res=10)
¶
Create a secondary field and optionally fit it to sample data.
A secondary field is a :class:MeshField with its own basis
functions and node topology that is co-located with the primary
coordinate mesh. It can represent any spatially varying quantity
– fibre directions, velocity vectors, pressures, stresses, etc.
The three-step construction algorithm is:
- Determine the new field node locations by evaluating the primary mesh at the node positions of new_basis.
- If field_locs and field_values are provided, embed the sample
points into the mesh with :meth:
embed_points. - Build the linear weight matrix and solve for nodal parameters with
:meth:
linear_fit.
After this call, the field is accessible as mesh[field_name].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
field_name
|
str
|
Key used to store and retrieve the new field, e.g.
|
required |
field_dimension
|
int
|
Dimensionality of the field values:
|
required |
new_basis
|
BasisGroup
|
Sequence of 1-D basis classes for the new field, one per
parametric direction. May differ from the primary mesh basis.
For example, use |
required |
field_locs
|
Optional[ndarray]
|
Physical-space sample locations where field values are known,
shape |
None
|
field_values
|
Optional[ndarray]
|
Target field values at field_locs, shape
|
None
|
res
|
Unused (reserved for future use). |
10
|
Examples:
Fit a unit-normal vector field and a scalar height field::
mesh.new_field(
'normals',
field_dimension=3,
field_locs=sample_pts, # shape (N, 3)
field_values=normal_vectors, # shape (N, 3)
new_basis=[H3Basis, H3Basis, H3Basis],
)
mesh.new_field(
'height',
field_dimension=1,
field_locs=sample_pts, # shape (N, 3)
field_values=sample_pts[:, 2], # scalar Z values
new_basis=[L1Basis, L1Basis, L1Basis],
)
# Retrieve and evaluate
normal_field = mesh['normals']
values_at_xis = normal_field.evaluate_embeddings(elem_ids, xis)
save(loc)
¶
Saves the mesh to a .json formated file in the given location
dump_to_dict()
¶
Returns a dict structure representing the mesh object, for ease of saving