Drake
MeshFieldLinear< T, MeshType > Class Template Reference

Detailed Description

template<class T, class MeshType>
class drake::geometry::MeshFieldLinear< T, MeshType >

MeshFieldLinear represents a continuous piecewise-linear scalar field f defined on a (triangular or tetrahedral) mesh; the field value changes linearly within each element E (triangle or tetrahedron), and the gradient ∇f is constant within each element.

The field is continuous across adjacent elements, but its gradient is discontinuous from one element to the other.

To represent a piecewise linear field f, we store one field value per vertex of the mesh. Each element E (triangle or tetrahedron) has (d+1) vertices, where d is the dimension of the element. For triangle, d = 2, and for tetrahedron, d = 3.

On each element E, we define a linear function fᵉ:ℝ³→ℝ using the field values at vertices of E. The gradient ∇fᵉ:ℝ³→ℝ³ is a constant map, so we write ∇fᵉ for the constant gradient vector on E as well. For a point Q in element E, we have:

   f(Q) = fᵉ(Q) for Q ∈ E,
  ∇f(Q) = ∇fᵉ for Q ∈ E.

Notice that the domain of fᵉ is the entire space of ℝ³, while the domain of f is the underlying space of the mesh.

The following sections are details for interested readers.

Barycentric coordinate

For a linear triangle or tetrahedron element E in 3-D, we use barycentric coordinate:

  (b₀, b₁, b₂)     for triangle,
  (b₀, b₁, b₂, b₃) for tetrahedron,
  ∑bᵢ = 1, bᵢ ≥ 0,

to identify a point Q that lies in the simplicial element E. The coefficient bᵢ is the weight of vertex Vᵉᵢ of the element E, where the index i is a local index within the element E, not the global index of the entire mesh. In other words, vertex Vᵉᵢ is the iᵗʰ vertex of E, not the iᵗʰ vertex among all vertices in the mesh. The point Q in E can be expressed as:

  Q = ∑bᵉᵢ(Q)Vᵉᵢ,

where we indicate the barycentric coordinate of a point Q on an element E as bᵉᵢ(Q).

Field value from barycentric coordinates

At a point Q in element E, the piecewise linear field f has value:

  f(Q) = fᵉ(Q) = ∑bᵉᵢ(Q)Fᵉᵢ

where Fᵉᵢ is the field value at the iᵗʰ vertex of element E.

Gradient

Consider each bᵉᵢ:ℝ³→ℝ as a linear function, its gradient ∇bᵉᵢ:ℝ³→ℝ³ is a constant map, and we write ∇bᵉᵢ for the constant gradient vector. The gradient of the piecewise linear field f at a point Q in an element E is:

  ∇f(Q) = ∇fᵉ = ∑Fᵉᵢ∇bᵉᵢ.

Field value from Cartesian coordinates

At a point Q in element E, the piecewise linear field f has value:

  f(Q) = ∇fᵉ⋅Q + fᵉ(0,0,0).

Notice that (0,0,0) may or may not lie in element E.

Template Parameters
Ta valid Eigen scalar for field values.
MeshTypethe type of the meshes: SurfaceMesh or VolumeMesh.

#include <drake/geometry/proximity/mesh_field_linear.h>

Public Member Functions

 MeshFieldLinear (std::string name, std::vector< T > &&values, const MeshType *mesh, bool calculate_gradient=true)
 Constructs a MeshFieldLinear. More...
 
const T & EvaluateAtVertex (typename MeshType::VertexIndex v) const
 Evaluates the field value at a vertex. More...
 
template<typename B >
promoted_numerical_t< B, T > Evaluate (typename MeshType::ElementIndex e, const typename MeshType::template Barycentric< B > &b) const
 Evaluates the field value at a location on an element. More...
 
template<typename C >
promoted_numerical_t< C, T > EvaluateCartesian (typename MeshType::ElementIndex e, const Vector3< C > &p_MQ) const
 Evaluates the field at a point Qp on an element. More...
 
Vector3< T > EvaluateGradient (typename MeshType::ElementIndex e) const
 Evaluates the gradient in the domain of the element indicated by e. More...
 
void TransformGradients (const math::RigidTransform< typename MeshType::ScalarType > &X_NM)
 Transforms the gradient vectors of this field from its initial frame M to the new frame N. More...
 
std::unique_ptr< MeshFieldLinearCloneAndSetMesh (const MeshType *new_mesh) const
 Copy to a new MeshFieldLinear and set the new MeshFieldLinear to use a new compatible mesh. More...
 
const MeshType & mesh () const
 
const std::string & name () const
 
const std::vector< T > & values () const
 
bool Equal (const MeshFieldLinear< T, MeshType > &field) const
 Checks to see whether the given MeshFieldLinear object is equal via deep exact comparison. More...
 
Implements CopyConstructible, CopyAssignable, MoveConstructible, MoveAssignable
 MeshFieldLinear (const MeshFieldLinear &)=default
 
MeshFieldLinearoperator= (const MeshFieldLinear &)=default
 
 MeshFieldLinear (MeshFieldLinear &&)=default
 
MeshFieldLinearoperator= (MeshFieldLinear &&)=default
 

Constructor & Destructor Documentation

◆ MeshFieldLinear() [1/3]

MeshFieldLinear ( const MeshFieldLinear< T, MeshType > &  )
default

◆ MeshFieldLinear() [2/3]

MeshFieldLinear ( MeshFieldLinear< T, MeshType > &&  )
default

◆ MeshFieldLinear() [3/3]

MeshFieldLinear ( std::string  name,
std::vector< T > &&  values,
const MeshType *  mesh,
bool  calculate_gradient = true 
)

Constructs a MeshFieldLinear.

Parameters
nameThe name of the field variable.
valuesThe field value at each vertex of the mesh.
meshThe mesh M to which this field refers.
calculate_gradientCalculate gradient field when true, default is true. Calculating gradient allows EvaluateCartesian() to evaluate the field directly instead of converting Cartesian coordinates to barycentric coordinates first. If calculate_gradient is false, EvaluateCartesian() will be slower. On the other hand, calculating gradient requires certain quality from mesh elements. If the mesh quality is very poor, calculating gradient may throw.

You can use the parameter calculate_gradient to trade time and space of this constructor for speed of EvaluateCartesian(). For calculate_gradient = true (by default), this constructor will take longer time to compute and will store one field-gradient vector for each element in the mesh, but the interpolation by EvaluateCartesian() will be faster because we will use a dot product with the Cartesian coordinates directly, instead of solving a linear system to convert Cartesian coordinates to barycentric coordinates first. For calculate_gradient = false, this constructor will be faster and use less memory, but EvaluateCartesian() will be slower.

When calculate_gradient = true, EvaluateGradient() on a mesh element will be available. Otherwise, EvaluateGradient() will throw.

The following features are independent of the choice of calculate_gradient.

  • Evaluating the field at a vertex.
  • Evaluating the field at a user-given barycentric coordinate.
Note
When calculate_gradient = true, a poor quality element can cause throw due to numerical errors in calculating field gradients. A poor quality element is defined as having an extremely large aspect ratio R=E/h, where E is the longest edge length and h is the shortest height. A height of a triangular element is the distance between a vertex and its opposite edge. A height of a tetrahedral element is the distance between a vertex and its opposite triangular face. For example, an extremely skinny triangle has poor quality, and a tetrahedron with four vertices almost co-planar also has poor quality. The exact threshold of the acceptable aspect ratio depends on many factors including the underlying scalar type and the exact shape and size of the element; however, a rough conservative estimation is 1e12.
Precondition
The mesh is non-null, and the number of entries in values is the same as the number of vertices of the mesh.

Member Function Documentation

◆ CloneAndSetMesh()

std::unique_ptr<MeshFieldLinear> CloneAndSetMesh ( const MeshType *  new_mesh) const

Copy to a new MeshFieldLinear and set the new MeshFieldLinear to use a new compatible mesh.

MeshFieldLinear needs a mesh to operate; however, MeshFieldLinear does not own the mesh. In fact, several MeshFieldLinear objects can use the same mesh.

◆ Equal()

bool Equal ( const MeshFieldLinear< T, MeshType > &  field) const

Checks to see whether the given MeshFieldLinear object is equal via deep exact comparison.

The name of the objects are exempt from this comparison. NaNs are treated as not equal as per the IEEE standard.

Parameters
fieldThe field for comparison.
Returns
true if the given field is equal.

◆ Evaluate()

promoted_numerical_t<B, T> Evaluate ( typename MeshType::ElementIndex  e,
const typename MeshType::template Barycentric< B > &  b 
) const

Evaluates the field value at a location on an element.

The return type depends on both the field's scalar type T and the Barycentric coordinate type B. See promoted_numerical_t for details.

Parameters
eThe index of the element.
bThe barycentric coordinates.
Template Parameters
BThe scalar type for the barycentric coordinate.

◆ EvaluateAtVertex()

const T& EvaluateAtVertex ( typename MeshType::VertexIndex  v) const

Evaluates the field value at a vertex.

Parameters
vThe index of the vertex.

◆ EvaluateCartesian()

promoted_numerical_t<C, T> EvaluateCartesian ( typename MeshType::ElementIndex  e,
const Vector3< C > &  p_MQ 
) const

Evaluates the field at a point Qp on an element.

If the element is a tetrahedron, Qp is the input point Q. If the element is a triangle, Qp is the projection of Q on the triangle's plane.

If gradients have been calculated, it evaluates the field value directly. Otherwise, it converts Cartesian coordinates to barycentric coordinates for barycentric interpolation.

The return type depends on both the field's scalar type T and the Cartesian coordinate type C. See promoted_numerical_t for details.

Parameters
eThe index of the element.
p_MQThe position of point Q expressed in frame M, in Cartesian coordinates. M is the frame of the mesh.

◆ EvaluateGradient()

Vector3<T> EvaluateGradient ( typename MeshType::ElementIndex  e) const

Evaluates the gradient in the domain of the element indicated by e.

The gradient is a vector in R³ expressed in frame M. For surface meshes, it will particularly lie parallel to the plane of the corresponding triangle.

Exceptions
std::exceptionif the gradient vector was not calculated.

◆ mesh()

const MeshType& mesh ( ) const

◆ name()

const std::string& name ( ) const

◆ operator=() [1/2]

MeshFieldLinear& operator= ( MeshFieldLinear< T, MeshType > &&  )
default

◆ operator=() [2/2]

MeshFieldLinear& operator= ( const MeshFieldLinear< T, MeshType > &  )
default

◆ TransformGradients()

void TransformGradients ( const math::RigidTransform< typename MeshType::ScalarType > &  X_NM)

Transforms the gradient vectors of this field from its initial frame M to the new frame N.

Warning
Use this function when the reference mesh of this field changes its frame in the same way.

◆ values()

const std::vector<T>& values ( ) const

The documentation for this class was generated from the following file: