MOAB: Mesh Oriented datABase  (version 5.3.0)
MBMesquite::QualityAssessor Class Reference

A QualityAssessor instance can be inserted into an InstructionQueue to calculate and summarize registered QualityMetric or QualityMetrics for the mesh. More...

#include <QualityAssessor.hpp>

+ Inheritance diagram for MBMesquite::QualityAssessor:
+ Collaboration diagram for MBMesquite::QualityAssessor:

Classes

class  Assessor
 Per-metric QualityAssessor data. More...
struct  Data

Public Types

typedef std::list< Assessor * > list_type

Public Member Functions

MESQUITE_EXPORT QualityAssessor (bool print_summary_to_std_out=true, bool free_elements_only=true, const char *inverted_element_tag_name=0, std::string name=std::string())
 Simple consturctor. Metrics registered separately.
MESQUITE_EXPORT QualityAssessor (std::ostream &output_stream, bool free_elements_only=true, const char *inverted_element_tag_name=0, std::string name=std::string())
 Simple consturctor. Metrics registered separately.
MESQUITE_EXPORT QualityAssessor (std::ostream &output_stream, QualityMetric *metric, int histogram_intervals=0, double power_mean=0.0, bool free_elements_only=true, const char *metric_value_tag_name=0, const char *inverted_element_tag_name=0, std::string name=std::string())
 Construct and register a QualityMetric.
MESQUITE_EXPORT QualityAssessor (QualityMetric *metric, int histogram_intervals=0, double power_mean=0.0, bool free_elements_only=true, const char *metric_value_tag_name=0, bool print_summary_to_std_out=true, const char *inverted_element_tag_name=0, std::string name=std::string())
 Construct and register a QualityMetric.
virtual MESQUITE_EXPORT ~QualityAssessor ()
MESQUITE_EXPORT void set_name (std::string name)
 Provides a name to the QualityAssessor (use it for default name in constructor).
virtual MESQUITE_EXPORT std::string get_name () const
 Retrieves the QualityAssessor name. A default name should be set in the constructor.
MESQUITE_EXPORT void measure_free_samples_only (bool yesno)
 All elements or only improvable ones.
MESQUITE_EXPORT bool measuring_free_samples_only () const
 All elements or only improvable ones.
MESQUITE_EXPORT void add_quality_assessment (QualityMetric *metric, int histogram_intervals=0, double power_mean=0.0, const char *metric_value_tag_name=0, const char *metric_label=0)
 Register a QualityMetric for use in quality assessment.
MESQUITE_EXPORT void set_stopping_assessment (QualityMetric *metric, int histogram_intervals=0, double power_mean=0.0, const char *metric_value_tag_name=0, const char *metric_label=0)
 Same as add_quality_assessment, except that the average metric value is also used as the return value from loop_over_mesh. Specify a power_mean value to control which average is used.
MESQUITE_EXPORT void add_histogram_assessment (QualityMetric *qm, double min, double max, int intervals, double power_mean=0.0, const char *metric_value_tag_name=0, const char *metric_label=0)
 Register a QualityMetric for use in quality assessment.
virtual MESQUITE_EXPORT void initialize_queue (MeshDomainAssoc *mesh_and_domain, const Settings *settings, MsqError &err)
virtual MESQUITE_EXPORT double loop_over_mesh (MeshDomainAssoc *mesh_and_domain, const Settings *settings, MsqError &err)
 Does one sweep over the mesh and assess the quality with the metrics previously added.
virtual MESQUITE_EXPORT double loop_over_mesh (ParallelMesh *mesh, MeshDomain *domain, const Settings *settings, MsqError &err)
 Does one sweep over the mesh and assess the quality with the metrics previously added.
MESQUITE_EXPORT void disable_printing_results ()
 Do not print results of assessment.
MESQUITE_EXPORT void print_summary (std::ostream &stream) const
 Print accumulated summary data to specified stream.
MESQUITE_EXPORT bool invalid_elements () const
MESQUITE_EXPORT bool get_inverted_element_count (int &inverted_elems, int &inverted_samples, MsqError &err)
MESQUITE_EXPORT void reset_data ()
 Reset calculated data.
MESQUITE_EXPORT void scale_histograms (QualityAssessor *optimal)
MESQUITE_EXPORT void tag_inverted_elements (std::string tagname)
MESQUITE_EXPORT void dont_tag_inverted_elements ()
MESQUITE_EXPORT bool tagging_inverted_elements () const
MESQUITE_EXPORT void tag_fixed_elements (std::string tagname)
MESQUITE_EXPORT void dont_tag_fixed_elements ()
MESQUITE_EXPORT bool tagging_fixed_elements () const
MESQUITE_EXPORT const Assessorget_results (QualityMetric *metric) const
 Request summary data for a specific QualityMetric This method allows the application to request the summary data for a metric it has registered with the QualityAssessor. If the passed QualityMetric has not been registered with the QualityAssessor instance, NULL is returned.
MESQUITE_EXPORT const Assessorget_results (const char *metric_name) const
 Request summary data for a specific QualityMetric This method allows the application to request the summary data for a metric it has registered with the QualityAssessor. If the passed QualityMetric has not been registered with the QualityAssessor instance, NULL is returned.
const list_typeget_all_results () const
 Get list of all summary data. Return a const reference to the internal list of calculated data.
MESQUITE_EXPORT QualityAssessor (const QualityAssessor &copy)
MESQUITE_EXPORT QualityAssessoroperator= (const QualityAssessor &copy)

Private Member Functions

double loop_over_mesh_internal (MeshDomainAssoc *mesh_and_domain, const Settings *settings, ParallelHelper *helper, MsqError &err)
 Common code for serial and parallel loop_over_mesh.
list_type::iterator find_or_add (QualityMetric *qm, const char *label=0)
list_type::iterator find_stopping_assessment ()
TagHandle get_tag (Mesh *mesh, std::string name, Mesh::TagType type, unsigned size, MsqError &err)
int get_terminal_width () const

Static Private Member Functions

static std::string element_name_as_string (int enum_name)
static double round_to_3_significant_digits (double number)

Private Attributes

DatamyData
std::string qualityAssessorName
list_type assessList
std::ostream & outputStream
bool printSummary
std::string invertedTagName
std::string fixedTagName
bool skipFixedSamples
int elementTypeCount [MIXED-POLYGON+1]
bool invalid_values

Detailed Description

A QualityAssessor instance can be inserted into an InstructionQueue to calculate and summarize registered QualityMetric or QualityMetrics for the mesh.

QualityAssessor provides a summary of the mesh quality. An instance of QualityAssessor may be inserted in the InstructionQueue at any point to print a summary of the mesh quality at that time during the optimization. The application is expected to register QualityMetric instances to be used in assessing the mesh quality. If no QualityMetrics are registered, the only assessment that will be performed is a simple count of inverted elements.

The "stopping assessor" and "stopping function", if set, determinte the value reported to Mesquite for the overall run of of the QualityAssessor.

All summary data except the histogram and custom power-means is accumulated for all registered metrics. QualityAssessment data can be obtained through three different mechanisms:

  • QualityAssessor can print a summary to std::out or a specified output stream after they are calculated.
  • The get_results and get_all_results methods can be used to obtain the sumary data programatically.
  • Quality measures for element-based or vertex-based metrics can be stored on the corresponding entities using "tags".

Definition at line 91 of file QualityAssessor.hpp.


Member Typedef Documentation

Definition at line 531 of file QualityAssessor.hpp.


Constructor & Destructor Documentation

MBMesquite::QualityAssessor::QualityAssessor ( bool  print_summary_to_std_out = true,
bool  free_elements_only = true,
const char *  inverted_element_tag_name = 0,
std::string  name = std::string() 
)

Simple consturctor. Metrics registered separately.

Parameters:
print_summary_to_std_outIf true, summary of mesh quality will be written to std::out. If false, quality assessment will be available via the get_results and get_all_results methods, but will not be printed.
free_elements_onlyIf true, only quality values that depend on at least one free vertex will be uses.
inverted_element_tag_nameIf a non-null value is specified, an integer tag with the specified name will be used it store value of 0 for normal elements and 1 for inverted elements.
nameName to include in output. Useful if several QualityAssessors are in use at the same time.

Definition at line 78 of file QualityAssessor.cpp.

References MBMesquite::default_name(), elementTypeCount, MBMesquite::MIXED, MBMesquite::POLYGON, qualityAssessorName, and tag_inverted_elements().

    : myData( new Data ), qualityAssessorName( p_name ), outputStream( std::cout ), printSummary( p_print_summary ),
      skipFixedSamples( free_only )
{
    if( inverted_tag_name ) tag_inverted_elements( inverted_tag_name );

    if( qualityAssessorName.empty() ) qualityAssessorName = default_name( free_only );

    for( int i = POLYGON; i <= MIXED; i++ )
        elementTypeCount[i - POLYGON] = 0;
}
MBMesquite::QualityAssessor::QualityAssessor ( std::ostream &  output_stream,
bool  free_elements_only = true,
const char *  inverted_element_tag_name = 0,
std::string  name = std::string() 
)

Simple consturctor. Metrics registered separately.

Parameters:
output_streamIO stream to which to write a summary of the mesh quality.
free_elements_onlyIf true, only quality values that depend on at least one free vertex will be uses.
inverted_element_tag_nameIf a non-null value is specified, an integer tag with the specified name will be used it store value of 0 for normal elements and 1 for inverted elements.
nameName to include in output. Useful if several QualityAssessors are in use at the same time.

Definition at line 91 of file QualityAssessor.cpp.

References MBMesquite::default_name(), elementTypeCount, MBMesquite::MIXED, MBMesquite::POLYGON, qualityAssessorName, and tag_inverted_elements().

    : myData( new Data ), qualityAssessorName( name ), outputStream( stream ), printSummary( true ),
      skipFixedSamples( free_only )
{
    if( inverted_tag_name ) tag_inverted_elements( inverted_tag_name );

    if( qualityAssessorName.empty() ) qualityAssessorName = default_name( free_only );

    for( int i = POLYGON; i <= MIXED; i++ )
        elementTypeCount[i - POLYGON] = 0;
}
MBMesquite::QualityAssessor::QualityAssessor ( std::ostream &  output_stream,
QualityMetric metric,
int  histogram_intervals = 0,
double  power_mean = 0.0,
bool  free_elements_only = true,
const char *  metric_value_tag_name = 0,
const char *  inverted_element_tag_name = 0,
std::string  name = std::string() 
)

Construct and register a QualityMetric.

Parameters:
output_streamIO stream to which to write a summary of the mesh quality.
metricQualtiyMetric to register for use in assessing mesh quality. Will also be used as the "stopping assessment".
historgram_intervalsIf non-zero, a histogram of quality metric values composed of the specified number of intervals will be generated.
power_meanIf non-zero, in addition to the normal summary statistics for the quality metric, an additional general power mean with the specified power will be calculated.
metric_value_tag_nameIf a non-null value is specified, a tag with the specified name will be populated with quality values for individual elements or vertices if metric is an element-based or vertex- based metric. If metric is not element-based or vertex-based, this argument has no effect.
free_elements_onlyIf true, only quality values that depend on at least one free vertex will be uses.
inverted_element_tag_nameIf a non-null value is specified, an integer tag with the specified name will be used it store value of 0 for normal elements and 1 for inverted elements.
nameName to include in output. Useful if several QualityAssessors are in use at the same time.

Definition at line 104 of file QualityAssessor.cpp.

References MBMesquite::default_name(), elementTypeCount, MBMesquite::MIXED, MBMesquite::POLYGON, qualityAssessorName, set_stopping_assessment(), and tag_inverted_elements().

    : myData( new Data ), qualityAssessorName( name ), outputStream( output_stream ), printSummary( true ),
      skipFixedSamples( free_only )
{
    if( inverted_tag_name ) tag_inverted_elements( inverted_tag_name );

    if( qualityAssessorName.empty() ) qualityAssessorName = default_name( free_only );

    set_stopping_assessment( metric, histogram_intervals, power_mean, metric_value_tag_name );

    for( int i = POLYGON; i <= MIXED; i++ )
        elementTypeCount[i - POLYGON] = 0;
}
MBMesquite::QualityAssessor::QualityAssessor ( QualityMetric metric,
int  histogram_intervals = 0,
double  power_mean = 0.0,
bool  free_elements_only = true,
const char *  metric_value_tag_name = 0,
bool  print_summary_to_std_out = true,
const char *  inverted_element_tag_name = 0,
std::string  name = std::string() 
)

Construct and register a QualityMetric.

Parameters:
print_summary_to_std_outIf true, summary of mesh quality will be written to std::out. If false, quality assessment will be available via the get_results and get_all_results methods, but will not be printed.
metricQualtiyMetric to register for use in assessing mesh quality. Will also be used as the "stopping assessment".
historgram_intervalsIf non-zero, a histogram of quality metric values composed of the specified number of intervals will be generated.
power_meanIf non-zero, in addition to the normal summary statistics for the quality metric, an additional general power mean with the specified power will be calculated.
metric_value_tag_nameIf a non-null value is specified, a tag with the specified name will be populated with quality values for individual elements or vertices if metric is an element-based or vertex- based metric. If metric is not element-based or vertex-based, this argument has no effect.
free_elements_onlyIf true, only quality values that depend on at least one free vertex will be uses.
inverted_element_tag_nameIf a non-null value is specified, an integer tag with the specified name will be used it store value of 0 for normal elements and 1 for inverted elements.
nameName to include in output. Useful if several QualityAssessors are in use at the same time.

Definition at line 120 of file QualityAssessor.cpp.

References MBMesquite::default_name(), elementTypeCount, MBMesquite::MIXED, MBMesquite::POLYGON, qualityAssessorName, set_stopping_assessment(), and tag_inverted_elements().

    : myData( new Data ), qualityAssessorName( name ), outputStream( std::cout ), printSummary( p_print_summary ),
      skipFixedSamples( free_only )
{
    if( inverted_tag_name ) tag_inverted_elements( inverted_tag_name );

    if( qualityAssessorName.empty() ) qualityAssessorName = default_name( free_only );

    set_stopping_assessment( metric, histogram_intervals, power_mean, metric_value_tag_name );

    for( int i = POLYGON; i <= MIXED; i++ )
        elementTypeCount[i - POLYGON] = 0;
}

Definition at line 178 of file QualityAssessor.cpp.

References assessList, myData, MBMesquite::QualityAssessor::Assessor::referenceCount, and MBMesquite::QualityAssessor::Data::referenceCount.

{
    list_type::iterator iter;
    for( iter = assessList.begin(); iter != assessList.end(); ++iter )
    {
        Assessor* assessor = *iter;
        if( 0 == --assessor->referenceCount ) delete assessor;
    }
    if( 0 == --myData->referenceCount ) delete myData;
}

Definition at line 136 of file QualityAssessor.cpp.

References assessList, elementTypeCount, MBMesquite::MIXED, myData, MBMesquite::POLYGON, and MBMesquite::QualityAssessor::Data::referenceCount.

    : myData( copy.myData ), qualityAssessorName( copy.qualityAssessorName ), assessList( copy.assessList ),
      outputStream( copy.outputStream ), printSummary( copy.printSummary ), invertedTagName( copy.invertedTagName ),
      fixedTagName( copy.fixedTagName ), skipFixedSamples( copy.skipFixedSamples )

{
    list_type::iterator iter;
    for( iter = assessList.begin(); iter != assessList.end(); ++iter )
        ( *iter )->referenceCount++;
    myData->referenceCount++;

    for( int i = POLYGON; i <= MIXED; i++ )
        elementTypeCount[i - POLYGON] = copy.elementTypeCount[i - POLYGON];
}

Member Function Documentation

void MBMesquite::QualityAssessor::add_histogram_assessment ( QualityMetric metric,
double  min_val,
double  max_val,
int  intervals,
double  power_mean = 0.0,
const char *  tag_name = 0,
const char *  label = 0 
)

Register a QualityMetric for use in quality assessment.

Add a quality metric to the list of metrics used to assess the quality of the mesh. Specify more parameters controlling histogram.

Parameters:
metricQualtiyMetric to register for use in assessing mesh quality. Will also be used as the "stopping assessment".
minMinimum of histogram rnage.
maxMaximum of histogram range.
intervalsHistogram intervals.
power_meanIf non-zero, in addition to the normal summary statistics for the quality metric, an additional general power mean with the specified power will be calculated.
metric_value_tag_nameIf a non-null value is specified, a tag with the specified name will be populated with quality values for individual elements or vertices if metric is an element-based or vertex- based metric. If metric is not element-based or vertex-based, this argument has no effect.
inverted_element_tag_nameIf a non-null value is specified, an integer tag with the specified name will be used it store value of 0 for normal elements and 1 for inverted elements.

Checks first to see if the QualityMetric, qm, has been added to this QualityAssessor, and if it has not, adds it. It then adds HISTOGRAM as a QAFunciton for that metric. It then sets the minimum and maximum values for the histogram.

Parameters:
qmPointer to the QualityMetric to be used in histogram.
min_val(double) Minimum range of histogram.
max_val(double) Maximum range of histogram.
intervalsNumber of histogram intervals

Definition at line 314 of file QualityAssessor.cpp.

References find_or_add().

Referenced by QualityAssessorTest::test_histogram_known_range(), and QualityAssessorTest::test_modify_metric().

{
    if( intervals < 1 ) intervals = 1;
    list_type::iterator i = find_or_add( metric, label );
    ( *i )->pMean         = power_mean;
    ( *i )->histMin       = min_val;
    ( *i )->histMax       = max_val;
    ( *i )->haveHistRange = min_val < max_val;
    ( *i )->histogram.resize( intervals + 2 );
    if( !tag_name )
        ( *i )->tagName.clear();
    else
        ( *i )->tagName = tag_name;
}
void MBMesquite::QualityAssessor::add_quality_assessment ( QualityMetric metric,
int  histogram_intervals = 0,
double  power_mean = 0.0,
const char *  metric_value_tag_name = 0,
const char *  metric_label = 0 
)

Register a QualityMetric for use in quality assessment.

Add a quality metric to the list of metrics used to assess the quality of the mesh.

Parameters:
metricQualtiyMetric to register for use in assessing mesh quality. Will also be used as the "stopping assessment".
historgram_intervalsIf non-zero, a histogram of quality metric values composed of the specified number of intervals will be generated.
power_meanIf non-zero, in addition to the normal summary statistics for the quality metric, an additional general power mean with the specified power will be calculated.
metric_value_tag_nameIf a non-null value is specified, a tag with the specified name will be populated with quality values for individual elements or vertices if metric is an element-based or vertex- based metric. If metric is not element-based or vertex-based, this argument has no effect.
inverted_element_tag_nameIf a non-null value is specified, an integer tag with the specified name will be used it store value of 0 for normal elements and 1 for inverted elements.

Definition at line 223 of file QualityAssessor.cpp.

References find_or_add().

Referenced by BCDTest::compare_bcd(), do_smoother(), main(), run(), MBMesquite::PaverMinEdgeLengthWrapper::run_wrapper(), MBMesquite::SizeAdaptShapeWrapper::run_wrapper(), MBMesquite::ViscousCFDTetShapeWrapper::run_wrapper(), MBMesquite::ShapeImprovementWrapper::run_wrapper(), MBMesquite::ShapeImprover::run_wrapper(), MBMesquite::LaplaceWrapper::run_wrapper(), MBMesquite::UntangleWrapper::run_wrapper(), ParShapeImprover::ParShapeImprovementWrapper::run_wrapper(), MBMesquite::DeformingDomainWrapper::run_wrapper(), smooth_mixed_mesh(), VertexCullingRegressionTest::test_laplacian_smoothing_with_cull(), QualityAssessorTest::test_modify_metric(), and QualityAssessorTest::test_power_mean().

{
    list_type::iterator i = find_or_add( metric, label );
    ( *i )->pMean         = power_mean;
    if( histogram_intervals > 0 )
        ( *i )->histogram.resize( histogram_intervals + 2 );
    else
        ( *i )->histogram.clear();
    ( *i )->haveHistRange = false;
    if( !tag_name )
        ( *i )->tagName.clear();
    else
        ( *i )->tagName = tag_name;
}

Definition at line 368 of file QualityAssessor.hpp.

References fixedTagName.

    {
        fixedTagName.clear();
    }
std::string MBMesquite::QualityAssessor::element_name_as_string ( int  enum_name) [static, private]

Definition at line 1608 of file QualityAssessor.cpp.

References MBMesquite::HEXAHEDRON, MBMesquite::MIXED, MBMesquite::POLYGON, MBMesquite::POLYHEDRON, MBMesquite::PRISM, MBMesquite::PYRAMID, MBMesquite::QUADRILATERAL, MBMesquite::SEPTAHEDRON, MBMesquite::TETRAHEDRON, and MBMesquite::TRIANGLE.

Referenced by print_summary().

{
    std::string str_value = "";

    switch( enum_name )
    {
        case POLYGON:
            str_value.assign( "polygon" );
            break;
        case TRIANGLE:
            str_value.assign( "triangle" );
            break;
        case QUADRILATERAL:
            str_value.assign( "quadrilateral" );
            break;
        case POLYHEDRON:
            str_value.assign( "polyhedron" );
            break;
        case TETRAHEDRON:
            str_value.assign( "tetrahedron" );
            break;
        case HEXAHEDRON:
            str_value.assign( "hexahedron" );
            break;
        case PRISM:
            str_value.assign( "prism" );
            break;
        case SEPTAHEDRON:
            str_value.assign( "septahedron" );
            break;
        case MIXED:
            str_value.assign( "mixed" );
            break;
        case PYRAMID:
            str_value.assign( "pyramid" );
            break;
    }

    return str_value;
}
QualityAssessor::list_type::iterator MBMesquite::QualityAssessor::find_or_add ( QualityMetric qm,
const char *  label = 0 
) [private]

Find an Assessor corresponding to the passed QualityMetric, or create it if is not found in the list.

Definition at line 239 of file QualityAssessor.cpp.

References assessList, MBMesquite::QualityMetric::get_metric_type(), MBMesquite::QualityAssessor::Assessor::referenceCount, and MBMesquite::QualityMetric::VERTEX_BASED.

Referenced by add_histogram_assessment(), add_quality_assessment(), and set_stopping_assessment().

{
    list_type::iterator iter;

    // If metric is already in list, find it
    for( iter = assessList.begin(); iter != assessList.end(); ++iter )
        if( ( *iter )->qualMetric == qm ) break;

    // If metric not found in list, add it
    if( iter == assessList.end() )
    {
        Assessor* new_assessor       = new Assessor( qm, label );
        new_assessor->referenceCount = 1;
        if( qm->get_metric_type() == QualityMetric::VERTEX_BASED )
        {
            assessList.push_back( new_assessor );
            iter = --assessList.end();
        }
        else
        {
            assessList.push_front( new_assessor );
            iter = assessList.begin();
        }
    }

    return iter;
}
QualityAssessor::list_type::iterator MBMesquite::QualityAssessor::find_stopping_assessment ( ) [private]

Find an Assessor corresponding to the passed QualityMetric, or create it if is not found in the list.

Definition at line 267 of file QualityAssessor.cpp.

References assessList.

Referenced by loop_over_mesh_internal(), and set_stopping_assessment().

{
    list_type::iterator iter;
    for( iter = assessList.begin(); iter != assessList.end(); ++iter )
        if( ( *iter )->stopping_function() ) break;
    return iter;
}

Get list of all summary data. Return a const reference to the internal list of calculated data.

Definition at line 555 of file QualityAssessor.hpp.

References assessList.

    {
        return assessList;
    }
bool MBMesquite::QualityAssessor::get_inverted_element_count ( int &  inverted_elems,
int &  inverted_samples,
MsqError err 
)

Provides the number of inverted elements, inverted_elmes, and the number of elements whose orientation can not be determined, undefined_elems. Returns false if this information is not yet available. Returns true, otherwise.

Definition at line 210 of file QualityAssessor.cpp.

References MBMesquite::MsqError::INVALID_STATE, MBMesquite::QualityAssessor::Data::invertedElementCount, MBMesquite::QualityAssessor::Data::invertedSampleCount, MSQ_SETERR, and myData.

Referenced by main(), MBMesquite::ShapeImprover::run_wrapper(), QualityAssessorTest::test_inverted_count(), QualityAssessorTest::test_print_inverted(), and uwt().

{
    if( myData->invertedElementCount == -1 )
    {
        MSQ_SETERR( err )
        ( "Number of inverted elements has not yet been calculated.", MsqError::INVALID_STATE );
        return false;
    }
    inverted_elems   = myData->invertedElementCount;
    inverted_samples = myData->invertedSampleCount;
    return true;
}
virtual MESQUITE_EXPORT std::string MBMesquite::QualityAssessor::get_name ( ) const [inline, virtual]

Retrieves the QualityAssessor name. A default name should be set in the constructor.

Implements MBMesquite::Instruction.

Definition at line 203 of file QualityAssessor.hpp.

References qualityAssessorName.

    {
        return qualityAssessorName;
    }

Request summary data for a specific QualityMetric This method allows the application to request the summary data for a metric it has registered with the QualityAssessor. If the passed QualityMetric has not been registered with the QualityAssessor instance, NULL is returned.

Definition at line 1130 of file QualityAssessor.cpp.

References assessList.

Referenced by ParShapeImprover::count_invalid_elements(), main(), run(), MBMesquite::ViscousCFDTetShapeWrapper::run_wrapper(), QualityAssessorTest::test_basic_stats_element(), QualityAssessorTest::test_basic_stats_sample(), QualityAssessorTest::test_basic_stats_vertex(), QualityAssessorTest::test_free_only(), QualityAssessorTest::test_histogram_known_range(), QualityAssessorTest::test_histogram_unknown_range(), QualityAssessorTest::test_invalid_count(), QualityAssessorTest::test_modify_metric(), QualityAssessorTest::test_power_mean(), and QualityAssessorTest::test_print_stats().

{
    list_type::const_iterator iter;
    for( iter = assessList.begin(); iter != assessList.end(); ++iter )
        if( ( *iter )->get_metric() == metric ) return *iter;
    return 0;
}
const QualityAssessor::Assessor * MBMesquite::QualityAssessor::get_results ( const char *  metric_name) const

Request summary data for a specific QualityMetric This method allows the application to request the summary data for a metric it has registered with the QualityAssessor. If the passed QualityMetric has not been registered with the QualityAssessor instance, NULL is returned.

Definition at line 1138 of file QualityAssessor.cpp.

References assessList.

{
    list_type::const_iterator iter;
    for( iter = assessList.begin(); iter != assessList.end(); ++iter )
        if( ( *iter )->get_label() == name ) return *iter;
    return 0;
}
TagHandle MBMesquite::QualityAssessor::get_tag ( Mesh mesh,
std::string  name,
Mesh::TagType  type,
unsigned  size,
MsqError err 
) [private]

Find or create tag

Definition at line 330 of file QualityAssessor.cpp.

References MBMesquite::MsqError::clear(), MBMesquite::MsqError::error_code(), MSQ_ERRZERO, MSQ_SETERR, MBMesquite::MsqError::TAG_ALREADY_EXISTS, MBMesquite::Mesh::tag_create(), MBMesquite::Mesh::tag_get(), MBMesquite::MsqError::TAG_NOT_FOUND, and MBMesquite::Mesh::tag_properties().

Referenced by loop_over_mesh_internal().

{
    TagHandle tag = mesh->tag_get( name, err );
    if( !err )
    {
        Mesh::TagType exist_type;
        std::string junk;
        unsigned exist_size;
        mesh->tag_properties( tag, junk, exist_type, exist_size, err );
        MSQ_ERRZERO( err );
        if( type != exist_type || size != exist_size )
        {
            MSQ_SETERR( err )
            ( MsqError::TAG_ALREADY_EXISTS, "Tag \"%s\" exists with incorrect type or length.", name.c_str() );
        }
    }
    else if( err.error_code() == MsqError::TAG_NOT_FOUND )
    {
        err.clear();
        tag = mesh->tag_create( name, type, size, 0, err );
        MSQ_ERRZERO( err );
    }
    else
    {
        MSQ_ERRZERO( err );
    }

    return tag;
}

Try to determine if output stream is a terminal and if so, the width of that terminal. Returns zero if width cannot be determined.

Definition at line 1585 of file QualityAssessor.cpp.

References outputStream.

Referenced by print_summary(), and scale_histograms().

{
#ifdef TIOCGWINSZ
    int fd = -1;
    if( &outputStream == &std::cout )
        fd = fileno( stdout );
    else if( &outputStream == &std::cerr )
        fd = fileno( stderr );
#ifdef FSTREAM_HAS_FD
    else if( std::ofstream* f = dynamic_cast< std::ofstream* >( &outputStream ) )
        fd = f->rdbuf()->fd();
#endif

    if( fd >= 0 )
    {
        struct winsize ws;
        if( ioctl( fd, TIOCGWINSZ, &ws ) >= 0 ) return ws.ws_col;
    }
#endif

    return 0;
}
void MBMesquite::QualityAssessor::initialize_queue ( MeshDomainAssoc mesh_and_domain,
const Settings settings,
MsqError err 
) [virtual]

Called for all instructions in queue before loop_over_mesh is called for any insetruction in queue. Default behavior is to do nothing.

Implements MBMesquite::Instruction.

Definition at line 360 of file QualityAssessor.cpp.

References assessList, and MSQ_ERRRTN.

{
    for( list_type::iterator i = assessList.begin(); i != assessList.end(); ++i )
    {
        ( *i )->get_metric()->initialize_queue( mesh_and_domain, settings, err );MSQ_ERRRTN( err );
    }
}

True if any metric evaluated to an invalid value for any element

Definition at line 772 of file QualityAssessor.cpp.

References assessList.

Referenced by main(), run_example(), and run_smoother().

{
    bool result = false;
    list_type::const_iterator iter;
    for( iter = assessList.begin(); iter != assessList.end(); ++iter )
        if( ( *iter )->get_invalid_element_count() ) result = true;
    return result;
}
double MBMesquite::QualityAssessor::loop_over_mesh ( MeshDomainAssoc mesh_and_domain,
const Settings settings,
MsqError err 
) [virtual]

Does one sweep over the mesh and assess the quality with the metrics previously added.

Computes the quality data for a given MeshSet, ms. What quality information is calculated, depends on what has been requested through the use of the QualityAssessor constructor, add_quality_assessment(), and set_stopping_assessment(). The resulting data is printed in a table unless disable_printing_results() has been called. The double returned depends on the QualityMetric and QAFunction "return" combination, which can be set using set_stopping_assessemnt().

Parameters:
ms(const MeshSet &) MeshSet used for quality assessment.

Implements MBMesquite::Instruction.

Definition at line 379 of file QualityAssessor.cpp.

References loop_over_mesh_internal().

Referenced by QualityAssessorTest::test_basic_stats_element(), QualityAssessorTest::test_basic_stats_sample(), QualityAssessorTest::test_basic_stats_vertex(), SphericalGeometryTest::test_cg_mesh_cond_sphere(), QualityAssessorTest::test_histogram_known_range(), QualityAssessorTest::test_histogram_unknown_range(), QualityAssessorTest::test_invalid_count(), QualityAssessorTest::test_inverted_count(), SphericalGeometryTest::test_lapl_geo_sphere(), QualityAssessorTest::test_output_control(), PlanarGeometryTest::test_plane_quad_tangled(), PlanarGeometryTest::test_plane_tri_tangled(), PlanarGeometryTest::test_plane_tri_xz(), QualityAssessorTest::test_power_mean(), QualityAssessorTest::test_print_inverted(), QualityAssessorTest::test_print_name(), QualityAssessorTest::test_print_stats(), SphericalGeometryTest::test_smart_lapl_sphere(), QualityAssessorTest::test_tag_element(), QualityAssessorTest::test_tag_inverted(), and QualityAssessorTest::test_tag_vertex().

{
    return loop_over_mesh_internal( mesh_and_domain, settings, NULL, err );
}
double MBMesquite::QualityAssessor::loop_over_mesh ( ParallelMesh mesh,
MeshDomain domain,
const Settings settings,
MsqError err 
) [virtual]

Does one sweep over the mesh and assess the quality with the metrics previously added.

Computes the quality data for a given MeshSet, ms. What quality information is calculated, depends on what has been requested through the use of the QualityAssessor constructor, add_quality_assessment(), and set_stopping_assessment(). The resulting data is printed in a table unless disable_printing_results() has been called. The double returned depends on the QualityMetric and QAFunction "return" combination, which can be set using set_stopping_assessemnt().

Parameters:
ms(const MeshSet &) MeshSet used for quality assessment.

Reimplemented from MBMesquite::Instruction.

Definition at line 395 of file QualityAssessor.cpp.

References loop_over_mesh_internal().

{
    MeshDomainAssoc mesh_and_domain = MeshDomainAssoc( (Mesh*)mesh, domain, false, true );
    return loop_over_mesh_internal( &mesh_and_domain, settings, mesh->get_parallel_helper(), err );
}
double MBMesquite::QualityAssessor::loop_over_mesh_internal ( MeshDomainAssoc mesh_and_domain,
const Settings settings,
ParallelHelper helper,
MsqError err 
) [private]

Common code for serial and parallel loop_over_mesh.

Definition at line 402 of file QualityAssessor.cpp.

References assessList, MBMesquite::PatchData::attach_settings(), MBMesquite::MsqError::BARRIER_VIOLATED, MBMesquite::MsqMeshEntity::check_element_orientation(), MBMesquite::MsqError::clear(), MBMesquite::ParallelHelper::communicate_histogram_to_zero(), MBMesquite::ParallelHelper::communicate_min_max_to_all(), MBMesquite::ParallelHelper::communicate_min_max_to_zero(), MBMesquite::ParallelHelper::communicate_power_sum_to_zero(), MBMesquite::ParallelHelper::communicate_sums_to_zero(), MBMesquite::Mesh::DOUBLE, MBMesquite::ELEMENT_AVG_QM, MBMesquite::PatchData::element_by_index(), MBMesquite::ELEMENT_MAX_QM, MBMesquite::QualityAssessor::Data::elementCount, elementTypeCount, MBMesquite::MsqError::error_code(), find_stopping_assessment(), fixedTagName, MBMesquite::QualityAssessor::Data::freeElementCount, MBMesquite::MeshDomainAssoc::get_domain(), MBMesquite::PatchData::get_element_handles_array(), MBMesquite::MsqMeshEntity::get_element_type(), MBMesquite::QualityMetric::get_evaluations(), MBMesquite::MeshDomainAssoc::get_mesh(), MBMesquite::ParallelHelper::get_nprocs(), MBMesquite::ElementPatches::get_patch(), MBMesquite::VertexPatches::get_patch(), MBMesquite::ElementPatches::get_patch_handles(), MBMesquite::VertexPatches::get_patch_handles(), MBMesquite::ParallelHelper::get_rank(), MBMesquite::QualityMetric::get_single_pass(), get_tag(), MBMesquite::Instruction::initialize_vertex_byte(), MBMesquite::Mesh::INT, invalid_values, MBMesquite::QualityAssessor::Data::invertedElementCount, MBMesquite::QualityAssessor::Data::invertedSampleCount, invertedTagName, MBMesquite::ParallelHelper::is_our_element(), mesh, MSQ_CHKERR, MSQ_ERRZERO, myData, MBMesquite::PatchData::num_elements(), MBMesquite::PatchData::num_free_vertices(), outputStream, MBMesquite::POLYGON, print_summary(), printSummary, MBMesquite::QUALITY_METRIC, reset_data(), MBMesquite::QualityAssessor::Data::sampleCount, MBMesquite::PatchData::set_domain(), MBMesquite::PatchSet::set_mesh(), MBMesquite::PatchData::set_mesh(), MBMesquite::PatchData::set_mesh_entities(), skipFixedSamples, MBMesquite::Mesh::tag_set_element_data(), MBMesquite::Mesh::tag_set_vertex_data(), tagging_fixed_elements(), tagging_inverted_elements(), MBMesquite::TMP_QUALITY_METRIC, value(), and MBMesquite::QualityMetric::VERTEX_BASED.

Referenced by loop_over_mesh().

{
    // Clear out any previous data
    reset_data();

    // Clear culling flag, set hard fixed flag, etc on all vertices
    initialize_vertex_byte( mesh_and_domain, settings, err );
    MSQ_ERRZERO( err );

    Mesh* mesh         = mesh_and_domain->get_mesh();
    MeshDomain* domain = mesh_and_domain->get_domain();
    invalid_values     = false;

    PatchData patch;
    patch.set_mesh( mesh );
    patch.set_domain( domain );
    if( settings ) patch.attach_settings( settings );

    ElementPatches elem_patches;
    elem_patches.set_mesh( mesh );
    VertexPatches vert_patches( 1, false );
    vert_patches.set_mesh( mesh );

    std::vector< PatchSet::PatchHandle > patches;
    std::vector< PatchSet::PatchHandle >::iterator p;
    std::vector< Mesh::VertexHandle > patch_verts;
    std::vector< Mesh::ElementHandle > patch_elems;
    std::vector< size_t > metric_handles;

    // Check if we really need the helper
    if( helper && helper->get_nprocs() == 1 ) helper = 0;

    // Get any necessary tag handles.
    TagHandle invertedTag = 0;
    if( tagging_inverted_elements() )
    {
        invertedTag = get_tag( mesh, invertedTagName, Mesh::INT, 1, err );
        MSQ_ERRZERO( err );
    }
    list_type::iterator iter;
    for( iter = assessList.begin(); iter != assessList.end(); ++iter )
    {
        if( ( *iter )->write_to_tag() )
        {
            ( *iter )->tagHandle = get_tag( mesh, ( *iter )->tagName, Mesh::DOUBLE, 1, err );
            MSQ_ERRZERO( err );
        }
    }

    TagHandle fixedTag = 0;
    if( tagging_fixed_elements() )
    {
        fixedTag = get_tag( mesh, fixedTagName, Mesh::INT, 1, err );
        MSQ_ERRZERO( err );
    }

    // Record the type of metric for each assessment so that it can be
    // included in the QualitySummary report.
    for( iter = assessList.begin(); iter != assessList.end(); ++iter )
    {
        ElementAvgQM* avg_ptr    = dynamic_cast< ElementAvgQM* >( ( *iter )->get_metric() );
        ElementMaxQM* max_ptr    = dynamic_cast< ElementMaxQM* >( ( *iter )->get_metric() );
        TMPQualityMetric* tq_ptr = dynamic_cast< TMPQualityMetric* >( ( *iter )->get_metric() );
        if( avg_ptr )
            ( *iter )->assessScheme = ELEMENT_AVG_QM;
        else if( max_ptr )
            ( *iter )->assessScheme = ELEMENT_MAX_QM;
        else if( tq_ptr )
            ( *iter )->assessScheme = TMP_QUALITY_METRIC;
        else
            ( *iter )->assessScheme = QUALITY_METRIC;
    }

    // Check for any metrics for which a histogram is to be
    // calculated and for which the user has not specified
    // minimum and maximum values.
    // Element-based metrics are first in list, followed
    // by vertex-based metrics.  Find first vertex-based
    // metric also such that element metrics go from
    // assessList.begin() to elem_end and vertex metrics
    // go from elem_end to assessList.end()
    list_type::iterator elem_end       = assessList.end();
    bool need_second_pass_for_elements = false;
    bool need_second_pass_for_vertices = false;
    for( iter = assessList.begin(); iter != assessList.end(); ++iter )
    {
        if( ( *iter )->get_metric()->get_metric_type() == QualityMetric::VERTEX_BASED ) break;

        if( ( *iter )->have_histogram() && !( *iter )->haveHistRange ) need_second_pass_for_elements = true;
    }
    elem_end = iter;
    for( ; iter != assessList.end(); ++iter )
    {
        if( ( *iter )->have_histogram() && !( *iter )->haveHistRange ) need_second_pass_for_vertices = true;
    }

    // Do element-based metrics
    elem_patches.get_patch_handles( patches, err );
    MSQ_ERRZERO( err );

    myData->invertedElementCount = myData->invertedSampleCount = myData->sampleCount = 0;
    myData->elementCount                                                             = patches.size();
    myData->freeElementCount                                                         = 0;

    int inverted, samples;
    bool first_pass = false;
    do
    {  // might need to loop twice to calculate histograms
        first_pass = !first_pass;

        // until there are no more patches
        // there is another get_next_patch at
        // the end of this loop
        for( p = patches.begin(); p != patches.end(); ++p )
        {
            elem_patches.get_patch( *p, patch_elems, patch_verts, err );
            MSQ_ERRZERO( err );

            if( helper )
            {
                bool ours = helper->is_our_element( patch_elems[0], err );
                MSQ_ERRZERO( err );
                if( !ours )
                {
                    --myData->elementCount;
                    continue;
                }
            }
            patch.set_mesh_entities( patch_elems, patch_verts, err );
            MSQ_ERRZERO( err );

            if( first_pass )
            {
                // record element type for use in print_summary
                for( size_t i = 0; i < patch.num_elements(); i++ )
                {
                    const MsqMeshEntity* elem = &patch.element_by_index( i );
                    EntityTopology topo       = elem->get_element_type();
                    elementTypeCount[topo - POLYGON]++;
                }
            }

            if( 0 == patch.num_free_vertices() )
            {
                if( tagging_fixed_elements() )
                {
                    Mesh::ElementHandle h = patch.get_element_handles_array()[0];
                    int val               = 1;
                    mesh->tag_set_element_data( fixedTag, 1, &h, &val, err );
                    MSQ_ERRZERO( err );
                }
                if( skipFixedSamples ) continue;
            }

            // first check for inverted elements
            if( first_pass )
            {
                ++myData->freeElementCount;
                inverted = samples = 0;
                patch.element_by_index( 0 ).check_element_orientation( patch, inverted, samples, err );
                MSQ_ERRZERO( err );
                myData->invertedElementCount += ( inverted != 0 );
                myData->invertedSampleCount += inverted;
                myData->sampleCount += samples;

                if( tagging_inverted_elements() )
                {
                    Mesh::ElementHandle h = patch.get_element_handles_array()[0];
                    int val               = ( inverted != 0 );
                    mesh->tag_set_element_data( invertedTag, 1, &h, &val, err );
                    MSQ_ERRZERO( err );
                }
            }

            // now process all element-based metrics
            for( iter = assessList.begin(); iter != elem_end; ++iter )
            {
                // If first pass, get values for all metrics
                if( first_pass )
                {
                    double value = 0.0;
                    metric_handles.clear();
                    QualityMetric* qm = ( *iter )->get_metric();
                    qm->get_single_pass( patch, metric_handles, skipFixedSamples, err );
                    MSQ_ERRZERO( err );
                    for( std::vector< size_t >::iterator j = metric_handles.begin(); j != metric_handles.end(); ++j )
                    {
                        bool valid = ( *iter )->get_metric()->evaluate( patch, *j, value, err );  // MSQ_ERRZERO(err);
                        if( err.error_code() == err.BARRIER_VIOLATED )
                        {
                            err.clear();
                            invalid_values = true;
                        }
                        ( *iter )->add_value( value );
                        if( !valid ) ( *iter )->add_invalid_value();
                    }
                    // we don't do tag stuff unless metric is truely element-based
                    // (only one value per element)
                    if( ( *iter )->write_to_tag() && metric_handles.size() == 1 )
                    {
                        Mesh::ElementHandle h = patch.get_element_handles_array()[0];
                        mesh->tag_set_element_data( ( *iter )->tagHandle, 1, &h, &value, err );
                        MSQ_ERRZERO( err );
                    }
                }
                // If second pass, only do metrics for which the
                // histogram hasn't been calculated yet.
                else if( ( *iter )->have_histogram() && !( *iter )->haveHistRange )
                {
                    metric_handles.clear();
                    QualityMetric* qm = ( *iter )->get_metric();
                    qm->get_evaluations( patch, metric_handles, skipFixedSamples, err );
                    MSQ_ERRZERO( err );
                    for( std::vector< size_t >::iterator j = metric_handles.begin(); j != metric_handles.end(); ++j )
                    {
                        double value;
                        ( *iter )->get_metric()->evaluate( patch, *j, value, err );
                        MSQ_ERRZERO( err );
                        ( *iter )->add_hist_value( value );
                    }
                }
            }
        }
        if( MSQ_CHKERR( err ) ) return 0.0;

        // Fix up any histogram ranges which were calculated
        for( iter = assessList.begin(); iter != elem_end; ++iter )
            if( ( *iter )->have_histogram() && !( *iter )->haveHistRange )
                if( first_pass )
                {
                    if( helper )
                    {
                        helper->communicate_min_max_to_all( &( ( *iter )->minimum ), &( ( *iter )->maximum ), err );
                        MSQ_ERRZERO( err );
                    }

                    ( *iter )->calculate_histogram_range();
                    // Uncomment the following to have the QA keep the first
                    // calculated histogram range for all subsequent iterations.
                    //          else
                    //            (*iter)->haveHistRange = true;
                }
    } while( first_pass && need_second_pass_for_elements && !invalid_values );

    // Do vertex-based metrics
    if( assessList.end() != elem_end )
    {
        vert_patches.get_patch_handles( patches, err );
        MSQ_ERRZERO( err );

        first_pass = false;
        do
        {  // might need to loop twice to calculate histograms
            first_pass = !first_pass;

            // until there are no more patches
            // there is another get_next_patch at
            // the end of this loop
            for( p = patches.begin(); p != patches.end(); ++p )
            {
                vert_patches.get_patch( *p, patch_elems, patch_verts, err );
                MSQ_ERRZERO( err );
                patch.set_mesh_entities( patch_elems, patch_verts, err );
                MSQ_ERRZERO( err );
                if( skipFixedSamples && 0 == patch.num_free_vertices() ) continue;

                Mesh::VertexHandle vert_handle = reinterpret_cast< Mesh::VertexHandle >( *p );

                for( iter = elem_end; iter != assessList.end(); ++iter )
                {
                    // If first pass, get values for all metrics
                    if( first_pass )
                    {
                        double value = 0.0;
                        metric_handles.clear();
                        QualityMetric* qm = ( *iter )->get_metric();
                        qm->get_single_pass( patch, metric_handles, skipFixedSamples, err );
                        MSQ_ERRZERO( err );
                        for( std::vector< size_t >::iterator j = metric_handles.begin(); j != metric_handles.end();
                             ++j )
                        {
                            bool valid = ( *iter )->get_metric()->evaluate( patch, *j, value, err );
                            MSQ_ERRZERO( err );
                            ( *iter )->add_value( value );
                            if( !valid ) ( *iter )->add_invalid_value();
                        }
                        // we don't do tag stuff unless metric is truely vertex-based
                        // (only one value per vertex)
                        if( ( *iter )->write_to_tag() && metric_handles.size() == 1 )
                        {
                            mesh->tag_set_vertex_data( ( *iter )->tagHandle, 1, &vert_handle, &value, err );
                            MSQ_ERRZERO( err );
                        }
                    }
                    // If second pass, only do metrics for which the
                    // histogram hasn't been calculated yet.
                    else if( ( *iter )->have_histogram() && !( *iter )->haveHistRange )
                    {
                        metric_handles.clear();
                        QualityMetric* qm = ( *iter )->get_metric();
                        qm->get_evaluations( patch, metric_handles, skipFixedSamples, err );
                        MSQ_ERRZERO( err );
                        for( std::vector< size_t >::iterator j = metric_handles.begin(); j != metric_handles.end();
                             ++j )
                        {
                            double value;
                            ( *iter )->get_metric()->evaluate( patch, *j, value, err );
                            MSQ_ERRZERO( err );
                            ( *iter )->add_hist_value( value );
                        }
                    }
                }
            }
            if( MSQ_CHKERR( err ) ) return 0.0;

            // Fix up any histogram ranges which were calculated
            for( iter = elem_end; iter != assessList.end(); ++iter )
                if( ( *iter )->have_histogram() && !( *iter )->haveHistRange )
                    if( first_pass )
                    {
                        if( helper )
                        {
                            helper->communicate_min_max_to_all( &( ( *iter )->minimum ), &( ( *iter )->maximum ), err );
                            MSQ_ERRZERO( err );
                        }
                        ( *iter )->calculate_histogram_range();
                        // Uncomment the following to have the QA keep the first
                        // calculated histogram range for all subsequent iterations.
                        //          else
                        //            (*iter)->haveHistRange = true;
                    }
        } while( first_pass && need_second_pass_for_vertices && !invalid_values );
    }

    if( helper )
    {
        for( iter = assessList.begin(); iter != assessList.end(); ++iter )
        {

            helper->communicate_min_max_to_zero( &( ( *iter )->minimum ), &( ( *iter )->maximum ), err );
            MSQ_ERRZERO( err );

            helper->communicate_sums_to_zero( &myData->freeElementCount, &myData->invertedElementCount,
                                              &myData->elementCount, &myData->invertedSampleCount, &myData->sampleCount,
                                              &( ( *iter )->count ), &( ( *iter )->numInvalid ), &( ( *iter )->sum ),
                                              &( ( *iter )->sqrSum ), err );
            MSQ_ERRZERO( err );

            if( ( *iter )->have_power_mean() )
            {
                helper->communicate_power_sum_to_zero( &( ( *iter )->pMean ), err );
                MSQ_ERRZERO( err );
            }

            if( ( *iter )->have_histogram() )
            {
                helper->communicate_histogram_to_zero( ( *iter )->histogram, err );
                MSQ_ERRZERO( err );
            }
        }
    }

    // Print results, if requested
    if( printSummary && ( !helper || helper->get_rank() == 0 ) ) print_summary( this->outputStream );

    list_type::iterator i = find_stopping_assessment();
    return i == assessList.end() ? 0 : ( *i )->stopping_function_value();
}

All elements or only improvable ones.

If set to true, the quality assessment results will include quality values only for those elements (or more precisely metric sample points) which are influenced by at least one free vertex. That is, quality for elements (or sample points) that the sovler cannot improve (e.g. an element with all vertices fixed) will not be included in the quality assessment.

If set to false, quality for all elements will be assessed.

Definition at line 219 of file QualityAssessor.hpp.

References skipFixedSamples.

Referenced by QualityAssessorTest::test_basic_stats_vertex(), QualityAssessorTest::test_invalid_count(), QualityAssessorTest::test_inverted_count(), and QualityAssessorTest::test_print_inverted().

    {
        skipFixedSamples = yesno;
    }

All elements or only improvable ones.

If set to true, the quality assessment results will include quality values only for those elements (or more precisely metric sample points) which are influenced by at least one free vertex. That is, quality for elements (or sample points) that the sovler cannot improve (e.g. an element with all vertices fixed) will not be included in the quality assessment.

If set to false, quality for all elements will be assessed.

Definition at line 235 of file QualityAssessor.hpp.

References skipFixedSamples.

    {
        return skipFixedSamples;
    }
QualityAssessor & MBMesquite::QualityAssessor::operator= ( const QualityAssessor copy)

Definition at line 151 of file QualityAssessor.cpp.

References assessList, elementTypeCount, fixedTagName, invertedTagName, MBMesquite::MIXED, myData, MBMesquite::POLYGON, printSummary, qualityAssessorName, MBMesquite::QualityAssessor::Assessor::referenceCount, MBMesquite::QualityAssessor::Data::referenceCount, and skipFixedSamples.

{
    list_type::iterator iter;
    for( iter = assessList.begin(); iter != assessList.end(); ++iter )
    {
        Assessor* assessor = *iter;
        if( 0 == --assessor->referenceCount ) delete assessor;
    }

    myData              = copy.myData;
    qualityAssessorName = copy.qualityAssessorName;
    assessList          = copy.assessList;
    printSummary        = copy.printSummary;
    invertedTagName     = copy.invertedTagName;
    fixedTagName        = copy.fixedTagName;
    skipFixedSamples    = copy.skipFixedSamples;

    for( iter = assessList.begin(); iter != assessList.end(); ++iter )
        ( *iter )->referenceCount++;
    myData->referenceCount++;

    for( int i = POLYGON; i <= MIXED; i++ )
        elementTypeCount[i - POLYGON] = copy.elementTypeCount[i - POLYGON];

    return *this;
}
void MBMesquite::QualityAssessor::print_summary ( std::ostream &  stream) const

Print accumulated summary data to specified stream.

Definition at line 1241 of file QualityAssessor.cpp.

References assessList, MBMesquite::ELEMENT_AVG_QM, MBMesquite::ELEMENT_MAX_QM, element_name_as_string(), MBMesquite::QualityAssessor::Data::elementCount, elementTypeCount, MBMesquite::QualityAssessor::Data::freeElementCount, get_terminal_width(), invalid_values, MBMesquite::QualityAssessor::Data::invertedElementCount, MBMesquite::QualityAssessor::Data::invertedSampleCount, MBMesquite::MIXED, myData, MBMesquite::POLYGON, MBMesquite::QUALITY_METRIC, qualityAssessorName, MBMesquite::QualityAssessor::Data::sampleCount, and MBMesquite::TMP_QUALITY_METRIC.

Referenced by loop_over_mesh_internal().

{
    const int NAMEW = 19;  // Width of name column in table output
    const int NUMW  = 12;  // Width of value columns in table output

    // Print title
    stream << std::endl
           << "************** " << qualityAssessorName << " Summary **************" << std::endl
           << std::endl;

    if( myData->freeElementCount != myData->elementCount )
        stream << "  Evaluating quality for " << myData->freeElementCount << " free elements of "
               << myData->elementCount << " total elements." << std::endl;
    else
        stream << "  Evaluating quality for " << myData->elementCount << " elements." << std::endl;

    // Print element type totals
    std::string str_value = "";
    for( int i = POLYGON; i <= MIXED; i++ )
    {
        if( elementTypeCount[i - POLYGON] )
        {
            str_value = element_name_as_string( i );
            if( str_value != "" )
                stream << "  This mesh had " << elementTypeCount[i - POLYGON] << " " << str_value << " elements."
                       << std::endl;
        }
    }

    if( myData->invertedElementCount )
    {
        stream << "  THERE ARE " << myData->invertedElementCount << " INVERTED ELEMENTS. " << std::endl
               << "  (Elements invalid at " << myData->invertedSampleCount << " of " << myData->sampleCount
               << " sample locations.)" << std::endl
               << std::endl;
    }
    else
    {
        stream << "  There were no inverted elements detected. " << std::endl;
    }

    // Check if there are invalid values for any metric
    list_type::const_iterator iter;
    bool some_invalid = false;
    for( iter = assessList.begin(); iter != assessList.end(); ++iter )
    {
        if( ( *iter )->get_invalid_element_count() )
        {
            some_invalid = true;
            stream << "  " << ( *iter )->get_invalid_element_count() << " OF " << ( *iter )->get_count()
                   << " ENTITIES EVALUATED TO AN UNDEFINED VALUE FOR " << ( *iter )->get_label() << std::endl
                   << std::endl;
        }
    }
    if( !some_invalid )
    {
        stream << "  No entities had undefined values for any computed metric." << std::endl << std::endl;
    }

    if( !invalid_values )
    {
        // Check if a user-define power-mean was calculated for any of the metrics
        std::set< double > pmeans;
        for( iter = assessList.begin(); iter != assessList.end(); ++iter )
            if( ( *iter )->have_power_mean() ) pmeans.insert( ( *iter )->get_power() );

        // If power-mean of 1 or 2 was requested, change titles rather
        // than printing redundant values
        std::string average_str( "average" ), rms_str( "rms" );
        if( pmeans.find( 1.0 ) != pmeans.end() )
        {
            pmeans.erase( pmeans.find( 1.0 ) );
            average_str = "1-mean";
        }
        if( pmeans.find( 2.0 ) != pmeans.end() )
        {
            pmeans.erase( pmeans.find( 2.0 ) );
            rms_str = "2-mean";
        }

        // Number of values in table
        unsigned num_values = pmeans.size() + 5;

        // Decide how wide of a table field should be used for the metric name
        unsigned twidth    = get_terminal_width();
        unsigned maxnwidth = NAMEW;
        if( twidth )
        {
            unsigned valwidth = NUMW * num_values;
            maxnwidth         = valwidth < twidth ? twidth - valwidth : 0;
        }
        unsigned namewidth = 0;
        for( iter = assessList.begin(); iter != assessList.end(); ++iter )
            if( ( *iter )->get_label().size() > namewidth ) namewidth = ( *iter )->get_label().size();
        if( namewidth > maxnwidth ) namewidth = maxnwidth;
        if( namewidth < 7 )  // at least enough width for the column header
            namewidth = 7;

        int number_of_assessments = 0;

        // print metric values
        for( iter = assessList.begin(); iter != assessList.end(); ++iter )
        {
            if( number_of_assessments > 0 ) stream << "    -------------------------------------------" << std::endl;

            // print assessment method used to calculate the statistics
            if( ( *iter )->assessScheme == TMP_QUALITY_METRIC )
                stream << "     Sample Point Quality Statistics" << std::endl << std::endl;
            else
                stream << "     Element Quality Statistics" << std::endl << std::endl;

            // print comlumn label line
            std::set< double >::const_iterator piter;
            stream << std::setw( NUMW ) << "minimum";
            for( piter = pmeans.begin(); piter != pmeans.end() && *piter < 1.0; ++piter )
                stream << std::setw( NUMW - 6 ) << *piter << "-mean ";
            stream << std::setw( NUMW ) << average_str;
            for( ; piter != pmeans.end() && *piter < 2.0; ++piter )
                stream << std::setw( NUMW - 6 ) << *piter << "-mean ";
            stream << std::setw( NUMW ) << rms_str;
            for( ; piter != pmeans.end(); ++piter )
                stream << std::setw( NUMW - 6 ) << *piter << "-mean ";
            stream << std::setw( NUMW ) << "maximum";
            stream << std::setw( NUMW ) << "std.dev.";
            stream << std::endl;

            stream << std::setw( NUMW ) << ( *iter )->get_minimum();
            // print power-means with P less than 1.0
            for( piter = pmeans.begin(); piter != pmeans.end() && *piter < 1.0; ++piter )
            {
                if( ( *iter )->have_power_mean() && ( *iter )->get_power() == *piter )
                    stream << std::setw( NUMW ) << ( *iter )->get_power_mean();
                else
                    stream << std::setw( NUMW ) << " ";
            }
            // print average
            stream << std::setw( NUMW ) << ( *iter )->get_average();
            // print power-means with P less than 2.0
            for( ; piter != pmeans.end() && *piter < 2.0; ++piter )
            {
                if( ( *iter )->have_power_mean() && ( *iter )->get_power() == *piter )
                    stream << std::setw( NUMW ) << ( *iter )->get_power_mean();
                else
                    stream << std::setw( NUMW ) << " ";
            }
            // print RMS
            stream << std::setw( NUMW ) << ( *iter )->get_rms();
            // print power-means with P greater than 2.0
            for( ; piter != pmeans.end(); ++piter )
            {
                if( ( *iter )->have_power_mean() && ( *iter )->get_power() == *piter )
                    stream << std::setw( NUMW ) << ( *iter )->get_power_mean();
                else
                    stream << std::setw( NUMW ) << " ";
            }
            // print maximum and standard deviation
            stream << std::setw( NUMW ) << ( *iter )->get_maximum();
            stream << std::setw( NUMW ) << ( *iter )->get_stddev();
            stream << std::endl << std::endl;

            stream << "     Number of statistics = " << ( *iter )->get_count() << std::endl;

            // print name
            stream << "     Metric = " << ( *iter )->get_label() << std::endl;

            // Output the method used to calcualte the quality values
            switch( ( *iter )->assessScheme )
            {
                case ELEMENT_AVG_QM:
                    stream << "     Element Quality = average over metric values at the elements' "
                              "sample points"
                           << std::endl
                           << std::endl;
                    break;
                case ELEMENT_MAX_QM:
                    stream << "     Element Quality = maximum over metric values at the elements' "
                              "sample points"
                           << std::endl
                           << std::endl;
                    break;
                case TMP_QUALITY_METRIC:
                    stream << std::endl << std::endl;
                    break;
                case QUALITY_METRIC:
                    stream << "     Element Quality not based on sample points." << std::endl << std::endl;
                    break;
                default:
                    stream << "     Scheme used for deriving qualitiy values unknown" << std::endl << std::endl;
            }
            if( ( *iter )->have_histogram() ) ( *iter )->print_histogram( stream, get_terminal_width() );
            number_of_assessments++;
        }
    }
    else
    {
        stream << "  Element Quality Statistics are Undefined for this Metric because" << std::endl
               << "  there are Inverted Elements" << std::endl
               << std::endl;
    }
}

Reset calculated data.

Definition at line 781 of file QualityAssessor.cpp.

References assessList, elementTypeCount, MBMesquite::QualityAssessor::Data::invertedElementCount, MBMesquite::QualityAssessor::Data::invertedSampleCount, MBMesquite::MIXED, myData, and MBMesquite::POLYGON.

Referenced by loop_over_mesh_internal().

{
    list_type::iterator iter;
    for( iter = assessList.begin(); iter != assessList.end(); ++iter )
        ( *iter )->reset_data();
    myData->invertedElementCount = -1;
    myData->invertedSampleCount  = -1;

    for( int i = POLYGON; i <= MIXED; i++ )
        elementTypeCount[i - POLYGON] = 0;
}
double MBMesquite::QualityAssessor::round_to_3_significant_digits ( double  number) [static, private]

Definition at line 1649 of file QualityAssessor.cpp.

References z.

Referenced by MBMesquite::QualityAssessor::Assessor::print_histogram(), and scale_histograms().

{
    double result = number;
    double p      = 1.0;

    if( number > 0 && number < 1000 )
    {
        if( number < 1000 )
        {
            while( number < 100 )
            {
                number *= 10;
                p *= 10;
            }
        }
        else
        {
            while( number >= 1000 )
            {
                number /= 10;
                p /= 10;
            }
        }
        int z  = int( number + 0.5 );
        result = z / p;
    }

    return result;
}

Produces two historgrams on a single scale from a before optimization histogram and an after optimization histogram. The histogram intervals are adjusted to include the enitre range of both histograms, the horizontal interval value bars are adjusted to be on the same scale, and the metric quality values are placed in the correct quality value 'bin' based on the new interval scale.

Definition at line 793 of file QualityAssessor.cpp.

References MBMesquite::arrptr(), assessList, get_terminal_width(), outputStream, and round_to_3_significant_digits().

Referenced by do_smoother().

{
    // find the histograms to scale
    list_type::iterator iter;
    list_type::iterator initial;
    list_type::iterator optimal;
    bool initial_found = false, optimal_found = false;
    for( iter = assessList.begin(); iter != assessList.end(); ++iter )
    {
        if( ( *iter )->histogram.size() > 0 )
        {
            if( initial_found == false )
            {
                initial       = iter;
                initial_found = true;
                break;
            }
        }
    }
    for( iter = optimized->assessList.begin(); iter != optimized->assessList.end(); ++iter )
    {
        if( ( *iter )->histogram.size() > 0 )
        {
            optimal       = iter;
            optimal_found = true;
            break;
        }
    }
    if( !initial_found || !optimal_found )
    {
        // issue warning: orig histograms not found
        if( !initial_found )
            outputStream << "WARNING: 'before' histogram not found" << std::endl;
        else
            outputStream << "WARNING: 'after' histogram not found" << std::endl;
        return;
    }

    // check number of intervals (bins) for each histogram
    int num_intervals = ( *initial )->histogram.size() - 2;
    if( num_intervals != int( ( *optimal )->histogram.size() - 2 ) )
    {
        // issue warning: number of intervals not the same
        outputStream << "WARNING: histogram intervals are not the same" << std::endl;
        return;
    }

    // calculate new max and min values
    double combined_min, combined_max;
    if( ( *initial )->histMin < ( *optimal )->histMin )
        combined_min = ( *initial )->histMin;
    else
        combined_min = ( *optimal )->histMin;

    if( ( *initial )->histMax > ( *optimal )->histMax )
        combined_max = ( *initial )->histMax;
    else
        combined_max = ( *optimal )->histMax;

    // put the before quality values into the correct new bins

    // First and last values in array are counts of valuesnum_intervals+1
    // outside the user-specified range of the histogram
    // (below and above, respectively.)
    std::vector< int > new_initial_histogram;
    new_initial_histogram.resize( ( *initial )->histogram.size(), 0 );
    new_initial_histogram[0] = ( *initial )->histogram[0];
    new_initial_histogram[new_initial_histogram.size() - 1] =
        ( *initial )->histogram[( *initial )->histogram.size() - 1];

    // Re-calculate which interval the value is in.  Add one
    // because first entry is for values below user-specifed
    // minimum value for histogram.
    double combined_range = combined_max - combined_min;
    double initial_min    = ( *initial )->histMin;
    double optimal_min    = ( *optimal )->histMin;
    double initial_range  = ( *initial )->histMax - ( *initial )->histMin;
    double optimal_range  = ( *optimal )->histMax - ( *optimal )->histMin;
    double combined_step  = combined_range / num_intervals;
    double initial_step   = initial_range / num_intervals;
    double optimal_step   = optimal_range / num_intervals;
    // round steps to 3 significant digits
    if( combined_step >= 0.001 ) combined_step = round_to_3_significant_digits( combined_step );
    if( initial_step >= 0.001 ) initial_step = round_to_3_significant_digits( initial_step );
    if( optimal_step >= 0.001 ) optimal_step = round_to_3_significant_digits( optimal_step );

    // populate initial histogram
    if( initial_range == combined_range )
    {
        // just copy histogram
        new_initial_histogram = ( *initial )->histogram;
    }
    else
    {
        for( size_t i = 1; i < new_initial_histogram.size() - 1; i++ )
        {
            double combined_bin_value = combined_min + ( combined_step * ( i - 1 ) );
            for( size_t j = 1; j < new_initial_histogram.size() - 1; j++ )
            {
                double initial_bin_value = initial_min + ( initial_step * ( j - 1 ) );
                if( initial_bin_value >= combined_bin_value && initial_bin_value < combined_bin_value + combined_step )
                {
                    new_initial_histogram[i] += ( *initial )->histogram[j];
                }
            }
        }
    }

    // put the optimal quality values into the correct new bins
    std::vector< int > new_optimal_histogram;
    new_optimal_histogram.resize( ( *optimal )->histogram.size(), 0 );
    new_optimal_histogram[0] = ( *optimal )->histogram[0];
    new_optimal_histogram[new_optimal_histogram.size() - 1] =
        ( *optimal )->histogram[( *optimal )->histogram.size() - 1];

    // populate optimal histogram
    if( optimal_range == combined_range )
    {
        // just copy histogram
        new_optimal_histogram = ( *optimal )->histogram;
    }
    else
    {
        for( size_t i = 1; i < new_optimal_histogram.size() - 1; i++ )
        {
            double combined_bin_value = combined_min + ( combined_step * ( i - 1 ) );
            for( size_t j = 1; j < new_optimal_histogram.size() - 1; j++ )
            {
                double optimal_bin_value = optimal_min + ( optimal_step * ( j - 1 ) );
                if( optimal_bin_value >= combined_bin_value && optimal_bin_value < combined_bin_value + combined_step )
                {
                    new_optimal_histogram[i] += ( *optimal )->histogram[j];
                }
            }
        }
    }

    // determine largest number of values in a 'bin' for both histograms
    unsigned i;
    int max_interval_num = 1;
    for( i = 0; i < new_initial_histogram.size(); ++i )
    {
        if( new_initial_histogram[i] > max_interval_num ) max_interval_num = new_initial_histogram[i];
    }
    for( i = 0; i < new_optimal_histogram.size(); ++i )
    {
        if( new_optimal_histogram[i] > max_interval_num ) max_interval_num = new_optimal_histogram[i];
    }

    // calculate how many bar graph characters will represent the
    // largest 'bin' value.
    // create the 'before' histogram
    int termwidth         = get_terminal_width();
    const char indent[]   = "   ";
    const char GRAPH_CHAR = '=';                              // Character used to create bar graphs
    const int TOTAL_WIDTH = termwidth > 30 ? termwidth : 70;  // Width of histogram
    int GRAPHW            = TOTAL_WIDTH - sizeof( indent );

    if( 0 == max_interval_num ) return;  // no data

    // Calculate width of field containing counts for
    // histogram intervals (log10(max_interval)).
    int num_width = 1;
    for( int temp = max_interval_num; temp > 0; temp /= 10 )
        ++num_width;
    GRAPHW -= num_width;

    // Create an array of bar graph characters for use in output
    std::vector< char > graph_chars( GRAPHW + 1, GRAPH_CHAR );

    // Check if bar-graph should be linear or log10 plot
    // Do log plot if standard deviation is less that 1.5
    // histogram intervals.

    bool log_plot = false;
    double stddev = ( *initial )->get_stddev();
    if( stddev > 0 && stddev < 2.0 * combined_step )
    {
        int new_interval = (int)( log10( (double)( 1 + max_interval_num ) ) );
        if( new_interval > 0 )
        {
            log_plot         = true;
            max_interval_num = new_interval;
        }
    }
    // output the 'before' histogram

    // Write title
    outputStream << std::endl << "************** Common-scale Histograms **************" << std::endl << std::endl;
    outputStream << indent << ( *initial )->get_label() << " histogram (initial mesh):";
    if( log_plot ) outputStream << " (log10 plot)";
    outputStream << std::endl;

    // Calculate width of a single quality interval value
    double interval_value  = 0.0;
    int max_interval_width = 0;
    std::stringstream str_stream;
    std::string interval_string;
    for( i = 0; i < new_initial_histogram.size(); ++i )
    {
        interval_value = combined_min + (i)*combined_step;
        if( combined_step >= .001 ) interval_value = round_to_3_significant_digits( interval_value );
        str_stream.clear();
        str_stream.str( "" );
        interval_string = "";
        str_stream << interval_value;
        interval_string = str_stream.str();
        if( interval_string.length() > (size_t)max_interval_width ) max_interval_width = interval_string.length();
    }

    // adjust graph width for actual size of interval values
    GRAPHW = GRAPHW - ( max_interval_width * 2 ) - 5;

    // For each interval of histogram
    for( i = 0; i < new_initial_histogram.size(); ++i )
    {
        // First value is the count of the number of values that
        // were below the minimum value of the histogram.
        if( 0 == i )
        {
            if( 0 == new_initial_histogram[i] ) continue;
            outputStream << indent << std::setw( max_interval_width ) << "under min";
        }
        // Last value is the count of the number of values that
        // were above the maximum value of the histogram.
        else if( i + 1 == new_initial_histogram.size() )
        {
            if( 0 == new_initial_histogram[i] ) continue;
            outputStream << indent << std::setw( max_interval_width ) << "over max";
        }
        // Anything else is a valid interval of the histogram.
        // Print the range for each interval.
        else
        {
            double start_value = combined_min + ( i - 1 ) * combined_step;
            double end_value   = combined_min + (i)*combined_step;

            if( combined_step >= 0.001 )
            {
                start_value = round_to_3_significant_digits( start_value );
                end_value   = round_to_3_significant_digits( end_value );
            }

            outputStream << indent << "(" << std::setw( max_interval_width ) << std::right << start_value << "-"
                         << std::setw( max_interval_width ) << std::left << end_value << ") |";
        }

        // Print bar graph

        // First calculate the number of characters to output
        int num_graph;
        if( log_plot )
            num_graph = GRAPHW * (int)log10( (double)( 1 + new_initial_histogram[i] ) ) / max_interval_num;
        else
            num_graph = GRAPHW * new_initial_histogram[i] / max_interval_num;

        // print num_graph characters using array of fill characters.
        graph_chars[num_graph] = '\0';
        outputStream << arrptr( graph_chars );
        graph_chars[num_graph] = GRAPH_CHAR;

        // Print interval count.
        outputStream << new_initial_histogram[i] << std::endl;
    }

    outputStream << "  metric was evaluated " << ( *initial )->count << " times." << std::endl << std::endl;

    // output the 'after' histogram
    outputStream << std::endl << indent << ( *optimal )->get_label() << " histogram (optimal mesh):";
    if( log_plot ) outputStream << " (log10 plot)";
    outputStream << std::endl;

    // For each interval of histogram
    for( i = 0; i < new_optimal_histogram.size(); ++i )
    {
        // First value is the count of the number of values that
        // were below the minimum value of the histogram.
        if( 0 == i )
        {
            if( 0 == new_optimal_histogram[i] ) continue;
            outputStream << indent << std::setw( max_interval_width ) << "under min";
        }
        // Last value is the count of the number of values that
        // were above the maximum value of the histogram.
        else if( i + 1 == new_optimal_histogram.size() )
        {
            if( 0 == new_optimal_histogram[i] ) continue;
            outputStream << indent << std::setw( max_interval_width ) << "over max";
        }
        // Anything else is a valid interval of the histogram.
        // Print the range for each interval.
        else
        {
            double start_value = combined_min + ( i - 1 ) * combined_step;
            double end_value   = combined_min + (i)*combined_step;

            if( combined_step >= 0.001 )
            {
                start_value = round_to_3_significant_digits( start_value );
                end_value   = round_to_3_significant_digits( end_value );
            }

            outputStream << indent << "(" << std::setw( max_interval_width ) << std::right << start_value << "-"
                         << std::setw( max_interval_width ) << std::left << end_value << ") |";
        }

        // Print bar graph

        // First calculate the number of characters to output
        int num_graph;
        if( log_plot )
            num_graph = GRAPHW * (int)log10( (double)( 1 + new_optimal_histogram[i] ) ) / max_interval_num;
        else
            num_graph = GRAPHW * new_optimal_histogram[i] / max_interval_num;

        // print num_graph characters using array of fill characters.
        graph_chars[num_graph] = '\0';
        outputStream << arrptr( graph_chars );
        graph_chars[num_graph] = GRAPH_CHAR;

        // Print interval count.
        outputStream << new_optimal_histogram[i] << std::endl;
    }

    outputStream << "  metric was evaluated " << ( *optimal )->count << " times." << std::endl << std::endl;

    return;
}
MESQUITE_EXPORT void MBMesquite::QualityAssessor::set_name ( std::string  name) [inline]

Provides a name to the QualityAssessor (use it for default name in constructor).

Definition at line 198 of file QualityAssessor.hpp.

References qualityAssessorName.

    {
        qualityAssessorName = name;
    };
void MBMesquite::QualityAssessor::set_stopping_assessment ( QualityMetric metric,
int  histogram_intervals = 0,
double  power_mean = 0.0,
const char *  tag_name = 0,
const char *  label = 0 
)

Same as add_quality_assessment, except that the average metric value is also used as the return value from loop_over_mesh. Specify a power_mean value to control which average is used.

Sets which QualityMetric and QAFunction combination is used to determine the value return from assess_mesh_quality(). It first ensures that the inputed QAFunction was not HISTOGRAM. It then calls add_quality_assessment with the given QualityMetric and QAFunction, to ensure that this combination will be computed. Finally, it sets the stoppingMetric pointer and the stoppingFunction data members.

Parameters:
qmPointer to QualityMetric.
func(QAFUNCTION) Wrapper function for qm (e.g. MINIMUM, MAXIMUM,...).

Definition at line 284 of file QualityAssessor.cpp.

References assessList, find_or_add(), and find_stopping_assessment().

Referenced by QualityAssessor().

{
    list_type::iterator i = find_stopping_assessment();
    if( i != assessList.end() ) ( *i )->set_stopping_function( false );

    i             = find_or_add( metric, label );
    ( *i )->pMean = power_mean;
    if( histogram_intervals > 0 )
        ( *i )->histogram.resize( histogram_intervals + 2 );
    else
        ( *i )->histogram.clear();
    ( *i )->haveHistRange = false;
    if( !tag_name )
        ( *i )->tagName.clear();
    else
        ( *i )->tagName = tag_name;
    ( *i )->set_stopping_function( true );
}
MESQUITE_EXPORT void MBMesquite::QualityAssessor::tag_fixed_elements ( std::string  tagname) [inline]

Definition at line 364 of file QualityAssessor.hpp.

References fixedTagName, and tagname.

Definition at line 351 of file QualityAssessor.hpp.

References invertedTagName, and tagname.

Referenced by QualityAssessor().

Definition at line 372 of file QualityAssessor.hpp.

References fixedTagName.

Referenced by loop_over_mesh_internal().

    {
        return !fixedTagName.empty();
    }

Definition at line 359 of file QualityAssessor.hpp.

References invertedTagName.

Referenced by loop_over_mesh_internal().

    {
        return !invertedTagName.empty();
    }

Member Data Documentation

Stream to which to write summary of metric data

Definition at line 635 of file QualityAssessor.hpp.

Referenced by get_terminal_width(), loop_over_mesh_internal(), and scale_histograms().

Disable printing

Definition at line 637 of file QualityAssessor.hpp.

Referenced by disable_printing_results(), loop_over_mesh_internal(), and operator=().

List of all members.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines