MOAB: Mesh Oriented datABase  (version 5.3.1)
MBMesquite::HexLagrangeShape Class Reference

Lagrange shape function for 27-node hexahedral elements. More...

#include <HexLagrangeShape.hpp>

+ Inheritance diagram for MBMesquite::HexLagrangeShape:
+ Collaboration diagram for MBMesquite::HexLagrangeShape:

Public Member Functions

virtual EntityTopology element_topology () const
 Get MBMesquite::EntityTopology handled by this mapping function.
virtual int num_nodes () const
 Get number of nodes in the element type.
virtual void coefficients (Sample location, NodeSet nodeset, double *coeff_out, size_t *indices_out, size_t &num_coeff_out, MsqError &err) const
 Mapping Function Coefficients.
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
 Mapping Function Derivatives.
virtual void ideal (Sample location, MsqMatrix< 3, 3 > &jacobian_out, MsqError &err) const
 Get ideal Jacobian matrix.

Detailed Description

Lagrange shape function for 27-node hexahedral elements.

This class implements the MappingFunction interface, providing a Lagrange shape function for hexahedral elements.

\(\vec{x}(\xi,\eta) = \sum_{i=0}^{n-1} N_i(r, s, t) \vec{x_i}\)

\(N_a = l^2_b(r) l^2_c(s) l^2_d(t)\)

\(l^2_1(\xi) = (\xi - 1) (2 \xi - 1)\)

\(l^2_2(\xi) = 4 \xi (1 - \xi)\)

\(l^2_3(\xi) = \xi (2 \xi - 1)\)

Mesquite / iTAPS / MBCN order

\(\begin{array}{cccc} a & b & c & d \\ \hline 0 & 1 & 1 & 1 \\ 1 & 3 & 1 & 1 \\ 2 & 3 & 3 & 1 \\ 3 & 1 & 3 & 1 \\ 4 & 1 & 1 & 3 \\ 5 & 3 & 1 & 3 \\ 6 & 3 & 3 & 3 \\ 7 & 1 & 3 & 3 \\ 8 & 2 & 1 & 1 \\ 9 & 3 & 2 & 1 \\ 10 & 2 & 3 & 1 \\ 11 & 1 & 2 & 1 \\ 12 & 1 & 1 & 2 \\ 13 & 3 & 1 & 2 \\ 14 & 3 & 3 & 2 \\ 15 & 1 & 3 & 2 \\ 16 & 2 & 1 & 3 \\ 17 & 3 & 2 & 3 \\ 18 & 2 & 3 & 3 \\ 19 & 1 & 2 & 3 \\ 20 & 2 & 1 & 2 \\ 21 & 3 & 2 & 2 \\ 22 & 2 & 3 & 2 \\ 23 & 1 & 2 & 2 \\ 24 & 2 & 2 & 1 \\ 25 & 2 & 2 & 3 \\ 26 & 2 & 2 & 2 \end{array}\)

MBCN ORDER

7 - 18- 6 / / 19 25 17 / / 4 - 16- 6

15- 22- 14 / / 23 26 21 / / 12- 20- 13

3 - 10- 2 / / 11 24 9 t s / / |/ 0 - 8 - 1 +-r

Definition at line 107 of file HexLagrangeShape.hpp.


Member Function Documentation

void MBMesquite::HexLagrangeShape::coefficients ( Sample  location,
NodeSet  nodeset,
double *  coeff_out,
size_t *  indices_out,
size_t &  num_coeff_out,
MsqError err 
) const [virtual]

Mapping Function Coefficients.

This function returns the list of scalar values ( \(N_i\)'s) resulting from the evaluation of the mapping function coefficient terms \(N_1(\vec{\xi}), N_2(\vec{\xi}), \ldots, N_n(\vec{\xi})\) for a given \(\vec{\xi}\).

Parameters:
locationWhere within the element at which to evaluate the coefficients.
nodesetList of which nodes are present in the element.
coefficients_outThe coefficients ( \(N_i(\vec{\xi})\)) for each vertex in the element.
indices_outThe index ($i$ in $N_i$) for each term in 'coeffs_out'. The assumption is that mapping function implementations will not return zero coefficients. This is not required, but for element types with large numbers of nodes it may have a significant impact on performance.

Implements MBMesquite::MappingFunction.

Definition at line 46 of file HexLagrangeShape.cpp.

References MBMesquite::Sample::dimension, MSQ_SETERR, MBMesquite::NodeSet::num_nodes(), MBMesquite::Sample::number, and MBMesquite::MsqError::UNSUPPORTED_ELEMENT.

{
    if( nodeset.num_nodes() != 27 )
    {
        MSQ_SETERR( err )
        ( "Mapping function supports only 27-node hexahedra with no slaved nodes.", MsqError::UNSUPPORTED_ELEMENT );
        return;
    }

    switch( loc.dimension )
    {
        case 0:  // Corner sample point - assume that it is there always
            num_coeff      = 1;
            indices_out[0] = loc.number;
            coeff_out[0]   = 1.0;
            break;
        case 1:  // Line sample point - check if it is there,
            num_coeff      = 1;
            indices_out[0] = loc.number + 8;
            coeff_out[0]   = 1.0;
            break;
        case 2:  // Face sample point - check if it is there,
            num_coeff      = 1;
            indices_out[0] = loc.number + 20;
            coeff_out[0]   = 1.0;
            break;
        case 3:  // Center sample point - check if it is there,
            num_coeff      = 1;
            indices_out[0] = 26;
            coeff_out[0]   = 1.0;
            break;
        default:
            MSQ_SETERR( err )
            ( MsqError::UNSUPPORTED_ELEMENT,
              "Request for dimension %d mapping function value"
              "for a quadratic hexahedral element",
              loc.dimension );
    }
}
void MBMesquite::HexLagrangeShape::derivatives ( Sample  location,
NodeSet  nodeset,
size_t *  vertex_indices_out,
MsqVector< 3 > *  d_coeff_d_xi_out,
size_t &  num_vtx,
MsqError err 
) const [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]\)

Parameters:
locationWhere within the element at which to evaluate the derivatives.
nodesetList of which nodes are present in the element.
vertices_outThe 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_outThe 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_vtxOutput: The number of vertex indices and derivitive tuples returned in vertices_out and d_coeff_d_xi_out, respectively.

Implements MBMesquite::MappingFunction3D.

Definition at line 87 of file HexLagrangeShape.cpp.

References MBMesquite::Sample::dimension, MSQ_SETERR, MBMesquite::NodeSet::num_nodes(), MBMesquite::Sample::number, and MBMesquite::MsqError::UNSUPPORTED_ELEMENT.

{
    if( nodeset.num_nodes() != 27 )
    {
        MSQ_SETERR( err )
        ( "Mapping function supports only 27-node hexahedra with no slaved nodes.", MsqError::UNSUPPORTED_ELEMENT );
        return;
    }

    // r coordinate
    const int HLS1[] = { 1, 3, 3, 1, 1, 3, 3, 1, 2, 3, 2, 1, 1, 3, 3, 1, 2, 3, 2, 1, 2, 3, 2, 1, 2, 2, 2 };
    // s coordinate
    const int HLS2[] = { 1, 1, 3, 3, 1, 1, 3, 3, 1, 2, 3, 2, 1, 1, 3, 3, 1, 2, 3, 2, 1, 2, 3, 2, 2, 2, 2 };
    // t coordinate
    const int HLS3[] = { 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 1, 3, 2 };

    const int HLSup1[] = { 12, 13, 14, 15, -1, -1, -1, -1, 20, 21, 22, 23, 4, 5,
                           6,  7,  -1, -1, -1, -1, 16, 17, 18, 19, 26, -1, 25 };
    const int HLSup2[] = { 4,  5,  6,  7,  -1, -1, -1, -1, 16, 17, 18, 19, -1, -1,
                           -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 25, -1, -1 };
    const int HLSdn1[] = { -1, -1, -1, -1, 12, 13, 14, 15, -1, -1, -1, -1, 0, 1,
                           2,  3,  20, 21, 22, 23, 8,  9,  10, 11, -1, 26, 24 };
    const int HLSdn2[] = { -1, -1, -1, -1, 0,  1,  2,  3,  -1, -1, -1, -1, -1, -1,
                           -1, -1, 8,  9,  10, 11, -1, -1, -1, -1, -1, 24, -1 };

    const int HLSlt1[] = { -1, 8,  10, -1, -1, 16, 18, -1, 0,  24, 3,  -1, -1, 20,
                           22, -1, 4,  25, 7,  -1, 12, 26, 15, -1, 11, 19, 23 };
    const int HLSlt2[] = { -1, 0,  3,  -1, -1, 4,  7,  -1, -1, 11, -1, -1, -1, 12,
                           15, -1, -1, 19, -1, -1, -1, 23, -1, -1, -1, -1, -1 };
    const int HLSrt1[] = { 8,  -1, -1, 10, 16, -1, -1, 18, 1,  -1, 2, 24, 20, -1,
                           -1, 22, 5,  -1, 6,  25, 13, -1, 14, 26, 9, 17, 21 };
    const int HLSrt2[] = { 1,  -1, -1, 2,  5,  -1, -1, 6,  -1, -1, -1, 9,  13, -1,
                           -1, 14, -1, -1, -1, 17, -1, -1, -1, 21, -1, -1, -1 };

    const int HLSft1[] = { -1, -1, 9,  11, -1, -1, 17, 19, -1, 1,  24, 0,  -1, -1,
                           21, 23, -1, 5,  25, 4,  -1, 13, 26, 12, 8,  16, 20 };
    const int HLSft2[] = { -1, -1, 1,  0,  -1, -1, 5,  4,  -1, -1, 8,  -1, -1, -1,
                           13, 12, -1, -1, 16, -1, -1, -1, 20, -1, -1, -1, -1 };
    const int HLSbk1[] = { 11, 9,  -1, -1, 19, 17, -1, -1, 24, 2,  -1, 3,  23, 21,
                           -1, -1, 25, 6,  -1, 7,  26, 14, -1, 15, 10, 18, 22 };
    const int HLSbk2[] = { 3,  2,  -1, -1, 7,  6,  -1, -1, 10, -1, -1, -1, 15, 14,
                           -1, -1, 18, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1 };

    double entries[] = { 0, -3, 0, 3 };

    int location = loc.number;

    switch( loc.dimension )
    {
        case 1:
            location += 8;
            break;
        case 2:
            location += 20;
            break;
        case 3:
            location += 26;
            break;
    }

    num_vtx = 0;

    if( location != 26 )
    {
        vertices[num_vtx]  = location;
        derivs[num_vtx][0] = entries[HLS1[location]];
        derivs[num_vtx][1] = entries[HLS2[location]];
        derivs[num_vtx][2] = entries[HLS3[location]];
        num_vtx++;
    }

    if( HLSup1[location] != -1 )
    {
        vertices[num_vtx] = HLSup1[location];
        if( HLS3[location] == 2 )
        {
            derivs[num_vtx][0] = 0;
            derivs[num_vtx][1] = 0;
            derivs[num_vtx][2] = 1;
        }
        else
        {
            derivs[num_vtx][0] = 0;
            derivs[num_vtx][1] = 0;
            derivs[num_vtx][2] = 4;
        }
        num_vtx++;
    }

    if( HLSdn1[location] != -1 )
    {
        vertices[num_vtx] = HLSdn1[location];
        if( HLS3[location] == 2 )
        {
            derivs[num_vtx][0] = 0;
            derivs[num_vtx][1] = 0;
            derivs[num_vtx][2] = -1;
        }
        else
        {
            derivs[num_vtx][0] = 0;
            derivs[num_vtx][1] = 0;
            derivs[num_vtx][2] = -4;
        }
        num_vtx++;
    }

    if( HLSup2[location] != -1 )
    {
        vertices[num_vtx]  = HLSup2[location];
        derivs[num_vtx][0] = 0;
        derivs[num_vtx][1] = 0;
        derivs[num_vtx][2] = -1;
        num_vtx++;
    }

    if( HLSdn2[location] != -1 )
    {
        vertices[num_vtx]  = HLSdn2[location];
        derivs[num_vtx][0] = 0;
        derivs[num_vtx][1] = 0;
        derivs[num_vtx][2] = 1;
        num_vtx++;
    }

    if( HLSlt1[location] != -1 )
    {
        vertices[num_vtx] = HLSlt1[location];
        if( HLS1[location] == 2 )
        {
            derivs[num_vtx][0] = -1;
            derivs[num_vtx][1] = 0;
            derivs[num_vtx][2] = 0;
        }
        else
        {
            derivs[num_vtx][0] = -4;
            derivs[num_vtx][1] = 0;
            derivs[num_vtx][2] = 0;
        }
        num_vtx++;
    }

    if( HLSrt1[location] != -1 )
    {
        vertices[num_vtx] = HLSrt1[location];
        if( HLS1[location] == 2 )
        {
            derivs[num_vtx][0] = 1;
            derivs[num_vtx][1] = 0;
            derivs[num_vtx][2] = 0;
        }
        else
        {
            derivs[num_vtx][0] = 4;
            derivs[num_vtx][1] = 0;
            derivs[num_vtx][2] = 0;
        }
        num_vtx++;
    }

    if( HLSlt2[location] != -1 )
    {
        vertices[num_vtx]  = HLSlt2[location];
        derivs[num_vtx][0] = 1;
        derivs[num_vtx][1] = 0;
        derivs[num_vtx][2] = 0;
        num_vtx++;
    }

    if( HLSrt2[location] != -1 )
    {
        vertices[num_vtx]  = HLSrt2[location];
        derivs[num_vtx][0] = -1;
        derivs[num_vtx][1] = 0;
        derivs[num_vtx][2] = 0;
        num_vtx++;
    }

    if( HLSft1[location] != -1 )
    {
        vertices[num_vtx] = HLSft1[location];
        if( HLS2[location] == 2 )
        {
            derivs[num_vtx][0] = 0;
            derivs[num_vtx][1] = -1;
            derivs[num_vtx][2] = 0;
        }
        else
        {
            derivs[num_vtx][0] = 0;
            derivs[num_vtx][1] = -4;
            derivs[num_vtx][2] = 0;
        }
        num_vtx++;
    }

    if( HLSbk1[location] != -1 )
    {
        vertices[num_vtx] = HLSbk1[location];
        if( HLS2[location] == 2 )
        {
            derivs[num_vtx][0] = 0;
            derivs[num_vtx][1] = 1;
            derivs[num_vtx][2] = 0;
        }
        else
        {
            derivs[num_vtx][0] = 0;
            derivs[num_vtx][1] = 4;
            derivs[num_vtx][2] = 0;
        }
        num_vtx++;
    }

    if( HLSft2[location] != -1 )
    {
        vertices[num_vtx]  = HLSft2[location];
        derivs[num_vtx][0] = 0;
        derivs[num_vtx][1] = 1;
        derivs[num_vtx][2] = 0;
        num_vtx++;
    }

    if( HLSbk2[location] != -1 )
    {
        vertices[num_vtx]  = HLSbk2[location];
        derivs[num_vtx][0] = 0;
        derivs[num_vtx][1] = -1;
        derivs[num_vtx][2] = 0;
        num_vtx++;
    }
}

Get MBMesquite::EntityTopology handled by this mapping function.

Implements MBMesquite::MappingFunction.

Definition at line 36 of file HexLagrangeShape.cpp.

References MBMesquite::HEXAHEDRON.

{
    return HEXAHEDRON;
}
void MBMesquite::HexLagrangeShape::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.

Parameters:
locationWhere within the element at which to evaluate the Jacobian. Typically doesn't matter except for degenerate elements (e.g. pyramid as degenerate hex.)
jacobian_outThe Jacobian of the mapping function at the specified logical location.

Reimplemented from MBMesquite::MappingFunction3D.

Definition at line 322 of file HexLagrangeShape.cpp.

{
    J = MsqMatrix< 3, 3 >( 1.0 );
}
int MBMesquite::HexLagrangeShape::num_nodes ( ) const [virtual]

Get number of nodes in the element type.

Get the number of nodes in the element type that the mapping function implements. It is assumed that the result of this function, in combination with the element topology, is sufficient to determine the element type.

Implements MBMesquite::MappingFunction.

Definition at line 41 of file HexLagrangeShape.cpp.

{
    return 27;
}

List of all members.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines