1 #include "Mesquite.hpp"
2 #include "MsqIBase.hpp"
3 #include "MsqIGeom.hpp"
4 #include "MsqIMesh.hpp"
6 #include "MeshImpl.hpp"
10 #include "FacetModifyEngine.hpp"
11 #include "MsqError.hpp"
12 #include "InstructionQueue.hpp"
13 #include "PatchData.hpp"
14 #include "TerminationCriterion.hpp"
15 #include "QualityAssessor.hpp"
16 #include "SphericalDomain.hpp"
17 #include "PlanarDomain.hpp"
18 #include "MeshWriter.hpp"
27 #include "IdealWeightInverseMeanRatio.hpp"
28 #include "TMPQualityMetric.hpp"
29 #include "AspectRatioGammaQualityMetric.hpp"
30 #include "ConditionNumberQualityMetric.hpp"
31 #include "VertexConditionNumberQualityMetric.hpp"
32 #include "MultiplyQualityMetric.hpp"
33 #include "LPtoPTemplate.hpp"
34 #include "LInfTemplate.hpp"
35 #include "PMeanPTemplate.hpp"
36 #include "SteepestDescent.hpp"
37 #include "FeasibleNewton.hpp"
38 #include "QuasiNewton.hpp"
39 #include "ConjugateGradient.hpp"
40 #include "SmartLaplacianSmoother.hpp"
41 #include "Randomize.hpp"
43 #include "ReferenceMesh.hpp"
44 #include "RefMeshTargetCalculator.hpp"
45 #include "TShapeB1.hpp"
46 #include "TQualityMetric.hpp"
47 #include "IdealShapeTarget.hpp"
57 using namespace MBMesquite;
59 static int print_iGeom_error(
const char* desc,
int err, iGeom_Instance geom,
const char* file,
int line )
65 std::cerr <<
"ERROR: " << desc << std::endl
66 <<
" Error code: " << err << std::endl
67 <<
" Error desc: " <<
buffer << std::endl
68 <<
" At : " << file <<
':' << line << std::endl;
73 static int print_iMesh_error(
const char* desc,
int err, iMesh_Instance mesh,
const char* file,
int line )
79 std::cerr <<
"ERROR: " << desc << std::endl
80 <<
" Error code: " << err << std::endl
81 <<
" Error desc: " <<
buffer << std::endl
82 <<
" At : " << file <<
':' << line << std::endl;
87 #define CHECK_IGEOM( STR ) \
88 if( err != iBase_SUCCESS ) return print_iGeom_error( STR, err, geom, __FILE__, __LINE__ )
90 #define CHECK_IMESH( STR ) \
91 if( err != iBase_SUCCESS ) return print_iMesh_error( STR, err, instance, __FILE__, __LINE__ )
101 int get_imesh_mesh( MBMesquite::Mesh**,
const char* file_name,
int dimension );
104 int get_native_mesh( MBMesquite::Mesh**,
const char* file_name,
int dimension );
113 int run_local_smoother( MeshDomainAssoc& mesh, MsqError& err,
double OF_value = 1e-3 );
114 int run_local_smoother2( MeshDomainAssoc& mesh_and_domain, MsqError& err,
double OF_value = 1e-3 );
123 return ( stat( name.c_str(), &
buffer ) == 0 );
126 int main(
int argc,
char* argv[] )
128 MBMesquite::MsqPrintError err( cout );
130 std::string file_name, geometry_file_name;
131 bool use_native =
false;
139 opts.
addOpt<
void >( std::string(
"native,N" ), std::string(
"Use native representation (default=false)" ),
141 opts.
addOpt<
int >( std::string(
"dim,d" ), std::string(
"Topological dimension of the mesh (default=2)" ),
143 opts.
addOpt< std::string >( std::string(
"input_geo,i" ),
144 std::string(
"Input file name for the geometry (pattern=*.stl, *.facet)" ),
145 &geometry_file_name );
146 opts.
addOpt< std::string >( std::string(
"input_mesh,m" ),
147 std::string(
"Input file name for the mesh (pattern=*.vtk, *.h5m)" ), &file_name );
151 if( !geometry_file_name.length() )
155 cout <<
"No file specified: Using defaults.\n";
157 cout <<
"\t Mesh filename = " << file_name << endl;
158 cout <<
"\t Geometry filename = " << geometry_file_name << endl;
167 if( !
file_exists( geometry_file_name ) ) geometry_file_name =
"";
183 std::cerr <<
"Failed to load input file. Aborting." << std::endl;
187 MeshDomainAssoc mesh_and_domain( mesh, plane );
215 for(
int iter = 0; iter < 5; iter++ )
256 Mesh* mesh = mesh_and_domain.get_mesh();
257 MeshDomain* domain = mesh_and_domain.get_domain();
260 InstructionQueue queue1;
263 IdealWeightInverseMeanRatio* mean_ratio =
new IdealWeightInverseMeanRatio( err );
269 mean_ratio->set_averaging_method( QualityMetric::RMS, err );
273 LPtoPTemplate* obj_func =
new LPtoPTemplate( mean_ratio, 1, err );
280 SteepestDescent* pass1 =
new SteepestDescent( obj_func );
281 pass1->use_element_on_vertex_patch();
282 pass1->do_block_coordinate_descent_optimization();
283 pass1->use_global_patch();
286 QualityAssessor stop_qa( mean_ratio );
289 TerminationCriterion tc_inner;
290 tc_inner.add_absolute_vertex_movement( OF_value );
292 TerminationCriterion tc_outer;
293 tc_inner.add_iteration_limit( 10 );
294 tc_outer.add_iteration_limit( 5 );
295 tc_outer.set_debug_output_level( 3 );
296 tc_inner.set_debug_output_level( 3 );
297 pass1->set_inner_termination_criterion( &tc_inner );
298 pass1->set_outer_termination_criterion( &tc_outer );
300 queue1.add_quality_assessor( &stop_qa, err );
304 queue1.set_master_quality_improver( pass1, err );
307 queue1.add_quality_assessor( &stop_qa, err );
313 queue1.run_instructions( &mesh_and_domain, err );
317 queue1.run_instructions( mesh, err );
326 cout <<
"Wrote \"feasible-newton-result.vtk\"" << endl;
335 reinterpret_cast< MBiMesh*
>(
dynamic_cast< MsqIMesh*
>( mesh )->get_imesh_instance() )->mbImpl;
342 int run_local_smoother2( MeshDomainAssoc& mesh_and_domain, MsqError& err,
double OF_value );
345 Mesh* mesh = mesh_and_domain.get_mesh();
347 reinterpret_cast< MBiMesh*
>(
dynamic_cast< MsqIMesh*
>( mesh )->get_imesh_instance() )->mbImpl;
365 cout <<
"Wrote \"smart-laplacian-result.vtk\"" << endl;
373 Mesh* mesh = mesh_and_domain.get_mesh();
374 MeshDomain* domain = mesh_and_domain.get_domain();
377 InstructionQueue queue1;
381 ConditionNumberQualityMetric* mean_ratio =
new ConditionNumberQualityMetric();
386 mean_ratio->set_averaging_method( QualityMetric::RMS, err );
390 LPtoPTemplate* obj_func =
new LPtoPTemplate( mean_ratio, 1, err );
395 InstructionQueue qtmp;
396 Randomize rand( -0.005 );
397 TerminationCriterion sc_rand;
398 sc_rand.add_iteration_limit( 2 );
399 rand.set_outer_termination_criterion( &sc_rand );
400 qtmp.set_master_quality_improver( &rand, err );
404 qtmp.run_instructions( &mesh_and_domain, err );
408 qtmp.run_instructions( mesh, err );
414 SmartLaplacianSmoother* pass1 =
new SmartLaplacianSmoother( obj_func );
417 QualityAssessor stop_qa( mean_ratio );
420 TerminationCriterion tc_inner;
421 tc_inner.add_absolute_vertex_movement( OF_value );
422 TerminationCriterion tc_outer;
423 tc_outer.add_iteration_limit( 10 );
424 pass1->set_inner_termination_criterion( &tc_inner );
425 pass1->set_outer_termination_criterion( &tc_outer );
427 queue1.add_quality_assessor( &stop_qa, err );
431 queue1.set_master_quality_improver( pass1, err );
434 queue1.add_quality_assessor( &stop_qa, err );
440 queue1.run_instructions( &mesh_and_domain, err );
444 queue1.run_instructions( mesh, err );
453 cout <<
"Wrote \"smart-laplacian-result.vtk\"" << endl;
461 Mesh* mesh = mesh_and_domain.get_mesh();
462 MeshDomain* domain = mesh_and_domain.get_domain();
468 const double eps = 0.01;
471 TQualityMetric metric( &w, &mu );
472 PMeanPTemplate func( 1.0, &metric );
474 SteepestDescent solver( &func );
475 solver.use_element_on_vertex_patch();
476 solver.do_jacobi_optimization();
478 TerminationCriterion
inner, outer;
479 inner.add_absolute_vertex_movement( 0.5 * eps );
480 outer.add_absolute_vertex_movement( 0.5 * eps );
482 QualityAssessor qa( &metric );
484 q.add_quality_assessor( &qa, err );
486 q.set_master_quality_improver( &solver, err );
488 q.add_quality_assessor( &qa, err );
494 q.run_instructions( &mesh_and_domain, err );
498 q.run_instructions( mesh, err );
507 cout <<
"Wrote \"ideal-shape-result.vtk\"" << endl;
509 print_timing_diagnostics( cout );
515 double OF_value = 0.01;
517 Mesh* mesh = mesh_and_domain.get_mesh();
518 MeshDomain* domain = mesh_and_domain.get_domain();
521 InstructionQueue queue1;
525 ConditionNumberQualityMetric* mean_ratio =
new ConditionNumberQualityMetric();
536 mean_ratio->set_averaging_method( QualityMetric::SUM_OF_RATIOS_SQUARED, err );
540 LPtoPTemplate* obj_func =
new LPtoPTemplate( mean_ratio, 1, err );
544 ConjugateGradient* pass1 =
new ConjugateGradient( obj_func, err );
547 pass1->use_global_patch();
549 QualityAssessor stop_qa( mean_ratio );
552 TerminationCriterion tc_inner;
553 tc_inner.add_absolute_vertex_movement( OF_value );
555 TerminationCriterion tc_outer;
556 tc_inner.add_iteration_limit( 20 );
557 tc_outer.add_iteration_limit( 5 );
558 pass1->set_inner_termination_criterion( &tc_inner );
559 pass1->set_outer_termination_criterion( &tc_outer );
560 pass1->set_debugging_level( 3 );
562 queue1.add_quality_assessor( &stop_qa, err );
566 queue1.set_master_quality_improver( pass1, err );
569 queue1.add_quality_assessor( &stop_qa, err );
575 queue1.run_instructions( &mesh_and_domain, err );
579 queue1.run_instructions( mesh, err );
588 cout <<
"Wrote \"solution-mesh-result.vtk\"" << endl;
590 print_timing_diagnostics( cout );
594 int get_imesh_mesh( MBMesquite::Mesh** mesh,
const char* file_name,
int dimension )
597 iMesh_Instance instance = 0;
598 iMesh_newMesh( NULL, &instance, &err, 0 );
601 iBase_EntitySetHandle root_set;
602 iMesh_getRootSet( instance, &root_set, &err );
605 iMesh_load( instance, root_set, file_name, 0, &err, strlen( file_name ), 0 );
608 iBase_TagHandle fixed_tag;
609 iMesh_getTagHandle( instance,
"fixed", &fixed_tag, &err, strlen(
"fixed" ) );
620 moab::Interface* mbi =
reinterpret_cast< MBiMesh*
>( instance )->mbImpl;
630 std::cout <<
"Found " << verts.
size() <<
" vertices and " << cells.
size() <<
" elements" << std::endl;
634 "Finding the skin of the mesh failed" );
637 std::vector< int > fix_tag( skin_verts.
size(), 1 );
639 std::cout <<
"Found " << skin_verts.
size() <<
" vertices on the skin of the domain." << std::endl;
645 iMesh_getTagHandle( instance,
"fixed", &fixed_tag, &err, strlen(
"fixed" ) );
646 CHECK_IMESH(
"Getting tag handle (fixed) failed" );
650 double def_val_dbl = 0.0;
654 for(
unsigned i = 0; i < cells.
size() / 4; i++ )
656 for(
unsigned i = cells.
size() / 4; i < 2 * cells.
size() / 4; i++ )
658 for(
unsigned i = 2 * cells.
size() / 4; i < 3 * cells.
size() / 4; i++ )
660 for(
unsigned i = 3 * cells.
size() / 4; i < cells.
size(); i++ )
667 MBMesquite::MsqIMesh* imesh =
668 new MBMesquite::MsqIMesh( instance, root_set, ( dimension == 3 ? iBase_REGION : iBase_FACE ), ierr,
670 if( MSQ_CHKERR( ierr ) )
675 CHECK_IMESH(
"Creation of MsqIMesh instance failed" );
680 return iBase_SUCCESS;
686 MBMesquite::MeshImpl* imesh =
new MBMesquite::MeshImpl();
687 imesh->read_vtk( file_name, err );
695 return iBase_SUCCESS;
701 if( filename == 0 || strlen( filename ) == 0 )
703 *odomain =
new PlanarDomain( PlanarDomain::XY );
709 iGeom_newGeom(
"", &geom, &err, 0 );
712 #ifdef MOAB_HAVE_CGM_FACET
713 FacetModifyEngine::set_modify_enabled( CUBIT_TRUE );
716 iGeom_load( geom, filename, 0, &err, strlen( filename ), 0 );
719 iBase_EntitySetHandle root_set;
720 iGeom_getRootSet( geom, &root_set, &err );
724 std::cout <<
"Model contents: " << std::endl;
725 const char* gtype[] = {
"vertices: ",
"edges: ",
"faces: ",
"regions: " };
727 for(
int i = 0; i <= 3; ++i )
729 iGeom_getNumOfType( geom, root_set, i, &nents[i], &err );
730 CHECK_IGEOM(
"Error: problem getting entities after gLoad." );
731 std::cout << gtype[i] << nents[i] << std::endl;
734 iBase_EntityHandle* hd_geom_ents;
735 int csize = 0, sizealloc = 0;
738 hd_geom_ents = (iBase_EntityHandle*)malloc(
sizeof( iBase_EntityHandle ) * nents[2] );
740 iGeom_getEntities( geom, root_set, 2, &hd_geom_ents, &csize, &sizealloc, &err );
744 hd_geom_ents = (iBase_EntityHandle*)malloc(
sizeof( iBase_EntityHandle ) * nents[1] );
746 iGeom_getEntities( geom, root_set, 1, &hd_geom_ents, &csize, &sizealloc, &err );
750 *odomain =
new MsqIGeom( geom, hd_geom_ents[0] );
751 return iBase_SUCCESS;