MOAB: Mesh Oriented datABase  (version 5.4.1)
MBMesquite::VertexConditionNumberQualityMetric Class Reference

Computes the condition numbers of the corner's of elements connected to the given vertex and then averages those values. More...

#include <VertexConditionNumberQualityMetric.hpp>

+ Inheritance diagram for MBMesquite::VertexConditionNumberQualityMetric:
+ Collaboration diagram for MBMesquite::VertexConditionNumberQualityMetric:

Public Member Functions

 VertexConditionNumberQualityMetric ()
virtual ~VertexConditionNumberQualityMetric ()
 virtual destructor ensures use of polymorphism during destruction
virtual std::string get_name () const
virtual int get_negate_flag () const
 1 if metric should be minimized, -1 if metric should be maximized.
virtual bool evaluate (PatchData &pd, size_t handle, double &value, MsqError &err)
 Get metric value at a logical location in the patch.
virtual bool evaluate_with_indices (PatchData &pd, size_t handle, double &value, std::vector< size_t > &indices, MsqError &err)
 Get metric value at a logical location in the patch.

Detailed Description

Computes the condition numbers of the corner's of elements connected to the given vertex and then averages those values.

The metric does not use the sample point functionality or the compute_weighted_jacobian. It uses the isotropic ideal element. This metric does require a feasible region, and the metric needs to be minimized.

Definition at line 53 of file VertexConditionNumberQualityMetric.hpp.


Constructor & Destructor Documentation

virtual destructor ensures use of polymorphism during destruction

Definition at line 59 of file VertexConditionNumberQualityMetric.hpp.

{}

Member Function Documentation

bool VertexConditionNumberQualityMetric::evaluate ( PatchData pd,
size_t  handle,
double &  value,
MsqError err 
) [virtual]

Get metric value at a logical location in the patch.

Evaluate the metric at one location in the PatchData.

Parameters:
pdThe patch.
handleThe location in the patch (as passed back from get_evaluations).
valueThe output metric value.

Implements MBMesquite::QualityMetric.

Definition at line 56 of file VertexConditionNumberQualityMetric.cpp.

References MBMesquite::arrptr(), MBMesquite::AveragingQM::average_metrics(), MBMesquite::condition_number_2d(), MBMesquite::condition_number_3d(), MBMesquite::MsqMeshEntity::get_connected_vertices(), MBMesquite::PatchData::get_element_array(), MBMesquite::PatchData::get_vertex_array(), MBMesquite::PatchData::get_vertex_element_adjacencies(), MBMesquite::HEXAHEDRON, MSQ_ERRZERO, MBMesquite::MSQ_MAX_CAP, MSQ_SETERR, MBMesquite::MSQ_SQRT_THREE, MBMesquite::MSQ_SQRT_THREE_INV, MBMesquite::MSQ_SQRT_TWO, MBMesquite::QUADRILATERAL, MBMesquite::TETRAHEDRON, MBMesquite::TRIANGLE, and MBMesquite::MsqError::UNSUPPORTED_ELEMENT.

Referenced by evaluate_with_indices().

{
    // pd.generate_vertex_to_element_data();
    bool return_flag;
    fval = MSQ_MAX_CAP;
    // get the element array
    MsqMeshEntity* elems = pd.get_element_array( err );
    // get the vertex to element array and the offset array
    // const size_t* elem_offset = pd.get_vertex_to_elem_offset(err);  MSQ_ERRZERO(err);
    // const size_t* v_to_e_array = pd.get_vertex_to_elem_array(err);  MSQ_ERRZERO(err);
    // find the offset for this vertex
    // size_t this_offset = elem_offset[this_vert];
    // get the number of elements attached to this vertex (given by the
    // first entry in the vertex to element array)
    // size_t num_elems = v_to_e_array[this_offset];
    // PRINT_INFO("\nIN LOCAL SIZE CPP, num_elements = %i",num_elems);
    // if no elements, then return true
    size_t num_elems;
    const size_t* v_to_e_array = pd.get_vertex_element_adjacencies( this_vert, num_elems, err );
    MSQ_ERRZERO( err );

    if( num_elems <= 0 )
    {
        return true;
    }

    // create an array to store the local metric values before averaging
    // Can we remove this dynamic allocatio?
    std::vector< double > met_vals( num_elems );
    // vector to hold the other verts which form a corner.
    vector< size_t > other_vertices;
    other_vertices.reserve( 4 );
    size_t i = 0;
    // only 3 temp_vec will be sent to cond-num calculator, but the
    // additional vector3Ds may be needed during the calculations
    size_t elem_index;
    Vector3D temp_vec[6];
    const MsqVertex* vertices = pd.get_vertex_array( err );
    // loop over the elements attached to this vertex
    for( i = 0; i < num_elems; ++i )
    {
        // get the vertices connected to this vertex for this element
        elem_index = v_to_e_array[i];
        elems[elem_index].get_connected_vertices( this_vert, other_vertices, err );
        MSQ_ERRZERO( err );
        // switch over the element type of this element
        switch( elems[v_to_e_array[i]].get_element_type() )
        {

            case TRIANGLE:
                temp_vec[0] = vertices[other_vertices[0]] - vertices[this_vert];
                temp_vec[2] = vertices[other_vertices[1]] - vertices[this_vert];
                // make relative to equilateral
                temp_vec[1] = ( ( 2 * temp_vec[2] ) - temp_vec[0] ) * MSQ_SQRT_THREE_INV;
                return_flag = condition_number_2d( temp_vec, elem_index, pd, met_vals[i], err );
                MSQ_ERRZERO( err );
                if( !return_flag ) return return_flag;
                break;
            case QUADRILATERAL:
                temp_vec[0] = vertices[other_vertices[0]] - vertices[this_vert];
                temp_vec[1] = vertices[other_vertices[1]] - vertices[this_vert];
                return_flag = condition_number_2d( temp_vec, elem_index, pd, met_vals[i], err );
                MSQ_ERRZERO( err );
                if( !return_flag ) return return_flag;
                break;
            case TETRAHEDRON:
                temp_vec[0] = vertices[other_vertices[0]] - vertices[this_vert];
                temp_vec[3] = vertices[other_vertices[1]] - vertices[this_vert];
                temp_vec[4] = vertices[other_vertices[2]] - vertices[this_vert];
                // transform to equilateral tet
                temp_vec[1] = ( ( 2 * temp_vec[3] ) - temp_vec[0] ) / MSQ_SQRT_THREE;
                temp_vec[2] = ( ( 3 * temp_vec[4] ) - temp_vec[0] - temp_vec[3] ) / ( MSQ_SQRT_THREE * MSQ_SQRT_TWO );
                return_flag = condition_number_3d( temp_vec, pd, met_vals[i], err );
                MSQ_ERRZERO( err );
                if( !return_flag ) return return_flag;
                break;
            case HEXAHEDRON:
                temp_vec[0] = vertices[other_vertices[0]] - vertices[this_vert];
                temp_vec[1] = vertices[other_vertices[1]] - vertices[this_vert];
                temp_vec[2] = vertices[other_vertices[2]] - vertices[this_vert];
                return_flag = condition_number_3d( temp_vec, pd, met_vals[i], err );
                MSQ_ERRZERO( err );
                if( !return_flag ) return return_flag;
                break;
            default:
                MSQ_SETERR( err )
                ( MsqError::UNSUPPORTED_ELEMENT, "Element type (%d) not uspported in VertexConditionNumberQM.\n",
                  (int)( elems[v_to_e_array[i]].get_element_type() ) );
                fval = MSQ_MAX_CAP;
                return false;

        }  // end switch over element type
        other_vertices.clear();
    }  // end loop over elements
    fval = average_metrics( arrptr( met_vals ), num_elems, err );
    MSQ_ERRZERO( err );
    return true;
}
bool VertexConditionNumberQualityMetric::evaluate_with_indices ( PatchData pd,
size_t  handle,
double &  value,
std::vector< size_t > &  indices,
MsqError err 
) [virtual]

Get metric value at a logical location in the patch.

Evaluate the metric at one location in the PatchData.

Parameters:
pdThe patch.
handleThe location in the patch (as passed back from get_evaluations).
valueThe output metric value.
indicesThe free vertices that the evaluation is a function of, specified as vertex indices in the PatchData.

Implements MBMesquite::QualityMetric.

Definition at line 155 of file VertexConditionNumberQualityMetric.cpp.

References evaluate(), MBMesquite::MsqMeshEntity::get_connected_vertices(), MBMesquite::PatchData::get_element_array(), MBMesquite::PatchData::get_vertex_element_adjacencies(), MSQ_ERRFALSE, MSQ_ERRZERO, and MBMesquite::PatchData::num_free_vertices().

{
    bool rval = evaluate( pd, this_vert, value, err );
    MSQ_ERRFALSE( err );

    indices.clear();

    MsqMeshEntity* elems = pd.get_element_array( err );
    size_t num_elems;
    const size_t* v_to_e_array = pd.get_vertex_element_adjacencies( this_vert, num_elems, err );
    MSQ_ERRZERO( err );

    // vector to hold the other verts which form a corner.
    vector< size_t > other_vertices;
    other_vertices.reserve( 4 );
    size_t i = 0;

    // loop over the elements attached to this vertex
    for( i = 0; i < num_elems; ++i )
    {
        // get the vertices connected to this vertex for this element
        elems[v_to_e_array[i]].get_connected_vertices( this_vert, other_vertices, err );
        MSQ_ERRZERO( err );
        for( unsigned j = 0; j < other_vertices.size(); ++j )
        {
            if( other_vertices[j] < pd.num_free_vertices() ) indices.push_back( other_vertices[j] );
        }
    }

    std::sort( indices.begin(), indices.end() );
    indices.erase( std::unique( indices.begin(), indices.end() ), indices.end() );
    if( this_vert < pd.num_free_vertices() ) indices.push_back( this_vert );
    return rval;
}
std::string VertexConditionNumberQualityMetric::get_name ( ) const [virtual]

Implements MBMesquite::QualityMetric.

Definition at line 46 of file VertexConditionNumberQualityMetric.cpp.

{
    return "Vertex Condition Number";
}

1 if metric should be minimized, -1 if metric should be maximized.

Implements MBMesquite::QualityMetric.

Definition at line 51 of file VertexConditionNumberQualityMetric.cpp.

{
    return 1;
}

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