MOAB: Mesh Oriented datABase
(version 5.4.1)
|
Computes the inverse mean ratio of given element. More...
#include <IdealWeightInverseMeanRatio.hpp>
Public Member Functions | |
MESQUITE_EXPORT | IdealWeightInverseMeanRatio (MsqError &err, double power=1.0) |
MESQUITE_EXPORT | IdealWeightInverseMeanRatio () |
virtual MESQUITE_EXPORT | ~IdealWeightInverseMeanRatio () |
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 Member Functions | |
void | set_metric_power (double pow_dbl, MsqError &err) |
Sets the power value in the metric computation. | |
Private Attributes | |
Vector3D | mCoords [4] |
Vector3D | mGradients [32] |
Matrix3D | mHessians [80] |
double | mMetrics [8] |
double | a2Con |
Exponent | b2Con |
Exponent | c2Con |
double | a3Con |
Exponent | b3Con |
Exponent | c3Con |
Computes the inverse mean ratio 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. Optionally, the metric computation can be raised to the 'pow_dbl' power. This does not necessarily raise the metric value to the 'pow_dbl' power but instead raises each local metric. For example, if the corner inverse mean ratios of a quadraliteral element were m1,m2,m3, and m4 and we set pow_dbl=2 and used linear averaging, the metric value would then be m = .25(m1*m1 + m2*m2 + m3*m3 + m4*m4). The metric does require a feasible region, and the metric needs to be minimized if pow_dbl is greater than zero and maximized if pow_dbl is less than zero. pow_dbl being equal to zero is invalid.
Definition at line 72 of file IdealWeightInverseMeanRatio.hpp.
MBMesquite::IdealWeightInverseMeanRatio::IdealWeightInverseMeanRatio | ( | MsqError & | err, |
double | power = 1.0 |
||
) |
Definition at line 51 of file IdealWeightInverseMeanRatio.cpp.
References MSQ_ERRRTN, and set_metric_power().
: AveragingQM( QualityMetric::LINEAR ) { set_metric_power( pow_dbl, err );MSQ_ERRRTN( err ); }
Definition at line 57 of file IdealWeightInverseMeanRatio.cpp.
References set_metric_power().
: AveragingQM( QualityMetric::LINEAR ) { MsqError err; set_metric_power( 1.0, err ); assert( !err ); }
virtual MESQUITE_EXPORT MBMesquite::IdealWeightInverseMeanRatio::~IdealWeightInverseMeanRatio | ( | ) | [inline, virtual] |
virtual destructor ensures use of polymorphism during destruction
Definition at line 79 of file IdealWeightInverseMeanRatio.hpp.
{}
bool MBMesquite::IdealWeightInverseMeanRatio::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 90 of file IdealWeightInverseMeanRatio.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 ); MSQ_ERRZERO( 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 ); 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]]]; 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 ); 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 IdealWeightInverseMeanRatio", (int)topo ); return false; } // end switch over element type return true; }
bool MBMesquite::IdealWeightInverseMeanRatio::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 201 of file IdealWeightInverseMeanRatio.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.
Referenced by TQualityMetricTest::regression_inverse_mean_ratio_grad().
{ 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 ); MSQ_ERRZERO( 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.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 IdealWeightInverseMeanRatio", (int)topo ); return false; } // end switch over element type remove_fixed_gradients( topo, fm, g ); return true; }
bool MBMesquite::IdealWeightInverseMeanRatio::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 508 of file IdealWeightInverseMeanRatio.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.
Referenced by TQualityMetricTest::regression_inverse_mean_ratio_hess().
{ 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 ); MSQ_ERRZERO( 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.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.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 IdealWeightInverseMeanRatio", (int)topo ); return false; } // end switch over element type remove_fixed_gradients( topo, fm, g ); remove_fixed_hessians( topo, fm, h ); return true; }
bool MBMesquite::IdealWeightInverseMeanRatio::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 342 of file IdealWeightInverseMeanRatio.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 ); MSQ_ERRZERO( 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.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.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 IdealWeightInverseMeanRatio", (int)topo ); return false; } // end switch over element type remove_fixed_diagonals( topo, fm, g, h ); return true; }
std::string MBMesquite::IdealWeightInverseMeanRatio::get_name | ( | ) | const [virtual] |
Implements MBMesquite::QualityMetric.
Definition at line 64 of file IdealWeightInverseMeanRatio.cpp.
{ return "Inverse Mean Ratio"; }
int MBMesquite::IdealWeightInverseMeanRatio::get_negate_flag | ( | ) | const [virtual] |
1 if metric should be minimized, -1 if metric should be maximized.
Implements MBMesquite::QualityMetric.
Definition at line 69 of file IdealWeightInverseMeanRatio.cpp.
References b2Con, and MBMesquite::Exponent::value().
void MBMesquite::IdealWeightInverseMeanRatio::set_metric_power | ( | double | pow_dbl, |
MsqError & | err | ||
) | [private] |
Sets the power value in the metric computation.
Definition at line 75 of file IdealWeightInverseMeanRatio.cpp.
References a2Con, a3Con, b2Con, b3Con, c2Con, c3Con, MBMesquite::MsqError::INVALID_ARG, MBMesquite::MSQ_MIN, and MSQ_SETERR.
Referenced by IdealWeightInverseMeanRatio().
{ if( fabs( pow_dbl ) <= MSQ_MIN ) { MSQ_SETERR( err )( MsqError::INVALID_ARG ); return; } a2Con = pow( .5, pow_dbl ); b2Con = pow_dbl; c2Con = -pow_dbl; a3Con = pow( 1.0 / 3.0, pow_dbl ); b3Con = pow_dbl; c3Con = -2.0 * pow_dbl / 3.0; }
double MBMesquite::IdealWeightInverseMeanRatio::a2Con [private] |
Definition at line 123 of file IdealWeightInverseMeanRatio.hpp.
Referenced by evaluate(), evaluate_with_gradient(), evaluate_with_Hessian(), evaluate_with_Hessian_diagonal(), and set_metric_power().
double MBMesquite::IdealWeightInverseMeanRatio::a3Con [private] |
Definition at line 127 of file IdealWeightInverseMeanRatio.hpp.
Referenced by evaluate(), evaluate_with_gradient(), evaluate_with_Hessian(), evaluate_with_Hessian_diagonal(), and set_metric_power().
Definition at line 124 of file IdealWeightInverseMeanRatio.hpp.
Referenced by evaluate(), evaluate_with_gradient(), evaluate_with_Hessian(), evaluate_with_Hessian_diagonal(), get_negate_flag(), and set_metric_power().
Definition at line 128 of file IdealWeightInverseMeanRatio.hpp.
Referenced by evaluate(), evaluate_with_gradient(), evaluate_with_Hessian(), evaluate_with_Hessian_diagonal(), and set_metric_power().
Definition at line 125 of file IdealWeightInverseMeanRatio.hpp.
Referenced by evaluate(), evaluate_with_gradient(), evaluate_with_Hessian(), evaluate_with_Hessian_diagonal(), and set_metric_power().
Definition at line 129 of file IdealWeightInverseMeanRatio.hpp.
Referenced by evaluate(), evaluate_with_gradient(), evaluate_with_Hessian(), evaluate_with_Hessian_diagonal(), and set_metric_power().
Vector3D MBMesquite::IdealWeightInverseMeanRatio::mCoords[4] [private] |
Definition at line 118 of file IdealWeightInverseMeanRatio.hpp.
Referenced by evaluate(), evaluate_with_gradient(), evaluate_with_Hessian(), and evaluate_with_Hessian_diagonal().
Vector3D MBMesquite::IdealWeightInverseMeanRatio::mGradients[32] [private] |
Definition at line 119 of file IdealWeightInverseMeanRatio.hpp.
Referenced by evaluate_with_gradient(), evaluate_with_Hessian(), and evaluate_with_Hessian_diagonal().
Matrix3D MBMesquite::IdealWeightInverseMeanRatio::mHessians[80] [private] |
Definition at line 120 of file IdealWeightInverseMeanRatio.hpp.
Referenced by evaluate_with_Hessian(), and evaluate_with_Hessian_diagonal().
double MBMesquite::IdealWeightInverseMeanRatio::mMetrics[8] [private] |
Definition at line 121 of file IdealWeightInverseMeanRatio.hpp.
Referenced by evaluate(), evaluate_with_gradient(), evaluate_with_Hessian(), and evaluate_with_Hessian_diagonal().