MOAB: Mesh Oriented datABase  (version 5.4.1)
idft_time_test.cpp File Reference
#include <iostream>
#include <sstream>
#include <cstdlib>
#include "Mesquite.hpp"
#include "MeshImpl.hpp"
#include "MsqError.hpp"
#include "InstructionQueue.hpp"
#include "TerminationCriterion.hpp"
#include "QualityAssessor.hpp"
#include "PlanarDomain.hpp"
#include "IdealWeightInverseMeanRatio.hpp"
#include "ElementPMeanP.hpp"
#include "TInverseMeanRatio.hpp"
#include "TQualityMetric.hpp"
#include "TOffset.hpp"
#include "IdealShapeTarget.hpp"
#include "PMeanPTemplate.hpp"
#include "SteepestDescent.hpp"
#include "ConjugateGradient.hpp"
#include "QuasiNewton.hpp"
#include "MeshWriter.hpp"
#include "MsqTimer.hpp"
#include "TestUtil.hpp"
+ Include dependency graph for idft_time_test.cpp:

Go to the source code of this file.

Classes

class  NumericQM
class  CompareMetric

Enumerations

enum  Solver { STEEP_DESCENT, CONJ_GRAD, QUASI_NEWT }

Functions

void usage (const char *argv0=0, bool err=true)
double run (QualityMetric *metric, Solver solver, const char *input_file, double &seconds_out, int &iterations_out)
int main (int argc, char *argv[])

Variables

std::string DEFAULT_INPUT = "unittest/mesquite/2D/vtk/tris/untangled/equil_tri2.vtk"
const char * vtk_file = 0
const char * eps_file = 0
const char * gpt_file = 0
const char * plot_file = 0

Enumeration Type Documentation

enum Solver
Enumerator:
STEEP_DESCENT 
CONJ_GRAD 
QUASI_NEWT 

Definition at line 96 of file idft_time_test.cpp.


Function Documentation

int main ( int  argc,
char *  argv[] 
)

Definition at line 208 of file idft_time_test.cpp.

References CONJ_GRAD, DEFAULT_INPUT, eps_file, gpt_file, input_file, plot_file, QUASI_NEWT, run(), STEEP_DESCENT, usage, and vtk_file.

{
    Solver solver              = STEEP_DESCENT;
    bool do_non_target_metric  = false;
    bool do_new_target_metric  = false;
    bool do_new_target_average = false;
    bool do_new_target_numeric = false;
    bool do_compare_metric     = false;
    const char* input_file     = DEFAULT_INPUT.c_str();
    bool no_more_flags         = false;

    std::list< const char** > exp_list;
    for( int i = 1; i < argc; ++i )
    {
        if( argv[i][0] == '-' && !no_more_flags )
        {
            for( int k = 1; argv[i][k]; ++k )
            {
                switch( argv[i][k] )
                {
                    case 'n':
                        solver = STEEP_DESCENT;
                        break;
                    case 'c':
                        solver = CONJ_GRAD;
                        break;
                    case 'q':
                        solver = QUASI_NEWT;
                        break;
                    case 'e':
                        do_non_target_metric = true;
                        break;
                    case 't':
                        do_new_target_metric = true;
                        break;
                    case 'a':
                        do_new_target_average = true;
                        break;
                    case 'N':
                        do_new_target_numeric = true;
                        break;
                    case 'C':
                        do_compare_metric = true;
                        break;
                    case 'v':
                        exp_list.push_back( &vtk_file );
                        break;
                    case 'g':
                        exp_list.push_back( &gpt_file );
                        break;
                    case 'p':
                        exp_list.push_back( &eps_file );
                        break;
                    case 'P':
                        exp_list.push_back( &plot_file );
                        break;
                    case 'h':
                        usage( argv[0], false );
                        return 0;
                    case '-':
                        no_more_flags = true;
                        break;
                    default:
                        cerr << "Invalid flag: '" << argv[i][k] << "'" << endl;
                        usage( argv[0] );
                }
            }
        }
        else if( !exp_list.empty() )
        {
            const char** ptr = exp_list.front();
            exp_list.pop_front();
            *ptr = argv[i];
        }
        else
        {
            if( !DEFAULT_INPUT.compare( input_file ) )
            {
                cerr << "Unexpected argument: \"" << argv[i] << '"' << endl;
                usage( argv[0] );
            }
            input_file = argv[i];
        }
    }

    int count = 0;
    if( do_non_target_metric ) ++count;
    if( do_new_target_metric ) ++count;
    if( do_new_target_average ) ++count;
    if( do_new_target_numeric ) ++count;
    if( do_compare_metric ) ++count;

    if( !count )
    {
        do_compare_metric = true;
        count             = 1;
    }

    if( ( vtk_file || gpt_file || eps_file ) && count != 1 )
    {
        cerr << "Error: Cannot write output file if running multiple tests" << endl;
        return 2;
    }

    IdealWeightInverseMeanRatio non_target_metric;
    IdealShapeTarget new_target;
    TInverseMeanRatio tmp;
    TOffset tmp_off( 1.0, &tmp );  // target metrics are zero-based
    TQualityMetric new_target_metric( &new_target, &tmp_off );
    ElementPMeanP new_target_average( 1.0, &new_target_metric );
    NumericQM new_target_numeric( &new_target_metric );
    CompareMetric comp_metric( &non_target_metric, &new_target_average, true );

    std::ostringstream os;
    double secs, qual;
    if( do_non_target_metric )
    {
        qual = run( &non_target_metric, solver, input_file, secs, count );
        os << "IdealWeightInverseMeanRatio: " << qual << " after " << count << " iterations in " << secs << " seconds"
           << endl;
    }
    if( do_new_target_metric )
    {
        qual = run( &new_target_metric, solver, input_file, secs, count );
        os << "TQualityMetric              : " << qual << " after " << count << " iterations in " << secs << " seconds"
           << endl;
    }
    if( do_new_target_average )
    {
        qual = run( &new_target_average, solver, input_file, secs, count );
        os << "ElementPMeanP              : " << qual << " after " << count << " iterations in " << secs << " seconds"
           << endl;
    }
    if( do_new_target_numeric )
    {
        qual = run( &new_target_numeric, solver, input_file, secs, count );
        os << "TQualityMetric (FD)         : " << qual << " after " << count << " iterations in " << secs << " seconds"
           << endl;
    }
    if( do_compare_metric )
    {
        qual = run( &comp_metric, solver, input_file, secs, count );
        os << "Metric comparison      : " << qual << " after " << count << " iterations in " << secs << " seconds"
           << endl;
    }

    cout << endl << os.str() << endl;
    return 0;
}
double run ( QualityMetric metric,
Solver  solver,
const char *  input_file,
double &  seconds_out,
int &  iterations_out 
)

Definition at line 358 of file idft_time_test.cpp.

References MBMesquite::TerminationCriterion::add_absolute_vertex_movement(), MBMesquite::TerminationCriterion::add_iteration_limit(), MBMesquite::QualityAssessor::add_quality_assessment(), MBMesquite::InstructionQueue::add_quality_assessor(), MBMesquite::arrptr(), CONJ_GRAD, eps_file, MBMesquite::MeshImpl::get_all_vertices(), MBMesquite::QualityAssessor::Assessor::get_average(), MBMesquite::TerminationCriterion::get_iteration_count(), MBMesquite::QualityAssessor::get_results(), gpt_file, MBMesquite::inner(), mesh, MBMesquite::outer(), plot_file, QUASI_NEWT, MBMesquite::MeshImpl::read_vtk(), MBMesquite::IQInterface::run_instructions(), MBMesquite::QualityImprover::set_inner_termination_criterion(), MBMesquite::InstructionQueue::set_master_quality_improver(), MBMesquite::QualityImprover::set_outer_termination_criterion(), MBMesquite::Timer::since_birth(), size, STEEP_DESCENT, MBMesquite::MeshImpl::vertices_get_coordinates(), vtk_file, MBMesquite::MeshWriter::write_eps(), MBMesquite::MeshWriter::write_gnuplot(), MBMesquite::TerminationCriterion::write_iterations(), MBMesquite::MeshWriter::write_vtk(), MBMesquite::PlanarDomain::XY, MBMesquite::PlanarDomain::XZ, and MBMesquite::PlanarDomain::YZ.

Referenced by main(), and mb_skin_adjacent_surf_patches().

{
    MsqPrintError err( cerr );
    IdealWeightInverseMeanRatio qa_metric;
    TerminationCriterion inner, outer;
    outer.add_iteration_limit( 1 );
    inner.add_absolute_vertex_movement( 1e-4 );
    inner.add_iteration_limit( 100 );
    PMeanPTemplate of( 1.0, metric );
    QualityAssessor qa( &qa_metric );
    qa.add_quality_assessment( metric );
    InstructionQueue q;
    SteepestDescent steep( &of );
    QuasiNewton quasi( &of );
    ConjugateGradient conj( &of );
    VertexMover* solver = 0;
    switch( solver_type )
    {
        case STEEP_DESCENT:
            solver = &steep;
            break;
        case QUASI_NEWT:
            solver = &quasi;
            break;
        case CONJ_GRAD:
            solver = &conj;
            break;
    }
    q.set_master_quality_improver( solver, err );
    q.add_quality_assessor( &qa, err );
    solver->set_inner_termination_criterion( &inner );
    solver->set_outer_termination_criterion( &outer );

    if( plot_file ) inner.write_iterations( plot_file, err );

    MeshImpl mesh;
    mesh.read_vtk( input_file, err );
    if( err )
    {
        cerr << "Failed to read input file: \"" << input_file << '"' << endl;
        exit( 1 );
    }

    std::vector< Mesh::VertexHandle > handles;
    mesh.get_all_vertices( handles, err );
    if( handles.empty() )
    {
        cerr << "no veritces in mesh" << endl;
        exit( 1 );
    }
    std::vector< MsqVertex > coords( handles.size() );
    mesh.vertices_get_coordinates( arrptr( handles ), arrptr( coords ), handles.size(), err );
    Vector3D min( HUGE_VAL ), max( -HUGE_VAL );
    for( size_t i = 0; i < coords.size(); ++i )
    {
        for( int j = 0; j < 3; ++j )
        {
            if( coords[i][j] < min[j] ) min[j] = coords[i][j];
            if( coords[i][j] > max[j] ) max[j] = coords[i][j];
        }
    }

    Vector3D size        = max - min;
    PlanarDomain* domain = 0;
    if( size[0] < 1e-4 )
        domain = new PlanarDomain( PlanarDomain::YZ, min[0] );
    else if( size[1] < 1e-4 )
        domain = new PlanarDomain( PlanarDomain::XZ, min[1] );
    else if( size[2] < 1e-4 )
        domain = new PlanarDomain( PlanarDomain::XY, min[2] );

    Timer timer;
    MeshDomainAssoc mesh_and_domain = MeshDomainAssoc( &mesh, domain );
    q.run_instructions( &mesh_and_domain, err );
    seconds_out = timer.since_birth();
    if( err )
    {
        cerr << "Optimization failed." << endl << err << endl;
        abort();
    }

    if( vtk_file )
    {
        MeshWriter::write_vtk( &mesh, vtk_file, err );
        if( err ) cerr << vtk_file << ": failed to write file." << endl;
    }
    if( gpt_file )
    {
        MeshWriter::write_gnuplot( &mesh, gpt_file, err );
        if( err ) cerr << gpt_file << ": failed to write file." << endl;
    }
    if( eps_file )
    {
        PlanarDomain xy( PlanarDomain::XY );
        MeshWriter::Projection proj( domain ? domain : &xy );
        MeshWriter::write_eps( &mesh, eps_file, proj, err );
        if( err ) cerr << eps_file << ": failed to write file." << endl;
    }
    delete domain;

    iterations_out = inner.get_iteration_count();

    const QualityAssessor::Assessor* a = qa.get_results( &qa_metric );
    return a->get_average();
}
void usage ( const char *  argv0 = 0,
bool  err = true 
)

Definition at line 64 of file idft_time_test.cpp.

References argv0, and DEFAULT_INPUT.

{
    std::ostream& s     = err ? cerr : cout;
    const char* defname = "main";
    if( !argv0 ) argv0 = defname;

    s << "Usage: " << defname << " [-n|-c|-q] [-e] [-t] [-a] [-N] [{-v|-g|-p} <output_file>] [<input_file>]" << endl
      << "       " << defname << " -h" << std::endl;

    if( err ) exit( 1 );

    s << "  -n : Use SteepestDescent solver (default)" << endl
      << "  -c : Use ConjugateGradient solver" << endl
      << "  -q : Use QuasiNewton solver" << endl
      << "  -e : Test IdealWeightInverseMeanRatio metric" << endl
      << "  -t : Test InverseMeanRatio3D target metric" << endl
      << "  -a : Test ElementPMeanP(InverseMeanRatio3D)" << endl
      << "  -N : Test InverseMeanRatio3D with finite difference derivatives" << endl
      << "  -C : Compare InverseMeanRatio3D and IdealWeightInverseMeanRatio" << endl
      << "  -v : Write output mesh to specified VTK file" << endl
      << "  -g : Write output mesh to specified GnuPlot file" << endl
      << "  -p : Write output mesh to specified EPS file" << endl
      << "  -P : Write solver plot data to specified file." << endl
      << "Default is all metrics if non specified." << endl
      << "Default input file: " << DEFAULT_INPUT << endl;
}

Variable Documentation

std::string DEFAULT_INPUT = "unittest/mesquite/2D/vtk/tris/untangled/equil_tri2.vtk"

Definition at line 61 of file idft_time_test.cpp.

Referenced by help(), main(), and usage().

const char* eps_file = 0

Definition at line 92 of file idft_time_test.cpp.

Referenced by main(), and run().

const char* gpt_file = 0

Definition at line 93 of file idft_time_test.cpp.

Referenced by main(), and run().

const char* plot_file = 0

Definition at line 94 of file idft_time_test.cpp.

Referenced by main(), and run().

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines