MOAB: Mesh Oriented datABase  (version 5.2.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 <assert.h>
00012 
00013 #include "domain.hpp"
00014 
00015 #include <iostream>
00016 #include <iomanip>
00017 #include <memory>
00018 #include <stdio.h>
00019 #include <string.h>
00020 #include <ctype.h>
00021 #include <stdlib.h>
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::auto_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 ) { pd.set_to_vertices_memento( memento, err ); }
00097 }
00098 
00099 int main( int argc, char* argv[] )
00100 {
00101     const double default_fraction = 0.05;
00102     const double zero             = 0.0;
00103     int one                       = 1;
00104     CLArgs::ToggleArg allow_invalid( false );
00105     CLArgs::DoubleRangeArg rand_percent( default_fraction, &zero, 0 );
00106     CLArgs::IntRangeArg unoptimize( 0, &one, 0 );
00107 
00108     CLArgs args( "vtkrandom", "Randomize mesh vertex locations.",
00109                  "Read VTK file, randomize locations of containded vertices, and re-write file." );
00110     args.toggle_flag( INVALID_FLAG, "Allow inverted elements in output", &allow_invalid );
00111     args.double_flag( PERCENT_FLAG, "fract", "Randomize fraction", &rand_percent );
00112     args.int_flag( UNOPTIMIZE_FLAG, "N", "Use UnOptimizer with N passes rather than Randomize", &unoptimize );
00113     add_domain_args( args );
00114     args.add_required_arg( "input_file" );
00115     args.add_required_arg( "output_file" );
00116 
00117     std::vector< std::string > files;
00118     if( !args.parse_options( argc, argv, files, std::cerr ) )
00119     {
00120         args.print_usage( std::cerr );
00121         exit( 1 );
00122     }
00123     std::string input_file  = files[0];
00124     std::string output_file = files[1];
00125 
00126     MsqError err;
00127     MeshImpl mesh;
00128     mesh.read_vtk( input_file.c_str(), err );
00129     if( err )
00130     {
00131         std::cerr << "ERROR READING FILE: " << input_file << std::endl << err << std::endl;
00132         return 2;
00133     }
00134     MeshDomain* domain = process_domain_args( &mesh );
00135 
00136     TerminationCriterion tc;
00137     QualityAssessor qa( false );
00138     InstructionQueue q;
00139     Randomize op( rand_percent.value() );
00140     IdealWeightInverseMeanRatio metric;
00141     PMeanPTemplate of( 1, &metric );
00142     UnOptimizer op2( &of );
00143     if( unoptimize.seen() )
00144     {
00145         tc.add_iteration_limit( unoptimize.value() );
00146         op2.set_outer_termination_criterion( &tc );
00147         q.add_preconditioner( &op, err );
00148         q.set_master_quality_improver( &op2, err );
00149     }
00150     else
00151     {
00152         q.set_master_quality_improver( &op, err );
00153     }
00154     q.add_quality_assessor( &qa, err );
00155     MeshDomainAssoc mesh_and_domain = MeshDomainAssoc( &mesh, domain );
00156     q.run_instructions( &mesh_and_domain, err );
00157     if( err )
00158     {
00159         std::cerr << err << std::endl;
00160         return 3;
00161     }
00162 
00163     int inverted, junk;
00164     if( qa.get_inverted_element_count( inverted, junk, err ) && inverted )
00165     {
00166         if( allow_invalid.value() )
00167             std::cerr << "Warning: output mesh contains " << inverted << " inverted elements" << std::endl;
00168         else
00169         {
00170             std::cerr << "Error: output mesh contains " << inverted << " inverted elements" << std::endl;
00171             return 4;
00172         }
00173     }
00174 
00175     mesh.write_vtk( output_file.c_str(), err );
00176     if( err )
00177     {
00178         std::cerr << "ERROR WRITING FILE: " << output_file << std::endl << err << std::endl;
00179         return 2;
00180     }
00181 
00182     return 0;
00183 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines