MOAB: Mesh Oriented datABase
(version 5.2.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2010 Sandia National Laboratories. Developed at the 00005 University of Wisconsin--Madison under SNL contract number 00006 624796. The U.S. Government and the University of Wisconsin 00007 retain certain rights to this software. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 (lgpl.txt) along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 (2010) kraftche@cae.wisc.edu 00024 00025 ***************************************************************** */ 00026 00027 /** \file untangle.cpp 00028 * \brief tast untangle wrapper 00029 * \author Jason Kraftcheck 00030 */ 00031 #include "TestUtil.hpp" 00032 00033 #include "MeshImpl.hpp" 00034 #include "MsqError.hpp" 00035 #include "MsqVertex.hpp" 00036 #include "PlanarDomain.hpp" 00037 #include "UntangleWrapper.hpp" 00038 #include "QualityAssessor.hpp" 00039 00040 #include <iostream> 00041 using std::cout; 00042 using std::endl; 00043 #include <cstdlib> 00044 00045 using namespace MBMesquite; 00046 00047 std::string VTK_2D_DIR = TestDir + "/2D/vtk/"; 00048 00049 // Test untangle wrapper 00050 // Assumes all meshes lie in a plane for which the normal is [0,0,1]. 00051 int uwt( bool skip, UntangleWrapper::UntangleMetric metric, const char* input_file, 00052 int expected_number_of_remaining_inverted_elems, bool flip_domain = false ); 00053 00054 bool brief_output = false; 00055 bool write_output = false; 00056 double mu_sigma = -1; 00057 double beta = -1; 00058 00059 void usage( const char* argv0 ) 00060 { 00061 std::cerr << "Usage: " << argv0 << " [-<flags>] [-c <sigma>] [-b <beta>]" << std::endl 00062 << " " << argv0 << " -h" << std::endl; 00063 } 00064 void help( const char* argv0 ) 00065 { 00066 std::cout << "Usage: " << argv0 << " [-<flags>] [-c <sigma>] [-b <beta>]" << std::endl 00067 << "Flags: -q : brief output" << std::endl 00068 << " -w : write result meshes" << std::endl 00069 << " -B : skip tests using untangle beta target metric" << std::endl 00070 << " -Z : skip tests using size untangle target metric" << std::endl 00071 << " -P : skip tests using shapesize untangle target metric" << std::endl 00072 << " -H : skip tests using 'tangled_horse1.vtk' as input" << std::endl 00073 << " -Q : skip tests using 'hole_in_square_tanglap.vtk' as input" << std::endl 00074 << " -I : skip tests using 'inverted-hole-2.vtk' as input" << std::endl 00075 << " -S : skip tests using 'shest_grid32.vtk' as input" << std::endl 00076 << " -c : specify sigma value for untangle metrics" << std::endl 00077 << " -b : specify beta value for untangle beta metric" << std::endl 00078 << std::endl; 00079 } 00080 00081 int main( int argc, char* argv[] ) 00082 { 00083 bool skip_beta = false; 00084 bool skip_size = false; 00085 bool skip_shape = false; 00086 bool skip_horse = false; 00087 bool skip_hole = false; 00088 bool skip_invrt = false; 00089 bool skip_shest = false; 00090 std::list< double* > expected; 00091 00092 for( int i = 1; i < argc; ++i ) 00093 { 00094 if( !expected.empty() ) 00095 { 00096 char* endptr; 00097 *expected.front() = strtod( argv[i], &endptr ); 00098 if( *endptr || *expected.front() <= 0 ) 00099 { 00100 std::cerr << "Expected positive number, found \"" << argv[i] << '"' << std::endl; 00101 usage( argv[0] ); 00102 return 1; 00103 } 00104 expected.pop_front(); 00105 } 00106 else if( argv[i][0] == '-' && argv[i][1] ) 00107 { 00108 for( int j = 1; argv[i][j]; ++j ) 00109 { 00110 switch( argv[i][j] ) 00111 { 00112 case 'q': 00113 brief_output = true; 00114 break; 00115 case 'w': 00116 write_output = true; 00117 break; 00118 case 'B': 00119 skip_beta = true; 00120 break; 00121 case 'Z': 00122 skip_size = true; 00123 break; 00124 case 'P': 00125 skip_shape = true; 00126 break; 00127 case 'H': 00128 skip_horse = true; 00129 break; 00130 case 'Q': 00131 skip_hole = true; 00132 break; 00133 case 'I': 00134 skip_invrt = true; 00135 break; 00136 case 'S': 00137 skip_shest = true; 00138 break; 00139 case 'c': 00140 expected.push_back( &mu_sigma ); 00141 break; 00142 case 'b': 00143 expected.push_back( &beta ); 00144 break; 00145 case 'h': 00146 help( argv[0] ); 00147 return 0; 00148 default: 00149 std::cerr << "Invalid flag: -" << argv[i][j] << std::endl; 00150 usage( argv[0] ); 00151 return 1; 00152 } 00153 } 00154 } 00155 else 00156 { 00157 std::cerr << "Unexpected argument: \"" << argv[i] << '"' << std::endl; 00158 usage( argv[0] ); 00159 return 1; 00160 } 00161 } 00162 00163 int result = 0; 00164 00165 result += uwt( skip_beta || skip_horse, UntangleWrapper::BETA, "quads/tangled/tangled_horse1.vtk", 0 ); 00166 result += uwt( skip_beta || skip_hole, UntangleWrapper::BETA, "quads/tangled/hole_in_square_tanglap.vtk", 0, true ); 00167 result += uwt( skip_beta || skip_invrt, UntangleWrapper::BETA, "quads/tangled/inverted-hole-2.vtk", 0 ); 00168 result += uwt( skip_beta || skip_shest, UntangleWrapper::BETA, "quads/untangled/shest_grid32.vtk", 0 ); 00169 00170 result += uwt( skip_size || skip_horse, UntangleWrapper::SIZE, "quads/tangled/tangled_horse1.vtk", 0 ); 00171 result += uwt( skip_size || skip_hole, UntangleWrapper::SIZE, "quads/tangled/hole_in_square_tanglap.vtk", 6, true ); 00172 result += uwt( skip_size || skip_invrt, UntangleWrapper::SIZE, "quads/tangled/inverted-hole-2.vtk", 0 ); 00173 result += uwt( skip_size || skip_shest, UntangleWrapper::SIZE, "quads/untangled/shest_grid32.vtk", 0 ); 00174 00175 result += uwt( skip_shape || skip_horse, UntangleWrapper::SHAPESIZE, "quads/tangled/tangled_horse1.vtk", 0 ); 00176 result += 00177 uwt( skip_shape || skip_hole, UntangleWrapper::SHAPESIZE, "quads/tangled/hole_in_square_tanglap.vtk", 0, true ); 00178 result += uwt( skip_shape || skip_invrt, UntangleWrapper::SHAPESIZE, "quads/tangled/inverted-hole-2.vtk", 8 ); 00179 result += uwt( skip_shape || skip_shest, UntangleWrapper::SHAPESIZE, "quads/untangled/shest_grid32.vtk", 0 ); 00180 00181 return result; 00182 } 00183 00184 const char* tostr( UntangleWrapper::UntangleMetric m ) 00185 { 00186 static const char BETA[] = "BETA"; 00187 static const char SIZE[] = "SIZE"; 00188 static const char SHAPESIZE[] = "SHAPESIZE"; 00189 switch( m ) 00190 { 00191 case UntangleWrapper::BETA: 00192 return BETA; 00193 case UntangleWrapper::SIZE: 00194 return SIZE; 00195 case UntangleWrapper::SHAPESIZE: 00196 return SHAPESIZE; 00197 } 00198 return 0; 00199 } 00200 00201 int uwt( bool skip, UntangleWrapper::UntangleMetric metric, const char* input_file_base, int expected, 00202 bool flip_domain ) 00203 { 00204 if( skip ) return 0; 00205 00206 if( !brief_output ) std::cout << std::endl << "**********************************************" << std::endl; 00207 std::cout << "Running \"" << input_file_base << "\" for " << tostr( metric ) << std::endl; 00208 if( !brief_output ) std::cout << "**********************************************" << std::endl << std::endl; 00209 00210 // get mesh 00211 MsqError err; 00212 MeshImpl mesh; 00213 std::string input_file( VTK_2D_DIR ); 00214 input_file += input_file_base; 00215 mesh.read_vtk( input_file.c_str(), err ); 00216 if( err ) 00217 { 00218 std::cerr << err << std::endl; 00219 std::cerr << "ERROR: " << input_file << " : failed to read file" << std::endl; 00220 return 1; 00221 } 00222 // get domain 00223 std::vector< Mesh::VertexHandle > verts; 00224 mesh.get_all_vertices( verts, err ); 00225 if( err || verts.empty() ) abort(); 00226 MsqVertex coords; 00227 mesh.vertices_get_coordinates( arrptr( verts ), &coords, 1, err ); 00228 if( err ) abort(); 00229 Vector3D norm( 0, 0, flip_domain ? -1 : 1 ); 00230 PlanarDomain domain( norm, coords ); 00231 // run wrapper 00232 UntangleWrapper wrapper( metric ); 00233 wrapper.set_vertex_movement_limit_factor( 0.005 ); 00234 double constant = ( metric == UntangleWrapper::BETA ) ? beta : mu_sigma; 00235 if( constant > 0 ) wrapper.set_metric_constant( constant ); 00236 if( brief_output ) wrapper.quality_assessor().disable_printing_results(); 00237 MeshDomainAssoc mesh_and_domain = MeshDomainAssoc( &mesh, &domain ); 00238 wrapper.run_instructions( &mesh_and_domain, err ); 00239 if( err ) 00240 { 00241 std::cerr << err << std::endl; 00242 std::cerr << "ERROR: optimization failed" << std::endl; 00243 return 1; 00244 } 00245 // write output file 00246 if( write_output ) 00247 { 00248 std::string result_file( tostr( metric ) ); 00249 result_file += "-"; 00250 result_file += input_file_base; 00251 mesh.write_vtk( result_file.c_str(), err ); 00252 if( err ) 00253 { 00254 std::cerr << err << std::endl; 00255 std::cerr << "ERROR: " << result_file << " : failed to write file" << std::endl; 00256 err.clear(); 00257 } 00258 else 00259 { 00260 std::cerr << "Wrote file: " << result_file << std::endl; 00261 } 00262 } 00263 00264 // test number of inverted elements 00265 int count, junk; 00266 wrapper.quality_assessor().get_inverted_element_count( count, junk, err ); 00267 if( err ) abort(); 00268 if( count < expected ) 00269 { 00270 std::cout << "WARNING: expected " << expected << " inverted elements but finished with only " << count 00271 << std::endl 00272 << "Test needs to be updated?" << std::endl 00273 << std::endl; 00274 return 0; 00275 } 00276 else if( count == expected ) 00277 { 00278 std::cout << "Completed with " << count << " inverted elements remaining" << std::endl << std::endl; 00279 return 0; 00280 } 00281 else 00282 { 00283 std::cerr << "ERROR: expected " << expected << " inverted elements but finished with " << count << std::endl 00284 << std::endl; 00285 return 1; 00286 } 00287 }