bool make_statistic::run(viennamesh::algorithm_handle &) { info(1) << "make_statistic started:" << std::endl; mesh_handle input_mesh = get_required_input<mesh_handle>("mesh"); /*original mesh for comparison statistics (hausdorff distance, curvature difference...)*/ mesh_handle original_mesh = get_input<mesh_handle>("original_mesh"); /*All provided cell quality metric types are implemented as header files, which are located in statistics/metrics. * Note that most metrics are only implemented for triangles*/ data_handle<viennamesh_string> metric_type = get_required_input<viennamesh_string>("metric_type"); /*Decision threshold for triangle qualitity classification * E.g., radius_ratio < 1.5 * Whether '<' or '>' is used for comparison is deduced from metric_ordering_tag*/ data_handle<viennagrid_numeric> good_element_threshold = get_input<viennagrid_numeric>("good_element_threshold"); /* comprehensive mesh quality metric is defined as alpha * (1 - good_elements_counted/count) + beta * min_dist_rms + gamma * mean_curvature + delta * volume_deviation; */ data_handle<viennagrid_numeric> alpha = get_input<viennagrid_numeric>("alpha"); data_handle<viennagrid_numeric> beta = get_input<viennagrid_numeric>("beta"); data_handle<viennagrid_numeric> gamma = get_input<viennagrid_numeric>("gamma"); data_handle<viennagrid_numeric> delta = get_input<viennagrid_numeric>("delta"); #if HIST data_handle<viennagrid_numeric> histogram_bins = get_input<viennagrid_numeric>("histogram_bin"); data_handle<viennagrid_numeric> histogram_min = get_input<viennagrid_numeric>("histogram_min"); data_handle<viennagrid_numeric> histogram_max = get_input<viennagrid_numeric>("histogram_max"); data_handle<int> histogram_bin_count = get_input<int>("histogram_bin_count"); #endif typedef viennagrid::mesh MeshType; typedef viennagrid::result_of::element<MeshType>::type ElementType; //=Triangle or Tetrahedron typedef viennamesh::statistic<viennagrid_numeric> StatisticType; StatisticType statistic; #if HIST typedef StatisticType::histogram_type HistogramType; if (histogram_bins.valid()) { std::vector<viennagrid_numeric> bins; for (int i = 0; i != histogram_bins.size(); ++i) bins.push_back( histogram_bins(i) ); statistic.set_histogram( StatisticType::histogram_type::make(bins.begin(), bins.end()) ); } else if (histogram_min.valid() && histogram_max.valid() && histogram_bin_count.valid()) { statistic.set_histogram( StatisticType::histogram_type::make_uniform(histogram_min(), histogram_max(), histogram_bin_count()) ); } else { //If histograms are about to be added again, returing false here will prevent the basic statistics features from working! error(1) << "No histogram configuration provided" << std::endl; return false; } #endif //Good element threshold input was set, call statistics with the appropriate metric if(good_element_threshold.valid()) { viennamesh::LoggingStack stack( std::string("High quality cell counter with metric type \"") + metric_type() + "\"" ); if (metric_type() == "aspect_ratio") statistic.cell_quality_count<viennamesh::aspect_ratio_tag>( input_mesh(), viennamesh::aspect_ratio<ElementType>, good_element_threshold()); else if (metric_type() == "min_angle") statistic.cell_quality_count<viennamesh::min_angle_tag>( input_mesh(), viennamesh::min_angle<ElementType>, good_element_threshold()); else if (metric_type() == "max_angle") statistic.cell_quality_count<viennamesh::max_angle_tag>( input_mesh(), viennamesh::max_angle<ElementType>, good_element_threshold()); else if (metric_type() == "min_dihedral_angle") statistic.cell_quality_count<viennamesh::min_dihedral_angle_tag>( input_mesh(), viennamesh::min_dihedral_angle<ElementType>, good_element_threshold()); else if (metric_type() == "radius_edge_ratio") statistic.cell_quality_count<viennamesh::radius_edge_ratio_tag>( input_mesh(), viennamesh::radius_edge_ratio<ElementType>, good_element_threshold()); else if (metric_type() == "radius_ratio") statistic.cell_quality_count<viennamesh::radius_ratio_tag>( input_mesh(), viennamesh::radius_ratio<ElementType>, good_element_threshold()); else if (metric_type() == "perimeter_inradius_ratio") statistic.cell_quality_count<viennamesh::perimeter_inradius_ratio_tag>( input_mesh(), viennamesh::perimeter_inradius_ratio<ElementType>, good_element_threshold()); else if (metric_type() == "edge_ratio") statistic.cell_quality_count<viennamesh::edge_ratio_tag>( input_mesh(), viennamesh::edge_ratio<ElementType>, good_element_threshold()); else if (metric_type() == "circum_perimeter_ratio") statistic.cell_quality_count<viennamesh::circum_perimeter_ratio_tag>( input_mesh(), viennamesh::circum_perimeter_ratio<ElementType>, good_element_threshold()); else if (metric_type() == "stretch") statistic.cell_quality_count<viennamesh::stretch_tag>( input_mesh(), viennamesh::stretch<ElementType>, good_element_threshold()); else if (metric_type() == "skewness") statistic.cell_quality_count<viennamesh::skewness_tag>( input_mesh(), viennamesh::skewness<ElementType>, good_element_threshold()); else { error(1) << "Metric type \"" << metric_type() << "\" is not supported for cell quality classifaction" << std::endl; return false; } } else //no triangle classifiction takes place { viennamesh::LoggingStack stack( std::string("Cell statistics with metric type \"") + metric_type() + "\"" ); if (metric_type() == "aspect_ratio") statistic.cell_stats( input_mesh(), viennamesh::aspect_ratio<ElementType> ); else if (metric_type() == "min_angle") statistic.cell_stats( input_mesh(), viennamesh::min_angle<ElementType> ); else if (metric_type() == "max_angle") statistic.cell_stats( input_mesh(), viennamesh::max_angle<ElementType> ); else if (metric_type() == "min_dihedral_angle") statistic.cell_stats( input_mesh(), viennamesh::min_dihedral_angle<ElementType> ); else if (metric_type() == "radius_edge_ratio") statistic.cell_stats( input_mesh(), viennamesh::radius_edge_ratio<ElementType> ); else if (metric_type() == "radius_ratio") statistic.cell_stats( input_mesh(), viennamesh::radius_ratio<ElementType> ); else if (metric_type() == "perimeter_inradius_ratio") statistic.cell_stats( input_mesh(), viennamesh::perimeter_inradius_ratio<ElementType> ); else if (metric_type() == "edge_ratio") statistic.cell_stats( input_mesh(), viennamesh::edge_ratio<ElementType> ); else if (metric_type() == "circum_perimeter_ratio") statistic.cell_stats( input_mesh(), viennamesh::circum_perimeter_ratio<ElementType> ); else if (metric_type() == "stretch") statistic.cell_stats( input_mesh(), viennamesh::stretch<ElementType> ); else if (metric_type() == "skewness") statistic.cell_stats( input_mesh(), viennamesh::skewness<ElementType> ); else { error(1) << "Metric type \"" << metric_type() << "\" is not supported" << std::endl; return false; } } if(original_mesh.valid())//a second mesh is set, calculate mesh comparison measures { viennamesh::LoggingStack stack( std::string("Calculation of Mesh Comparison Measures") ); statistic.mesh_comparison_quality(input_mesh(), original_mesh()); ConstTriangleRange tr_orig(original_mesh()); ConstTriangleRange tr(input_mesh()); StatisticType statistic_orig; statistic_orig.cell_stats( original_mesh(), viennamesh::aspect_ratio<ElementType> ); //use median of orig mesh for input mesh triangle shape characterization statistic.cell_quality_count<viennamesh::aspect_ratio_tag>( input_mesh(), viennamesh::aspect_ratio<ElementType>, statistic_orig.median()); if(alpha.valid() && beta.valid() && gamma.valid() && delta.valid() ) { statistic.set_mesh_quality_weights(alpha(), beta(), gamma(), delta()); info(5) << "values for comprehensive mesh quality metric: alpha = " << alpha() << ", beta = " << beta() << ", gamma = " << gamma() << ", delta = "<< delta() << std::endl; } else { info(5) << "default values for comprehensive mesh quality metric used: alpha = 0.25, beta = 20, gamma = 1.0, delta = 1.3" << std::endl; } set_output("minimum_distance_rms", statistic.min_dist_rms()); set_output("mean_curvature_difference", statistic.mean_curvature()); set_output("area_deviation", statistic.volume_deviation()); set_output("triangle_shape", statistic.good_elements()/statistic.count()); set_output("mesh_quality_metric", statistic.mesh_quality_metric()); } info(5) << statistic << "\n"; #if HIST statistic.normalize(); std::vector<viennagrid_numeric> bins; for (HistogramType::const_iterator bit = statistic.histogram().begin(); bit != statistic.histogram().end(); ++bit) bins.push_back( (*bit).second ); bins.push_back( statistic.histogram().overflow_bin() ); data_handle<viennagrid_numeric> output_bins = make_data<viennagrid_numeric>(); output_bins.set( bins ); set_output( "bins", output_bins ); #endif set_output( "min", statistic.min() ); set_output( "max", statistic.max() ); set_output( "mean", statistic.mean() ); set_output( "median", statistic.median()); return true; }
bool make_statistic::generic_run() { typedef viennagrid::segmented_mesh<MeshT, SegmentationT> SegmentedMeshType; typename viennamesh::result_of::const_parameter_handle<SegmentedMeshType>::type imp = input_mesh.get<SegmentedMeshType>(); if (imp) { typedef viennamesh::statistic<double> StatisticType; typedef typename viennagrid::result_of::cell<MeshT>::type CellType; output_parameter_proxy<StatisticType> osp(output_statistic); if (histogram_bins.valid()) { osp().set_histogram( StatisticType::histogram_type::make(histogram_bins().begin(), histogram_bins().end()) ); } else if (histogram_min.valid() && histogram_max.valid() && histogram_bin_count.valid()) { osp().set_histogram( StatisticType::histogram_type::make_uniform(histogram_min(), histogram_max(), histogram_bin_count()) ); } else { error(1) << "No histogram configuration provided" << std::endl; return false; } try { if (metric_type() == "aspect_ratio") osp()( imp().mesh, viennamesh::aspect_ratio<CellType> ); else if (metric_type() == "condition_number") osp()( imp().mesh, viennamesh::condition_number<CellType> ); else if (metric_type() == "min_angle") osp()( imp().mesh, viennamesh::min_angle<CellType> ); else if (metric_type() == "max_angle") osp()( imp().mesh, viennamesh::max_angle<CellType> ); else if (metric_type() == "min_dihedral_angle") osp()( imp().mesh, viennamesh::min_dihedral_angle<CellType> ); else if (metric_type() == "radius_edge_ratio") osp()( imp().mesh, viennamesh::radius_edge_ratio<CellType> ); else { error(1) << "Metric type \"" << metric_type() << "\" is not supported" << std::endl; return false; } } catch ( metric_not_implemented_or_supported_exception const & ex ) { error(1) << "Metric type \"" << metric_type() << "\" is not supported" << std::endl; error(1) << ex.what() << std::endl; } info(5) << osp() << std::endl; return true; } return false; }