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

The untangle beta quality metric. More...

#include <UntangleBetaQualityMetric.hpp>

+ Inheritance diagram for MBMesquite::UntangleBetaQualityMetric:
+ Collaboration diagram for MBMesquite::UntangleBetaQualityMetric:

Public Member Functions

MESQUITE_EXPORT UntangleBetaQualityMetric (double bet=0.05)
 For untangle beta, the constructor defaults to the SUM averaging method, and to the ELEMENT_VERTICES evaluation mode.
virtual MESQUITE_EXPORT ~UntangleBetaQualityMetric ()
MESQUITE_EXPORT void set_beta (double beta_in)
MESQUITE_EXPORT double get_beta ()
virtual MESQUITE_EXPORT std::string get_name () const
virtual MESQUITE_EXPORT int get_negate_flag () const
 1 if metric should be minimized, -1 if metric should be maximized.
virtual MESQUITE_EXPORT bool evaluate (PatchData &pd, size_t handle, double &value, MsqError &err)
 Get metric value at a logical location in the patch.

Private Attributes

double mBeta

Detailed Description

The untangle beta quality metric.

Given a scalar value beta and local signed element volume alpha_i, define delta_i to be alpha_i minus beta. The Untangle beta value is then defined as square root of the sum over sample points of the absolute value of delta_i minus delta_i, difference squared. That is, the root mean square of the difference, abs(delta_i) minus delta_i.

The constructor defaults to RMS AveragingMethod and ELEMENT_VERTICES evaluationMode. The default beta value is .05.

Definition at line 61 of file UntangleBetaQualityMetric.hpp.


Constructor & Destructor Documentation

For untangle beta, the constructor defaults to the SUM averaging method, and to the ELEMENT_VERTICES evaluation mode.

Definition at line 84 of file UntangleBetaQualityMetric.cpp.

: AveragingQM( RMS ), mBeta( bet ) {}

Member Function Documentation

bool UntangleBetaQualityMetric::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 96 of file UntangleBetaQualityMetric.cpp.

References MBMesquite::AveragingQM::average_metrics(), MBMesquite::PatchData::element_by_index(), MBMesquite::MsqMeshEntity::get_element_type(), MBMesquite::PatchData::get_vertex_array(), MBMesquite::MsqMeshEntity::get_vertex_index_array(), MBMesquite::HEXAHEDRON, mBeta, MSQ_ERRZERO, MBMesquite::MSQ_MAX_CAP, MBMesquite::MSQ_MAX_NUM_VERT_PER_ENT, MSQ_SETERR, MBMesquite::MSQ_SQRT_THREE, MBMesquite::MSQ_SQRT_THREE_INV, MBMesquite::MSQ_SQRT_TWO, MBMesquite::PRISM, MBMesquite::PYRAMID, MBMesquite::QUADRILATERAL, MBMesquite::TETRAHEDRON, MBMesquite::TRIANGLE, MBMesquite::MsqError::UNSUPPORTED_ELEMENT, untangle_function_2d(), and untangle_function_3d().

{

    double met_vals[MSQ_MAX_NUM_VERT_PER_ENT];
    fval                         = MSQ_MAX_CAP;
    const MsqMeshEntity* element = &pd.element_by_index( e_ind );
    const size_t* v_i            = element->get_vertex_index_array();
    // only 3 temp_vec will be sent to untangle calculator, but the
    // additional vector3Ds may be needed during the calculations
    Vector3D temp_vec[5];
    const MsqVertex* vertices = pd.get_vertex_array( err );
    MSQ_ERRZERO( err );
    EntityTopology type = element->get_element_type();
    switch( type )
    {
        case TRIANGLE:
            temp_vec[0] = vertices[v_i[1]] - vertices[v_i[0]];
            temp_vec[2] = vertices[v_i[2]] - vertices[v_i[0]];
            // make relative to equilateral
            temp_vec[1] = ( ( 2 * temp_vec[2] ) - temp_vec[0] ) * MSQ_SQRT_THREE_INV;
            untangle_function_2d( mBeta, temp_vec, e_ind, pd, fval, err );
            break;
        case QUADRILATERAL:
            temp_vec[0] = vertices[v_i[1]] - vertices[v_i[0]];
            temp_vec[1] = vertices[v_i[3]] - vertices[v_i[0]];
            untangle_function_2d( mBeta, temp_vec, e_ind, pd, met_vals[0], err );
            MSQ_ERRZERO( err );

            temp_vec[0] = vertices[v_i[2]] - vertices[v_i[1]];
            temp_vec[1] = vertices[v_i[0]] - vertices[v_i[1]];
            untangle_function_2d( mBeta, temp_vec, e_ind, pd, met_vals[1], err );
            MSQ_ERRZERO( err );

            temp_vec[0] = vertices[v_i[3]] - vertices[v_i[2]];
            temp_vec[1] = vertices[v_i[1]] - vertices[v_i[2]];
            untangle_function_2d( mBeta, temp_vec, e_ind, pd, met_vals[2], err );
            MSQ_ERRZERO( err );

            temp_vec[0] = vertices[v_i[0]] - vertices[v_i[3]];
            temp_vec[1] = vertices[v_i[2]] - vertices[v_i[3]];
            untangle_function_2d( mBeta, temp_vec, e_ind, pd, met_vals[3], err );
            MSQ_ERRZERO( err );
            fval = average_metrics( met_vals, 4, err );
            MSQ_ERRZERO( err );
            break;
        case TETRAHEDRON:
            temp_vec[0] = vertices[v_i[1]] - vertices[v_i[0]];
            temp_vec[3] = vertices[v_i[2]] - vertices[v_i[0]];
            temp_vec[4] = vertices[v_i[3]] - vertices[v_i[0]];
            // 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 );
            untangle_function_3d( mBeta, temp_vec, fval );
            break;
        case HEXAHEDRON:
            // transform to v_i[0]
            temp_vec[0] = vertices[v_i[1]] - vertices[v_i[0]];
            temp_vec[1] = vertices[v_i[3]] - vertices[v_i[0]];
            temp_vec[2] = vertices[v_i[4]] - vertices[v_i[0]];
            untangle_function_3d( mBeta, temp_vec, met_vals[0] );

            temp_vec[0] = vertices[v_i[2]] - vertices[v_i[1]];
            temp_vec[1] = vertices[v_i[0]] - vertices[v_i[1]];
            temp_vec[2] = vertices[v_i[5]] - vertices[v_i[1]];
            untangle_function_3d( mBeta, temp_vec, met_vals[1] );

            temp_vec[0] = vertices[v_i[3]] - vertices[v_i[2]];
            temp_vec[1] = vertices[v_i[1]] - vertices[v_i[2]];
            temp_vec[2] = vertices[v_i[6]] - vertices[v_i[2]];
            untangle_function_3d( mBeta, temp_vec, met_vals[2] );

            temp_vec[0] = vertices[v_i[0]] - vertices[v_i[3]];
            temp_vec[1] = vertices[v_i[2]] - vertices[v_i[3]];
            temp_vec[2] = vertices[v_i[7]] - vertices[v_i[3]];
            untangle_function_3d( mBeta, temp_vec, met_vals[3] );

            temp_vec[0] = vertices[v_i[7]] - vertices[v_i[4]];
            temp_vec[1] = vertices[v_i[5]] - vertices[v_i[4]];
            temp_vec[2] = vertices[v_i[0]] - vertices[v_i[4]];
            untangle_function_3d( mBeta, temp_vec, met_vals[4] );

            temp_vec[0] = vertices[v_i[4]] - vertices[v_i[5]];
            temp_vec[1] = vertices[v_i[6]] - vertices[v_i[5]];
            temp_vec[2] = vertices[v_i[1]] - vertices[v_i[5]];
            untangle_function_3d( mBeta, temp_vec, met_vals[5] );

            temp_vec[0] = vertices[v_i[5]] - vertices[v_i[6]];
            temp_vec[1] = vertices[v_i[7]] - vertices[v_i[6]];
            temp_vec[2] = vertices[v_i[2]] - vertices[v_i[6]];
            untangle_function_3d( mBeta, temp_vec, met_vals[6] );

            temp_vec[0] = vertices[v_i[6]] - vertices[v_i[7]];
            temp_vec[1] = vertices[v_i[4]] - vertices[v_i[7]];
            temp_vec[2] = vertices[v_i[3]] - vertices[v_i[7]];
            untangle_function_3d( mBeta, temp_vec, met_vals[7] );
            fval = average_metrics( met_vals, 8, err );
            MSQ_ERRZERO( err );
            break;
        case PYRAMID:
            for( unsigned i = 0; i < 4; ++i )
            {
                temp_vec[0] = vertices[v_i[( i + 1 ) % 4]] - vertices[v_i[i]];
                temp_vec[1] = vertices[v_i[( i + 3 ) % 4]] - vertices[v_i[i]];
                temp_vec[3] = vertices[v_i[4]] - vertices[v_i[i]];
                temp_vec[2] = ( 4 * temp_vec[3] - temp_vec[0] - temp_vec[1] ) / ( 2.0 - MSQ_SQRT_TWO );
                untangle_function_3d( mBeta, temp_vec, met_vals[i] );
            }
            fval = average_metrics( met_vals, 4, err );
            MSQ_ERRZERO( err );
            break;
        case PRISM:
            temp_vec[0] = vertices[v_i[1]] - vertices[v_i[0]];
            temp_vec[3] = vertices[v_i[2]] - vertices[v_i[0]];
            temp_vec[1] = ( ( 2 * temp_vec[3] ) - temp_vec[0] ) * MSQ_SQRT_THREE_INV;
            temp_vec[2] = vertices[v_i[3]] - vertices[v_i[0]];
            untangle_function_3d( mBeta, temp_vec, met_vals[0] );

            temp_vec[0] = vertices[v_i[2]] - vertices[v_i[1]];
            temp_vec[3] = vertices[v_i[0]] - vertices[v_i[1]];
            temp_vec[1] = ( ( 2 * temp_vec[3] ) - temp_vec[0] ) * MSQ_SQRT_THREE_INV;
            temp_vec[2] = vertices[v_i[4]] - vertices[v_i[1]];
            untangle_function_3d( mBeta, temp_vec, met_vals[1] );

            temp_vec[0] = vertices[v_i[0]] - vertices[v_i[2]];
            temp_vec[3] = vertices[v_i[1]] - vertices[v_i[2]];
            temp_vec[1] = ( ( 2 * temp_vec[3] ) - temp_vec[0] ) * MSQ_SQRT_THREE_INV;
            temp_vec[2] = vertices[v_i[5]] - vertices[v_i[2]];
            untangle_function_3d( mBeta, temp_vec, met_vals[2] );

            temp_vec[0] = vertices[v_i[5]] - vertices[v_i[3]];
            temp_vec[3] = vertices[v_i[4]] - vertices[v_i[3]];
            temp_vec[1] = ( ( 2 * temp_vec[3] ) - temp_vec[0] ) * MSQ_SQRT_THREE_INV;
            temp_vec[2] = vertices[v_i[0]] - vertices[v_i[3]];
            untangle_function_3d( mBeta, temp_vec, met_vals[3] );

            temp_vec[0] = vertices[v_i[3]] - vertices[v_i[4]];
            temp_vec[3] = vertices[v_i[5]] - vertices[v_i[4]];
            temp_vec[1] = ( ( 2 * temp_vec[3] ) - temp_vec[0] ) * MSQ_SQRT_THREE_INV;
            temp_vec[2] = vertices[v_i[1]] - vertices[v_i[4]];
            untangle_function_3d( mBeta, temp_vec, met_vals[4] );

            temp_vec[0] = vertices[v_i[4]] - vertices[v_i[5]];
            temp_vec[3] = vertices[v_i[3]] - vertices[v_i[5]];
            temp_vec[1] = ( ( 2 * temp_vec[3] ) - temp_vec[0] ) * MSQ_SQRT_THREE_INV;
            temp_vec[2] = vertices[v_i[2]] - vertices[v_i[5]];
            untangle_function_3d( mBeta, temp_vec, met_vals[5] );

            fval = average_metrics( met_vals, 6, err );
            MSQ_ERRZERO( err );
            break;
        default:
            MSQ_SETERR( err )
            ( MsqError::UNSUPPORTED_ELEMENT, "Unsupported cell type (%d) for Untangle quality metric.", type );

            fval = MSQ_MAX_CAP;
            return false;
    }  // end switch over element type
    return true;
}

Function to allow the user to check the value of beta.

Definition at line 76 of file UntangleBetaQualityMetric.hpp.

References mBeta.

    {
        return mBeta;
    }
std::string UntangleBetaQualityMetric::get_name ( ) const [virtual]

Implements MBMesquite::QualityMetric.

Definition at line 86 of file UntangleBetaQualityMetric.cpp.

{
    return "Untangle Beta";
}

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

Implements MBMesquite::QualityMetric.

Definition at line 91 of file UntangleBetaQualityMetric.cpp.

{
    return 1;
}

Function to allow users to set the beta value after the metric has already been created.

Definition at line 71 of file UntangleBetaQualityMetric.hpp.

References mBeta.

    {
        mBeta = beta_in;
    }

Member Data Documentation

Definition at line 88 of file UntangleBetaQualityMetric.hpp.

Referenced by evaluate(), get_beta(), and set_beta().

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