MOAB: Mesh Oriented datABase
(version 5.4.1)
|
Computes the mean ratio quality metric of given element. More...
#include <IdealWeightMeanRatio.hpp>
Public Member Functions | |
MESQUITE_EXPORT | IdealWeightMeanRatio () |
virtual MESQUITE_EXPORT | ~IdealWeightMeanRatio () |
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_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. | |
virtual 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, MsqError &err) |
Get metric value and gradient at a logical location in the patch. | |
virtual 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. | |
Private Attributes | |
Vector3D | mCoords [4] |
Vector3D | mGradients [32] |
Matrix3D | mHessians [80] |
double | mMetrics [8] |
const double | a2Con |
const Exponent | b2Con |
const Exponent | c2Con |
const double | a3Con |
const Exponent | b3Con |
const Exponent | c3Con |
Computes the mean ratio quality metric of given element.
The metric does not use the sample point functionality or the compute_weighted_jacobian. It evaluates the metric at the element vertices, and uses the isotropic ideal element. It does require a feasible region, and the metric needs to be maximized.
Definition at line 62 of file IdealWeightMeanRatio.hpp.
Definition at line 65 of file IdealWeightMeanRatio.hpp.
: AveragingQM( QualityMetric::LINEAR ), a2Con( 2.0 ), b2Con( -1.0 ), c2Con( 1.0 ), a3Con( 3.0 ), b3Con( -1.0 ), c3Con( 2.0 / 3.0 ) { }
virtual MESQUITE_EXPORT MBMesquite::IdealWeightMeanRatio::~IdealWeightMeanRatio | ( | ) | [inline, virtual] |
virtual destructor ensures use of polymorphism during destruction
Definition at line 72 of file IdealWeightMeanRatio.hpp.
{}
bool IdealWeightMeanRatio::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 58 of file IdealWeightMeanRatio.cpp.
References a2Con, a3Con, MBMesquite::AveragingQM::average_metrics(), b2Con, b3Con, c2Con, c3Con, MBMesquite::PatchData::element_by_index(), MBMesquite::PatchData::get_domain_normal_at_element(), MBMesquite::MsqMeshEntity::get_element_type(), MBMesquite::PatchData::get_vertex_array(), MBMesquite::MsqMeshEntity::get_vertex_index_array(), MBMesquite::HEXAHEDRON, MBMesquite::Vector3D::length(), MBMesquite::m_fcn_2e(), MBMesquite::m_fcn_2i(), MBMesquite::m_fcn_3e(), MBMesquite::m_fcn_3i(), MBMesquite::m_fcn_3p(), MBMesquite::m_fcn_3w(), mCoords, mMetrics, MSQ_ERRZERO, MSQ_SETERR, n, MBMesquite::PRISM, MBMesquite::PYRAMID, MBMesquite::QUADRILATERAL, MBMesquite::TETRAHEDRON, MBMesquite::TRIANGLE, and MBMesquite::MsqError::UNSUPPORTED_ELEMENT.
{ const MsqMeshEntity* e = &pd.element_by_index( handle ); EntityTopology topo = e->get_element_type(); const MsqVertex* vertices = pd.get_vertex_array( err ); const size_t* v_i = e->get_vertex_index_array(); Vector3D n; // Surface normal for 2D objects // Prism and Hex element descriptions static const int locs_pri[6][4] = { { 0, 1, 2, 3 }, { 1, 2, 0, 4 }, { 2, 0, 1, 5 }, { 3, 5, 4, 0 }, { 4, 3, 5, 1 }, { 5, 4, 3, 2 } }; static const int locs_hex[8][4] = { { 0, 1, 3, 4 }, { 1, 2, 0, 5 }, { 2, 3, 1, 6 }, { 3, 0, 2, 7 }, { 4, 7, 5, 0 }, { 5, 4, 6, 1 }, { 6, 5, 7, 2 }, { 7, 6, 4, 3 } }; const Vector3D d_con( 1.0, 1.0, 1.0 ); int i; m = 0.0; bool metric_valid = false; switch( topo ) { case TRIANGLE: pd.get_domain_normal_at_element( e, n, err ); MSQ_ERRZERO( err ); n = n / n.length(); // Need unit normal mCoords[0] = vertices[v_i[0]]; mCoords[1] = vertices[v_i[1]]; mCoords[2] = vertices[v_i[2]]; metric_valid = m_fcn_2e( m, mCoords, n, a2Con, b2Con, c2Con ); if( !metric_valid ) return false; break; case QUADRILATERAL: pd.get_domain_normal_at_element( e, n, err ); MSQ_ERRZERO( err ); for( i = 0; i < 4; ++i ) { n = n / n.length(); // Need unit normal mCoords[0] = vertices[v_i[locs_hex[i][0]]]; mCoords[1] = vertices[v_i[locs_hex[i][1]]]; mCoords[2] = vertices[v_i[locs_hex[i][2]]]; metric_valid = m_fcn_2i( mMetrics[i], mCoords, n, a2Con, b2Con, c2Con, d_con ); if( !metric_valid ) return false; } m = average_metrics( mMetrics, 4, err ); MSQ_ERRZERO( err ); break; case TETRAHEDRON: mCoords[0] = vertices[v_i[0]]; mCoords[1] = vertices[v_i[1]]; mCoords[2] = vertices[v_i[2]]; mCoords[3] = vertices[v_i[3]]; metric_valid = m_fcn_3e( m, mCoords, a3Con, b3Con, c3Con ); if( !metric_valid ) return false; break; case PYRAMID: for( i = 0; i < 4; ++i ) { mCoords[0] = vertices[v_i[i]]; mCoords[1] = vertices[v_i[( i + 1 ) % 4]]; mCoords[2] = vertices[v_i[( i + 3 ) % 4]]; mCoords[3] = vertices[v_i[4]]; metric_valid = m_fcn_3p( mMetrics[i], mCoords, a3Con, b3Con, c3Con ); if( !metric_valid ) return false; } m = average_metrics( mMetrics, 4, err ); MSQ_ERRZERO( err ); break; case PRISM: for( i = 0; i < 6; ++i ) { mCoords[0] = vertices[v_i[locs_pri[i][0]]]; mCoords[1] = vertices[v_i[locs_pri[i][1]]]; mCoords[2] = vertices[v_i[locs_pri[i][2]]]; mCoords[3] = vertices[v_i[locs_pri[i][3]]]; metric_valid = m_fcn_3w( mMetrics[i], mCoords, a3Con, b3Con, c3Con ); if( !metric_valid ) return false; } m = average_metrics( mMetrics, 6, err ); MSQ_ERRZERO( err ); break; case HEXAHEDRON: for( i = 0; i < 8; ++i ) { mCoords[0] = vertices[v_i[locs_hex[i][0]]]; mCoords[1] = vertices[v_i[locs_hex[i][1]]]; mCoords[2] = vertices[v_i[locs_hex[i][2]]]; mCoords[3] = vertices[v_i[locs_hex[i][3]]]; metric_valid = m_fcn_3i( mMetrics[i], mCoords, a3Con, b3Con, c3Con, d_con ); if( !metric_valid ) return false; } m = average_metrics( mMetrics, 8, err ); MSQ_ERRZERO( err ); break; default: MSQ_SETERR( err ) ( MsqError::UNSUPPORTED_ELEMENT, "Element type (%d) not supported in IdealWeightMeanRatio", (int)topo ); return false; } // end switch over element type return true; }
bool IdealWeightMeanRatio::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.
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. |
gradient | The 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 168 of file IdealWeightMeanRatio.cpp.
References a2Con, a3Con, MBMesquite::AveragingQM::analytical_average_gradient(), MBMesquite::arrptr(), MBMesquite::AveragingQM::average_corner_gradients(), b2Con, b3Con, c2Con, c3Con, MBMesquite::PatchData::element_by_index(), MBMesquite::QualityMetric::fixed_vertex_bitmap(), MBMesquite::g_fcn_2e(), MBMesquite::g_fcn_2i(), MBMesquite::g_fcn_3e(), MBMesquite::g_fcn_3i(), MBMesquite::g_fcn_3p(), MBMesquite::g_fcn_3w(), MBMesquite::PatchData::get_domain_normal_at_element(), MBMesquite::MsqMeshEntity::get_element_type(), MBMesquite::PatchData::get_vertex_array(), MBMesquite::MsqMeshEntity::get_vertex_index_array(), MBMesquite::HEXAHEDRON, MBMesquite::Vector3D::length(), mCoords, mGradients, mMetrics, MSQ_DBGOUT, MSQ_ERRZERO, MSQ_SETERR, n, MBMesquite::print(), MBMesquite::PRISM, MBMesquite::PYRAMID, MBMesquite::QUADRILATERAL, MBMesquite::QualityMetric::remove_fixed_gradients(), MBMesquite::TETRAHEDRON, MBMesquite::TRIANGLE, and MBMesquite::MsqError::UNSUPPORTED_ELEMENT.
{ // FUNCTION_TIMER_START(__FUNC__); const MsqMeshEntity* e = &pd.element_by_index( handle ); EntityTopology topo = e->get_element_type(); if( !analytical_average_gradient() && topo != TRIANGLE && topo != TETRAHEDRON ) { static bool print = true; if( print ) { MSQ_DBGOUT( 1 ) << "Analyical gradient not available for selected averaging scheme. " << "Using (possibly much slower) numerical approximation of gradient" << " of quality metric. " << std::endl; print = false; } return QualityMetric::evaluate_with_gradient( pd, handle, m, indices, g, err ); } const MsqVertex* vertices = pd.get_vertex_array( err ); const size_t* v_i = e->get_vertex_index_array(); Vector3D n; // Surface normal for 2D objects // double nm, t=0; // Prism and Hex element descriptions static const int locs_pri[6][4] = { { 0, 1, 2, 3 }, { 1, 2, 0, 4 }, { 2, 0, 1, 5 }, { 3, 5, 4, 0 }, { 4, 3, 5, 1 }, { 5, 4, 3, 2 } }; static const int locs_hex[8][4] = { { 0, 1, 3, 4 }, { 1, 2, 0, 5 }, { 2, 3, 1, 6 }, { 3, 0, 2, 7 }, { 4, 7, 5, 0 }, { 5, 4, 6, 1 }, { 6, 5, 7, 2 }, { 7, 6, 4, 3 } }; const Vector3D d_con( 1.0, 1.0, 1.0 ); int i; bool metric_valid = false; const uint32_t fm = fixed_vertex_bitmap( pd, e, indices ); m = 0.0; switch( topo ) { case TRIANGLE: pd.get_domain_normal_at_element( e, n, err ); MSQ_ERRZERO( err ); n = n / n.length(); // Need unit normal mCoords[0] = vertices[v_i[0]]; mCoords[1] = vertices[v_i[1]]; mCoords[2] = vertices[v_i[2]]; g.resize( 3 ); if( !g_fcn_2e( m, arrptr( g ), mCoords, n, a2Con, b2Con, c2Con ) ) return false; break; case QUADRILATERAL: pd.get_domain_normal_at_element( e, n, err ); MSQ_ERRZERO( err ); n /= n.length(); // Need unit normal for( i = 0; i < 4; ++i ) { mCoords[0] = vertices[v_i[locs_hex[i][0]]]; mCoords[1] = vertices[v_i[locs_hex[i][1]]]; mCoords[2] = vertices[v_i[locs_hex[i][2]]]; if( !g_fcn_2i( mMetrics[i], mGradients + 3 * i, mCoords, n, a2Con, b2Con, c2Con, d_con ) ) return false; } g.resize( 4 ); m = average_corner_gradients( QUADRILATERAL, fm, 4, mMetrics, mGradients, arrptr( g ), err ); MSQ_ERRZERO( err ); break; case TETRAHEDRON: mCoords[0] = vertices[v_i[0]]; mCoords[1] = vertices[v_i[1]]; mCoords[2] = vertices[v_i[2]]; mCoords[3] = vertices[v_i[3]]; g.resize( 4 ); metric_valid = g_fcn_3e( m, arrptr( g ), mCoords, a3Con, b3Con, c3Con ); if( !metric_valid ) return false; break; case PYRAMID: for( i = 0; i < 4; ++i ) { mCoords[0] = vertices[v_i[i]]; mCoords[1] = vertices[v_i[( i + 1 ) % 4]]; mCoords[2] = vertices[v_i[( i + 3 ) % 4]]; mCoords[3] = vertices[v_i[4]]; metric_valid = g_fcn_3p( mMetrics[i], mGradients + 4 * i, mCoords, a3Con, b3Con, c3Con ); if( !metric_valid ) return false; } g.resize( 5 ); m = average_corner_gradients( PYRAMID, fm, 4, mMetrics, mGradients, arrptr( g ), err ); MSQ_ERRZERO( err ); break; case PRISM: for( i = 0; i < 6; ++i ) { mCoords[0] = vertices[v_i[locs_pri[i][0]]]; mCoords[1] = vertices[v_i[locs_pri[i][1]]]; mCoords[2] = vertices[v_i[locs_pri[i][2]]]; mCoords[3] = vertices[v_i[locs_pri[i][3]]]; if( !g_fcn_3w( mMetrics[i], mGradients + 4 * i, mCoords, a3Con, b3Con, c3Con ) ) return false; } g.resize( 6 ); m = average_corner_gradients( PRISM, fm, 6, mMetrics, mGradients, arrptr( g ), err ); MSQ_ERRZERO( err ); break; case HEXAHEDRON: for( i = 0; i < 8; ++i ) { mCoords[0] = vertices[v_i[locs_hex[i][0]]]; mCoords[1] = vertices[v_i[locs_hex[i][1]]]; mCoords[2] = vertices[v_i[locs_hex[i][2]]]; mCoords[3] = vertices[v_i[locs_hex[i][3]]]; if( !g_fcn_3i( mMetrics[i], mGradients + 4 * i, mCoords, a3Con, b3Con, c3Con, d_con ) ) return false; } g.resize( 8 ); m = average_corner_gradients( HEXAHEDRON, fm, 8, mMetrics, mGradients, arrptr( g ), err ); MSQ_ERRZERO( err ); break; default: MSQ_SETERR( err ) ( MsqError::UNSUPPORTED_ELEMENT, "Element type (%d) not supported in IdealWeightMeanRatio", (int)topo ); return false; } remove_fixed_gradients( topo, fm, g ); return true; }
bool IdealWeightMeanRatio::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.
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. |
gradient | The gradient of the metric as a function of the coordinates of the free vertices passed back in the indices list. |
Hessian | The 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 464 of file IdealWeightMeanRatio.cpp.
References a2Con, a3Con, MBMesquite::AveragingQM::analytical_average_hessian(), MBMesquite::arrptr(), MBMesquite::AveragingQM::average_corner_hessians(), b2Con, b3Con, c2Con, c3Con, MBMesquite::PatchData::element_by_index(), MBMesquite::QualityMetric::fixed_vertex_bitmap(), MBMesquite::PatchData::get_domain_normal_at_element(), MBMesquite::MsqMeshEntity::get_element_type(), MBMesquite::PatchData::get_vertex_array(), MBMesquite::MsqMeshEntity::get_vertex_index_array(), MBMesquite::h_fcn_2e(), MBMesquite::h_fcn_2i(), MBMesquite::h_fcn_3e(), MBMesquite::h_fcn_3i(), MBMesquite::h_fcn_3p(), MBMesquite::h_fcn_3w(), MBMesquite::HEXAHEDRON, MBMesquite::Vector3D::length(), mCoords, mGradients, mHessians, mMetrics, MSQ_DBGOUT, MSQ_ERRZERO, MSQ_SETERR, n, MBMesquite::print(), MBMesquite::PRISM, MBMesquite::PYRAMID, MBMesquite::QUADRILATERAL, MBMesquite::QualityMetric::remove_fixed_gradients(), MBMesquite::QualityMetric::remove_fixed_hessians(), MBMesquite::TETRAHEDRON, MBMesquite::TRIANGLE, and MBMesquite::MsqError::UNSUPPORTED_ELEMENT.
{ // FUNCTION_TIMER_START(__FUNC__); const MsqMeshEntity* e = &pd.element_by_index( handle ); EntityTopology topo = e->get_element_type(); if( !analytical_average_hessian() && topo != TRIANGLE && topo != TETRAHEDRON ) { static bool print = true; if( print ) { MSQ_DBGOUT( 1 ) << "Analyical gradient not available for selected averaging scheme. " << "Using (possibly much slower) numerical approximation of gradient" << " of quality metric. " << std::endl; print = false; } return QualityMetric::evaluate_with_Hessian( pd, handle, m, indices, g, h, err ); } const MsqVertex* vertices = pd.get_vertex_array( err ); const size_t* v_i = e->get_vertex_index_array(); Vector3D n; // Surface normal for 2D objects // Prism and Hex element descriptions static const int locs_pri[6][4] = { { 0, 1, 2, 3 }, { 1, 2, 0, 4 }, { 2, 0, 1, 5 }, { 3, 5, 4, 0 }, { 4, 3, 5, 1 }, { 5, 4, 3, 2 } }; static const int locs_hex[8][4] = { { 0, 1, 3, 4 }, { 1, 2, 0, 5 }, { 2, 3, 1, 6 }, { 3, 0, 2, 7 }, { 4, 7, 5, 0 }, { 5, 4, 6, 1 }, { 6, 5, 7, 2 }, { 7, 6, 4, 3 } }; const Vector3D d_con( 1.0, 1.0, 1.0 ); int i; bool metric_valid = false; const uint32_t fm = fixed_vertex_bitmap( pd, e, indices ); m = 0.0; switch( topo ) { case TRIANGLE: pd.get_domain_normal_at_element( e, n, err ); MSQ_ERRZERO( err ); n = n / n.length(); // Need unit normal mCoords[0] = vertices[v_i[0]]; mCoords[1] = vertices[v_i[1]]; mCoords[2] = vertices[v_i[2]]; g.resize( 3 ), h.resize( 6 ); if( !h_fcn_2e( m, arrptr( g ), arrptr( h ), mCoords, n, a2Con, b2Con, c2Con ) ) return false; break; case QUADRILATERAL: pd.get_domain_normal_at_element( e, n, err ); MSQ_ERRZERO( err ); n = n / n.length(); // Need unit normal for( i = 0; i < 4; ++i ) { mCoords[0] = vertices[v_i[locs_hex[i][0]]]; mCoords[1] = vertices[v_i[locs_hex[i][1]]]; mCoords[2] = vertices[v_i[locs_hex[i][2]]]; if( !h_fcn_2i( mMetrics[i], mGradients + 3 * i, mHessians + 6 * i, mCoords, n, a2Con, b2Con, c2Con, d_con ) ) return false; } g.resize( 4 ), h.resize( 10 ); m = average_corner_hessians( QUADRILATERAL, fm, 4, mMetrics, mGradients, mHessians, arrptr( g ), arrptr( h ), err ); MSQ_ERRZERO( err ); break; case TETRAHEDRON: mCoords[0] = vertices[v_i[0]]; mCoords[1] = vertices[v_i[1]]; mCoords[2] = vertices[v_i[2]]; mCoords[3] = vertices[v_i[3]]; g.resize( 4 ), h.resize( 10 ); metric_valid = h_fcn_3e( m, arrptr( g ), arrptr( h ), mCoords, a3Con, b3Con, c3Con ); if( !metric_valid ) return false; break; case PYRAMID: for( i = 0; i < 4; ++i ) { mCoords[0] = vertices[v_i[i]]; mCoords[1] = vertices[v_i[( i + 1 ) % 4]]; mCoords[2] = vertices[v_i[( i + 3 ) % 4]]; mCoords[3] = vertices[v_i[4]]; metric_valid = h_fcn_3p( mMetrics[i], mGradients + 4 * i, mHessians + 10 * i, mCoords, a3Con, b3Con, c3Con ); if( !metric_valid ) return false; } g.resize( 5 ), h.resize( 15 ); m = average_corner_hessians( PYRAMID, fm, 4, mMetrics, mGradients, mHessians, arrptr( g ), arrptr( h ), err ); MSQ_ERRZERO( err ); break; case PRISM: for( i = 0; i < 6; ++i ) { mCoords[0] = vertices[v_i[locs_pri[i][0]]]; mCoords[1] = vertices[v_i[locs_pri[i][1]]]; mCoords[2] = vertices[v_i[locs_pri[i][2]]]; mCoords[3] = vertices[v_i[locs_pri[i][3]]]; if( !h_fcn_3w( mMetrics[i], mGradients + 4 * i, mHessians + 10 * i, mCoords, a3Con, b3Con, c3Con ) ) return false; } g.resize( 6 ), h.resize( 21 ); m = average_corner_hessians( PRISM, fm, 6, mMetrics, mGradients, mHessians, arrptr( g ), arrptr( h ), err ); MSQ_ERRZERO( err ); break; case HEXAHEDRON: for( i = 0; i < 8; ++i ) { mCoords[0] = vertices[v_i[locs_hex[i][0]]]; mCoords[1] = vertices[v_i[locs_hex[i][1]]]; mCoords[2] = vertices[v_i[locs_hex[i][2]]]; mCoords[3] = vertices[v_i[locs_hex[i][3]]]; if( !h_fcn_3i( mMetrics[i], mGradients + 4 * i, mHessians + 10 * i, mCoords, a3Con, b3Con, c3Con, d_con ) ) return false; } g.resize( 8 ), h.resize( 36 ); m = average_corner_hessians( HEXAHEDRON, fm, 8, mMetrics, mGradients, mHessians, arrptr( g ), arrptr( h ), err ); MSQ_ERRZERO( err ); break; default: MSQ_SETERR( err ) ( MsqError::UNSUPPORTED_ELEMENT, "Element type (%d) not supported in IdealWeightMeanRatio", (int)topo ); return false; } // end switch over element type remove_fixed_gradients( topo, fm, g ); remove_fixed_hessians( topo, fm, h ); // FUNCTION_TIMER_END(); return true; }
bool IdealWeightMeanRatio::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.
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. |
gradient | The gradient of the metric as a function of the coordinates of the free vertices passed back in the indices list. |
Hessian_diagonal | The 3x3 blocks along the diagonal of the Hessian matrix. |
Reimplemented from MBMesquite::QualityMetric.
Definition at line 307 of file IdealWeightMeanRatio.cpp.
References a2Con, a3Con, MBMesquite::AveragingQM::analytical_average_hessian(), MBMesquite::arrptr(), MBMesquite::AveragingQM::average_corner_hessian_diagonals(), b2Con, b3Con, c2Con, c3Con, MBMesquite::PatchData::element_by_index(), MBMesquite::QualityMetric::fixed_vertex_bitmap(), MBMesquite::PatchData::get_domain_normal_at_element(), MBMesquite::MsqMeshEntity::get_element_type(), MBMesquite::PatchData::get_vertex_array(), MBMesquite::MsqMeshEntity::get_vertex_index_array(), MBMesquite::h_fcn_2e(), MBMesquite::h_fcn_2i(), MBMesquite::h_fcn_3e(), MBMesquite::h_fcn_3i(), MBMesquite::h_fcn_3p(), MBMesquite::h_fcn_3w(), MBMesquite::HEXAHEDRON, MBMesquite::Vector3D::length(), mCoords, mGradients, mHessians, mMetrics, MSQ_DBGOUT, MSQ_ERRZERO, MSQ_SETERR, n, MBMesquite::print(), MBMesquite::PRISM, MBMesquite::PYRAMID, MBMesquite::QUADRILATERAL, MBMesquite::QualityMetric::remove_fixed_diagonals(), MBMesquite::TETRAHEDRON, MBMesquite::TRIANGLE, MBMesquite::MsqError::UNSUPPORTED_ELEMENT, and MBMesquite::Matrix3D::upper().
{ const MsqMeshEntity* e = &pd.element_by_index( handle ); EntityTopology topo = e->get_element_type(); if( !analytical_average_hessian() && topo != TRIANGLE && topo != TETRAHEDRON ) { static bool print = true; if( print ) { MSQ_DBGOUT( 1 ) << "Analyical gradient not available for selected averaging scheme. " << "Using (possibly much slower) numerical approximation of gradient" << " of quality metric. " << std::endl; print = false; } return QualityMetric::evaluate_with_Hessian_diagonal( pd, handle, m, indices, g, h, err ); } const MsqVertex* vertices = pd.get_vertex_array( err ); const size_t* v_i = e->get_vertex_index_array(); Vector3D n; // Surface normal for 2D objects // Prism and Hex element descriptions static const int locs_pri[6][4] = { { 0, 1, 2, 3 }, { 1, 2, 0, 4 }, { 2, 0, 1, 5 }, { 3, 5, 4, 0 }, { 4, 3, 5, 1 }, { 5, 4, 3, 2 } }; static const int locs_hex[8][4] = { { 0, 1, 3, 4 }, { 1, 2, 0, 5 }, { 2, 3, 1, 6 }, { 3, 0, 2, 7 }, { 4, 7, 5, 0 }, { 5, 4, 6, 1 }, { 6, 5, 7, 2 }, { 7, 6, 4, 3 } }; const Vector3D d_con( 1.0, 1.0, 1.0 ); int i; bool metric_valid = false; const uint32_t fm = fixed_vertex_bitmap( pd, e, indices ); m = 0.0; switch( topo ) { case TRIANGLE: pd.get_domain_normal_at_element( e, n, err ); MSQ_ERRZERO( err ); n = n / n.length(); // Need unit normal mCoords[0] = vertices[v_i[0]]; mCoords[1] = vertices[v_i[1]]; mCoords[2] = vertices[v_i[2]]; g.resize( 3 ), h.resize( 3 ); if( !h_fcn_2e( m, arrptr( g ), mHessians, mCoords, n, a2Con, b2Con, c2Con ) ) return false; h[0] = mHessians[0].upper(); h[1] = mHessians[3].upper(); h[2] = mHessians[5].upper(); break; case QUADRILATERAL: pd.get_domain_normal_at_element( e, n, err ); MSQ_ERRZERO( err ); n = n / n.length(); // Need unit normal for( i = 0; i < 4; ++i ) { mCoords[0] = vertices[v_i[locs_hex[i][0]]]; mCoords[1] = vertices[v_i[locs_hex[i][1]]]; mCoords[2] = vertices[v_i[locs_hex[i][2]]]; if( !h_fcn_2i( mMetrics[i], mGradients + 3 * i, mHessians + 6 * i, mCoords, n, a2Con, b2Con, c2Con, d_con ) ) return false; } g.resize( 4 ), h.resize( 4 ); m = average_corner_hessian_diagonals( QUADRILATERAL, fm, 4, mMetrics, mGradients, mHessians, arrptr( g ), arrptr( h ), err ); MSQ_ERRZERO( err ); break; case TETRAHEDRON: mCoords[0] = vertices[v_i[0]]; mCoords[1] = vertices[v_i[1]]; mCoords[2] = vertices[v_i[2]]; mCoords[3] = vertices[v_i[3]]; g.resize( 4 ), h.resize( 4 ); metric_valid = h_fcn_3e( m, arrptr( g ), mHessians, mCoords, a3Con, b3Con, c3Con ); if( !metric_valid ) return false; h[0] = mHessians[0].upper(); h[1] = mHessians[4].upper(); h[2] = mHessians[7].upper(); h[3] = mHessians[9].upper(); break; case PYRAMID: for( i = 0; i < 4; ++i ) { mCoords[0] = vertices[v_i[i]]; mCoords[1] = vertices[v_i[( i + 1 ) % 4]]; mCoords[2] = vertices[v_i[( i + 3 ) % 4]]; mCoords[3] = vertices[v_i[4]]; metric_valid = h_fcn_3p( mMetrics[i], mGradients + 4 * i, mHessians + 10 * i, mCoords, a3Con, b3Con, c3Con ); if( !metric_valid ) return false; } g.resize( 5 ), h.resize( 5 ); m = average_corner_hessian_diagonals( PYRAMID, fm, 4, mMetrics, mGradients, mHessians, arrptr( g ), arrptr( h ), err ); MSQ_ERRZERO( err ); break; case PRISM: for( i = 0; i < 6; ++i ) { mCoords[0] = vertices[v_i[locs_pri[i][0]]]; mCoords[1] = vertices[v_i[locs_pri[i][1]]]; mCoords[2] = vertices[v_i[locs_pri[i][2]]]; mCoords[3] = vertices[v_i[locs_pri[i][3]]]; if( !h_fcn_3w( mMetrics[i], mGradients + 4 * i, mHessians + 10 * i, mCoords, a3Con, b3Con, c3Con ) ) return false; } g.resize( 6 ), h.resize( 6 ); m = average_corner_hessian_diagonals( PRISM, fm, 6, mMetrics, mGradients, mHessians, arrptr( g ), arrptr( h ), err ); MSQ_ERRZERO( err ); break; case HEXAHEDRON: for( i = 0; i < 8; ++i ) { mCoords[0] = vertices[v_i[locs_hex[i][0]]]; mCoords[1] = vertices[v_i[locs_hex[i][1]]]; mCoords[2] = vertices[v_i[locs_hex[i][2]]]; mCoords[3] = vertices[v_i[locs_hex[i][3]]]; if( !h_fcn_3i( mMetrics[i], mGradients + 4 * i, mHessians + 10 * i, mCoords, a3Con, b3Con, c3Con, d_con ) ) return false; } g.resize( 8 ), h.resize( 8 ); m = average_corner_hessian_diagonals( HEXAHEDRON, fm, 8, mMetrics, mGradients, mHessians, arrptr( g ), arrptr( h ), err ); MSQ_ERRZERO( err ); break; default: MSQ_SETERR( err ) ( MsqError::UNSUPPORTED_ELEMENT, "Element type (%d) not supported in IdealWeightMeanRatio", (int)topo ); return false; } // end switch over element type remove_fixed_diagonals( topo, fm, g, h ); return true; }
std::string IdealWeightMeanRatio::get_name | ( | ) | const [virtual] |
Implements MBMesquite::QualityMetric.
Definition at line 48 of file IdealWeightMeanRatio.cpp.
{ return "Mean Ratio"; }
int IdealWeightMeanRatio::get_negate_flag | ( | ) | const [virtual] |
1 if metric should be minimized, -1 if metric should be maximized.
Implements MBMesquite::QualityMetric.
Definition at line 53 of file IdealWeightMeanRatio.cpp.
{
return -1;
}
const double MBMesquite::IdealWeightMeanRatio::a2Con [private] |
Definition at line 113 of file IdealWeightMeanRatio.hpp.
Referenced by evaluate(), evaluate_with_gradient(), evaluate_with_Hessian(), and evaluate_with_Hessian_diagonal().
const double MBMesquite::IdealWeightMeanRatio::a3Con [private] |
Definition at line 117 of file IdealWeightMeanRatio.hpp.
Referenced by evaluate(), evaluate_with_gradient(), evaluate_with_Hessian(), and evaluate_with_Hessian_diagonal().
const Exponent MBMesquite::IdealWeightMeanRatio::b2Con [private] |
Definition at line 114 of file IdealWeightMeanRatio.hpp.
Referenced by evaluate(), evaluate_with_gradient(), evaluate_with_Hessian(), and evaluate_with_Hessian_diagonal().
const Exponent MBMesquite::IdealWeightMeanRatio::b3Con [private] |
Definition at line 118 of file IdealWeightMeanRatio.hpp.
Referenced by evaluate(), evaluate_with_gradient(), evaluate_with_Hessian(), and evaluate_with_Hessian_diagonal().
const Exponent MBMesquite::IdealWeightMeanRatio::c2Con [private] |
Definition at line 115 of file IdealWeightMeanRatio.hpp.
Referenced by evaluate(), evaluate_with_gradient(), evaluate_with_Hessian(), and evaluate_with_Hessian_diagonal().
const Exponent MBMesquite::IdealWeightMeanRatio::c3Con [private] |
Definition at line 119 of file IdealWeightMeanRatio.hpp.
Referenced by evaluate(), evaluate_with_gradient(), evaluate_with_Hessian(), and evaluate_with_Hessian_diagonal().
Vector3D MBMesquite::IdealWeightMeanRatio::mCoords[4] [private] |
Definition at line 108 of file IdealWeightMeanRatio.hpp.
Referenced by evaluate(), evaluate_with_gradient(), evaluate_with_Hessian(), and evaluate_with_Hessian_diagonal().
Vector3D MBMesquite::IdealWeightMeanRatio::mGradients[32] [private] |
Definition at line 109 of file IdealWeightMeanRatio.hpp.
Referenced by evaluate_with_gradient(), evaluate_with_Hessian(), and evaluate_with_Hessian_diagonal().
Matrix3D MBMesquite::IdealWeightMeanRatio::mHessians[80] [private] |
Definition at line 110 of file IdealWeightMeanRatio.hpp.
Referenced by evaluate_with_Hessian(), and evaluate_with_Hessian_diagonal().
double MBMesquite::IdealWeightMeanRatio::mMetrics[8] [private] |
Definition at line 111 of file IdealWeightMeanRatio.hpp.
Referenced by evaluate(), evaluate_with_gradient(), evaluate_with_Hessian(), and evaluate_with_Hessian_diagonal().