MOAB: Mesh Oriented datABase
(version 5.4.1)
|
Computes the condition numbers of the corner's of elements connected to the given vertex and then averages those values. More...
#include <VertexConditionNumberQualityMetric.hpp>
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. |
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.
Definition at line 44 of file VertexConditionNumberQualityMetric.cpp.
: AveragingQM( QualityMetric::LINEAR ) {}
virtual MBMesquite::VertexConditionNumberQualityMetric::~VertexConditionNumberQualityMetric | ( | ) | [inline, virtual] |
virtual destructor ensures use of polymorphism during destruction
Definition at line 59 of file VertexConditionNumberQualityMetric.hpp.
{}
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.
pd | The patch. |
handle | The location in the patch (as passed back from get_evaluations). |
value | The 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.
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 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"; }
int VertexConditionNumberQualityMetric::get_negate_flag | ( | ) | const [virtual] |
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;
}