MOAB: Mesh Oriented datABase  (version 5.4.1)
CompareMetric Class Reference
+ Inheritance diagram for CompareMetric:
+ Collaboration diagram for CompareMetric:

Public Member Functions

 CompareMetric (QualityMetric *qm1, QualityMetric *qm2, bool mask_qm2_coord=false)
MetricType get_metric_type () const
std::string get_name () const
int get_negate_flag () const
 1 if metric should be minimized, -1 if metric should be maximized.
void get_evaluations (PatchData &pd, std::vector< size_t > &handles, bool free_vertices_only, MsqError &err)
 Get locations at which metric can be evaluated.
bool evaluate (PatchData &pd, size_t handle, double &value, MsqError &err)
 Get metric value at a logical location in the patch.
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.
bool evaluate_with_gradient (PatchData &pd, size_t handle, double &value, std::vector< size_t > &indices, std::vector< Vector3D > &gradient, MsqError &err)
 Get metric value and gradient at a logical location in the patch.
bool evaluate_with_Hessian_diagonal (PatchData &pd, size_t handle, double &value, std::vector< size_t > &indices, std::vector< Vector3D > &gradient, std::vector< SymMatrix3D > &Hessian_diagonal, MsqError &err)
 Get metric value and gradient at a logical location in the patch.
bool evaluate_with_Hessian (PatchData &pd, size_t handle, double &value, std::vector< size_t > &indices, std::vector< Vector3D > &gradient, std::vector< Matrix3D > &Hessian, MsqError &err)
 Get metric value and deravitives at a logical location in the patch.
void get_mask_axis (PatchData &pd)
bool equal (Vector3D grad1, const Vector3D &grad2) const
bool equal (SymMatrix3D hess1, const SymMatrix3D &hess2) const
bool equal (Matrix3D hess1, const Matrix3D &hess2) const

Private Attributes

QualityMetricmetric1
QualityMetricmetric2
bool maskPlane
int maskAxis
std::vector< size_t > m2Handles
std::vector< Vector3Dm2Grad
std::vector< SymMatrix3Dm2Diag
std::vector< Matrix3Dm2Hess

Static Private Attributes

static const double epsilon = 5e-2

Detailed Description

Definition at line 143 of file idft_time_test.cpp.


Constructor & Destructor Documentation

CompareMetric::CompareMetric ( QualityMetric qm1,
QualityMetric qm2,
bool  mask_qm2_coord = false 
) [inline]

Definition at line 156 of file idft_time_test.cpp.

        : metric1( qm1 ), metric2( qm2 ), maskPlane( mask_qm2_coord ), maskAxis( -1 )
    {
    }

Member Function Documentation

bool CompareMetric::equal ( Vector3D  grad1,
const Vector3D grad2 
) const

Definition at line 880 of file idft_time_test.cpp.

References epsilon, and MBMesquite::Vector3D::length_squared().

{
    if( maskAxis >= 0 ) grad1[maskAxis] = grad2[maskAxis];
    return ( grad1 - grad2 ).length_squared() <= epsilon * epsilon;
}
bool CompareMetric::equal ( SymMatrix3D  hess1,
const SymMatrix3D hess2 
) const

Definition at line 886 of file idft_time_test.cpp.

References epsilon, and MBMesquite::Frobenius_2().

{
    if( maskAxis >= 0 )
    {
        for( unsigned i = 0; i < 3; ++i )
        {
            hess1( maskAxis, i ) = hess2( maskAxis, i );
            hess1( i, maskAxis ) = hess2( i, maskAxis );
        }
    }
    return Frobenius_2( hess1 - hess2 ) <= epsilon * epsilon;
}
bool CompareMetric::equal ( Matrix3D  hess1,
const Matrix3D hess2 
) const

Definition at line 899 of file idft_time_test.cpp.

References epsilon, and MBMesquite::Frobenius_2().

{
    if( maskAxis >= 0 )
    {
        for( unsigned i = 0; i < 3; ++i )
        {
            hess1[maskAxis][i] = hess2[maskAxis][i];
            hess1[i][maskAxis] = hess2[i][maskAxis];
        }
    }
    return Frobenius_2( hess1 - hess2 ) <= epsilon * epsilon;
}
bool CompareMetric::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 534 of file idft_time_test.cpp.

References epsilon, MBMesquite::MsqError::INVALID_STATE, MSQ_ERRZERO, and MSQ_SETERR.

{
    double m2val;
    bool r1, r2;
    r1 = metric1->evaluate( pd, handle, value, err );
    MSQ_ERRZERO( err );
    r2 = metric2->evaluate( pd, handle, m2val, err );
    MSQ_ERRZERO( err );
    if( r1 != r2 || ( r1 && fabs( value - m2val ) > epsilon ) )
    {
        MSQ_SETERR( err )
        ( MsqError::INVALID_STATE,
          "Metrics returned different values for handle %lu "
          "in evaluate:\n"
          "\t%s %f vs. %s %f\n",
          (unsigned long)handle, r1 ? "true" : "false", value, r2 ? "true" : "false", m2val );
    }

    return r1 && !err;
}
bool CompareMetric::evaluate_with_gradient ( PatchData pd,
size_t  handle,
double &  value,
std::vector< size_t > &  indices,
std::vector< Vector3D > &  gradient,
MsqError err 
) [virtual]

Get metric value and gradient 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.
gradientThe gradient of the metric as a function of the coordinates of the free vertices passed back in the indices list.

Reimplemented from MBMesquite::QualityMetric.

Definition at line 596 of file idft_time_test.cpp.

References epsilon, MBMesquite::MsqError::INVALID_STATE, MSQ_ERRZERO, and MSQ_SETERR.

{
    double m2val;
    bool r1, r2;
    m2Handles.clear();
    m2Grad.clear();
    r1 = metric1->evaluate_with_gradient( pd, handle, value, indices, gradient, err );
    MSQ_ERRZERO( err );
    r2 = metric2->evaluate_with_gradient( pd, handle, m2val, m2Handles, m2Grad, err );
    MSQ_ERRZERO( err );
    if( r1 != r2 || ( r1 && fabs( value - m2val ) > epsilon ) )
    {
        MSQ_SETERR( err )
        ( MsqError::INVALID_STATE,
          "Metrics returned different values for handle %lu in "
          "evaluate_with_gradient:\n"
          "\t%s %f vs. %s %f\n",
          (unsigned long)handle, r1 ? "true" : "false", value, r2 ? "true" : "false", m2val );
    }
    else
    {
        std::vector< size_t >::const_iterator i, j;
        std::vector< Vector3D >::const_iterator r, s;
        int grad_diff = 0;
        bool same     = ( indices.size() == m2Handles.size() );
        std::sort( m2Handles.begin(), m2Handles.end() );
        for( i = indices.begin(); i != indices.end(); ++i )
        {
            j = std::lower_bound( m2Handles.begin(), m2Handles.end(), *i );
            if( j == m2Handles.end() || *j != *i )
            {
                same = false;
                continue;
            }

            r = gradient.begin() + ( i - indices.begin() );
            s = m2Grad.begin() + ( j - m2Handles.begin() );
            if( !equal( *r, *s ) ) ++grad_diff;
        }

        if( !same )
        {
            MSQ_SETERR( err )
            ( MsqError::INVALID_STATE,
              "Metrics returned incompatible lists of vertex indices"
              " for handle %lu in evaluate_with_gradient\n.",
              (unsigned long)handle );
        }
        else if( grad_diff )
        {
            MSQ_SETERR( err )
            ( MsqError::INVALID_STATE,
              "Metrics returned different gradient vectors for "
              " %d of %u vertices for handle %lu in "
              "evaluate_with_gradient\n.",
              grad_diff, (unsigned)gradient.size(), (unsigned long)handle );
        }
    }

    return r1 && !err;
}
bool CompareMetric::evaluate_with_Hessian ( PatchData pd,
size_t  handle,
double &  value,
std::vector< size_t > &  indices,
std::vector< Vector3D > &  gradient,
std::vector< Matrix3D > &  Hessian,
MsqError err 
) [virtual]

Get metric value and deravitives 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.
gradientThe gradient of the metric as a function of the coordinates of the free vertices passed back in the indices list.
HessianThe Hessian of the metric as a function of the coordinates. The Hessian is passed back as the upper-triangular portion of the matrix in row-major order, where each Matrix3D is the portion of the Hessian with respect to the vertices at the corresponding positions in the indices list.

Reimplemented from MBMesquite::QualityMetric.

Definition at line 746 of file idft_time_test.cpp.

References epsilon, MBMesquite::MsqError::INVALID_STATE, MSQ_ERRZERO, MSQ_SETERR, and MBMesquite::transpose().

{
    double m2val;
    bool r1, r2;
    m2Handles.clear();
    m2Grad.clear();
    m2Hess.clear();
    r1 = metric1->evaluate_with_Hessian( pd, handle, value, indices, gradient, Hessian, err );
    MSQ_ERRZERO( err );
    r2 = metric2->evaluate_with_Hessian( pd, handle, m2val, m2Handles, m2Grad, m2Hess, err );
    MSQ_ERRZERO( err );
    if( r1 != r2 || fabs( value - m2val ) > epsilon )
    {
        MSQ_SETERR( err )
        ( MsqError::INVALID_STATE,
          "Metrics returned different values for handle %lu in "
          "evaluate_with_Hessian:\n"
          "\t%s %f vs. %s %f\n",
          (unsigned long)handle, r1 ? "true" : "false", value, r2 ? "true" : "false", m2val );
    }
    else
    {
        std::vector< size_t >::const_iterator i, j;
        std::vector< Vector3D >::const_iterator r, s;
        int grad_diff = 0, hess_diff = 0;
        bool same = ( indices.size() == m2Handles.size() );
        std::sort( m2Handles.begin(), m2Handles.end() );
        for( i = indices.begin(); i != indices.end(); ++i )
        {
            j = std::lower_bound( m2Handles.begin(), m2Handles.end(), *i );
            if( j == m2Handles.end() || *j != *i )
            {
                same = false;
                continue;
            }

            r = gradient.begin() + ( i - indices.begin() );
            s = m2Grad.begin() + ( j - m2Handles.begin() );
            if( !equal( *r, *s ) )
            {
                ++grad_diff;
                // call again for so debugger can step into it after failure is found
                std::vector< size_t > i2;
                std::vector< Vector3D > g2;
                std::vector< Matrix3D > h2;
                metric2->evaluate_with_Hessian( pd, handle, m2val, i2, g2, h2, err );
            }
        }

        if( !same )
        {
            MSQ_SETERR( err )
            ( MsqError::INVALID_STATE,
              "Metrics returned incompatible lists of vertex indices"
              " for handle %lu in evaluate_with_Hessian\n.",
              (unsigned long)handle );
        }
        else if( grad_diff )
        {
            MSQ_SETERR( err )
            ( MsqError::INVALID_STATE,
              "Metrics returned different gradient vectors for "
              " %d of %u vertices for handle %lu in "
              "evaluate_with_Hessian\n.",
              grad_diff, (unsigned)gradient.size(), (unsigned long)handle );
        }
        else
        {
            size_t row, col, row2, col2, idx, idx2;
            for( row = idx = 0; row < indices.size(); ++row )
            {
                row2 = std::lower_bound( m2Handles.begin(), m2Handles.end(), indices[row] ) - m2Handles.begin();
                for( col = row; col < indices.size(); ++col, ++idx )
                {
                    col2 = std::lower_bound( m2Handles.begin(), m2Handles.end(), indices[col] ) - m2Handles.begin();
                    if( row2 <= col2 )
                    {
                        idx2 = indices.size() * row2 - row2 * ( row2 + 1 ) / 2 + col2;
                        if( !equal( Hessian[idx], m2Hess[idx2] ) ) ++hess_diff;
                    }
                    else
                    {
                        idx2 = indices.size() * col2 - col2 * ( col2 + 1 ) / 2 + row2;
                        if( !equal( Hessian[idx], transpose( m2Hess[idx2] ) ) ) ++hess_diff;
                    }
                }
            }

            if( hess_diff )
            {
                MSQ_SETERR( err )
                ( MsqError::INVALID_STATE,
                  "Metrics returned different Hessian blocks for "
                  " %d of %u vertices for handle %lu in "
                  "evaluate_with_Hessian\n.",
                  hess_diff, (unsigned)Hessian.size(), (unsigned long)handle );
            }
        }
    }

    return r1 && !err;
}
bool CompareMetric::evaluate_with_Hessian_diagonal ( PatchData pd,
size_t  handle,
double &  value,
std::vector< size_t > &  indices,
std::vector< Vector3D > &  gradient,
std::vector< SymMatrix3D > &  Hessian_diagonal,
MsqError err 
) [virtual]

Get metric value and gradient 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.
gradientThe gradient of the metric as a function of the coordinates of the free vertices passed back in the indices list.
Hessian_diagonalThe 3x3 blocks along the diagonal of the Hessian matrix.

Reimplemented from MBMesquite::QualityMetric.

Definition at line 663 of file idft_time_test.cpp.

References epsilon, MBMesquite::MsqError::INVALID_STATE, MSQ_ERRZERO, MSQ_SETERR, and u.

{
    double m2val;
    bool r1, r2;
    m2Handles.clear();
    m2Grad.clear();
    m2Diag.clear();
    r1 = metric1->evaluate_with_Hessian_diagonal( pd, handle, value, indices, gradient, diagonal, err );
    MSQ_ERRZERO( err );
    r2 = metric2->evaluate_with_Hessian_diagonal( pd, handle, m2val, m2Handles, m2Grad, m2Diag, err );
    MSQ_ERRZERO( err );
    if( r1 != r2 || ( r1 && fabs( value - m2val ) > epsilon ) )
    {
        MSQ_SETERR( err )
        ( MsqError::INVALID_STATE,
          "Metrics returned different values for handle %lu in "
          "evaluate_with_Hessian_diagonal:\n"
          "\t%s %f vs. %s %f\n",
          (unsigned long)handle, r1 ? "true" : "false", value, r2 ? "true" : "false", m2val );
    }
    else
    {
        std::vector< size_t >::const_iterator i, j;
        std::vector< Vector3D >::const_iterator r, s;
        std::vector< SymMatrix3D >::const_iterator u, v;
        int grad_diff = 0, hess_diff = 0;
        bool same = ( indices.size() == m2Handles.size() );
        std::sort( m2Handles.begin(), m2Handles.end() );
        for( i = indices.begin(); i != indices.end(); ++i )
        {
            j = std::lower_bound( m2Handles.begin(), m2Handles.end(), *i );
            if( j == m2Handles.end() || *j != *i )
            {
                same = false;
                continue;
            }

            r = gradient.begin() + ( i - indices.begin() );
            s = m2Grad.begin() + ( j - m2Handles.begin() );
            if( !equal( *r, *s ) ) ++grad_diff;

            u = diagonal.begin() + ( i - indices.begin() );
            v = m2Diag.begin() + ( j - m2Handles.begin() );
            if( !equal( *u, *v ) ) ++hess_diff;
        }

        if( !same )
        {
            MSQ_SETERR( err )
            ( MsqError::INVALID_STATE,
              "Metrics returned incompatible lists of vertex indices"
              " for handle %lu in evaluate_with_Hessian_diagonal\n.",
              (unsigned long)handle );
        }
        else if( grad_diff )
        {
            MSQ_SETERR( err )
            ( MsqError::INVALID_STATE,
              "Metrics returned different gradient vectors for "
              " %d of %u vertices for handle %lu in "
              "evaluate_with_Hessian_diagonal\n.",
              grad_diff, (unsigned)gradient.size(), (unsigned long)handle );
        }
        else if( hess_diff )
        {
            MSQ_SETERR( err )
            ( MsqError::INVALID_STATE,
              "Metrics returned different Hessian blocks for "
              " %d of %u vertices for handle %lu in "
              "evaluate_with_Hessian_diagonal\n.",
              hess_diff, (unsigned)diagonal.size(), (unsigned long)handle );
        }
    }

    return r1 && !err;
}
bool CompareMetric::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 555 of file idft_time_test.cpp.

References epsilon, MBMesquite::MsqError::INVALID_STATE, MSQ_ERRZERO, and MSQ_SETERR.

{
    double m2val;
    bool r1, r2;
    m2Handles.clear();
    r1 = metric1->evaluate_with_indices( pd, handle, value, indices, err );
    MSQ_ERRZERO( err );
    r2 = metric2->evaluate_with_indices( pd, handle, m2val, m2Handles, err );
    MSQ_ERRZERO( err );
    if( r1 != r2 || ( r1 && fabs( value - m2val ) > epsilon ) )
    {
        MSQ_SETERR( err )
        ( MsqError::INVALID_STATE,
          "Metrics returned different values for handle %lu "
          "in evaluate_with_indices:\n"
          "\t%s %f vs. %s %f\n",
          (unsigned long)handle, r1 ? "true" : "false", value, r2 ? "true" : "false", m2val );
    }
    else
    {
        bool same = ( indices.size() == m2Handles.size() );
        std::sort( m2Handles.begin(), m2Handles.end() );
        for( std::vector< size_t >::iterator i = indices.begin(); i != indices.end(); ++i )
            if( !std::binary_search( m2Handles.begin(), m2Handles.end(), *i ) ) same = false;
        if( !same )
        {
            MSQ_SETERR( err )
            ( MsqError::INVALID_STATE,
              "Metrics returned incompatible lists of vertex indices"
              " for handle %lu in evaluate_with_indices\n.",
              (unsigned long)handle );
        }
    }

    return r1 && !err;
}
void CompareMetric::get_evaluations ( PatchData pd,
std::vector< size_t > &  handles,
bool  free_vertices_only,
MsqError err 
) [virtual]

Get locations at which metric can be evaluated.

Different metrics are evaluated for different things within a patch. For example, an element-based metric will be evaluated once for each element in patch, a vertex-based metric once for each veretx, and a target/sample-point based metric will be evaluated once for each samle point in each element. This method returns a list of handles, one for each location in the patch at which the metric can be evaluated. The handle values are used as input to the evaluate methods.

Parameters:
pdThe patch
handlesOutput list of handles
free_vertices_onlyIf true, only pass back evaluation points that depend on at least one free vertex.

Implements MBMesquite::QualityMetric.

Definition at line 513 of file idft_time_test.cpp.

References MBMesquite::MsqError::INVALID_STATE, MSQ_ERRRTN, and MSQ_SETERR.

{
    if( maskPlane ) get_mask_axis( pd );

    m2Handles.clear();
    metric1->get_evaluations( pd, handles, free_vertices_only, err );MSQ_ERRRTN( err );
    metric2->get_evaluations( pd, m2Handles, free_vertices_only, err );MSQ_ERRRTN( err );
    bool same = ( handles.size() == m2Handles.size() );
    std::sort( m2Handles.begin(), m2Handles.end() );
    for( std::vector< size_t >::iterator i = handles.begin(); i != handles.end(); ++i )
        if( !std::binary_search( m2Handles.begin(), m2Handles.end(), *i ) ) same = false;
    if( !same )
    {
        MSQ_SETERR( err )
        ( "Metrics have incompatible lists of evaluation handles.\n", MsqError::INVALID_STATE );
    }
}

Definition at line 855 of file idft_time_test.cpp.

References epsilon, MBMesquite::PatchData::get_domain(), MBMesquite::PlanarDomain::get_normal(), and n.

{
    maskAxis          = -1;
    PlanarDomain* dom = reinterpret_cast< PlanarDomain* >( pd.get_domain() );
    int bits          = 0;
    if( dom )
    {
        Vector3D n = dom->get_normal();
        for( int i = 0; i < 3; ++i )
            if( fabs( n[i] ) < epsilon ) bits |= ( 1 << i );
        switch( bits )
        {
            case 3:
                maskAxis = 2;
                break;
            case 5:
                maskAxis = 1;
                break;
            case 6:
                maskAxis = 0;
                break;
        }
    }
}

Implements MBMesquite::QualityMetric.

Definition at line 492 of file idft_time_test.cpp.

{
    MetricType t1 = metric1->get_metric_type();
    assert( metric2->get_metric_type() == t1 );
    return t1;
}
std::string CompareMetric::get_name ( ) const [virtual]

Implements MBMesquite::QualityMetric.

Definition at line 499 of file idft_time_test.cpp.

References n.

{
    std::string n = metric1->get_name();
    n += " =? ";
    n += metric2->get_name();
    return n;
}
int CompareMetric::get_negate_flag ( ) const [virtual]

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

Implements MBMesquite::QualityMetric.

Definition at line 507 of file idft_time_test.cpp.


Member Data Documentation

const double CompareMetric::epsilon = 5e-2 [static, private]

Definition at line 153 of file idft_time_test.cpp.

std::vector< SymMatrix3D > CompareMetric::m2Diag [private]

Definition at line 151 of file idft_time_test.cpp.

std::vector< Vector3D > CompareMetric::m2Grad [private]

Definition at line 150 of file idft_time_test.cpp.

std::vector< size_t > CompareMetric::m2Handles [private]

Definition at line 149 of file idft_time_test.cpp.

std::vector< Matrix3D > CompareMetric::m2Hess [private]

Definition at line 152 of file idft_time_test.cpp.

int CompareMetric::maskAxis [private]

Definition at line 148 of file idft_time_test.cpp.

bool CompareMetric::maskPlane [private]

Definition at line 147 of file idft_time_test.cpp.

Definition at line 146 of file idft_time_test.cpp.

Definition at line 146 of file idft_time_test.cpp.

List of all members.


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