MOAB: Mesh Oriented datABase
(version 5.4.1)
|
Computes the local size metric for a given vertex. More...
#include <LocalSizeQualityMetric.hpp>
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. |
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.
Definition at line 59 of file LocalSizeQualityMetric.hpp.
: AveragingQM( RMS ) {}
LocalSizeQualityMetric::~LocalSizeQualityMetric | ( | ) | [virtual] |
Definition at line 65 of file LocalSizeQualityMetric.cpp.
{}
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 85 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 ); break; // 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 ); break; default: // 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 " "get_connected_vertices.", 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. other_vertices.clear(); // 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.
pd | The patch. |
handle | The location in the patch (as passed back from get_evaluations). |
value | The output metric value. |
indices | The free vertices that the evaluation is a function of, specified as vertex indices in the PatchData. |
Implements MBMesquite::QualityMetric.
Definition at line 181 of file LocalSizeQualityMetric.cpp.
References evaluate(), MBMesquite::PatchData::get_adjacent_vertex_indices(), MSQ_CHKERR, MSQ_ERRZERO, and MBMesquite::PatchData::num_free_vertices().
{ indices.clear(); 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; ++w; } } 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 67 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 72 of file LocalSizeQualityMetric.cpp.
{
return 1;
}