MOAB: Mesh Oriented datABase
(version 5.4.1)
|
MappingFunction for topologically 3D (volume) elements. More...
#include <MappingFunction.hpp>
Public Member Functions | |
virtual | ~MappingFunction3D () |
virtual void | derivatives (Sample location, NodeSet nodeset, size_t *vertex_indices_out, MsqVector< 3 > *d_coeff_d_xi_out, size_t &num_vtx, MsqError &err) const =0 |
Mapping Function Derivatives. | |
virtual void | jacobian (const PatchData &pd, size_t element_number, NodeSet nodeset, Sample location, size_t *vertex_patch_indices_out, MsqVector< 3 > *d_coeff_d_xi_out, size_t &num_vtx_out, MsqMatrix< 3, 3 > &jacobian_out, MsqError &err) const |
Mapping function derivatives and Jacobian. | |
virtual void | ideal (Sample location, MsqMatrix< 3, 3 > &jacobian_out, MsqError &err) const |
Get ideal Jacobian matrix. |
MappingFunction for topologically 3D (volume) elements.
Definition at line 343 of file MappingFunction.hpp.
virtual MBMesquite::MappingFunction3D::~MappingFunction3D | ( | ) | [inline, virtual] |
Definition at line 346 of file MappingFunction.hpp.
{}
virtual void MBMesquite::MappingFunction3D::derivatives | ( | Sample | location, |
NodeSet | nodeset, | ||
size_t * | vertex_indices_out, | ||
MsqVector< 3 > * | d_coeff_d_xi_out, | ||
size_t & | num_vtx, | ||
MsqError & | err | ||
) | const [pure virtual] |
Mapping Function Derivatives.
This group of methods return the partial derivatives of the mapping function coefficient terms \(\nabla N_1(\vec{\xi}), \nabla N_2(\vec{\xi}), \ldots, \nabla N_n(\vec{\xi})\) evaluated for a given \(\vec{\xi}\), where \(\vec{x_i}\) is a point in \(\mathbf{R}^3\) (i.e. \(x_i,y_i,z_i\)). \(\vec{\xi_i} = \left\{\begin{array}{c}\xi_i\\ \eta_i\\ \end{array}\right\}\) for surface elements and \(\vec{\xi_i} = \left\{\begin{array}{c}\xi_i\\ \eta_i\\ \zeta_i\\ \end{array}\right\}\) for volume elements.
The list of returned partial derivatives may be considered list of elements of a matrix \(\mathbf{D}\) in row major order. For surface elements, \(\mathbf{D}\) is a \(n\times 2\) matrix and for volume elements it is a \(n \times 3\) matrix. Each row of \(\mathbf{D}\) corresponds to one of the coefficient functions \(N_i(\vec{\xi})\) and each column corresponds to one of the components of \(\vec{\xi}\) that the corresponding coefficient function is differentiated with respect to.
\( \mathbf{D} = \left[ \begin{array}{ccc} \frac{\delta N_1}{\delta \xi} & \frac{\delta N_1}{\delta \eta} & \ldots \\ \frac{\delta N_2}{\delta \xi} & \frac{\delta N_2}{\delta \eta} & \ldots \\ \vdots & \vdots & \ddots \end{array} \right]\)
The Jacobian matrix ( \(\mathbf{J}\)) of the mapping function can be calculated as follows. Define a matrix \(\mathbf{X}\) such that each column contains the coordinates of the element nodes.
\( \mathbf{X} = \left[ \begin{array}{ccc} x_1 & x_2 & \ldots \\ y_1 & y_2 & \ldots \\ z_1 & z_2 & \ldots \end{array}\right]\)
The Jacobian matrix is then:
\(\mathbf{J} = \mathbf{X} \times \mathbf{D}\)
\(\mathbf{X}\) is always \(3\times n\), so \(\mathbf{J}\) is either \(3\times 2\) (surface elements) or \(3\times 3\) (volume elements) depending on the dimensions of \(\mathbf{D}\).
If the Jacobian matrix of the mapping function is considered as a function of the element vertex coordinates \(\mathbf{J}(\vec{x_1},\vec{x_2},\ldots)\) with \(\vec{\xi}\) constant, then the gradient of that Jacobian matrix function (with respect to the vertex coordinates) can be obtained from the same output list of partial deravitves.
\(\frac{\delta \mathbf{J}}{\delta x_i} = \left[ \begin{array}{ccc} \frac{\delta N_i}{\delta \xi} & \frac{\delta N_i}{\delta \eta} & \ldots \\ 0 & 0 & \ldots \\ 0 & 0 & \ldots \end{array} \right]\) \(\frac{\delta \mathbf{J}}{\delta y_i} = \left[ \begin{array}{ccc} 0 & 0 & \ldots \\ \frac{\delta N_i}{\delta \xi} & \frac{\delta N_i}{\delta \eta} & \ldots \\ 0 & 0 & \ldots \end{array} \right]\) \(\frac{\delta \mathbf{J}}{\delta z_i} = \left[ \begin{array}{ccc} 0 & 0 & \ldots \\ 0 & 0 & \ldots \\ \frac{\delta N_i}{\delta \xi} & \frac{\delta N_i}{\delta \eta} & \ldots \end{array} \right]\)
location | Where within the element at which to evaluate the derivatives. |
nodeset | List of which nodes are present in the element. |
vertices_out | The list of vertices for which the corresponding coefficient in the mapping function is non-zero. The vertices are specified by their index in the canonical ordering for an element with all mid-nodes present (i.e. first all the corner nodes, then the mid-edge nodes, ...). |
d_coeff_d_xi_out | The mapping function is composed of a series of coefficient functions \(N_i(\vec{\xi})\), one correspoding to the position \(\vec{x_i}\) of each node in the element such that the mapping function is of the form: \(\vec{x}(\vec{\xi})=\sum_{i=1}^n N_i(\vec{\xi})\vec{x_i}\). For each vertex indicated in vertex_indices_out, this list contains the partial derivatives of the cooresponding coefficient function \(N_i\) with respect to each component of \(\vec{\xi}\) in the same order as the corresponding nodes in vertex_indices_out. |
num_vtx | Output: The number of vertex indices and derivitive tuples returned in vertices_out and d_coeff_d_xi_out, respectively. |
Implemented in CenterMF3D, MBMesquite::HexLagrangeShape, MBMesquite::TetLagrangeShape, MBMesquite::LinearPyramid, MBMesquite::LinearHexahedron, MBMesquite::LinearPrism, and MBMesquite::LinearTetrahedron.
Referenced by LinearMappingFunctionTest::do_deriv_test(), IdealTargetTest::get_ideal_target(), MBMesquite::JacobianCalculator::get_Jacobian_3D(), ideal(), jacobian(), MBMesquite::TargetCalculator::jacobian_3D(), and LinearMappingFunctionTest::test_deriv_fail().
void MBMesquite::MappingFunction3D::ideal | ( | Sample | location, |
MsqMatrix< 3, 3 > & | jacobian_out, | ||
MsqError & | err | ||
) | const [virtual] |
Get ideal Jacobian matrix.
Returns the Jacobian matrix of an ideal element. The orientation of element or corresponding matrix is arbitrary. The "ideal" element should be scaled such the Jacobian (determinant of the Jacobian matrix) is 1.0.
location | Where within the element at which to evaluate the Jacobian. Typically doesn't matter except for degenerate elements (e.g. pyramid as degenerate hex.) |
jacobian_out | The Jacobian of the mapping function at the specified logical location. |
Reimplemented in MBMesquite::HexLagrangeShape, MBMesquite::TetLagrangeShape, MBMesquite::LinearPyramid, MBMesquite::LinearHexahedron, MBMesquite::LinearPrism, and MBMesquite::LinearTetrahedron.
Definition at line 229 of file MappingFunction.cpp.
References MBMesquite::cbrt(), derivatives(), MBMesquite::det(), MBMesquite::divide(), MBMesquite::MappingFunction::element_topology(), MAX_VERTS, MSQ_ERRRTN, MSQ_SETERR, size, MBMesquite::transpose(), MBMesquite::unit_element(), MBMesquite::MsqError::UNSUPPORTED_ELEMENT, and MBMesquite::MsqMatrix< R, C >::zero().
Referenced by LinearMappingFunctionTest::do_ideal_test(), MBMesquite::TargetCalculator::ideal_shape_3D(), and MBMesquite::TargetCalculator::ideal_skew_3D().
{ const Vector3D* coords = unit_element( element_topology(), true ); if( !coords ) { MSQ_SETERR( err )( MsqError::UNSUPPORTED_ELEMENT ); return; } const unsigned MAX_VERTS = 8; MsqVector< 3 > d_coeff_d_xi[MAX_VERTS]; size_t indices[MAX_VERTS], num_vtx = 0; derivatives( location, NodeSet(), indices, d_coeff_d_xi, num_vtx, err );MSQ_ERRRTN( err ); assert( num_vtx > 0 && num_vtx <= MAX_VERTS ); J.zero(); for( size_t r = 0; r < num_vtx; ++r ) { MsqMatrix< 3, 1 > c( coords[indices[r]].to_array() ); J += c * transpose( d_coeff_d_xi[r] ); } double size = MBMesquite::cbrt( fabs( det( J ) ) ); assert( size > -1e-15 ); // no negative jacobians for ideal elements! divide( 1.0, size, size ); J *= size; }
void MBMesquite::MappingFunction3D::jacobian | ( | const PatchData & | pd, |
size_t | element_number, | ||
NodeSet | nodeset, | ||
Sample | location, | ||
size_t * | vertex_patch_indices_out, | ||
MsqVector< 3 > * | d_coeff_d_xi_out, | ||
size_t & | num_vtx_out, | ||
MsqMatrix< 3, 3 > & | jacobian_out, | ||
MsqError & | err | ||
) | const [virtual] |
Mapping function derivatives and Jacobian.
This function returns the partial derivatives of the mapping function coefficient terms and the Jacobian calculated from those terms and the cooresponding vertex coordinates.
This function returns the same logical data as 'derivatives', except that it also calculates the Jacobian from the actual vertex coordinates. Also, unlike the 'derivatives' function which returns the vertex indices as positions in the element connectivity list, this function is expected to a) return the actual indices of the vertices in the PatchData vertex list and b) remove from the list of indices and derivatives and values corresponding to fixed vertices.
The default implementation of this function will calculate the Jacobian and modify the vertex and derivative lists returned from "derivatives". The default implementation serves as a utility function for other classes using this one. The function is virtual to allow mapping function implementations to provide an optimized version that avoids extra calculations for zero terms in the derivative list.
pd | The PatchData instance containing the vertex coordinates and element connectcivity. |
element_number | The index of the mesh element in the PatchData. |
nodeset | List of which nodes are present in the element. |
location | Where within the element at which to evaluate the Jacobian. |
vertex_patch_indices_out | For each free vertex in the element the influences the mapping function value at the specified logical location, the index of that vertex in the PatchData. |
d_coeff_d_xi_out | For each vertex in 'vertex_patch_indices_out', the partial derivatives of the corresponding coefficient of the mapping function. |
num_vtx_out | The number of values passed back in 'vertex_patch_indices_out' and 'd_coeff_d_xi_out'. |
jacobian_out | The Jacobian of the mapping function at the specified logical location. |
Definition at line 195 of file MappingFunction.cpp.
References conn, MBMesquite::MappingFunction::convert_connectivity_indices(), derivatives(), MBMesquite::PatchData::element_by_index(), MBMesquite::MsqMeshEntity::get_vertex_index_array(), MSQ_ERRRTN, MBMesquite::MsqMeshEntity::node_count(), MBMesquite::PatchData::num_free_vertices(), MBMesquite::Vector3D::to_array(), MBMesquite::transpose(), MBMesquite::PatchData::vertex_by_index(), and MBMesquite::MsqMatrix< R, C >::zero().
Referenced by MBMesquite::AWQualityMetric::evaluate_internal(), MBMesquite::TQualityMetric::evaluate_internal(), MBMesquite::AWQualityMetric::evaluate_with_gradient(), MBMesquite::TQualityMetric::evaluate_with_gradient(), MBMesquite::TQualityMetric::evaluate_with_Hessian(), MBMesquite::AWQualityMetric::evaluate_with_Hessian(), MBMesquite::TQualityMetric::evaluate_with_Hessian_diagonal(), MBMesquite::AWQualityMetric::evaluate_with_Hessian_diagonal(), MBMesquite::MsqMeshEntity::inverted_jacobian_3d(), and MBMesquite::MeshUtil::lambda_distribution().
{ const MsqMeshEntity& elem = pd.element_by_index( element_number ); const size_t* conn = elem.get_vertex_index_array(); derivatives( location, nodeset, vertex_patch_indices_out, d_coeff_d_xi_out, num_vtx_out, err );MSQ_ERRRTN( err ); convert_connectivity_indices( elem.node_count(), vertex_patch_indices_out, num_vtx_out, err );MSQ_ERRRTN( err ); jacobian_out.zero(); size_t w = 0; for( size_t r = 0; r < num_vtx_out; ++r ) { size_t i = conn[vertex_patch_indices_out[r]]; MsqMatrix< 3, 1 > coords( pd.vertex_by_index( i ).to_array() ); jacobian_out += coords * transpose( d_coeff_d_xi_out[r] ); if( i < pd.num_free_vertices() ) { vertex_patch_indices_out[w] = i; d_coeff_d_xi_out[w] = d_coeff_d_xi_out[r]; ++w; } } num_vtx_out = w; }