MOAB: Mesh Oriented datABase
(version 5.4.1)
|
Combines two quality metrics (qMetric1 and qMetric2 defined in the parent class CompositeQualityMetric) by multiplication for two- and three-diminsional elements. Note: This function should not be used to combine a node-based metric with an element-based metric. More...
#include <MultiplyQualityMetric.hpp>
Public Member Functions | |
MultiplyQualityMetric (QualityMetric *qm1, QualityMetric *qm2, MsqError &err) | |
virtual | ~MultiplyQualityMetric () |
MetricType | get_metric_type () const |
std::string | get_name () const |
int | get_negate_flag () const |
1 if metric should be minimized, -1 if metric should be maximized. | |
QualityMetric * | get_first_metric () const |
QualityMetric * | get_second_metric () const |
virtual void | get_evaluations (PatchData &pd, std::vector< size_t > &handles, bool free_vertices_only, MsqError &err) |
Get locations at which metric can be evaluated. | |
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. | |
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 (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 | |
QualityMetric & | metric1 |
QualityMetric & | metric2 |
std::vector< size_t > | mHandles |
std::vector< size_t > | indices1 |
std::vector< size_t > | indices2 |
std::vector< Vector3D > | grad1 |
std::vector< Vector3D > | grad2 |
std::vector< Matrix3D > | Hess1 |
std::vector< Matrix3D > | Hess2 |
Combines two quality metrics (qMetric1 and qMetric2 defined in the parent class CompositeQualityMetric) by multiplication for two- and three-diminsional elements. Note: This function should not be used to combine a node-based metric with an element-based metric.
Definition at line 59 of file MultiplyQualityMetric.hpp.
MultiplyQualityMetric::MultiplyQualityMetric | ( | QualityMetric * | qm1, |
QualityMetric * | qm2, | ||
MsqError & | err | ||
) |
Ensures that qm1 and qm2 are not NULL. If either qm1 or qm2 are valid only on a feasible region, then the composite metric's feasibility flag is set to one. If qm1 and qm2 have different negateFlags, then a warning is printed, and the composite metric's negate flag is set to one. Otherwise, the composite metric's negateFlag is set to qm1's negateFlag (and, thus, qm2's negateFlag).
Definition at line 42 of file MultiplyQualityMetric.cpp.
References MBMesquite::QualityMetric::get_metric_type(), MBMesquite::QualityMetric::get_negate_flag(), MBMesquite::MsqError::INVALID_ARG, and MSQ_SETERR.
: metric1( *qm1 ), metric2( *qm2 ) { if( qm1->get_metric_type() != qm2->get_metric_type() || qm1->get_negate_flag() != qm2->get_negate_flag() ) { MSQ_SETERR( err )( "Incompatible metrics", MsqError::INVALID_ARG ); } }
MultiplyQualityMetric::~MultiplyQualityMetric | ( | ) | [virtual] |
Definition at line 51 of file MultiplyQualityMetric.cpp.
{}
bool MultiplyQualityMetric::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 81 of file MultiplyQualityMetric.cpp.
References MBMesquite::QualityMetric::evaluate(), metric1, metric2, and MSQ_ERRZERO.
{ double val1, val2; bool rval1, rval2; rval1 = metric1.evaluate( pd, handle, val1, err ); MSQ_ERRZERO( err ); rval2 = metric2.evaluate( pd, handle, val2, err ); MSQ_ERRZERO( err ); value = val1 * val2; return rval1 && rval2; }
bool MultiplyQualityMetric::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 115 of file MultiplyQualityMetric.cpp.
References MBMesquite::QualityMetric::evaluate_with_gradient(), grad1, grad2, indices1, indices2, metric1, metric2, and MSQ_ERRZERO.
{ std::vector< size_t >::iterator i; size_t j; double val1, val2; bool rval1, rval2; rval1 = metric1.evaluate_with_gradient( pd, handle, val1, indices1, grad1, err ); MSQ_ERRZERO( err ); rval2 = metric2.evaluate_with_gradient( pd, handle, val2, indices2, grad2, err ); MSQ_ERRZERO( err ); indices.resize( indices1.size() + indices2.size() ); i = std::copy( indices1.begin(), indices1.end(), indices.begin() ); std::copy( indices2.begin(), indices2.end(), i ); std::sort( indices.begin(), indices.end() ); indices.erase( std::unique( indices.begin(), indices.end() ), indices.end() ); gradient.clear(); gradient.resize( indices.size(), Vector3D( 0.0 ) ); for( j = 0; j < indices1.size(); ++j ) { i = std::lower_bound( indices.begin(), indices.end(), indices1[j] ); size_t k = i - indices.begin(); gradient[k] += val2 * grad1[j]; } for( j = 0; j < indices2.size(); ++j ) { i = std::lower_bound( indices.begin(), indices.end(), indices2[j] ); size_t k = i - indices.begin(); gradient[k] += val1 * grad2[j]; } value = val1 * val2; return rval1 && rval2; }
bool MultiplyQualityMetric::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 156 of file MultiplyQualityMetric.cpp.
References MBMesquite::QualityMetric::evaluate_with_Hessian(), grad1, grad2, Hess1, Hess2, indices1, indices2, metric1, metric2, MSQ_ERRZERO, n, N, nr, MBMesquite::outer(), MBMesquite::Matrix3D::outer_product(), and MBMesquite::Matrix3D::plus_transpose_equal().
{ std::vector< size_t >::iterator i; size_t j, r, c, n, h; double val1, val2; bool rval1, rval2; rval1 = metric1.evaluate_with_Hessian( pd, handle, val1, indices1, grad1, Hess1, err ); MSQ_ERRZERO( err ); rval2 = metric2.evaluate_with_Hessian( pd, handle, val2, indices2, grad2, Hess2, err ); MSQ_ERRZERO( err ); // merge index lists indices.resize( indices1.size() + indices2.size() ); i = std::copy( indices1.begin(), indices1.end(), indices.begin() ); std::copy( indices2.begin(), indices2.end(), i ); std::sort( indices.begin(), indices.end() ); indices.erase( std::unique( indices.begin(), indices.end() ), indices.end() ); // calculate grads and convert index lists to indices into output list gradient.clear(); gradient.resize( indices.size(), Vector3D( 0.0 ) ); for( j = 0; j < indices1.size(); ++j ) { i = std::lower_bound( indices.begin(), indices.end(), indices1[j] ); indices1[j] = i - indices.begin(); gradient[indices1[j]] += val2 * grad1[j]; } for( j = 0; j < indices2.size(); ++j ) { i = std::lower_bound( indices.begin(), indices.end(), indices2[j] ); indices2[j] = i - indices.begin(); gradient[indices2[j]] += val1 * grad2[j]; } // allocate space for hessians, and zero it const size_t N = indices.size(); Hessian.clear(); Hessian.resize( N * ( N + 1 ) / 2, Matrix3D( 0.0 ) ); // add hessian terms from first metric n = indices1.size(); h = 0; for( r = 0; r < n; ++r ) { const size_t nr = indices1[r]; for( c = r; c < n; ++c ) { const size_t nc = indices1[c]; Hess1[h] *= val2; if( nr <= nc ) Hessian[N * nr - nr * ( nr + 1 ) / 2 + nc] += Hess1[h]; else Hessian[N * nc - nc * ( nc + 1 ) / 2 + nr].plus_transpose_equal( Hess1[h] ); ++h; } } // add hessian terms from second metric n = indices2.size(); h = 0; for( r = 0; r < n; ++r ) { const size_t nr = indices2[r]; for( c = r; c < n; ++c ) { const size_t nc = indices2[c]; Hess2[h] *= val1; if( nr <= nc ) Hessian[N * nr - nr * ( nr + 1 ) / 2 + nc] += Hess2[h]; else Hessian[N * nc - nc * ( nc + 1 ) / 2 + nr].plus_transpose_equal( Hess2[h] ); ++h; } } // add gradient outer products n = indices1.size(); size_t m = indices2.size(); Matrix3D outer; for( r = 0; r < n; ++r ) { const size_t nr = indices1[r]; for( c = 0; c < m; ++c ) { const size_t nc = indices2[c]; outer.outer_product( grad1[r], grad2[c] ); if( nr == nc ) Hessian[N * nr - nr * ( nr + 1 ) / 2 + nc] += outer.plus_transpose_equal( outer ); else if( nr < nc ) Hessian[N * nr - nr * ( nr + 1 ) / 2 + nc] += outer; else Hessian[N * nc - nc * ( nc + 1 ) / 2 + nr].plus_transpose_equal( outer ); } } value = val1 * val2; return rval1 && rval2; }
bool MultiplyQualityMetric::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 93 of file MultiplyQualityMetric.cpp.
References MBMesquite::QualityMetric::evaluate_with_indices(), indices1, indices2, metric1, metric2, and MSQ_ERRZERO.
{ double val1, val2; bool rval1, rval2; rval1 = metric1.evaluate_with_indices( pd, handle, val1, indices1, err ); MSQ_ERRZERO( err ); rval2 = metric2.evaluate_with_indices( pd, handle, val2, indices2, err ); MSQ_ERRZERO( err ); indices.clear(); std::sort( indices1.begin(), indices1.end() ); std::sort( indices2.begin(), indices2.end() ); std::set_union( indices1.begin(), indices1.end(), indices2.begin(), indices2.end(), std::back_inserter( indices ) ); value = val1 * val2; return rval1 && rval2; }
void MultiplyQualityMetric::get_evaluations | ( | PatchData & | pd, |
std::vector< size_t > & | handles, | ||
bool | free_vertices_only, | ||
MsqError & | err | ||
) | [virtual] |
Get locations at which metric can be evaluated.
Different metrics are evaluated for different things within a patch. For example, an element-based metric will be evaluated once for each element in patch, a vertex-based metric once for each veretx, and a target/sample-point based metric will be evaluated once for each samle point in each element. This method returns a list of handles, one for each location in the patch at which the metric can be evaluated. The handle values are used as input to the evaluate methods.
pd | The patch |
handles | Output list of handles |
free_vertices_only | If true, only pass back evaluation points that depend on at least one free vertex. |
Implements MBMesquite::QualityMetric.
Definition at line 68 of file MultiplyQualityMetric.cpp.
References MBMesquite::QualityMetric::get_evaluations(), MBMesquite::MsqError::INVALID_STATE, metric1, metric2, mHandles, MSQ_ERRRTN, and MSQ_SETERR.
{ metric1.get_evaluations( pd, handles, free_only, err );MSQ_ERRRTN( err ); metric2.get_evaluations( pd, mHandles, free_only, err );MSQ_ERRRTN( err ); if( handles != mHandles ) { MSQ_SETERR( err )( "Incompatible metrics", MsqError::INVALID_STATE ); } }
QualityMetric* MBMesquite::MultiplyQualityMetric::get_first_metric | ( | ) | const [inline] |
QualityMetric::MetricType MultiplyQualityMetric::get_metric_type | ( | ) | const [virtual] |
Implements MBMesquite::QualityMetric.
Definition at line 53 of file MultiplyQualityMetric.cpp.
References MBMesquite::QualityMetric::get_metric_type(), and metric1.
{ return metric1.get_metric_type(); }
std::string MultiplyQualityMetric::get_name | ( | ) | const [virtual] |
Implements MBMesquite::QualityMetric.
Definition at line 58 of file MultiplyQualityMetric.cpp.
References MBMesquite::QualityMetric::get_name(), metric1, and metric2.
int MultiplyQualityMetric::get_negate_flag | ( | ) | const [virtual] |
1 if metric should be minimized, -1 if metric should be maximized.
Implements MBMesquite::QualityMetric.
Definition at line 63 of file MultiplyQualityMetric.cpp.
References MBMesquite::QualityMetric::get_negate_flag(), and metric1.
{ return metric1.get_negate_flag(); }
QualityMetric* MBMesquite::MultiplyQualityMetric::get_second_metric | ( | ) | const [inline] |
std::vector< Vector3D > MBMesquite::MultiplyQualityMetric::grad1 [mutable, private] |
Definition at line 123 of file MultiplyQualityMetric.hpp.
Referenced by evaluate_with_gradient(), and evaluate_with_Hessian().
std::vector< Vector3D > MBMesquite::MultiplyQualityMetric::grad2 [mutable, private] |
Definition at line 123 of file MultiplyQualityMetric.hpp.
Referenced by evaluate_with_gradient(), and evaluate_with_Hessian().
std::vector< Matrix3D > MBMesquite::MultiplyQualityMetric::Hess1 [mutable, private] |
Definition at line 124 of file MultiplyQualityMetric.hpp.
Referenced by evaluate_with_Hessian().
std::vector< Matrix3D > MBMesquite::MultiplyQualityMetric::Hess2 [mutable, private] |
Definition at line 124 of file MultiplyQualityMetric.hpp.
Referenced by evaluate_with_Hessian().
std::vector< size_t > MBMesquite::MultiplyQualityMetric::indices1 [mutable, private] |
Definition at line 122 of file MultiplyQualityMetric.hpp.
Referenced by evaluate_with_gradient(), evaluate_with_Hessian(), and evaluate_with_indices().
std::vector< size_t > MBMesquite::MultiplyQualityMetric::indices2 [mutable, private] |
Definition at line 122 of file MultiplyQualityMetric.hpp.
Referenced by evaluate_with_gradient(), evaluate_with_Hessian(), and evaluate_with_indices().
Definition at line 119 of file MultiplyQualityMetric.hpp.
Referenced by evaluate(), evaluate_with_gradient(), evaluate_with_Hessian(), evaluate_with_indices(), get_evaluations(), get_first_metric(), get_metric_type(), get_name(), and get_negate_flag().
Definition at line 120 of file MultiplyQualityMetric.hpp.
Referenced by evaluate(), evaluate_with_gradient(), evaluate_with_Hessian(), evaluate_with_indices(), get_evaluations(), get_name(), and get_second_metric().
std::vector< size_t > MBMesquite::MultiplyQualityMetric::mHandles [mutable, private] |
Definition at line 121 of file MultiplyQualityMetric.hpp.
Referenced by get_evaluations().