MOAB: Mesh Oriented datABase  (version 5.2.1)
MBMesquite::MsqMeshEntity Class Reference

MsqMeshEntity is the Mesquite object that stores information about the elements in the mesh. More...

#include <MsqMeshEntity.hpp>

Public Member Functions

 MsqMeshEntity ()
EntityTopology get_element_type () const
 Returns element type.
std::size_t vertex_count () const
std::size_t node_count () const
std::size_t corner_count () const
 Returns number of target matrices for this element type.
void get_vertex_indices (std::vector< std::size_t > &vertex_list) const
 gets the vertices of the mesh entity
void append_vertex_indices (std::vector< std::size_t > &vertex_list) const
size_t get_local_matrix_map_about_vertex (PatchData &pd, MsqVertex *vert, size_t local_map_size, int *local_map, MsqError &err) const
void get_node_indices (std::vector< std::size_t > &vertex_list) const
 gets the vertices of the mesh entity
void append_node_indices (std::vector< std::size_t > &vertex_list) const
const std::size_t * get_vertex_index_array () const
std::size_t * get_vertex_index_array ()
void set_element_type (EntityTopology type)
 Sets element data.
void set_connectivity (std::size_t *indices, size_t num_vertices)
std::size_t get_vertex_index (std::size_t vertex_in_element) const
void get_centroid (Vector3D &centroid, const PatchData &pd, MsqError &err) const
 Returns the centroid of the element.
void get_connected_vertices (std::size_t vertex_index, std::vector< std::size_t > &vert_indices, MsqError &err)
double compute_unsigned_area (PatchData &pd, MsqError &err)
 Computes the area of the given element. Returned value is always non-negative. If the entity passed is not a two-dimensional element, an error is set.
double compute_signed_area (PatchData &pd, MsqError &err)
 Computes the signed area of the element.
void check_element_orientation (PatchData &pd, int &inverted_count, int &tested_count, MsqError &err)
void check_element_orientation_corners (PatchData &pd, int &inverted_count, int &tested_count, MsqError &err)
void compute_corner_normals (Vector3D normals[], PatchData &pd, MsqError &err)
 Uses a MeshDomain call-back function to compute the normal at the corner.
NodeSet all_nodes (MsqError &err) const
 Get NodeSet indicating all nodes present for this element type.

Private Member Functions

bool inverted_jacobian_3d (PatchData &pd, NodeSet nodes, Sample sample, MsqError &err)
bool inverted_jacobian_2d (PatchData &pd, NodeSet nodes, Sample sample, MsqError &err)

Private Attributes

EntityTopology mType
size_t * vertexIndices
size_t numVertexIndices

Friends

std::ostream & operator<< (std::ostream &stream, const MsqMeshEntity &entity)

Detailed Description

MsqMeshEntity is the Mesquite object that stores information about the elements in the mesh.

Definition at line 61 of file MsqMeshEntity.hpp.


Constructor & Destructor Documentation

Definition at line 64 of file MsqMeshEntity.hpp.


Member Function Documentation

Get NodeSet indicating all nodes present for this element type.

Definition at line 608 of file MsqMeshEntity.cpp.

References mType, node_count(), MBMesquite::NodeSet::set_all_corner_nodes(), MBMesquite::NodeSet::set_all_mid_edge_nodes(), MBMesquite::NodeSet::set_all_mid_face_nodes(), and MBMesquite::NodeSet::set_all_mid_region_nodes().

Referenced by check_element_orientation(), and MsqMeshEntityTest::test_all_nodes().

{
    bool mid_edge, mid_face, mid_vol;
    TopologyInfo::higher_order( mType, node_count(), mid_edge, mid_face, mid_vol, err );
    NodeSet result;
    result.set_all_corner_nodes( mType );
    if( mid_edge ) result.set_all_mid_edge_nodes( mType );
    if( mid_face ) result.set_all_mid_face_nodes( mType );
    if( mid_vol ) result.set_all_mid_region_nodes( mType );
    return result;
}
void MBMesquite::MsqMeshEntity::append_node_indices ( std::vector< std::size_t > &  vertex_list) const

Definition at line 85 of file MsqMeshEntity.cpp.

References node_count(), and vertexIndices.

{
    indices.insert( indices.end(), vertexIndices, vertexIndices + node_count() );
}
void MBMesquite::MsqMeshEntity::append_vertex_indices ( std::vector< std::size_t > &  vertex_list) const

Gets the indices of the vertices of this element. The indices are only valid in the PatchData from which this element was retrieved. The order of the vertices is the canonical order for this element's type. The indices are placed appended to the end of the list. The list is not cleared before appending this entity's vertices.

Definition at line 74 of file MsqMeshEntity.cpp.

References vertex_count(), and vertexIndices.

{
    vertex_list.insert( vertex_list.end(), vertexIndices, vertexIndices + vertex_count() );
}
void MBMesquite::MsqMeshEntity::check_element_orientation ( PatchData pd,
int &  inverted_count,
int &  tested_count,
MsqError err 
)

Check sign of the determinant mapping fuction Jacobian at representative sample points in the element.

Parameters:
inverted_countNumber of sampling locations within the element for which the determinant of the mapping function Jacobian was negative.
tested_countThe number of sampling locations in the element for which the Jacobian was tested.

Definition at line 493 of file MsqMeshEntity.cpp.

References all_nodes(), check_element_orientation_corners(), MBMesquite::NodeSet::corner_node(), corners, MBMesquite::PatchData::domain_set(), MBMesquite::edges, MBMesquite::faces, MBMesquite::PatchData::get_mapping_function_2D(), MBMesquite::PatchData::get_mapping_function_3D(), MBMesquite::NodeSet::have_any_corner_node(), MBMesquite::NodeSet::have_any_mid_edge_node(), MBMesquite::NodeSet::have_any_mid_face_node(), MBMesquite::NodeSet::have_any_mid_region_node(), inverted_jacobian_2d(), inverted_jacobian_3d(), MBMesquite::NodeSet::mid_edge_node(), MBMesquite::NodeSet::mid_face_node(), MSQ_ERRRTN, mType, MBMesquite::NodeSet::num_nodes(), sample, and MBMesquite::MappingFunction::sample_points().

Referenced by MBMesquite::TerminationCriterion::count_inverted(), QualityMetricTester::get_inverted_element(), MBMesquite::QualityAssessor::loop_over_mesh_internal(), MBMesquite::SmartLaplacianSmoother::num_inverted(), and TerminationCriterionTest::test_untangled_mesh().

{
    NodeSet all = all_nodes( err );MSQ_ERRRTN( err );
    unsigned i;

    if( TopologyInfo::dimension( mType ) == 2 )
    {
        if( !pd.domain_set() )
        {
            total    = 0;
            inverted = 0;
            return;
        }

        const MappingFunction2D* mf = pd.get_mapping_function_2D( mType );
        if( !mf )
        {
            check_element_orientation_corners( pd, inverted, total, err );
            return;
        }

        NodeSet sample = mf->sample_points( all );
        total          = sample.num_nodes();
        inverted       = 0;

        if( sample.have_any_corner_node() )
        {
            for( i = 0; i < TopologyInfo::corners( mType ); ++i )
                if( sample.corner_node( i ) ) inverted += inverted_jacobian_2d( pd, all, Sample( 0, i ), err );
        }
        if( sample.have_any_mid_edge_node() )
        {
            for( i = 0; i < TopologyInfo::edges( mType ); ++i )
                if( sample.mid_edge_node( i ) ) inverted += inverted_jacobian_2d( pd, all, Sample( 1, i ), err );
        }
        if( sample.have_any_mid_face_node() ) inverted += inverted_jacobian_2d( pd, all, Sample( 2, 0 ), err );
    }
    else
    {
        const MappingFunction3D* mf = pd.get_mapping_function_3D( mType );
        if( !mf )
        {
            check_element_orientation_corners( pd, inverted, total, err );
            return;
        }

        NodeSet sample = mf->sample_points( all );
        total          = sample.num_nodes();
        inverted       = 0;

        if( sample.have_any_corner_node() )
        {
            for( i = 0; i < TopologyInfo::corners( mType ); ++i )
                if( sample.corner_node( i ) ) inverted += inverted_jacobian_3d( pd, all, Sample( 0, i ), err );
        }
        if( sample.have_any_mid_edge_node() )
        {
            for( i = 0; i < TopologyInfo::edges( mType ); ++i )
                if( sample.mid_edge_node( i ) ) inverted += inverted_jacobian_3d( pd, all, Sample( 1, i ), err );
        }
        if( sample.have_any_mid_face_node() )
        {
            for( i = 0; i < TopologyInfo::faces( mType ); ++i )
                if( sample.mid_face_node( i ) ) inverted += inverted_jacobian_3d( pd, all, Sample( 2, i ), err );
        }
        if( sample.have_any_mid_region_node() ) { inverted += inverted_jacobian_3d( pd, all, Sample( 3, 0 ), err ); }
    }
}
void MBMesquite::MsqMeshEntity::check_element_orientation_corners ( PatchData pd,
int &  inverted_count,
int &  tested_count,
MsqError err 
)

Definition at line 620 of file MsqMeshEntity.cpp.

References corner_count(), MBMesquite::PatchData::domain_set(), MBMesquite::PatchData::get_domain_normal_at_element(), MBMesquite::PatchData::get_vertex_array(), MBMesquite::MsqError::INVALID_ARG, MBMesquite::Vector3D::length(), MSQ_ERRRTN, MSQ_SETERR, mType, node_count(), MBMesquite::POLYGON, MBMesquite::QUADRILATERAL, MBMesquite::TETRAHEDRON, MBMesquite::TRIANGLE, MBMesquite::MsqError::UNSUPPORTED_ELEMENT, vertex_count(), and vertexIndices.

Referenced by check_element_orientation().

{
    int num_nodes = node_count();
    total = inverted = 0;

    if( node_count() > vertex_count() )
    {
        MSQ_SETERR( err )
        ( "Cannot perform inversion test for higher-order element"
          " without mapping function.",
          MsqError::UNSUPPORTED_ELEMENT );
        return;
    }

    const MsqVertex* vertices = pd.get_vertex_array( err );MSQ_ERRRTN( err );

    const Vector3D d_con( 1.0, 1.0, 1.0 );

    int i;
    Vector3D coord_vectors[3];
    Vector3D center_vector;

    switch( mType )
    {
        case TRIANGLE:

            if( !pd.domain_set() ) return;

            pd.get_domain_normal_at_element( this, coord_vectors[2], err );MSQ_ERRRTN( err );
            coord_vectors[2] = coord_vectors[2] / coord_vectors[2].length();  // Need unit normal
            center_vector    = vertices[vertexIndices[0]];
            coord_vectors[0] = vertices[vertexIndices[1]] - center_vector;
            coord_vectors[1] = vertices[vertexIndices[2]] - center_vector;
            total            = 1;
            inverted         = ( coord_vectors[2] % ( coord_vectors[0] * coord_vectors[1] ) <= 0.0 );
            break;

        case QUADRILATERAL:

            if( !pd.domain_set() ) return;

            pd.get_domain_normal_at_element( this, coord_vectors[2], err );MSQ_ERRRTN( err );
            coord_vectors[2] = coord_vectors[2] / coord_vectors[2].length();  // Need unit normal

            for( i = 0; i < 4; ++i )
            {
                center_vector    = vertices[vertexIndices[i]];
                coord_vectors[0] = vertices[vertexIndices[( i + 1 ) % 4]] - center_vector;
                coord_vectors[1] = vertices[vertexIndices[( i + 3 ) % 4]] - center_vector;
                ++total;
                inverted += ( coord_vectors[2] % ( coord_vectors[0] * coord_vectors[1] ) <= 0.0 );
            }
            break;

        case TETRAHEDRON:
            center_vector    = vertices[vertexIndices[0]];
            coord_vectors[0] = vertices[vertexIndices[1]] - center_vector;
            coord_vectors[1] = vertices[vertexIndices[2]] - center_vector;
            coord_vectors[2] = vertices[vertexIndices[3]] - center_vector;
            total            = 1;
            inverted         = ( coord_vectors[0] % ( coord_vectors[1] * coord_vectors[2] ) <= 0.0 );
            break;

        case POLYGON:

            if( !pd.domain_set() ) return;

            pd.get_domain_normal_at_element( this, coord_vectors[2], err );MSQ_ERRRTN( err );
            coord_vectors[2] = coord_vectors[2] / coord_vectors[2].length();  // Need unit normal

            for( i = 0; i < num_nodes; ++i )
            {
                center_vector    = vertices[vertexIndices[i]];
                coord_vectors[0] = vertices[vertexIndices[( i + 1 ) % num_nodes]] - center_vector;
                coord_vectors[1] = vertices[vertexIndices[( i + num_nodes - 1 ) % num_nodes]] - center_vector;
                ++total;
                inverted += ( coord_vectors[2] % ( coord_vectors[0] * coord_vectors[1] ) <= 0.0 );
            }
            break;

        default:  // generic code for 3D elements
        {
            size_t num_corners = corner_count();
            unsigned num_adj;
            const unsigned* adj_idx;
            for( unsigned j = 0; j < num_corners; ++j )
            {
                adj_idx = TopologyInfo::adjacent_vertices( mType, j, num_adj );
                if( 3 != num_adj )
                {
                    MSQ_SETERR( err )( "Unsupported element type.", MsqError::INVALID_ARG );
                    return;
                }

                center_vector    = vertices[vertexIndices[j]];
                coord_vectors[0] = vertices[vertexIndices[adj_idx[0]]] - center_vector;
                coord_vectors[1] = vertices[vertexIndices[adj_idx[1]]] - center_vector;
                coord_vectors[2] = vertices[vertexIndices[adj_idx[2]]] - center_vector;
                ++total;
                inverted += ( coord_vectors[0] % ( coord_vectors[1] * coord_vectors[2] ) <= 0.0 );
            }
            break;
        }
    }  // end switch over element type
}

Uses a MeshDomain call-back function to compute the normal at the corner.

Gives the normal at the surface point corner_pt ... but if not available, gives the normalized cross product of corner_vec1 and corner_vec2.

Definition at line 338 of file MsqMeshEntity.cpp.

References MBMesquite::PatchData::domain_set(), MBMesquite::PatchData::get_domain_normals_at_corners(), MBMesquite::PatchData::get_element_index(), get_element_type(), MBMesquite::MsqError::INVALID_ARG, MBMesquite::Vector3D::length(), MBMesquite::length(), MSQ_ERRRTN, MSQ_SETERR, MBMesquite::Vector3D::normalize(), MBMesquite::POLYGON, MBMesquite::QUADRILATERAL, MBMesquite::TRIANGLE, MBMesquite::PatchData::vertex_by_index(), vertex_count(), and vertexIndices.

{
    EntityTopology type = get_element_type();
    if( type != TRIANGLE && type != QUADRILATERAL && type != POLYGON )
    {
        MSQ_SETERR( err )
        ( "Should only be used for faces (tri, quads, ...).", MsqError::INVALID_ARG );
        return;
    }

    // There are two cases where we cannot get a normal from the
    // geometry that are not errors:
    // 1) There is no domain set
    // 2) The vertex is at a degenerate point on the geometry (e.g.
    //     tip of a cone.)

    // Get normal from domain
    if( pd.domain_set() )
    {
        size_t index = pd.get_element_index( this );
        pd.get_domain_normals_at_corners( index, normals, err );MSQ_ERRRTN( err );
    }

    // Check if normals are valid (none are valid if !pd.domain_set())
    const unsigned count = vertex_count();
    for( unsigned i = 0; i < count; ++i )
    {
        // If got valid normal from domain,
        // make it a unit vector and continue.
        if( pd.domain_set() )
        {
            double length = normals[i].length();
            if( length > DBL_EPSILON )
            {
                normals[i] /= length;
                continue;
            }
        }

        const size_t prev_idx = vertexIndices[( i + count - 1 ) % count];
        const size_t this_idx = vertexIndices[i];
        const size_t next_idx = vertexIndices[( i + 1 ) % count];

        // Calculate normal using edges adjacent to corner
        normals[i] = ( pd.vertex_by_index( next_idx ) - pd.vertex_by_index( this_idx ) ) *
                     ( pd.vertex_by_index( prev_idx ) - pd.vertex_by_index( this_idx ) );
        normals[i].normalize();
    }
}

Computes the signed area of the element.

Computes the area of the given element. Returned value can be negative. If the entity passed is not a two-dimensional element, an error is set.

Definition at line 203 of file MsqMeshEntity.cpp.

References MBMesquite::PatchData::get_domain_normal_at_element(), MBMesquite::PatchData::get_element_index(), MBMesquite::PatchData::get_vertex_array(), MBMesquite::Vector3D::length(), MSQ_ERRZERO, MSQ_SETERR, mType, MBMesquite::QUADRILATERAL, MBMesquite::TRIANGLE, MBMesquite::MsqError::UNSUPPORTED_ELEMENT, and vertexIndices.

{
    const MsqVertex* verts = pd.get_vertex_array( err );
    MSQ_ERRZERO( err );
    double tem  = 0.0;
    double tem2 = 0.0;
    Vector3D surface_normal;
    Vector3D cross_vec;
    size_t element_index = pd.get_element_index( this );

    switch( mType )
    {

        case TRIANGLE:
            cross_vec = ( ( verts[vertexIndices[1]] - verts[vertexIndices[0]] ) *
                          ( verts[vertexIndices[2]] - verts[vertexIndices[0]] ) );
            pd.get_domain_normal_at_element( element_index, surface_normal, err );
            MSQ_ERRZERO( err );
            tem = ( cross_vec.length() / 2.0 );
            // if normals do not point in same general direction, negate area
            if( cross_vec % surface_normal < 0 ) { tem *= -1; }

            return tem;

        case QUADRILATERAL:
            cross_vec = ( ( verts[vertexIndices[1]] - verts[vertexIndices[0]] ) *
                          ( verts[vertexIndices[3]] - verts[vertexIndices[0]] ) );
            pd.get_domain_normal_at_element( element_index, surface_normal, err );
            MSQ_ERRZERO( err );
            tem = ( cross_vec.length() / 2.0 );
            // if normals do not point in same general direction, negate area
            if( cross_vec % surface_normal < 0 ) { tem *= -1; }
            cross_vec = ( ( verts[vertexIndices[3]] - verts[vertexIndices[2]] ) *
                          ( verts[vertexIndices[1]] - verts[vertexIndices[2]] ) );
            tem2      = ( cross_vec.length() / 2.0 );
            // if normals do not point in same general direction, negate area
            if( cross_vec % surface_normal < 0 )
            {
                tem2 *= -1;
                // test to make sure surface normal existed
                // if(surface_normal.length_squared()<.5){
                // err.set_msg("compute_signed_area called without surface_normal available.");
                //}
            }
            return ( tem + tem2 );

        default:
            MSQ_SETERR( err )
            ( "Invalid type of element passed to compute unsigned area.", MsqError::UNSUPPORTED_ELEMENT );
            return 0;
    };
    return 0.0;
}

Computes the area of the given element. Returned value is always non-negative. If the entity passed is not a two-dimensional element, an error is set.

Computes the area of the element. The returned value is always non-negative.

Definition at line 113 of file MsqMeshEntity.cpp.

References MBMesquite::corner_volume(), MBMesquite::PatchData::get_vertex_array(), MBMesquite::HEXAHEDRON, MBMesquite::length(), MSQ_ERRZERO, MSQ_SETERR, mType, numVertexIndices, MBMesquite::POLYGON, MBMesquite::PRISM, MBMesquite::PYRAMID, MBMesquite::QUADRILATERAL, MBMesquite::TETRAHEDRON, MBMesquite::TRIANGLE, MBMesquite::MsqError::UNSUPPORTED_ELEMENT, and vertexIndices.

Referenced by MBMesquite::SizeMetric::evaluate(), MsqMeshEntityTest::test_unsigned_area(), MsqMeshEntityTest::test_unsigned_area_common(), and MsqMeshEntityTest::test_unsigned_area_poly().

{
    const MsqVertex* verts = pd.get_vertex_array( err );
    MSQ_ERRZERO( err );
    double tem = 0.0;
    switch( mType )
    {

        case TRIANGLE:
            tem = ( ( verts[vertexIndices[1]] - verts[vertexIndices[0]] ) *
                    ( verts[vertexIndices[2]] - verts[vertexIndices[0]] ) )
                      .length();
            return 0.5 * tem;

        case QUADRILATERAL:
            tem = ( ( verts[vertexIndices[1]] - verts[vertexIndices[0]] ) *
                    ( verts[vertexIndices[3]] - verts[vertexIndices[0]] ) )
                      .length();
            tem += ( ( verts[vertexIndices[3]] - verts[vertexIndices[2]] ) *
                     ( verts[vertexIndices[1]] - verts[vertexIndices[2]] ) )
                       .length();
            return ( tem / 2.0 );

        case POLYGON:
            // assume convex
            for( unsigned i = 1; i < numVertexIndices - 1; ++i )
                tem += ( ( verts[vertexIndices[i]] - verts[vertexIndices[0]] ) *
                         ( verts[vertexIndices[i + 1]] - verts[vertexIndices[0]] ) )
                           .length();
            return 0.5 * tem;

        case TETRAHEDRON:
            return 1.0 / 6.0 *
                   fabs( corner_volume( verts[vertexIndices[0]], verts[vertexIndices[1]], verts[vertexIndices[2]],
                                        verts[vertexIndices[3]] ) );

        case PYRAMID: {
            Vector3D m =
                verts[vertexIndices[0]] + verts[vertexIndices[1]] + verts[vertexIndices[2]] + verts[vertexIndices[3]];
            Vector3D t1 = verts[vertexIndices[0]] - verts[vertexIndices[2]];
            Vector3D t2 = verts[vertexIndices[1]] - verts[vertexIndices[3]];
            tem         = ( ( t1 + t2 ) * ( t1 - t2 ) ) % ( verts[vertexIndices[4]] - 0.25 * m );
            return ( 1.0 / 12.0 ) * fabs( tem );
        }

        case PRISM: {
            tem = corner_volume( verts[vertexIndices[0]], verts[vertexIndices[1]], verts[vertexIndices[2]],
                                 verts[vertexIndices[3]] );

            tem += corner_volume( verts[vertexIndices[1]], verts[vertexIndices[2]], verts[vertexIndices[3]],
                                  verts[vertexIndices[4]] );

            tem += corner_volume( verts[vertexIndices[2]], verts[vertexIndices[3]], verts[vertexIndices[4]],
                                  verts[vertexIndices[5]] );

            return 1.0 / 6.0 * fabs( tem );
        }

        case HEXAHEDRON: {

            tem = corner_volume( verts[vertexIndices[1]], verts[vertexIndices[2]], verts[vertexIndices[0]],
                                 verts[vertexIndices[5]] );

            tem += corner_volume( verts[vertexIndices[3]], verts[vertexIndices[0]], verts[vertexIndices[2]],
                                  verts[vertexIndices[7]] );

            tem += corner_volume( verts[vertexIndices[4]], verts[vertexIndices[7]], verts[vertexIndices[5]],
                                  verts[vertexIndices[0]] );

            tem += corner_volume( verts[vertexIndices[6]], verts[vertexIndices[5]], verts[vertexIndices[7]],
                                  verts[vertexIndices[2]] );

            tem += corner_volume( verts[vertexIndices[5]], verts[vertexIndices[2]], verts[vertexIndices[0]],
                                  verts[vertexIndices[7]] );

            return ( 1.0 / 6.0 ) * fabs( tem );
        }

        default:
            MSQ_SETERR( err )
            ( "Invalid type of element passed to compute unsigned area.", MsqError::UNSUPPORTED_ELEMENT );
            return 0;
    }
    return 0;
}
std::size_t MBMesquite::MsqMeshEntity::corner_count ( ) const [inline]

Returns number of target matrices for this element type.

Definition at line 82 of file MsqMeshEntity.hpp.

References MBMesquite::PYRAMID.

Referenced by check_element_orientation_corners(), FauxMetric< B >::get_element_evaluations(), and PatchDataTest::test_quad8_patch().

    {
        return mType == PYRAMID ? 4 : vertex_count();
    }
void MBMesquite::MsqMeshEntity::get_centroid ( Vector3D centroid,
const PatchData pd,
MsqError err 
) const

Returns the centroid of the element.

The centroid of an element containing n vertices with equal masses is located at

\[ \b{x} = \frac{ \sum_{i=1}^{n} \b{x}_i }{ n } \]

where \( \b{x}_i ,\, i=1,...,n\) are the vertices coordinates.

Definition at line 94 of file MsqMeshEntity.cpp.

References MBMesquite::PatchData::get_vertex_array(), MSQ_ERRRTN, vertex_count(), and vertexIndices.

Referenced by MsqMeshEntityTest::test_centroid().

{
    centroid               = 0.0;
    const MsqVertex* vtces = pd.get_vertex_array( err );MSQ_ERRRTN( err );
    size_t nve = vertex_count();
    for( size_t i = 0; i < nve; ++i )
        centroid += vtces[vertexIndices[i]];
    centroid /= nve;
}
void MBMesquite::MsqMeshEntity::get_connected_vertices ( std::size_t  vertex_index,
std::vector< std::size_t > &  vert_indices,
MsqError err 
)

Fills a vector<size_t> with vertices connected to the given vertex through the edges of this MsqMeshEntity.

Appends the indices (in the vertex array) of the vertices to connected to vertex_array[vertex_index] to the end of the vector vert_indices. The connected vertices are right-hand ordered as defined by the entity.

Definition at line 263 of file MsqMeshEntity.cpp.

References MBMesquite::MsqError::INVALID_ARG, MSQ_SETERR, mType, n, vertex_count(), and vertexIndices.

Referenced by MBMesquite::VertexConditionNumberQualityMetric::evaluate(), MBMesquite::LocalSizeQualityMetric::evaluate(), and MBMesquite::VertexConditionNumberQualityMetric::evaluate_with_indices().

{
    // index is set to the index in the vertexIndices corresponding
    // to vertex_index
    int index;
    for( index = vertex_count() - 1; index >= 0; --index )
        if( vertexIndices[index] == vertex_index ) break;
    if( index < 0 )
    {
        MSQ_SETERR( err )( "Invalid vertex index.", MsqError::INVALID_ARG );
        return;
    }

    unsigned n;
    const unsigned* indices = TopologyInfo::adjacent_vertices( mType, index, n );
    if( !indices ) MSQ_SETERR( err )( "Element type not available", MsqError::INVALID_ARG );
    for( unsigned i = 0; i < n; ++i )
        vert_indices.push_back( vertexIndices[indices[i]] );
}

Returns element type.

Definition at line 67 of file MsqMeshEntity.hpp.

Referenced by MBMesquite::append_elem_samples(), MBMesquite::RefSizeTargetCalculator::average_edge_length(), PatchDataTest::check_sub_patch(), compute_corner_normals(), MBMesquite::EdgeLengthMetric::evaluate(), MBMesquite::AspectRatioGammaQualityMetric::evaluate(), MBMesquite::ConditionNumberQualityMetric::evaluate(), MBMesquite::AffineMapMetric::evaluate(), MBMesquite::IdealWeightMeanRatio::evaluate(), MBMesquite::UntangleBetaQualityMetric::evaluate(), MBMesquite::IdealWeightInverseMeanRatio::evaluate(), MBMesquite::AWQualityMetric::evaluate_internal(), MBMesquite::TQualityMetric::evaluate_internal(), MBMesquite::TMPQualityMetric::evaluate_surface_common(), MBMesquite::EdgeLengthMetric::evaluate_with_gradient(), MBMesquite::AWQualityMetric::evaluate_with_gradient(), MBMesquite::IdealWeightMeanRatio::evaluate_with_gradient(), MBMesquite::TQualityMetric::evaluate_with_gradient(), MBMesquite::IdealWeightInverseMeanRatio::evaluate_with_gradient(), MBMesquite::IdealWeightMeanRatio::evaluate_with_Hessian(), MBMesquite::AWQualityMetric::evaluate_with_Hessian(), MBMesquite::TQualityMetric::evaluate_with_Hessian(), MBMesquite::IdealWeightInverseMeanRatio::evaluate_with_Hessian(), MBMesquite::IdealWeightMeanRatio::evaluate_with_Hessian_diagonal(), MBMesquite::TQualityMetric::evaluate_with_Hessian_diagonal(), MBMesquite::AWQualityMetric::evaluate_with_Hessian_diagonal(), MBMesquite::IdealWeightInverseMeanRatio::evaluate_with_Hessian_diagonal(), MBMesquite::AffineMapMetric::evaluate_with_indices(), MBMesquite::EdgeQM::evaluate_with_indices(), MBMesquite::IdealShapeTarget::get_2D_target(), MBMesquite::TargetReader::get_2D_target(), FakeTargetCalc::get_2D_target(), MBMesquite::IdealShapeTarget::get_3D_target(), MBMesquite::TargetReader::get_3D_target(), FakeTargetCalc::get_3D_target(), MBMesquite::EdgeIterator::get_adjacent_vertices(), MBMesquite::PatchData::get_domain_normal_at_element(), MBMesquite::PatchData::get_domain_normal_at_mid_edge(), MBMesquite::EdgeQM::get_edge_evaluations(), MBMesquite::PatchData::get_minmax_edge_length(), MBMesquite::TargetCalculator::get_refmesh_Jacobian_2D(), MBMesquite::TargetCalculator::get_refmesh_Jacobian_3D(), MBMesquite::PatchData::get_sample_location(), MBMesquite::PatchData::get_samples(), MBMesquite::PatchData::get_subpatch(), MBMesquite::TargetReader::get_surface_target(), FakeTargetCalc::get_surface_target(), MBMesquite::NonGradient::getPatchDimension(), MBMesquite::MeshUtil::lambda_distribution(), MBMesquite::TargetWriter::loop_over_mesh(), MBMesquite::QualityAssessor::loop_over_mesh_internal(), MBMesquite::PatchData::non_slave_node_set(), MBMesquite::CachingTargetCalculator::notify_sub_patch(), MBMesquite::populate_data(), PatchDataTest::test_patch_contents(), PatchDataTest::test_quad8_patch(), MBMesquite::PatchData::update_slave_node_coordinates(), and MBMesquite::MeshWriter::write_vtk().

    {
        return mType;
    }
size_t MBMesquite::MsqMeshEntity::get_local_matrix_map_about_vertex ( PatchData pd,
MsqVertex vert,
size_t  local_map_size,
int *  local_map,
MsqError err 
) const

Get a array of indices that specifies for the given vertex the correct matrix map. This is used by the I_DFT point relaxation methods in the laplacian smoothers.

Definition at line 403 of file MsqMeshEntity.cpp.

References MBMesquite::PatchData::get_vertex_array(), MBMesquite::HEXAHEDRON, MBMesquite::MsqError::INVALID_ARG, MSQ_SETERR, mType, NOT_IMPLEMENTED, MBMesquite::QUADRILATERAL, MBMesquite::TETRAHEDRON, MBMesquite::TRIANGLE, MBMesquite::MsqError::UNSUPPORTED_ELEMENT, and vertexIndices.

{
    // i iterates through elem's vertices
    int i = 0;
    // index is set to the index in the vertexIndices corresponding
    // to vertex_index
    int index                     = -1;
    int return_val                = 0;
    const MsqVertex* vertex_array = pd.get_vertex_array( err );
    if( err ) return return_val;

    switch( mType )
    {
        case TRIANGLE:
            MSQ_SETERR( err )
            ( "Requested function not yet supported for Triangles.", MsqError::NOT_IMPLEMENTED );

            break;

        case QUADRILATERAL:
            MSQ_SETERR( err )
            ( "Requested function not yet supported for Quadrilaterals.", MsqError::NOT_IMPLEMENTED );

            break;

        case TETRAHEDRON:
            if( local_map_size < 4 )
            {
                MSQ_SETERR( err )
                ( "Array of incorrect length sent to function.", MsqError::INVALID_ARG );
                return return_val;
            }
            return_val = 4;
            while( i < 4 )
            {
                if( &vertex_array[vertexIndices[i]] == vert )
                {
                    index = i;
                    break;
                }
                ++i;
            }
            switch( index )
            {
                case( 0 ):
                    local_map[0] = 0;
                    local_map[1] = 1;
                    local_map[2] = 2;
                    local_map[3] = 3;
                    break;
                case( 1 ):
                    local_map[0] = 1;
                    local_map[1] = 0;
                    local_map[2] = 3;
                    local_map[3] = 2;
                    break;
                case( 2 ):
                    local_map[0] = 2;
                    local_map[1] = 3;
                    local_map[2] = 0;
                    local_map[3] = 1;
                    break;
                case( 3 ):
                    local_map[0] = 3;
                    local_map[1] = 2;
                    local_map[2] = 1;
                    local_map[3] = 0;
                    break;
                default:
                    local_map[0] = -1;
                    local_map[1] = -1;
                    local_map[2] = -1;
                    local_map[3] = -1;
            };

            break;

        case HEXAHEDRON:
            MSQ_SETERR( err )
            ( "Requested function not yet supported for Hexahedrons.", MsqError::NOT_IMPLEMENTED );

            break;
        default:
            MSQ_SETERR( err )( "Element type not available", MsqError::UNSUPPORTED_ELEMENT );
            break;
    }
    return return_val;
}
void MBMesquite::MsqMeshEntity::get_node_indices ( std::vector< std::size_t > &  vertex_list) const

gets the vertices of the mesh entity

Definition at line 79 of file MsqMeshEntity.cpp.

References node_count(), and vertexIndices.

Referenced by PatchDataTest::check_sub_patch(), PatchDataTest::test_quad8_patch(), and MBMesquite::MeshWriter::write_vtk().

{
    indices.resize( node_count() );
    std::copy( vertexIndices, vertexIndices + node_count(), indices.begin() );
}
std::size_t MBMesquite::MsqMeshEntity::get_vertex_index ( std::size_t  vertex_in_element) const [inline]

Definition at line 196 of file MsqMeshEntity.hpp.

References vertex_count(), and vertexIndices.

Referenced by MBMesquite::EdgeLengthMetric::evaluate(), MBMesquite::EdgeLengthMetric::evaluate_with_gradient(), and MBMesquite::EdgeIterator::get_adjacent_vertices().

{
    // Make sure we're in range
    assert( vertex_in_element < vertex_count() );
    // Return the index
    return vertexIndices[vertex_in_element];
}
const std::size_t * MBMesquite::MsqMeshEntity::get_vertex_index_array ( ) const [inline]

Very efficient retrieval of vertices indexes (corresponding to the PatchData vertex array).

Definition at line 186 of file MsqMeshEntity.hpp.

References vertexIndices.

Referenced by MsqHessianTest::accumulate_entries(), MBMesquite::RefSizeTargetCalculator::average_edge_length(), MBMesquite::ConditionNumberQualityMetric::evaluate(), MBMesquite::AffineMapMetric::evaluate(), MBMesquite::IdealWeightMeanRatio::evaluate(), MBMesquite::UntangleBetaQualityMetric::evaluate(), MBMesquite::IdealWeightInverseMeanRatio::evaluate(), FauxMetric< B >::evaluate(), MBMesquite::IdealWeightMeanRatio::evaluate_with_gradient(), MBMesquite::IdealWeightInverseMeanRatio::evaluate_with_gradient(), MBMesquite::IdealWeightMeanRatio::evaluate_with_Hessian(), MBMesquite::IdealWeightInverseMeanRatio::evaluate_with_Hessian(), MBMesquite::IdealWeightMeanRatio::evaluate_with_Hessian_diagonal(), MBMesquite::IdealWeightInverseMeanRatio::evaluate_with_Hessian_diagonal(), MBMesquite::ElementQM::evaluate_with_indices(), MBMesquite::AffineMapMetric::evaluate_with_indices(), MBMesquite::EdgeQM::evaluate_with_indices(), FauxMetric< B >::evaluate_with_indices(), ConstantElementMetric::evaluate_with_indices(), TriTauMetric::evaluate_with_indices(), MBMesquite::QualityMetric::fixed_vertex_bitmap(), MBMesquite::EdgeIterator::get_adjacent_vertices(), QualityMetricTester::get_degenerate_element(), MBMesquite::PatchData::get_domain_normal_at_corner(), MBMesquite::PatchData::get_domain_normal_at_element(), MBMesquite::PatchData::get_domain_normal_at_mid_edge(), MBMesquite::PatchData::get_domain_normals_at_corners(), MBMesquite::EdgeQM::get_edge_evaluations(), MBMesquite::ElementQM::get_element_evaluations(), QualityMetricTester::get_inverted_element(), MBMesquite::PatchData::get_minmax_edge_length(), QualityMetricTester::get_nonideal_element(), MBMesquite::TargetCalculator::get_refmesh_Jacobian_2D(), MBMesquite::TargetCalculator::get_refmesh_Jacobian_3D(), MBMesquite::PatchData::get_sample_location(), MBMesquite::PatchData::get_subpatch(), MBMesquite::VertexQM::get_vertex_corner_handles(), QualityMetricTester::get_zero_element(), MBMesquite::MsqHessian::initialize(), MBMesquite::MappingFunction2D::jacobian(), MBMesquite::MappingFunction3D::jacobian(), TriTauMetric::matrix(), MBMesquite::PatchData::non_slave_node_set(), QualityMetricTest::test_fixed_vertex_list(), QualityMetricTester::test_get_indices_fixed(), QualityMetricTester::test_gradient_reflects_quality(), MappingFunctionTest::test_jacobian_2d(), MappingFunctionTest::test_jacobian_3d(), QualityMetricTester::test_measures_quality(), PatchDataTest::test_patch_contents(), TerminationCriterionTest::test_untangled_mesh(), PatchDataTest::test_update_slave_node_coords(), PMeanPMetricTest::test_vertex_evaluate(), MBMesquite::PatchData::update_slave_node_coordinates(), and MBMesquite::NonSmoothDescent::validity_check().

{
    return vertexIndices;
}

Definition at line 191 of file MsqMeshEntity.hpp.

References vertexIndices.

{
    return vertexIndices;
}
void MBMesquite::MsqMeshEntity::get_vertex_indices ( std::vector< std::size_t > &  vertices) const

gets the vertices of the mesh entity

Gets the indices of the vertices of this element. The indices are only valid in the PatchData from which this element was retrieved. The order of the vertices is the canonical order for this element's type.

Definition at line 61 of file MsqMeshEntity.cpp.

References vertex_count(), and vertexIndices.

Referenced by QualityMetricTester::test_diagonal_with_fixed_vertex(), QualityMetricTester::test_get_element_indices(), QualityMetricTester::test_get_sample_indices(), QualityMetricTester::test_gradient_with_fixed_vertex(), QualityMetricTester::test_hessian_with_fixed_vertex(), VtkTest::tet_validity_check(), and VtkTest::tri_check_validity().

{
    vertices.resize( vertex_count() );
    std::copy( vertexIndices, vertexIndices + vertex_count(), vertices.begin() );
}
bool MBMesquite::MsqMeshEntity::inverted_jacobian_2d ( PatchData pd,
NodeSet  nodes,
Sample  sample,
MsqError err 
) [private]

Check for a negative Jacobian at the specified sample point of a surface element.

Definition at line 580 of file MsqMeshEntity.cpp.

References MBMesquite::MsqMatrix< R, C >::column(), moab::cross(), MBMesquite::PatchData::domain_set(), MBMesquite::PatchData::get_domain_normal_at_sample(), MBMesquite::PatchData::get_element_index(), MBMesquite::PatchData::get_mapping_function_2D(), MBMesquite::MappingFunction2D::jacobian(), MSQ_ERRZERO, mType, N, node_count(), and sample.

Referenced by check_element_orientation().

{
    MsqMatrix< 3, 2 > J;
    MsqVector< 2 > junk[9];
    size_t junk2[9], junk3;
    assert( node_count() <= 9 );

    const int idx               = pd.get_element_index( this );
    const MappingFunction2D* mf = pd.get_mapping_function_2D( mType );
    mf->jacobian( pd, idx, nodes, sample, junk2, junk, junk3, J, err );
    MSQ_ERRZERO( err );
    const MsqVector< 3 > cross = J.column( 0 ) * J.column( 1 );

    if( pd.domain_set() )
    {
        Vector3D norm;
        pd.get_domain_normal_at_sample( pd.get_element_index( this ), sample, norm, err );
        MSQ_ERRZERO( err );

        const MsqVector< 3 > N( &norm[0] );
        if( cross % N < 0.0 ) return true;
    }

    const double l1 = J.column( 0 ) % J.column( 0 );
    const double l2 = J.column( 1 ) % J.column( 1 );
    return cross % cross < DBL_EPSILON * DBL_EPSILON * l1 * l2;
}
bool MBMesquite::MsqMeshEntity::inverted_jacobian_3d ( PatchData pd,
NodeSet  nodes,
Sample  sample,
MsqError err 
) [private]

Check for a negative Jacobian at the specified sample point of a volume element.

Definition at line 562 of file MsqMeshEntity.cpp.

References MBMesquite::det(), MBMesquite::PatchData::get_element_index(), MBMesquite::PatchData::get_mapping_function_3D(), MBMesquite::MappingFunction3D::jacobian(), MSQ_ERRZERO, mType, node_count(), and sample.

Referenced by check_element_orientation().

{
    MsqMatrix< 3, 3 > J;
    MsqVector< 3 > junk[27];
    size_t junk2[27], junk3;
    assert( node_count() <= 27 );

    const MappingFunction3D* mf = pd.get_mapping_function_3D( mType );
    mf->jacobian( pd, pd.get_element_index( this ), nodes, sample, junk2, junk, junk3, J, err );
    MSQ_ERRZERO( err );
    // const double size_eps_sqr = sqr_Frobenius( J ) * DBL_EPSILON;
    const double d = det( J );
    double l1      = J.column( 0 ) % J.column( 0 );
    double l2      = J.column( 1 ) % J.column( 1 );
    double l3      = J.column( 2 ) % J.column( 2 );
    return d < 0 || d * d < DBL_EPSILON * DBL_EPSILON * l1 * l2 * l3;
}
void MBMesquite::MsqMeshEntity::set_connectivity ( std::size_t *  indices,
size_t  num_vertices 
) [inline]

Set connectivity data (vertex array) for element. MsqMeshEntity keeps the pointer to the passed array, it does not copy it. The caller is still responsible for releasing the memory for the passed index array after the MsqMeshEntity is destroyed. The intention is that this is a pointer to a portion of a larger connectivity array managed by the owning PatchData.

Definition at line 180 of file MsqMeshEntity.hpp.

References numVertexIndices, and vertexIndices.

{
    vertexIndices    = indices;
    numVertexIndices = num_vertices;
}

Sets element data.

Definition at line 101 of file MsqMeshEntity.hpp.

Referenced by MBMesquite::PatchData::fill().

    {
        mType = type;
    }

Friends And Related Function Documentation

std::ostream& operator<< ( std::ostream &  stream,
const MsqMeshEntity entity 
) [friend]

Member Data Documentation

Definition at line 167 of file MsqMeshEntity.hpp.

Referenced by compute_unsigned_area(), and set_connectivity().

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