MOAB: Mesh Oriented datABase  (version 5.4.1)
randomize.cpp
Go to the documentation of this file.
00001 #include "Randomize.hpp"
00002 #include "InstructionQueue.hpp"
00003 #include "QualityAssessor.hpp"
00004 #include "MeshImpl.hpp"
00005 
00006 #include "PatchData.hpp"
00007 #include "MsqVertex.hpp"
00008 #include "IdealWeightInverseMeanRatio.hpp"
00009 #include "PMeanPTemplate.hpp"
00010 #include "TerminationCriterion.hpp"
00011 #include <cassert>
00012 
00013 #include "domain.hpp"
00014 
00015 #include <iostream>
00016 #include <iomanip>
00017 #include <memory>
00018 #include <cstdio>
00019 #include <cstring>
00020 #include <cctype>
00021 #include <cstdlib>
00022 
00023 using namespace MBMesquite;
00024 
00025 const char INVALID_FLAG    = 'i';
00026 const char PERCENT_FLAG    = 'p';
00027 const char UNOPTIMIZE_FLAG = 'u';
00028 
00029 class UnOptimizer : public VertexMover
00030 {
00031   public:
00032     UnOptimizer( ObjectiveFunction* of ) : objectiveFunction( of ) {}
00033 
00034     virtual ~UnOptimizer() {}
00035 
00036     virtual std::string get_name() const;
00037 
00038     virtual PatchSet* get_patch_set();
00039 
00040   protected:
00041     virtual void initialize( PatchData& pd, MsqError& err );
00042 
00043     virtual void optimize_vertex_positions( PatchData& pd, MsqError& err );
00044 
00045     virtual void initialize_mesh_iteration( PatchData& pd, MsqError& err );
00046 
00047     virtual void terminate_mesh_iteration( PatchData& pd, MsqError& err );
00048 
00049     virtual void cleanup();
00050 
00051   private:
00052     std::vector< size_t > adjVtxList;
00053     VertexPatches patchSet;
00054     ObjectiveFunction* objectiveFunction;
00055 };
00056 
00057 std::string UnOptimizer::get_name() const
00058 {
00059     return "UnOptimize";
00060 }
00061 PatchSet* UnOptimizer::get_patch_set()
00062 {
00063     return &patchSet;
00064 }
00065 void UnOptimizer::initialize( PatchData&, MsqError& ) {}
00066 void UnOptimizer::initialize_mesh_iteration( PatchData&, MsqError& ) {}
00067 void UnOptimizer::terminate_mesh_iteration( PatchData&, MsqError& ) {}
00068 void UnOptimizer::cleanup() {}
00069 
00070 void UnOptimizer::optimize_vertex_positions( PatchData& pd, MsqError& err )
00071 {
00072     assert( pd.num_free_vertices() == 1 && pd.vertex_by_index( 0 ).is_free_vertex() );
00073     std::vector< Vector3D > grad( 1 );
00074     double val, junk, coeff;
00075     bool state;
00076 
00077     state = objectiveFunction->evaluate_with_gradient( ObjectiveFunction::CALCULATE, pd, val, grad, err );MSQ_ERRRTN( err );
00078     if( !state )
00079     {
00080         MSQ_SETERR( err )( MsqError::INVALID_MESH );
00081         return;
00082     }
00083     grad[0] /= grad[0].length();
00084 
00085     PatchDataVerticesMemento* memento = pd.create_vertices_memento( err );MSQ_ERRRTN( err );
00086     std::unique_ptr< PatchDataVerticesMemento > deleter( memento );
00087     pd.get_minmax_edge_length( junk, coeff );
00088 
00089     for( int i = 0; i < 100; ++i )
00090     {
00091         pd.set_free_vertices_constrained( memento, arrptr( grad ), 1, coeff, err );MSQ_ERRRTN( err );
00092         state = objectiveFunction->evaluate( ObjectiveFunction::CALCULATE, pd, val, true, err );MSQ_ERRRTN( err );
00093         if( state ) break;
00094         coeff *= 0.5;
00095     }
00096     if( !state )
00097     {
00098         pd.set_to_vertices_memento( memento, err );
00099     }
00100 }
00101 
00102 int main( int argc, char* argv[] )
00103 {
00104     const double default_fraction = 0.05;
00105     const double zero             = 0.0;
00106     int one                       = 1;
00107     CLArgs::ToggleArg allow_invalid( false );
00108     CLArgs::DoubleRangeArg rand_percent( default_fraction, &zero, 0 );
00109     CLArgs::IntRangeArg unoptimize( 0, &one, 0 );
00110 
00111     CLArgs args( "vtkrandom", "Randomize mesh vertex locations.",
00112                  "Read VTK file, randomize locations of containded vertices, and re-write file." );
00113     args.toggle_flag( INVALID_FLAG, "Allow inverted elements in output", &allow_invalid );
00114     args.double_flag( PERCENT_FLAG, "fract", "Randomize fraction", &rand_percent );
00115     args.int_flag( UNOPTIMIZE_FLAG, "N", "Use UnOptimizer with N passes rather than Randomize", &unoptimize );
00116     add_domain_args( args );
00117     args.add_required_arg( "input_file" );
00118     args.add_required_arg( "output_file" );
00119 
00120     std::vector< std::string > files;
00121     if( !args.parse_options( argc, argv, files, std::cerr ) )
00122     {
00123         args.print_usage( std::cerr );
00124         exit( 1 );
00125     }
00126     std::string input_file  = files[0];
00127     std::string output_file = files[1];
00128 
00129     MsqError err;
00130     MeshImpl mesh;
00131     mesh.read_vtk( input_file.c_str(), err );
00132     if( err )
00133     {
00134         std::cerr << "ERROR READING FILE: " << input_file << std::endl << err << std::endl;
00135         return 2;
00136     }
00137     MeshDomain* domain = process_domain_args( &mesh );
00138 
00139     TerminationCriterion tc;
00140     QualityAssessor qa( false );
00141     InstructionQueue q;
00142     Randomize op( rand_percent.value() );
00143     IdealWeightInverseMeanRatio metric;
00144     PMeanPTemplate of( 1, &metric );
00145     UnOptimizer op2( &of );
00146     if( unoptimize.seen() )
00147     {
00148         tc.add_iteration_limit( unoptimize.value() );
00149         op2.set_outer_termination_criterion( &tc );
00150         q.add_preconditioner( &op, err );
00151         q.set_master_quality_improver( &op2, err );
00152     }
00153     else
00154     {
00155         q.set_master_quality_improver( &op, err );
00156     }
00157     q.add_quality_assessor( &qa, err );
00158     MeshDomainAssoc mesh_and_domain = MeshDomainAssoc( &mesh, domain );
00159     q.run_instructions( &mesh_and_domain, err );
00160     if( err )
00161     {
00162         std::cerr << err << std::endl;
00163         return 3;
00164     }
00165 
00166     int inverted, junk;
00167     if( qa.get_inverted_element_count( inverted, junk, err ) && inverted )
00168     {
00169         if( allow_invalid.value() )
00170             std::cerr << "Warning: output mesh contains " << inverted << " inverted elements" << std::endl;
00171         else
00172         {
00173             std::cerr << "Error: output mesh contains " << inverted << " inverted elements" << std::endl;
00174             return 4;
00175         }
00176     }
00177 
00178     mesh.write_vtk( output_file.c_str(), err );
00179     if( err )
00180     {
00181         std::cerr << "ERROR WRITING FILE: " << output_file << std::endl << err << std::endl;
00182         return 2;
00183     }
00184 
00185     return 0;
00186 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines