13 #include "Mesquite.hpp"
14 #include "MsqIBase.hpp"
15 #include "MsqIGeom.hpp"
16 #include "MsqIMesh.hpp"
17 #include "MBiMesh.hpp"
18 #include "MeshImpl.hpp"
22 #include "FacetModifyEngine.hpp"
23 #include "MsqError.hpp"
24 #include "InstructionQueue.hpp"
25 #include "PatchData.hpp"
26 #include "TerminationCriterion.hpp"
27 #include "QualityAssessor.hpp"
28 #include "SphericalDomain.hpp"
29 #include "PlanarDomain.hpp"
30 #include "MeshWriter.hpp"
39 #include "IdealWeightInverseMeanRatio.hpp"
40 #include "TMPQualityMetric.hpp"
41 #include "AspectRatioGammaQualityMetric.hpp"
42 #include "ConditionNumberQualityMetric.hpp"
43 #include "VertexConditionNumberQualityMetric.hpp"
44 #include "MultiplyQualityMetric.hpp"
45 #include "LPtoPTemplate.hpp"
46 #include "LInfTemplate.hpp"
47 #include "PMeanPTemplate.hpp"
48 #include "SteepestDescent.hpp"
49 #include "FeasibleNewton.hpp"
50 #include "QuasiNewton.hpp"
51 #include "ConjugateGradient.hpp"
52 #include "SmartLaplacianSmoother.hpp"
53 #include "Randomize.hpp"
55 #include "ReferenceMesh.hpp"
56 #include "RefMeshTargetCalculator.hpp"
57 #include "TShapeB1.hpp"
58 #include "TQualityMetric.hpp"
59 #include "IdealShapeTarget.hpp"
69 using namespace MBMesquite;
71 static int print_iGeom_error(
const char* desc,
int err, iGeom_Instance geom,
const char* file,
int line )
77 std::cerr <<
"ERROR: " << desc << std::endl
78 <<
" Error code: " << err << std::endl
79 <<
" Error desc: " <<
buffer << std::endl
80 <<
" At : " << file <<
':' << line << std::endl;
85 static int print_iMesh_error(
const char* desc,
int err, iMesh_Instance mesh,
const char* file,
int line )
91 std::cerr <<
"ERROR: " << desc << std::endl
92 <<
" Error code: " << err << std::endl
93 <<
" Error desc: " <<
buffer << std::endl
94 <<
" At : " << file <<
':' << line << std::endl;
99 #define CHECK_IGEOM( STR ) \
100 if( err != iBase_SUCCESS ) return print_iGeom_error( STR, err, geom, __FILE__, __LINE__ )
102 #define CHECK_IMESH( STR ) \
103 if( err != iBase_SUCCESS ) return print_iMesh_error( STR, err, instance, __FILE__, __LINE__ )
113 int get_imesh_mesh( MBMesquite::Mesh**,
const char* file_name,
int dimension );
116 int get_native_mesh( MBMesquite::Mesh**,
const char* file_name,
int dimension );
125 int run_local_smoother( MeshDomainAssoc& mesh, MsqError& err,
double OF_value = 1e-3 );
126 int run_local_smoother2( MeshDomainAssoc& mesh_and_domain, MsqError& err,
double OF_value = 1e-3 );
135 return ( stat( name.c_str(), &
buffer ) == 0 );
138 int main(
int argc,
char* argv[] )
140 MBMesquite::MsqPrintError err( cout );
142 std::string file_name, geometry_file_name;
143 bool use_native =
false;
151 opts.
addOpt<
void >( std::string(
"native,N" ), std::string(
"Use native representation (default=false)" ),
153 opts.
addOpt<
int >( std::string(
"dim,d" ), std::string(
"Topological dimension of the mesh (default=2)" ),
155 opts.
addOpt< std::string >( std::string(
"input_geo,i" ),
156 std::string(
"Input file name for the geometry (pattern=*.stl, *.facet)" ),
157 &geometry_file_name );
158 opts.
addOpt< std::string >( std::string(
"input_mesh,m" ),
159 std::string(
"Input file name for the mesh (pattern=*.vtk, *.h5m)" ), &file_name );
163 if( !geometry_file_name.length() )
167 cout <<
"No file specified: Using defaults.\n";
169 cout <<
"\t Mesh filename = " << file_name << endl;
170 cout <<
"\t Geometry filename = " << geometry_file_name << endl;
179 if( !
file_exists( geometry_file_name ) ) geometry_file_name =
"";
195 std::cerr <<
"Failed to load input file. Aborting." << std::endl;
199 MeshDomainAssoc mesh_and_domain( mesh, plane );
227 for(
int iter = 0; iter < 5; iter++ )
268 Mesh* mesh = mesh_and_domain.get_mesh();
269 MeshDomain* domain = mesh_and_domain.get_domain();
272 InstructionQueue queue1;
275 IdealWeightInverseMeanRatio* mean_ratio =
new IdealWeightInverseMeanRatio( err );
281 mean_ratio->set_averaging_method( QualityMetric::RMS, err );
285 LPtoPTemplate* obj_func =
new LPtoPTemplate( mean_ratio, 1, err );
292 SteepestDescent* pass1 =
new SteepestDescent( obj_func );
293 pass1->use_element_on_vertex_patch();
294 pass1->do_block_coordinate_descent_optimization();
295 pass1->use_global_patch();
298 QualityAssessor stop_qa( mean_ratio );
301 TerminationCriterion tc_inner;
302 tc_inner.add_absolute_vertex_movement( OF_value );
304 TerminationCriterion tc_outer;
305 tc_inner.add_iteration_limit( 10 );
306 tc_outer.add_iteration_limit( 5 );
307 tc_outer.set_debug_output_level( 3 );
308 tc_inner.set_debug_output_level( 3 );
309 pass1->set_inner_termination_criterion( &tc_inner );
310 pass1->set_outer_termination_criterion( &tc_outer );
312 queue1.add_quality_assessor( &stop_qa, err );
316 queue1.set_master_quality_improver( pass1, err );
319 queue1.add_quality_assessor( &stop_qa, err );
325 queue1.run_instructions( &mesh_and_domain, err );
329 queue1.run_instructions( mesh, err );
338 cout <<
"Wrote \"feasible-newton-result.vtk\"" << endl;
347 reinterpret_cast< MBiMesh*
>(
dynamic_cast< MsqIMesh*
>( mesh )->get_imesh_instance() )->mbImpl;
354 int run_local_smoother2( MeshDomainAssoc& mesh_and_domain, MsqError& err,
double OF_value );
357 Mesh* mesh = mesh_and_domain.get_mesh();
359 reinterpret_cast< MBiMesh*
>(
dynamic_cast< MsqIMesh*
>( mesh )->get_imesh_instance() )->mbImpl;
377 cout <<
"Wrote \"smart-laplacian-result.vtk\"" << endl;
385 Mesh* mesh = mesh_and_domain.get_mesh();
386 MeshDomain* domain = mesh_and_domain.get_domain();
389 InstructionQueue queue1;
393 ConditionNumberQualityMetric* mean_ratio =
new ConditionNumberQualityMetric();
398 mean_ratio->set_averaging_method( QualityMetric::RMS, err );
402 LPtoPTemplate* obj_func =
new LPtoPTemplate( mean_ratio, 1, err );
407 InstructionQueue qtmp;
408 Randomize rand( -0.005 );
409 TerminationCriterion sc_rand;
410 sc_rand.add_iteration_limit( 2 );
411 rand.set_outer_termination_criterion( &sc_rand );
412 qtmp.set_master_quality_improver( &rand, err );
416 qtmp.run_instructions( &mesh_and_domain, err );
420 qtmp.run_instructions( mesh, err );
426 SmartLaplacianSmoother* pass1 =
new SmartLaplacianSmoother( obj_func );
429 QualityAssessor stop_qa( mean_ratio );
432 TerminationCriterion tc_inner;
433 tc_inner.add_absolute_vertex_movement( OF_value );
434 TerminationCriterion tc_outer;
435 tc_outer.add_iteration_limit( 10 );
436 pass1->set_inner_termination_criterion( &tc_inner );
437 pass1->set_outer_termination_criterion( &tc_outer );
439 queue1.add_quality_assessor( &stop_qa, err );
443 queue1.set_master_quality_improver( pass1, err );
446 queue1.add_quality_assessor( &stop_qa, err );
452 queue1.run_instructions( &mesh_and_domain, err );
456 queue1.run_instructions( mesh, err );
465 cout <<
"Wrote \"smart-laplacian-result.vtk\"" << endl;
473 Mesh* mesh = mesh_and_domain.get_mesh();
474 MeshDomain* domain = mesh_and_domain.get_domain();
480 const double eps = 0.01;
483 TQualityMetric metric( &w, &mu );
484 PMeanPTemplate func( 1.0, &metric );
486 SteepestDescent solver( &func );
487 solver.use_element_on_vertex_patch();
488 solver.do_jacobi_optimization();
490 TerminationCriterion
inner, outer;
491 inner.add_absolute_vertex_movement( 0.5 * eps );
492 outer.add_absolute_vertex_movement( 0.5 * eps );
494 QualityAssessor qa( &metric );
496 q.add_quality_assessor( &qa, err );
498 q.set_master_quality_improver( &solver, err );
500 q.add_quality_assessor( &qa, err );
506 q.run_instructions( &mesh_and_domain, err );
510 q.run_instructions( mesh, err );
519 cout <<
"Wrote \"ideal-shape-result.vtk\"" << endl;
521 print_timing_diagnostics( cout );
527 double OF_value = 0.01;
529 Mesh* mesh = mesh_and_domain.get_mesh();
530 MeshDomain* domain = mesh_and_domain.get_domain();
533 InstructionQueue queue1;
537 ConditionNumberQualityMetric* mean_ratio =
new ConditionNumberQualityMetric();
548 mean_ratio->set_averaging_method( QualityMetric::SUM_OF_RATIOS_SQUARED, err );
552 LPtoPTemplate* obj_func =
new LPtoPTemplate( mean_ratio, 1, err );
556 ConjugateGradient* pass1 =
new ConjugateGradient( obj_func, err );
559 pass1->use_global_patch();
561 QualityAssessor stop_qa( mean_ratio );
564 TerminationCriterion tc_inner;
565 tc_inner.add_absolute_vertex_movement( OF_value );
567 TerminationCriterion tc_outer;
568 tc_inner.add_iteration_limit( 20 );
569 tc_outer.add_iteration_limit( 5 );
570 pass1->set_inner_termination_criterion( &tc_inner );
571 pass1->set_outer_termination_criterion( &tc_outer );
572 pass1->set_debugging_level( 3 );
574 queue1.add_quality_assessor( &stop_qa, err );
578 queue1.set_master_quality_improver( pass1, err );
581 queue1.add_quality_assessor( &stop_qa, err );
587 queue1.run_instructions( &mesh_and_domain, err );
591 queue1.run_instructions( mesh, err );
600 cout <<
"Wrote \"solution-mesh-result.vtk\"" << endl;
602 print_timing_diagnostics( cout );
606 int get_imesh_mesh( MBMesquite::Mesh** mesh,
const char* file_name,
int dimension )
609 iMesh_Instance instance = 0;
610 iMesh_newMesh( NULL, &instance, &err, 0 );
613 iBase_EntitySetHandle root_set;
614 iMesh_getRootSet( instance, &root_set, &err );
617 iMesh_load( instance, root_set, file_name, 0, &err, strlen( file_name ), 0 );
620 iBase_TagHandle fixed_tag;
621 iMesh_getTagHandle( instance,
"fixed", &fixed_tag, &err, strlen(
"fixed" ) );
632 moab::Interface* mbi =
reinterpret_cast< MBiMesh*
>( instance )->mbImpl;
639 "Getting tag handle failed" );
643 std::cout <<
"Found " << verts.
size() <<
" vertices and " << cells.
size() <<
" elements" << std::endl;
647 "Finding the skin of the mesh failed" );
650 std::vector< int > fix_tag( skin_verts.
size(), 1 );
652 std::cout <<
"Found " << skin_verts.
size() <<
" vertices on the skin of the domain." << std::endl;
658 iMesh_getTagHandle( instance,
"fixed", &fixed_tag, &err, strlen(
"fixed" ) );
659 CHECK_IMESH(
"Getting tag handle (fixed) failed" );
663 double def_val_dbl = 0.0;
666 "Getting tag handle failed" );
668 for(
unsigned i = 0; i < cells.
size() / 4; i++ )
670 for(
unsigned i = cells.
size() / 4; i < 2 * cells.
size() / 4; i++ )
672 for(
unsigned i = 2 * cells.
size() / 4; i < 3 * cells.
size() / 4; i++ )
674 for(
unsigned i = 3 * cells.
size() / 4; i < cells.
size(); i++ )
681 MBMesquite::MsqIMesh* imesh =
682 new MBMesquite::MsqIMesh( instance, root_set, ( dimension == 3 ? iBase_REGION : iBase_FACE ), ierr,
684 if( MSQ_CHKERR( ierr ) )
689 CHECK_IMESH(
"Creation of MsqIMesh instance failed" );
694 return iBase_SUCCESS;
700 MBMesquite::MeshImpl* imesh =
new MBMesquite::MeshImpl();
701 imesh->read_vtk( file_name, err );
709 return iBase_SUCCESS;
715 if( filename == 0 || strlen( filename ) == 0 )
717 *odomain =
new PlanarDomain( PlanarDomain::XY );
723 iGeom_newGeom(
"", &geom, &err, 0 );
726 #ifdef MOAB_HAVE_CGM_FACET
727 FacetModifyEngine::set_modify_enabled( CUBIT_TRUE );
730 iGeom_load( geom, filename, 0, &err, strlen( filename ), 0 );
733 iBase_EntitySetHandle root_set;
734 iGeom_getRootSet( geom, &root_set, &err );
738 std::cout <<
"Model contents: " << std::endl;
739 const char* gtype[] = {
"vertices: ",
"edges: ",
"faces: ",
"regions: " };
741 for(
int i = 0; i <= 3; ++i )
743 iGeom_getNumOfType( geom, root_set, i, &nents[i], &err );
744 CHECK_IGEOM(
"Error: problem getting entities after gLoad." );
745 std::cout << gtype[i] << nents[i] << std::endl;
748 iBase_EntityHandle* hd_geom_ents;
749 int csize = 0, sizealloc = 0;
752 hd_geom_ents = (iBase_EntityHandle*)malloc(
sizeof( iBase_EntityHandle ) * nents[2] );
754 iGeom_getEntities( geom, root_set, 2, &hd_geom_ents, &csize, &sizealloc, &err );
758 hd_geom_ents = (iBase_EntityHandle*)malloc(
sizeof( iBase_EntityHandle ) * nents[1] );
760 iGeom_getEntities( geom, root_set, 1, &hd_geom_ents, &csize, &sizealloc, &err );
764 *odomain =
new MsqIGeom( geom, hd_geom_ents[0] );
765 return iBase_SUCCESS;