MOAB: Mesh Oriented datABase
(version 5.4.1)
|
Compare targets to mapping function Jacobian matrices. More...
#include <AWQualityMetric.hpp>
Public Types | |
typedef AWMetric | MetricType |
Public Member Functions | |
AWQualityMetric (TargetCalculator *tc, WeightCalculator *wc, AWMetric *target_metric) | |
AWQualityMetric (TargetCalculator *tc, AWMetric *target_metric) | |
virtual MESQUITE_EXPORT std::string | get_name () const |
virtual MESQUITE_EXPORT 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 MESQUITE_EXPORT 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_diagonal, MsqError &err) |
Get metric value and gradient at a logical location in the patch. | |
virtual MESQUITE_EXPORT 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. | |
AWMetric * | get_target_metric () const |
void | set_target_metric (AWMetric *m) |
Protected Member Functions | |
virtual MESQUITE_EXPORT bool | evaluate_internal (PatchData &pd, size_t handle, double &value, size_t *indices, size_t &num_indices, MsqError &err) |
Private Attributes | |
AWMetric * | targetMetric |
Compare targets to mapping function Jacobian matrices.
A quality metric defined using 2D and 3D target metrics, where the active (A) matrix compared to the target by the underlying metrics is the Jacobian matrix of the mapping function at a given sample point. For surface elements, A is rotated to align the normal with W, such that both matrices can be reduced from 3x2 to 2x2.
Definition at line 53 of file AWQualityMetric.hpp.
Used in tests and other templatized code
Reimplemented from MBMesquite::QualityMetric.
Definition at line 57 of file AWQualityMetric.hpp.
MBMesquite::AWQualityMetric::AWQualityMetric | ( | TargetCalculator * | tc, |
WeightCalculator * | wc, | ||
AWMetric * | target_metric | ||
) | [inline] |
tc | The target calculator |
wc | The weight calculator |
target_metric | The target metric to use |
Definition at line 64 of file AWQualityMetric.hpp.
: TMPQualityMetric( tc, wc ), targetMetric( target_metric ) { }
MBMesquite::AWQualityMetric::AWQualityMetric | ( | TargetCalculator * | tc, |
AWMetric * | target_metric | ||
) | [inline] |
tc | The target calculator |
target_metric | The target metric to use |
Definition at line 73 of file AWQualityMetric.hpp.
: TMPQualityMetric( tc, 0 ), targetMetric( target_metric ) { }
bool MBMesquite::AWQualityMetric::evaluate_internal | ( | PatchData & | pd, |
size_t | handle, | ||
double & | value, | ||
size_t * | indices, | ||
size_t & | num_indices, | ||
MsqError & | err | ||
) | [protected, virtual] |
Implements MBMesquite::TMPQualityMetric.
Definition at line 64 of file AWQualityMetric.cpp.
References MBMesquite::ElemSampleQM::elem(), MBMesquite::PatchData::element_by_index(), MBMesquite::AWMetric::evaluate(), MBMesquite::TMPQualityMetric::evaluate_surface_common(), MBMesquite::TargetCalculator::get_3D_target(), MBMesquite::MsqMeshEntity::get_element_type(), MBMesquite::PatchData::get_mapping_function_3D(), MBMesquite::inverse(), MBMesquite::MappingFunction3D::jacobian(), MBMesquite::TMPQualityMetric::mDerivs2D, MBMesquite::TMPQualityMetric::mDerivs3D, MSQ_CHKERR, MSQ_ERRZERO, MSQ_SETERR, MBMesquite::PatchData::non_slave_node_set(), MBMesquite::ElemSampleQM::sample(), MBMesquite::TMPQualityMetric::targetCalc, targetMetric, and MBMesquite::MsqError::UNSUPPORTED_ELEMENT.
{ const Sample s = ElemSampleQM::sample( p_handle ); const size_t e = ElemSampleQM::elem( p_handle ); MsqMeshEntity& p_elem = pd.element_by_index( e ); EntityTopology type = p_elem.get_element_type(); unsigned edim = TopologyInfo::dimension( type ); const NodeSet bits = pd.non_slave_node_set( e ); bool rval; if( edim == 3 ) { // 3x3 or 3x2 targets ? const MappingFunction3D* mf = pd.get_mapping_function_3D( type ); if( !mf ) { MSQ_SETERR( err ) ( "No mapping function for element type", MsqError::UNSUPPORTED_ELEMENT ); return false; } MsqMatrix< 3, 3 > A, W; mf->jacobian( pd, e, bits, s, indices, mDerivs3D, num_indices, A, err ); MSQ_ERRZERO( err ); targetCalc->get_3D_target( pd, e, s, W, err ); MSQ_ERRZERO( err ); rval = targetMetric->evaluate( A, W, value, err ); MSQ_ERRZERO( err ); #ifdef PRINT_INFO print_info< 3 >( e, s, A, W, A * inverse( W ) ); #endif } else if( edim == 2 ) { MsqMatrix< 2, 2 > W, A; MsqMatrix< 3, 2 > S_a_transpose_Theta; rval = evaluate_surface_common( pd, s, e, bits, indices, num_indices, mDerivs2D, W, A, S_a_transpose_Theta, err ); if( MSQ_CHKERR( err ) || !rval ) return false; rval = targetMetric->evaluate( A, W, value, err ); MSQ_ERRZERO( err ); #ifdef PRINT_INFO print_info< 2 >( e, s, J, Wp, A * inverse( W ) ); #endif } else { assert( false ); return false; } return rval; }
bool MBMesquite::AWQualityMetric::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 122 of file AWQualityMetric.cpp.
References MBMesquite::arrptr(), MBMesquite::ElemSampleQM::elem(), MBMesquite::PatchData::element_by_index(), MBMesquite::TMPQualityMetric::evaluate_surface_common(), MBMesquite::AWMetric::evaluate_with_grad(), MBMesquite::TargetCalculator::get_3D_target(), MBMesquite::MsqMeshEntity::get_element_type(), MBMesquite::PatchData::get_mapping_function_3D(), MBMesquite::grad(), MBMesquite::inverse(), MBMesquite::MappingFunction3D::jacobian(), MBMesquite::TMPQualityMetric::mDerivs2D, MBMesquite::TMPQualityMetric::mDerivs3D, MBMesquite::TMPQualityMetric::mIndices, MSQ_CHKERR, MSQ_ERRZERO, MSQ_SETERR, MBMesquite::PatchData::non_slave_node_set(), MBMesquite::ElemSampleQM::sample(), MBMesquite::TMPQualityMetric::targetCalc, targetMetric, MBMesquite::MsqError::UNSUPPORTED_ELEMENT, and MBMesquite::TMPQualityMetric::weight().
{ const Sample s = ElemSampleQM::sample( p_handle ); const size_t e = ElemSampleQM::elem( p_handle ); MsqMeshEntity& p_elem = pd.element_by_index( e ); EntityTopology type = p_elem.get_element_type(); unsigned edim = TopologyInfo::dimension( type ); size_t num_idx = 0; const NodeSet bits = pd.non_slave_node_set( e ); bool rval; if( edim == 3 ) { // 3x3 or 3x2 targets ? const MappingFunction3D* mf = pd.get_mapping_function_3D( type ); if( !mf ) { MSQ_SETERR( err ) ( "No mapping function for element type", MsqError::UNSUPPORTED_ELEMENT ); return false; } MsqMatrix< 3, 3 > A, W, dmdA; mf->jacobian( pd, e, bits, s, mIndices, mDerivs3D, num_idx, A, err ); MSQ_ERRZERO( err ); targetCalc->get_3D_target( pd, e, s, W, err ); MSQ_ERRZERO( err ); rval = targetMetric->evaluate_with_grad( A, W, value, dmdA, err ); MSQ_ERRZERO( err ); gradient< 3 >( num_idx, mDerivs3D, dmdA, grad ); #ifdef PRINT_INFO print_info< 3 >( e, s, A, W, A * inverse( W ) ); #endif } else if( edim == 2 ) { MsqMatrix< 2, 2 > W, A, dmdA; MsqMatrix< 3, 2 > S_a_transpose_Theta; rval = evaluate_surface_common( pd, s, e, bits, mIndices, num_idx, mDerivs2D, W, A, S_a_transpose_Theta, err ); if( MSQ_CHKERR( err ) || !rval ) return false; rval = targetMetric->evaluate_with_grad( A, W, value, dmdA, err ); MSQ_ERRZERO( err ); gradient< 2 >( num_idx, mDerivs2D, S_a_transpose_Theta * dmdA, grad ); #ifdef PRINT_INFO print_info< 2 >( e, s, J, Wp, A * inverse( W ) ); #endif } else { assert( false ); return false; } // pass back index list indices.resize( num_idx ); std::copy( mIndices, mIndices + num_idx, indices.begin() ); // apply target weight to value weight( pd, s, e, num_idx, value, grad.empty() ? 0 : arrptr( grad ), 0, 0, err ); MSQ_ERRZERO( err ); return rval; }
bool MBMesquite::AWQualityMetric::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 189 of file AWQualityMetric.cpp.
References MBMesquite::arrptr(), MBMesquite::ElemSampleQM::elem(), MBMesquite::PatchData::element_by_index(), MBMesquite::TMPQualityMetric::evaluate_surface_common(), MBMesquite::AWMetric::evaluate_with_hess(), MBMesquite::TargetCalculator::get_3D_target(), MBMesquite::MsqMeshEntity::get_element_type(), MBMesquite::PatchData::get_mapping_function_3D(), MBMesquite::grad(), MBMesquite::TMPQualityMetric::hess2d, MBMesquite::inverse(), MBMesquite::MappingFunction3D::jacobian(), MBMesquite::TMPQualityMetric::mDerivs2D, MBMesquite::TMPQualityMetric::mDerivs3D, MBMesquite::TMPQualityMetric::mIndices, MSQ_CHKERR, MSQ_ERRZERO, MSQ_SETERR, n, MBMesquite::PatchData::non_slave_node_set(), MBMesquite::ElemSampleQM::sample(), MBMesquite::TMPQualityMetric::targetCalc, targetMetric, MBMesquite::transpose(), MBMesquite::MsqError::UNSUPPORTED_ELEMENT, and MBMesquite::TMPQualityMetric::weight().
{ const Sample s = ElemSampleQM::sample( p_handle ); const size_t e = ElemSampleQM::elem( p_handle ); MsqMeshEntity& p_elem = pd.element_by_index( e ); EntityTopology type = p_elem.get_element_type(); unsigned edim = TopologyInfo::dimension( type ); size_t num_idx = 0; const NodeSet bits = pd.non_slave_node_set( e ); bool rval; if( edim == 3 ) { // 3x3 or 3x2 targets ? const MappingFunction3D* mf = pd.get_mapping_function_3D( type ); if( !mf ) { MSQ_SETERR( err ) ( "No mapping function for element type", MsqError::UNSUPPORTED_ELEMENT ); return false; } MsqMatrix< 3, 3 > A, W, dmdA, d2mdA2[6]; mf->jacobian( pd, e, bits, s, mIndices, mDerivs3D, num_idx, A, err ); MSQ_ERRZERO( err ); targetCalc->get_3D_target( pd, e, s, W, err ); MSQ_ERRZERO( err ); rval = targetMetric->evaluate_with_hess( A, W, value, dmdA, d2mdA2, err ); MSQ_ERRZERO( err ); gradient< 3 >( num_idx, mDerivs3D, dmdA, grad ); Hessian.resize( num_idx * ( num_idx + 1 ) / 2 ); if( num_idx ) hessian< 3 >( num_idx, mDerivs3D, d2mdA2, arrptr( Hessian ) ); #ifdef PRINT_INFO print_info< 3 >( e, s, A, W, A * inverse( W ) ); #endif } else if( edim == 2 ) { #ifdef NUMERICAL_2D_HESSIAN // return finite difference approximation for now return QualityMetric::evaluate_with_Hessian( pd, p_handle, value, indices, grad, Hessian, err ); #else MsqMatrix< 2, 2 > W, A, dmdA, d2mdA2[3]; MsqMatrix< 3, 2 > M; rval = evaluate_surface_common( pd, s, e, bits, mIndices, num_idx, mDerivs2D, W, A, M, err ); if( MSQ_CHKERR( err ) || !rval ) return false; rval = targetMetric->evaluate_with_hess( A, W, value, dmdA, d2mdA2, err ); MSQ_ERRZERO( err ); gradient< 2 >( num_idx, mDerivs2D, M * dmdA, grad ); const size_t n = num_idx * ( num_idx + 1 ) / 2; // calculate 2D hessian hess2d.resize( n ); if( n ) hessian< 2 >( num_idx, mDerivs2D, d2mdA2, arrptr( hess2d ) ); // calculate surface hessian as transform of 2D hessian Hessian.resize( n ); for( size_t i = 0; i < n; ++i ) Hessian[i] = Matrix3D( ( M * hess2d[i] * transpose( M ) ).data() ); #ifdef PRINT_INFO print_info< 2 >( e, s, J, Wp, A * inverse( W ) ); #endif #endif } else { assert( 0 ); return false; } // pass back index list indices.resize( num_idx ); std::copy( mIndices, mIndices + num_idx, indices.begin() ); // apply target weight to value if( !num_idx ) weight( pd, s, e, num_idx, value, 0, 0, 0, err ); else weight( pd, s, e, num_idx, value, arrptr( grad ), 0, arrptr( Hessian ), err ); MSQ_ERRZERO( err ); return rval; }
bool MBMesquite::AWQualityMetric::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 277 of file AWQualityMetric.cpp.
References MBMesquite::arrptr(), MBMesquite::ElemSampleQM::elem(), MBMesquite::PatchData::element_by_index(), MBMesquite::TMPQualityMetric::evaluate_surface_common(), MBMesquite::AWMetric::evaluate_with_hess(), MBMesquite::TargetCalculator::get_3D_target(), MBMesquite::MsqMeshEntity::get_element_type(), MBMesquite::PatchData::get_mapping_function_3D(), MBMesquite::grad(), MBMesquite::inverse(), MBMesquite::MappingFunction3D::jacobian(), MBMesquite::TMPQualityMetric::mDerivs2D, MBMesquite::TMPQualityMetric::mDerivs3D, MBMesquite::TMPQualityMetric::mIndices, MSQ_CHKERR, MSQ_ERRZERO, MSQ_SETERR, MBMesquite::PatchData::non_slave_node_set(), MBMesquite::MsqMatrix< R, C >::row(), MBMesquite::ElemSampleQM::sample(), MBMesquite::TMPQualityMetric::targetCalc, targetMetric, MBMesquite::transpose(), MBMesquite::MsqError::UNSUPPORTED_ELEMENT, and MBMesquite::TMPQualityMetric::weight().
{ const Sample s = ElemSampleQM::sample( p_handle ); const size_t e = ElemSampleQM::elem( p_handle ); MsqMeshEntity& p_elem = pd.element_by_index( e ); EntityTopology type = p_elem.get_element_type(); unsigned edim = TopologyInfo::dimension( type ); size_t num_idx = 0; const NodeSet bits = pd.non_slave_node_set( e ); bool rval; if( edim == 3 ) { // 3x3 or 3x2 targets ? const MappingFunction3D* mf = pd.get_mapping_function_3D( type ); if( !mf ) { MSQ_SETERR( err ) ( "No mapping function for element type", MsqError::UNSUPPORTED_ELEMENT ); return false; } MsqMatrix< 3, 3 > A, W, dmdA, d2mdA2[6]; mf->jacobian( pd, e, bits, s, mIndices, mDerivs3D, num_idx, A, err ); MSQ_ERRZERO( err ); targetCalc->get_3D_target( pd, e, s, W, err ); MSQ_ERRZERO( err ); rval = targetMetric->evaluate_with_hess( A, W, value, dmdA, d2mdA2, err ); MSQ_ERRZERO( err ); gradient< 3 >( num_idx, mDerivs3D, dmdA, grad ); diagonal.resize( num_idx ); hessian_diagonal< 3 >( num_idx, mDerivs3D, d2mdA2, arrptr( diagonal ) ); #ifdef PRINT_INFO print_info< 3 >( e, s, A, W, A * inverse( W ) ); #endif } else if( edim == 2 ) { #ifdef NUMERICAL_2D_HESSIAN // use finite diference approximation for now return QualityMetric::evaluate_with_Hessian_diagonal( pd, p_handle, value, indices, grad, diagonal, err ); #else MsqMatrix< 2, 2 > W, A, dmdA, d2mdA2[3]; MsqMatrix< 3, 2 > M; rval = evaluate_surface_common( pd, s, e, bits, mIndices, num_idx, mDerivs2D, W, A, M, err ); if( MSQ_CHKERR( err ) || !rval ) return false; rval = targetMetric->evaluate_with_hess( A, W, value, dmdA, d2mdA2, err ); MSQ_ERRZERO( err ); gradient< 2 >( num_idx, mDerivs2D, M * dmdA, grad ); diagonal.resize( num_idx ); for( size_t i = 0; i < num_idx; ++i ) { MsqMatrix< 2, 2 > block2d; block2d( 0, 0 ) = transpose( mDerivs2D[i] ) * d2mdA2[0] * mDerivs2D[i]; block2d( 0, 1 ) = transpose( mDerivs2D[i] ) * d2mdA2[1] * mDerivs2D[i]; block2d( 1, 0 ) = block2d( 0, 1 ); block2d( 1, 1 ) = transpose( mDerivs2D[i] ) * d2mdA2[2] * mDerivs2D[i]; MsqMatrix< 3, 2 > p = M * block2d; SymMatrix3D& H = diagonal[i]; H[0] = p.row( 0 ) * transpose( M.row( 0 ) ); H[1] = p.row( 0 ) * transpose( M.row( 1 ) ); H[2] = p.row( 0 ) * transpose( M.row( 2 ) ); H[3] = p.row( 1 ) * transpose( M.row( 1 ) ); H[4] = p.row( 1 ) * transpose( M.row( 2 ) ); H[5] = p.row( 2 ) * transpose( M.row( 2 ) ); } #ifdef PRINT_INFO print_info< 2 >( e, s, J, Wp, A * inverse( W ) ); #endif #endif } else { assert( 0 ); return false; } // pass back index list indices.resize( num_idx ); std::copy( mIndices, mIndices + num_idx, indices.begin() ); // apply target weight to value if( !num_idx ) weight( pd, s, e, num_idx, value, 0, 0, 0, err ); else weight( pd, s, e, num_idx, value, arrptr( grad ), arrptr( diagonal ), 0, err );MSQ_CHKERR( err ); return rval; }
std::string MBMesquite::AWQualityMetric::get_name | ( | ) | const [virtual] |
Implements MBMesquite::QualityMetric.
Definition at line 59 of file AWQualityMetric.cpp.
References MBMesquite::AWMetric::get_name(), and targetMetric.
{ return targetMetric->get_name(); }
AWMetric* MBMesquite::AWQualityMetric::get_target_metric | ( | ) | const [inline] |
Definition at line 103 of file AWQualityMetric.hpp.
References targetMetric.
{ return targetMetric; }
void MBMesquite::AWQualityMetric::set_target_metric | ( | AWMetric * | m | ) | [inline] |
Definition at line 121 of file AWQualityMetric.hpp.
Referenced by evaluate_internal(), evaluate_with_gradient(), evaluate_with_Hessian(), evaluate_with_Hessian_diagonal(), get_name(), get_target_metric(), and set_target_metric().