API¶
Core¶
This module manages the low level parameters describing the mesh.
-
class
morphic.core.Core¶ -
add_map(src_pid, dst_pid, scale)¶
-
add_params(params)¶
-
add_pca_node(pca_node)¶
-
add_variables(cids)¶
-
debug(msg)¶
-
evaluate(cid, xi, deriv=None)¶
-
evaluate_fields(cid, xi, fields)¶
-
evaluates(cids, xi, deriv=None, X=None)¶
-
evaluates_weights(cids, Phi, X=None)¶
-
fix_parameters(cids, fixed)¶
-
generate_dependent_node_map(mesh)¶
-
generate_element_map(mesh)¶
-
generate_fixed_index()¶
-
get_gauss_points(ng)¶
-
get_variables()¶
-
remove_variables(cids)¶
-
set_variables(variables)¶
-
update_dependent_nodes()¶
-
update_maps()¶
-
update_params(cids, params)¶
-
update_pca_nodes()¶
-
weights(cid, xi, deriv=None)¶
-
-
class
morphic.core.ObjectList¶ This object is used by a few morphic modules to store collections of objects. For example, nodes, elements, fixed points.
-
add(obj, group=None)¶ Adds an object to the collection. The object requires an id attribute (e.g., obj.id) to be able to be added and referenced. If a group is specified then the object will be added to the group.
-
add_to_group(uids, group)¶
-
get_groups(groups)¶
-
get_unique_id(random_chars=0)¶
-
ids¶
-
keys()¶
-
remove(obj)¶
-
reset_object_list()¶
-
set_counter(value)¶ Sets the counter value for finding unique ids.
Typically, this function would be used if you wanted to start the counter at 1 instead of 0. In which case, the numbering of objects, like nodes or elements, will start at 1.
This function can be used to reset the counter to zero, for example, so that unused object ids can be reused. Unused object ids might occur when objects are deleted from the list.
Parameters: value – value to reset the counter to Returns: None
-
size()¶ Returns the number of objects in the list.
-
-
morphic.core.dimensions(basis)¶
-
morphic.core.element_face_nodes(basis, node_ids)¶
-
morphic.core.element_line_nodes(basis, node_ids)¶
Fitter¶
-
class
morphic.fitter.BoundElementPoint(element_id, xi, data_label, data_index=None, fields=None, weight=1)¶ -
get_bind_weight()¶
-
get_data(data, field, mesh)¶
-
get_field_id(field_index)¶
-
get_param_ids(field_index)¶
-
get_param_weights(field)¶
-
update_from_mesh(mesh)¶
-
-
class
morphic.fitter.BoundNodeValue(node_id, field_id, comp_id, data_label, index=None, weight=1)¶ -
get_bind_weight()¶
-
get_data(data, field, mesh)¶
-
get_field_id(field)¶
-
get_param_ids(field)¶
-
get_param_weights(field)¶
-
update_from_mesh(mesh)¶
-
-
class
morphic.fitter.Data(label, values)¶ -
add_point(point)¶
-
find_closest(x, num=1)¶
-
get_data(ind)¶
-
init_phi(M, N)¶
-
update_point_data(params)¶
-
-
class
morphic.fitter.Fit(method='data_to_mesh_closest')¶ -
bind_element_point(element_id, xi, data, data_index=None, fields=None, weight=1)¶
-
bind_node_value(node_id, field_id, comp_id, data, index=None, weight=1)¶
-
compute_rms_err()¶
-
delete_all_data()¶
-
generate_fast_data()¶
-
generate_matrix()¶
-
get_column_index(param_ids)¶
-
get_data(mesh)¶
-
invert_matrix()¶
-
objfn_data_to_mesh_closest(x0, args)¶
-
objfn_data_to_mesh_project(x0, args)¶
-
objfn_mesh_to_data_closest(x0, args)¶
-
optimize(mesh, Xd, ftol=1e-09, xtol=1e-09, maxiter=0, output=True)¶
-
optimize2(mesh, data, ftol=1e-09, xtol=1e-09, epsfcn=None, maxiter=0, output=True)¶
-
optimize_fmin(mesh, data, ftol=1e-09, xtol=1e-09, maxiter=0, output=True)¶
-
set_data(label, values)¶
-
solve(mesh, max_iterations=1000, drms=1e-09, output=False)¶
-
update_from_mesh(mesh)¶
-
Interpolator¶
-
morphic.interpolator.H3(x)¶ Cubic-Hermite basis function.
Parameters: x (numpy array (npoints)) – points to interpolate Returns: basis weights Return type: numpy array(npoints, 4)
-
morphic.interpolator.H3d1(x)¶ First derivative of the cubic-Hermite basis function.
Parameters: x (numpy array (npoints)) – points to interpolate Returns: basis weights Return type: numpy array(npoints, 4)
-
morphic.interpolator.H3d1d1(x)¶ First derivative of the cubic-Hermite basis function.
Parameters: x (numpy array (npoints)) – points to interpolate Returns: basis weights Return type: numpy array(npoints, 4)
-
morphic.interpolator.L1(x)¶ Linear lagrange basis function.
Parameters: x (numpy array (npoints)) – points to interpolate Returns: basis weights Return type: numpy array (npoints, 2)
-
morphic.interpolator.L1d1(x)¶ First derivative for the linear lagrange basis function.
Parameters: x (numpy array (npoints)) – points to interpolate Returns: basis weights Return type: numpy array (npoints, 2)
-
morphic.interpolator.L1d1d1(x)¶ Second derivative for the linear lagrange basis function.
Parameters: x (numpy array (npoints)) – points to interpolate Returns: basis weights Return type: numpy array (npoints, 2)
-
morphic.interpolator.L2(x)¶ Quadratic lagrange basis function.
Parameters: x (numpy array (npoints)) – points to interpolate Returns: basis weights Return type: numpy array(npoints, 3)
-
morphic.interpolator.L2d1(x)¶ First derivative of the quadratic lagrange basis function.
Parameters: x (numpy array (npoints)) – points to interpolate Returns: basis weights Return type: numpy array(npoints, 3)
-
morphic.interpolator.L3(x)¶ Cubic lagrange basis function.
Parameters: x (numpy array (npoints)) – points to interpolate Returns: basis weights Return type: numpy array(npoints, 4)
-
morphic.interpolator.L3d1(x)¶ First derivative of the cubic lagrange basis function.
Parameters: x (numpy array (npoints)) – points to interpolate Returns: basis weights Return type: numpy array(npoints, 4)
-
morphic.interpolator.L4(x)¶ Quartic lagrange basis function.
Parameters: x (numpy array (npoints)) – points to interpolate Returns: basis weights Return type: numpy array(npoints, 5)
-
morphic.interpolator.L4d1(x)¶ First derivative of the quartic lagrange basis function.
Parameters: x (numpy array (npoints)) – points to interpolate Returns: basis weights Return type: numpy array(npoints, 5)
-
morphic.interpolator.T11(x)¶ Linear lagrange triangle element.
Parameters: x (numpy array (npoints)) – points to interpolate 0<=x<=1, x1+x2<=1 Returns: basis weights Return type: numpy array(npoints, 3)
-
morphic.interpolator.T22(x)¶ Quadratic lagrange triangle element.
Parameters: x (numpy array (npoints, 2)) – points to interpolate 0<=x<=1, x1+x2<=1 Returns: basis weights Return type: numpy array(npoints, 6)
-
morphic.interpolator.T33(x)¶ Cubic lagrange triangle element.
Parameters: x (numpy array (npoints, 2)) – points to interpolate 0<=x<=1, x1+x2<=1 Returns: basis weights Return type: numpy array(npoints, 10)
-
morphic.interpolator.T33d1(x)¶ First derivative in dimension 1 for the cubic lagrange triangle element.
Parameters: x (numpy array(npoints, 2)) – points to interpolate 0<=x<=1, x1+x2<=1 Returns: basis weights Return type: numpy array(npoints, 10)
-
morphic.interpolator.T33d2(x)¶ First derivative in dimension 2 for the cubic lagrange triangle element.
Parameters: x (numpy array(npoints, 2)) – points to interpolate 0<=x<=1, x1+x2<=1 Returns: basis weights Return type: numpy array(npoints, 10)
-
morphic.interpolator.T44(x)¶ Quartic lagrange triangle element.
Parameters: x (numpy array(npoints, 2)) – points to interpolate 0<=x<=1, x1+x2<=1 Returns: basis weights Return type: numpy array(npoints, 15)
-
morphic.interpolator.T44d1(x)¶ First derivative in dimension 1 for the quartic lagrange triangle element.
Parameters: x (numpy array(npoints, 2)) – points to interpolate 0<=x<=1, x1+x2<=1 Returns: basis weights Return type: numpy array(npoints, 15)
-
morphic.interpolator.T44d2(x)¶ First derivative in dimension 2 for the quartic lagrange triangle element.
Parameters: x (numpy array(npoints, 2)) – points to interpolate 0<=x1<=1, 0<=x2<=1, x1+x2<=1 Returns: basis weights Return type: numpy array(npoints, 15)
-
morphic.interpolator.weights(basis, X, deriv=None)¶ Calculates the interpolant value or derivative weights for points X.
Parameters: - basis (list of strings) – interpolation function in each direction, eg,
['L1', 'L1']for bilinear. - X (list or numpy array (npoints, ndims)) – locations to calculate interpolant weights
- deriv (list of integers) – derivative in each dimension, e.g.,
deriv=[1, 1]
Returns: basis weights (ndims)
Return type: numpy array, size: (npoints, nweights)
>>> import numpy >>> x = numpy.array([[0.13, 0.23], [0.77, 0.06]]) >>> weights(['L1', 'L2'], x, deriv=[0, 1]) array([[-1.8096, -0.2704, 1.8792, 0.2808, -0.0696, -0.0104], [-0.6348, -2.1252, 0.8096, 2.7104, -0.1748, -0.5852]])
- basis (list of strings) – interpolation function in each direction, eg,
Mesher¶
This module contains the higher level functions for creating and manipulating meshes.
Todo:
Fix values for fitting purposes.
MapNode - ability to map values from other nodes. Essentially, use their parameters.
DepNode with calculation of derivatives to allow calculating derivatives on lagrange elements to be used by a hanging node for a cubic-Hermite element. Might also allow the flipping of derivatives in case the hanging element has an opposite orientation. This is included here because it already does calculations.
Field class to describe the field structure. Maybe we can access values using node.x or node.x.0 for values and node.x.1 for other components.
Different interpolation types for each field. For example, one might have x, y, z and Temperature field. Could describe x, y, z using a bilinear interpolation but temperature as a bicubic-Hermite interpolation.
-
class
morphic.mesher.Element(mesh, uid, basis, node_ids)¶ -
add_faces()¶
-
add_to_group(groups)¶
-
area(ng=3)¶
-
compute_weighted_sum(xi, field, deriv=None)¶
-
evaluate(xi, deriv=None)¶
-
get_field_cids(field_index)¶
-
grid(res=[8, 8])¶
-
integrate(fields, func=None, ng=4)¶ Integration using gaussian quadrature.
Only supports up to two dimensions. The generation of the gauss points for 3 dimensions and up is required to extend this.
- Input:
- fields is a list of fields to integrate. The format is [[field no, derivative wrt x1, derivative wrt x2,... ], ...] For example, [[0, 0, 0], [2, 1, 0], [1, 0, 2]] will return the integral of Field0, dField2/dx1, and d^2Field1/dx2^2.
- func is a function that will take the field values process them and return the processed values for the fields
- ng is the number of gauss point. Default is 4. Max is 6. For 2D, the number of gauss points in each direction is given using [ng1, ng2, ...].
- Returns:
- integral of the fields or processed fields by ‘func’
-
interp¶
-
interpolate(xi, deriv=None)¶
-
length(ng=3)¶
-
nodes¶
-
normal(Xi)¶ Calculates the surface normals at xi locations on an element.
Xi is an
mxnndarray wheremis the number of element locations andnis the number of element dimensions.For example,
Xi = numpy.array([[0.1, 0.1], [0.3, 0.2], [0.7, 0.2]])
-
project(x, xi=None, xtol=0.0001, ftol=0.0001)¶
-
set_core_id(cid)¶
-
volume(ng=3)¶
-
weights(xi, deriv=None)¶
-
-
class
morphic.mesher.Mesh(filepath=None, label='/', units='m')¶ This is the top level object for a mesh which allows:
- building a mesh
- analysis or rendering of a mesh
- saving and loading meshes.
A mesh consists of nodes and elements. There are two types of nodes that can be added to a mesh:
- standard nodes, which is stores fields values, for example, x, y, and z coordinates.
- dependent nodes, which are embedded in an element. A hanging node can be added to a mesh using a dependent node.
There are many interpolation schemes that can be used to create an element:
- 1D and 2D lagrange basis up to 4th order
- 1D and 2D Hermite basis (cubic only)
- 2D triangular elements up to 4th order.
Note
Higher order interpolants (3D) will be added in the future.
Building a 1D Mesh
Here is an example of a simple 1D mesh which consists of two 1D linear element. First, we initialise a mesh,
>>> mesh = Mesh()
Add a few nodes,
>>> n = mesh.add_stdnode(1, [0, 0]) >>> n = mesh.add_stdnode(2, [1, 0.5]) >>> n = mesh.add_stdnode(3, [2, 0.3])
Add two linear elements,
>>> e = mesh.add_element(1, ['L1'], [1, 2]) >>> e = mesh.add_element(2, ['L1'], [2, 3])
>>> xi = [0, 0.25, 0.5, 0.75, 1.0] >>> X = mesh.evaluate(1, xi) >>> X array([[ 0. , 0. ], [ 0.25 , 0.125], [ 0.5 , 0.25 ], [ 0.75 , 0.375], [ 1. , 0.5 ]])
Building a 2D Mesh
Here is an example of a 2D mesh which consists of two quadratic-linear elements. First, we initialise a mesh,
>>> mesh = Mesh()
Add ten nodes,
>>> n = mesh.add_stdnode(1, [0, 0, 0]) >>> n = mesh.add_stdnode(2, [1, 0, 0.5]) >>> n = mesh.add_stdnode(3, [2, 0, 0.3]) >>> n = mesh.add_stdnode(4, [3, 0, 0.2]) >>> n = mesh.add_stdnode(5, [4, 0, -0.1]) >>> n = mesh.add_stdnode(6, [0, 1.2, 0]) >>> n = mesh.add_stdnode(7, [1, 1.2, 0.5]) >>> n = mesh.add_stdnode(8, [2, 1.2, 0.3]) >>> n = mesh.add_stdnode(9, [3, 1.2, 0.2]) >>> n = mesh.add_stdnode(10, [4, 1.2, -0.1])
Add two quadratic-linear lagrange elements,
>>> e = mesh.add_element(1, ['L2', 'L1'], [1, 2, 3, 6, 7, 8]) >>> e = mesh.add_element(2, ['L2', 'L1'], [3, 4, 5, 8, 9, 10])
>>> # Analyse (evaluate, calculate derivatives and normals) >>> xi = [[0.3, 0.5]]
Interpolate coordinates at xi=[0.3, 0.5] on element 1,
>>> X = mesh.evaluate(1, xi)
Calculate derivatives at xi = [0.3, 0.5] on element 2,
>>> dx1 = mesh.evaluate(2, xi, deriv=[1, 0]) # dx/dxi1 >>> dx2 = mesh.evaluate(2, xi, deriv=[0, 1]) # dx/dxi2 >>> dx12 = mesh.evaluate(2, xi, deriv=[1, 1]) # d2x/dxi1.dxi2
Calculate the element normal vector at xi=[0.3, 0.5] on element 1,
>>> dn = mesh.normal(1, xi) # normal vector
-
add_depnode(uid, element, node_id, shape=None, scale=None, group=None)¶ Adds a dependent node to a mesh. A dependent node is typically an interpolated location on an element. The location on the element is defined by a node.
>>> mesh = Mesh() >>> node1 = mesh.add_stdnode(1, [0, 0]) >>> node2 = mesh.add_stdnode(2, [2, 1]) >>> elem1 = mesh.add_element('elem1', ['L1'], [1, 2]) >>> hang1 = mesh.add_stdnode('xi', [0.6]) # element location >>> node3 = mesh.add_depnode(3, 'elem1', 'xi') # hanging node >>> print mesh.get_nodes([3]) [[ 1.2 0.6]]
Parameters: uid –
-
add_elem(uid, basis, node_ids, group='_default')¶
-
add_element(uid, basis, node_ids, group=None)¶ Adds a element to a mesh.
>>> mesh = Mesh() >>> n1 = mesh.add_stdnode(1, [0.1]) >>> n2 = mesh.add_stdnode(2, [0.2]) >>> elem = mesh.add_element(1, ['L1'], [1, 2]) >>> print elem.id, elem.basis, elem.node_ids 1 ['L1'] [1, 2]
-
add_face(element, face_index=0, nodes=None)¶ Adds a face to the mesh, typically used to store element faces for graphics - basis: the intepolation functions in each dimension
e.g., [‘L2’, ‘H3’]- nodes: the node indices for the face
- face index: the face position on a cube, range [0:7]
-
add_map(src, dst, scale=1.0)¶ Parameters: - scale –
- src –
- dst –
Returns:
-
add_node(uid, values, group='_default')¶
-
add_pcanode(uid, values, weights_nid, variance_nid, group=None)¶ Adds a pca node to a mesh.
-
add_stdnode(uid, values, group=None, add_components=0)¶ Adds a node to a mesh.
If None is given for the uid, the mesh will automatically increment a counter (starting at 1) and assign a unique id. If you would like to start the counter at 1, create your mesh as follows: >>> mesh = Mesh() >>> mesh.nodes.set_counter(1) >>> id = mesh.nodes.get_unique_id() >>> print id 1
There are two forms for entering node values for the variable x: - Simple form for when there is one type of value for each dimension e.g., [x, y, z] or [xi1, xi2] values - Component form for when each dimension has different types of values, e.g., x = [[x, dx1, dx2, dx12], [y, dy1, dy2, dy12]]
>>> mesh = Mesh() >>> node1 = mesh.add_stdnode(1, [0.2, 0.1, 3.], group='xyz') >>> node2 = mesh.add_stdnode(None, [0.1], group='xi') >>> node3 = mesh.add_stdnode(None, [0.2], group='xi') >>> print node1.id, node1.values 1 [ 0.2 0.1 3. ] >>> print node2.id, node2.values 0 [ 0.1] >>> print node3.id, node3.values 2 [ 0.2]
-
append_lines(lines, elements, lindex, res=8)¶
-
collapse_pca_mesh(group='pca')¶ Collapses a PCA mesh to a flat mesh based of the currently set weights and “pca” node group. This node group can be set using the “group” keyword argument.
-
copy_mesh(elements=None)¶
-
debug(msg)¶
-
deformation_gradient_tensor(deformed_mesh, xi)¶
-
evaluate(element_ids, xi, deriv=None)¶
-
export(filepath, element_ids='all', node_ids=[], precision='%0.6f', format='json')¶
-
export_data(filepath, precision='%0.3f', format='json')¶
-
fix_values(uids, fix)¶
-
generate(force=False)¶ Generates a flat representation of the mesh for faster computation.
-
get_element_cids(elements=None)¶
-
get_faces(res=8, exterior_only=True, include_xi=False, elements=None)¶
-
get_lines(res=8, elements='all')¶
-
get_lines_old(res=8, group='_default')¶
-
get_node_ids(nodes=None, group='_default')¶
-
get_nodes(nodes=None, group='_default')¶
-
get_surfaces(res=8, elements=None, groups=None, include_xi=False)¶
-
get_variables()¶
-
grid(res=[8, 8], shape='quad', method='fit')¶
-
groups(group_type=None)¶
-
interpolate(element_ids, xi, deriv=None)¶
-
load(filepath)¶ Loads a mesh.
>>> mesh = Mesh('../test/data/cube.mesh')
or
>>> mesh = Mesh() >>> mesh.load('../test/data/cube.mesh')
-
normal(element_ids, xi, normalise=False)¶
-
params¶
-
reflect_nodes(origin, axis, nodes)¶
-
save(filepath=None, format='pytables')¶ Saves a mesh.
>>> mesh = Mesh() >>> mesh.save('data/cube.mesh')
-
set_debug(state)¶
-
set_variables(variables)¶
-
translate(translation_node_id, groups=None, update=True)¶
-
update(force=False)¶ Updates the dependent node. This update may be required if some mesh nodes or parameters have been changed. This function can be called with force=True to force an update, e.g., mesh.update(force=True)
-
update_dependent_nodes()¶
-
update_maps()¶
-
update_parameters(param_ids, values)¶
-
update_pca_nodes(update_depnodes=True)¶
-
volume()¶
-
class
morphic.mesher.Node(mesh, uid)¶ This is the super-class for StdNode and DepNode.
-
add_to_group(groups)¶
-
field_cids¶
-
fix(fix)¶ This function will the values of the node, which is used for fitting. The values can be fixed in three forms:
- node.fix(True) will fix all the values
- node.fix([False, True, False]) will fix all the values in field 2 and unfix all others.
- node.fix([[True, False], [False, True]] will fix the first component in field 1 and the second component in field 2.
-
get_pid(index)¶
-
get_values(index=None)¶
-
get_x()¶
-
groups()¶
-
in_group(groups)¶
-
is_depnode()¶
-
is_pcanode()¶
-
is_stdnode()¶
-
set_values(values)¶ Sets the values for the node by adding them to core. If the nodes values have already been set, it will update the values. Note, the number of fields and components cannot change when updating the values.
valuescan be of the form:- [0.2, 0.5] or [[0.2], [0.5]] which sets two field values
- [[0.2 1, 0], [0.5, .3, 1]] which sets two fields with two components each.
-
set_x(values)¶
-
values¶
-
variables(state=True, fields=None)¶
-
-
class
morphic.mesher.NodeValues¶
-
class
morphic.mesher.PCANode(mesh, uid, node_id, weights_id, variance_id)¶
-
class
morphic.mesher.StdNode(mesh, uid, values=None, cids=None, shape=None)¶ -
class
Node(mesh, uid)¶ This is the super-class for StdNode and DepNode.
-
StdNode.smooth_derivatives(axis=[0, 1])¶
-
class
The Mesh class is used to create, manipulate and analyse meshes.
-
class
morphic.mesher.Mesh(filepath=None, label='/', units='m') This is the top level object for a mesh which allows:
- building a mesh
- analysis or rendering of a mesh
- saving and loading meshes.
A mesh consists of nodes and elements. There are two types of nodes that can be added to a mesh:
- standard nodes, which is stores fields values, for example, x, y, and z coordinates.
- dependent nodes, which are embedded in an element. A hanging node can be added to a mesh using a dependent node.
There are many interpolation schemes that can be used to create an element:
- 1D and 2D lagrange basis up to 4th order
- 1D and 2D Hermite basis (cubic only)
- 2D triangular elements up to 4th order.
Note
Higher order interpolants (3D) will be added in the future.
Building a 1D Mesh
Here is an example of a simple 1D mesh which consists of two 1D linear element. First, we initialise a mesh,
>>> mesh = Mesh()
Add a few nodes,
>>> n = mesh.add_stdnode(1, [0, 0]) >>> n = mesh.add_stdnode(2, [1, 0.5]) >>> n = mesh.add_stdnode(3, [2, 0.3])
Add two linear elements,
>>> e = mesh.add_element(1, ['L1'], [1, 2]) >>> e = mesh.add_element(2, ['L1'], [2, 3])
>>> xi = [0, 0.25, 0.5, 0.75, 1.0] >>> X = mesh.evaluate(1, xi) >>> X array([[ 0. , 0. ], [ 0.25 , 0.125], [ 0.5 , 0.25 ], [ 0.75 , 0.375], [ 1. , 0.5 ]])
Building a 2D Mesh
Here is an example of a 2D mesh which consists of two quadratic-linear elements. First, we initialise a mesh,
>>> mesh = Mesh()
Add ten nodes,
>>> n = mesh.add_stdnode(1, [0, 0, 0]) >>> n = mesh.add_stdnode(2, [1, 0, 0.5]) >>> n = mesh.add_stdnode(3, [2, 0, 0.3]) >>> n = mesh.add_stdnode(4, [3, 0, 0.2]) >>> n = mesh.add_stdnode(5, [4, 0, -0.1]) >>> n = mesh.add_stdnode(6, [0, 1.2, 0]) >>> n = mesh.add_stdnode(7, [1, 1.2, 0.5]) >>> n = mesh.add_stdnode(8, [2, 1.2, 0.3]) >>> n = mesh.add_stdnode(9, [3, 1.2, 0.2]) >>> n = mesh.add_stdnode(10, [4, 1.2, -0.1])
Add two quadratic-linear lagrange elements,
>>> e = mesh.add_element(1, ['L2', 'L1'], [1, 2, 3, 6, 7, 8]) >>> e = mesh.add_element(2, ['L2', 'L1'], [3, 4, 5, 8, 9, 10])
>>> # Analyse (evaluate, calculate derivatives and normals) >>> xi = [[0.3, 0.5]]
Interpolate coordinates at xi=[0.3, 0.5] on element 1,
>>> X = mesh.evaluate(1, xi)
Calculate derivatives at xi = [0.3, 0.5] on element 2,
>>> dx1 = mesh.evaluate(2, xi, deriv=[1, 0]) # dx/dxi1 >>> dx2 = mesh.evaluate(2, xi, deriv=[0, 1]) # dx/dxi2 >>> dx12 = mesh.evaluate(2, xi, deriv=[1, 1]) # d2x/dxi1.dxi2
Calculate the element normal vector at xi=[0.3, 0.5] on element 1,
>>> dn = mesh.normal(1, xi) # normal vector
Nodes¶
There are four types of nodes that can be added to a mesh:
- Standard Nodes
mesh.add_stdnode(id, values)- Stores field values. The fields can include components, for example, in the case where field derivatives or PCA modes are included.
- Dependent Nodes
- Describes a node that depends on other parts of a mesh, typically, a node embedded in an element.
- PCA Nodes (TODO)
- This is a convinient description of a node derived from principal component analysis. This would store the mean node values and it’s modes, and the associated weights and variance, which are stored as standard nodes.
- Mapping Nodes (TODO)
- Descibes a node which uses values from other nodes. This is typically used when creating a Hermite node based of derivative values from a lagrange element or when a there are different versions of node values.
-
Mesh.add_stdnode(uid, values, group=None, add_components=0) Adds a node to a mesh.
If None is given for the uid, the mesh will automatically increment a counter (starting at 1) and assign a unique id. If you would like to start the counter at 1, create your mesh as follows: >>> mesh = Mesh() >>> mesh.nodes.set_counter(1) >>> id = mesh.nodes.get_unique_id() >>> print id 1
There are two forms for entering node values for the variable x: - Simple form for when there is one type of value for each dimension e.g., [x, y, z] or [xi1, xi2] values - Component form for when each dimension has different types of values, e.g., x = [[x, dx1, dx2, dx12], [y, dy1, dy2, dy12]]
>>> mesh = Mesh() >>> node1 = mesh.add_stdnode(1, [0.2, 0.1, 3.], group='xyz') >>> node2 = mesh.add_stdnode(None, [0.1], group='xi') >>> node3 = mesh.add_stdnode(None, [0.2], group='xi') >>> print node1.id, node1.values 1 [ 0.2 0.1 3. ] >>> print node2.id, node2.values 0 [ 0.1] >>> print node3.id, node3.values 2 [ 0.2]
-
Mesh.add_depnode(uid, element, node_id, shape=None, scale=None, group=None) Adds a dependent node to a mesh. A dependent node is typically an interpolated location on an element. The location on the element is defined by a node.
>>> mesh = Mesh() >>> node1 = mesh.add_stdnode(1, [0, 0]) >>> node2 = mesh.add_stdnode(2, [2, 1]) >>> elem1 = mesh.add_element('elem1', ['L1'], [1, 2]) >>> hang1 = mesh.add_stdnode('xi', [0.6]) # element location >>> node3 = mesh.add_depnode(3, 'elem1', 'xi') # hanging node >>> print mesh.get_nodes([3]) [[ 1.2 0.6]]
Parameters: uid –
Elements¶
-
Mesh.add_element(uid, basis, node_ids, group=None) Adds a element to a mesh.
>>> mesh = Mesh() >>> n1 = mesh.add_stdnode(1, [0.1]) >>> n2 = mesh.add_stdnode(2, [0.2]) >>> elem = mesh.add_element(1, ['L1'], [1, 2]) >>> print elem.id, elem.basis, elem.node_ids 1 ['L1'] [1, 2]