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

Computes the local size metric for a given vertex. More...

#include <LocalSizeQualityMetric.hpp>

+ Inheritance diagram for MBMesquite::LocalSizeQualityMetric:
+ Collaboration diagram for MBMesquite::LocalSizeQualityMetric:

Public Member Functions

 LocalSizeQualityMetric ()
virtual ~LocalSizeQualityMetric ()
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)
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 local size metric for a given vertex.

LocalSizeQualityMetric is a vertex based metric which computes the corner volume (or area) for the element corners attached to a given element. Then these volumes (or areas) are averaged together. The default averaging method is QualityMetric::RMS.

Definition at line 55 of file LocalSizeQualityMetric.hpp.

Constructor & Destructor Documentation

Member Function Documentation

bool LocalSizeQualityMetric::evaluate ( PatchData pd,
size_t  this_vert,
double &  fval,
MsqError err 
) [virtual]

For the given vertex, vert, with connected elements, e_i for i=1...K, the LocalSizeQualityMetric computes the corner volumes (or areas) of each e_i at the corner defined by vert. The corner volume is defined as the volume of the tet defined by the edges of an element which contain the common vertex, vert. That volume is then diveded by the average corner volume of all the element corners connected to this vertex. For vertices attached to pyramid elements, this metric is undefined.

Implements MBMesquite::QualityMetric.

Definition at line 81 of file LocalSizeQualityMetric.cpp.

References MBMesquite::AveragingQM::average_metrics(), compute_corner_area(), compute_corner_volume(), MBMesquite::MsqMeshEntity::get_connected_vertices(), MBMesquite::PatchData::get_element_array(), MBMesquite::PatchData::get_vertex_element_adjacencies(), MSQ_ERRZERO, MSQ_SETERR, and MBMesquite::MsqError::UNSUPPORTED_ELEMENT.

Referenced by evaluate_with_indices().

    fval = 0.0;
    // get the element array
    MsqMeshEntity* elems = pd.get_element_array( err );
    MSQ_ERRZERO( 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);
    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?
    double* met_vals = new double[num_elems];
    // vector to hold the other verts which form a corner.
    std::vector< size_t > other_vertices;
    other_vertices.reserve( 4 );
    double total_val = 0.0;
    size_t i         = 0;
    // loop over the elements attached to this vertex
    for( i = 0; i < num_elems; ++i )
        // get the vertices which (with this_vert) form the corner of
        // the ith element.
        elems[v_to_e_array[i]].get_connected_vertices( this_vert, other_vertices, err );
        MSQ_ERRZERO( err );
        ////PRINT_INFO("\nINSIDE LOCAL SIZE CPP other_vertices size = %i",other_vertices.size());

        switch( other_vertices.size() )
                // if a surface element, compute the corner area
            case 2:
                met_vals[i] = compute_corner_area( pd, this_vert, other_vertices[0], other_vertices[1], err );
                MSQ_ERRZERO( err );
                // if a volume element, compute the corner volume
            case 3:
                met_vals[i] = compute_corner_volume( pd, this_vert, other_vertices[0], other_vertices[1],
                                                     other_vertices[2], err );
                MSQ_ERRZERO( err );
                // otherwise, there is was an error.  Either the wrong number
                // of vertices were returned fom get_connected_vertices or
                // the element does not have the correct number of edges
                // connected to this vertex (possibly a pyramid element).
                met_vals[i] = 0.0;
                MSQ_SETERR( err )
                ( "Incorrect number of vertices returned from "
                  MsqError::UNSUPPORTED_ELEMENT );
                return false;
        // keep track of total so that we can compute the linear average
        total_val += met_vals[i];
        // PRINT_INFO("\nIN LOCAL SIZE CPP, total_val = %f, i = %i",total_val,i);
        // clear the vector of other_vertices for re-use.
        // PRINT_INFO("\nIN LOCAL SIZE CPP, after clean size = %f",other_vertices.size());
    // calculate the linear average... num_elems is non-zero here.
    total_val /= (double)num_elems;
    // PRINT_INFO("\nIN LOCAL SIZE CPP, average = %f",total_val);
    // if the average is non-zero
    // divide each entry by the linear average
    if( total_val != 0 )
        for( i = 0; i < num_elems; ++i )
            met_vals[i] /= total_val;
        // calculate fval by averaging the corner values
        fval = average_metrics( met_vals, num_elems, err );
        MSQ_ERRZERO( err );
        // PRINT_INFO("\nIN LOCAL SIZE CPP, inside if statement");
    // PRINT_INFO("\nIN LOCAL SIZE CPP, fval = %f",fval);
    // clean up the dynamically allocated array
    delete[] met_vals;
    // always return true... the vertex position is never invalid
    return true;
bool LocalSizeQualityMetric::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.

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 174 of file LocalSizeQualityMetric.cpp.

References evaluate(), MBMesquite::PatchData::get_adjacent_vertex_indices(), MSQ_CHKERR, MSQ_ERRZERO, and MBMesquite::PatchData::num_free_vertices().

    pd.get_adjacent_vertex_indices( vertex, indices, err );
    MSQ_ERRZERO( err );

    std::vector< size_t >::iterator r, w;
    for( r = w = indices.begin(); r != indices.end(); ++r )
        if( *r < pd.num_free_vertices() )
            *w = *r;
    indices.erase( w, indices.end() );
    if( vertex < pd.num_free_vertices() ) indices.push_back( vertex );

    bool rval = evaluate( pd, vertex, value, err );
    return !MSQ_CHKERR( err ) && rval;
std::string LocalSizeQualityMetric::get_name ( ) const [virtual]

Implements MBMesquite::QualityMetric.

Definition at line 63 of file LocalSizeQualityMetric.cpp.

    return "Local Size";
int LocalSizeQualityMetric::get_negate_flag ( ) const [virtual]

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

Implements MBMesquite::QualityMetric.

Definition at line 68 of file LocalSizeQualityMetric.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