Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
OptimizeMeshMesquite.cpp
Go to the documentation of this file.
1 /** @example OptimizeMeshMesquite.cpp
2  * This example demonstrates mesh optimization using the Mesquite library.
3  * It shows how to load meshes using both native MOAB and iMesh interfaces,
4  * apply various mesh optimization algorithms from Mesquite,
5  * use different quality metrics (aspect ratio, condition number, etc.),
6  * perform global and local mesh smoothing,
7  * handle geometry constraints using domain definitions,
8  * and measure mesh quality before and after optimization.
9  * The example demonstrates integration between MOAB and Mesquite
10  * for advanced mesh optimization and quality improvement.
11  */
12 
13 #include "Mesquite.hpp"
14 #include "MsqIBase.hpp"
15 #include "MsqIGeom.hpp"
16 #include "MsqIMesh.hpp"
17 #include "MBiMesh.hpp"
18 #include "MeshImpl.hpp"
19 #include "moab/Core.hpp"
20 #include "moab/Skinner.hpp"
21 #include "moab/LloydSmoother.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"
31 
32 #include "moab/Core.hpp"
33 #include "moab/ProgOptions.hpp"
34 #ifdef MOAB_HAVE_MPI
35 #include "moab/ParallelComm.hpp"
36 #endif
37 
38 // algorithms
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"
54 
55 #include "ReferenceMesh.hpp"
56 #include "RefMeshTargetCalculator.hpp"
57 #include "TShapeB1.hpp"
58 #include "TQualityMetric.hpp"
59 #include "IdealShapeTarget.hpp"
60 
61 #include <sys/stat.h>
62 #include <iostream>
63 using std::cerr;
64 using std::cout;
65 using std::endl;
66 
67 #include "iBase.h"
68 
69 using namespace MBMesquite;
70 
71 static int print_iGeom_error( const char* desc, int err, iGeom_Instance geom, const char* file, int line )
72 {
73  char buffer[1024];
74  iGeom_getDescription( geom, buffer, sizeof( buffer ) );
75  buffer[sizeof( buffer ) - 1] = '\0';
76 
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;
81 
82  return -1; // must always return false or CHECK macro will break
83 }
84 
85 static int print_iMesh_error( const char* desc, int err, iMesh_Instance mesh, const char* file, int line )
86 {
87  char buffer[1024];
88  iMesh_getDescription( mesh, buffer, sizeof( buffer ) );
89  buffer[sizeof( buffer ) - 1] = '\0';
90 
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;
95 
96  return -1; // must always return false or CHECK macro will break
97 }
98 
99 #define CHECK_IGEOM( STR ) \
100  if( err != iBase_SUCCESS ) return print_iGeom_error( STR, err, geom, __FILE__, __LINE__ )
101 
102 #define CHECK_IMESH( STR ) \
103  if( err != iBase_SUCCESS ) return print_iMesh_error( STR, err, instance, __FILE__, __LINE__ )
104 
105 const std::string default_file_name = std::string( MESH_DIR ) + std::string( "/surfrandomtris-4part.h5m" );
106 const std::string default_geometry_file_name = std::string( MESH_DIR ) + std::string( "/surfrandom.facet" );
107 
108 std::vector< double > solution_indicator;
109 
110 int write_vtk_mesh( Mesh* mesh, const char* filename );
111 
112 // Construct a MeshTSTT from the file
113 int get_imesh_mesh( MBMesquite::Mesh**, const char* file_name, int dimension );
114 
115 // Construct a MeshImpl from the file
116 int get_native_mesh( MBMesquite::Mesh**, const char* file_name, int dimension );
117 
118 int get_itaps_domain( MeshDomain**, const char* );
119 int get_mesquite_domain( MeshDomain**, const char* );
120 
121 // Run FeasibleNewton solver
122 int run_global_smoother( MeshDomainAssoc& mesh, MsqError& err, double OF_value = 1e-4 );
123 
124 // Run SmoothLaplacian solver
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 );
127 
128 int run_quality_optimizer( MeshDomainAssoc& mesh_and_domain, MsqError& err );
129 
130 int run_solution_mesh_optimizer( MeshDomainAssoc& mesh_and_domain, MsqError& err );
131 
132 bool file_exists( const std::string& name )
133 {
134  struct stat buffer;
135  return ( stat( name.c_str(), &buffer ) == 0 );
136 }
137 
138 int main( int argc, char* argv[] )
139 {
140  MBMesquite::MsqPrintError err( cout );
141  // command line arguments
142  std::string file_name, geometry_file_name;
143  bool use_native = false;
144  int dimension = 2;
145 
146 #ifdef MOAB_HAVE_MPI
147 // MPI_Init(&argc, &argv);
148 #endif
149  ProgOptions opts;
150 
151  opts.addOpt< void >( std::string( "native,N" ), std::string( "Use native representation (default=false)" ),
152  &use_native );
153  opts.addOpt< int >( std::string( "dim,d" ), std::string( "Topological dimension of the mesh (default=2)" ),
154  &dimension );
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 );
160 
161  opts.parseCommandLine( argc, argv );
162 
163  if( !geometry_file_name.length() )
164  {
165  file_name = default_file_name;
166  geometry_file_name = default_geometry_file_name;
167  cout << "No file specified: Using defaults.\n";
168  }
169  cout << "\t Mesh filename = " << file_name << endl;
170  cout << "\t Geometry filename = " << geometry_file_name << endl;
171 
172  // Vector3D pnt(0,0,0);
173  // Vector3D s_norm(0,0,1);
174  // PlanarDomain plane(s_norm, pnt);
175 
176  // PlanarDomain plane( PlanarDomain::XY );
177  MeshDomain* plane;
178  int ierr;
179  if( !file_exists( geometry_file_name ) ) geometry_file_name = "";
180  ierr = get_itaps_domain( &plane, geometry_file_name.c_str() ); // MB_CHK_ERR(ierr);
181 
182  // Try running a global smoother on the mesh
183  Mesh* mesh = 0;
184  if( use_native )
185  {
186  ierr = get_native_mesh( &mesh, file_name.c_str(), dimension ); // MB_CHK_ERR(ierr);
187  }
188  else
189  {
190  ierr = get_imesh_mesh( &mesh, file_name.c_str(), dimension ); // MB_CHK_ERR(ierr);
191  }
192 
193  if( !mesh )
194  {
195  std::cerr << "Failed to load input file. Aborting." << std::endl;
196  return 1;
197  }
198 
199  MeshDomainAssoc mesh_and_domain( mesh, plane );
200 
201  // ierr = write_vtk_mesh( mesh, "original.vtk");MB_CHK_ERR(ierr);
202  // cout << "Wrote \"original.vtk\"" << endl;
203 
204  // run_global_smoother( mesh_and_domain, err );
205  // if (err) return 1;
206 
207  // Try running a local smoother on the mesh
208  // Mesh* meshl=0;
209  // if(use_native)
210  // ierr = get_native_mesh(&meshl, file_name.c_str(), dimension);
211  // else
212  // ierr = get_imesh_mesh(&meshl, file_name.c_str(), dimension);
213  // if (!mesh || ierr) {
214  // std::cerr << "Failed to load input file. Aborting." << std::endl;
215  // return 1;
216  // }
217 
218  // MeshDomainAssoc mesh_and_domain_local(meshl, plane);
219 
220  // run_solution_mesh_optimizer( mesh_and_domain, err );
221  // if (err) return 1;
222 
223  run_local_smoother( mesh_and_domain, err, 1e-4 ); // MB_CHK_ERR(err);
224  if( err ) return 1;
225 
226  double reps = 5e-2;
227  for( int iter = 0; iter < 5; iter++ )
228  {
229 
230  if( !( iter % 2 ) )
231  {
232  run_local_smoother2( mesh_and_domain, err,
233  reps * 10 ); // CHECK_IMESH("local smoother2 failed");
234  if( err ) return 1;
235  }
236 
237  // run_global_smoother( mesh_and_domain, err, reps );MB_CHK_ERR(ierr);
238 
239  run_solution_mesh_optimizer( mesh_and_domain,
240  err ); // CHECK_IMESH("solution mesh optimizer failed");
241  if( err ) return 1;
242 
243  reps *= 0.01;
244  }
245 
246  run_local_smoother2( mesh_and_domain, err, 1e-4 ); // CHECK_IMESH("local smoother2 failed");
247  if( err ) return 1;
248 
249  // run_quality_optimizer( mesh_and_domain, err );MB_CHK_ERR(ierr);
250 
251  // run_local_smoother( mesh_and_domain, err );MB_CHK_ERR(ierr);
252 
253  // Delete MOAB instance
254  delete mesh;
255  delete plane;
256 
257 #ifdef MOAB_HAVE_MPI
258  // MPI_Finalize();
259 #endif
260 
261  return 0;
262 }
263 
264 int run_global_smoother( MeshDomainAssoc& mesh_and_domain, MsqError& err, double OF_value )
265 {
266  // double OF_value = 1e-6;
267 
268  Mesh* mesh = mesh_and_domain.get_mesh();
269  MeshDomain* domain = mesh_and_domain.get_domain();
270 
271  // creates an intruction queue
272  InstructionQueue queue1;
273 
274  // creates a mean ratio quality metric ...
275  IdealWeightInverseMeanRatio* mean_ratio = new IdealWeightInverseMeanRatio( err );
276  // ConditionNumberQualityMetric* mean_ratio = new ConditionNumberQualityMetric();
277  // TMPQualityMetric* mean_ratio = new TMPQualityMetric();
278 
279  // VertexConditionNumberQualityMetric* mean_ratio = new VertexConditionNumberQualityMetric();
280  if( err ) return 1;
281  mean_ratio->set_averaging_method( QualityMetric::RMS, err );
282  if( err ) return 1;
283 
284  // ... and builds an objective function with it
285  LPtoPTemplate* obj_func = new LPtoPTemplate( mean_ratio, 1, err );
286  // LInfTemplate* obj_func = new LInfTemplate(mean_ratio);
287  if( err ) return 1;
288 
289  // creates the feas newt optimization procedures
290  // ConjugateGradient* pass1 = new ConjugateGradient( obj_func, err );
291  // FeasibleNewton* pass1 = new FeasibleNewton( obj_func );
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();
296  if( err ) return 1;
297 
298  QualityAssessor stop_qa( mean_ratio );
299 
300  // **************Set stopping criterion****************
301  TerminationCriterion tc_inner;
302  tc_inner.add_absolute_vertex_movement( OF_value );
303  if( err ) return 1;
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 );
311 
312  queue1.add_quality_assessor( &stop_qa, err );
313  if( err ) return 1;
314 
315  // adds 1 pass of pass1 to mesh_set1
316  queue1.set_master_quality_improver( pass1, err );
317  if( err ) return 1;
318 
319  queue1.add_quality_assessor( &stop_qa, err );
320  if( err ) return 1;
321 
322  // launches optimization on mesh_set
323  if( domain )
324  {
325  queue1.run_instructions( &mesh_and_domain, err );
326  }
327  else
328  {
329  queue1.run_instructions( mesh, err );
330  }
331  if( err ) return 1;
332 
333  // Construct a MeshTSTT from the file
334  int ierr = write_vtk_mesh( mesh, "feasible-newton-result.vtk" );
335  if( ierr ) return 1;
336  // MeshWriter::write_vtk(mesh, "feasible-newton-result.vtk", err);
337  // if (err) return 1;
338  cout << "Wrote \"feasible-newton-result.vtk\"" << endl;
339 
340  // print_timing_diagnostics( cout );
341  return 0;
342 }
343 
344 int write_vtk_mesh( Mesh* mesh, const char* filename )
345 {
346  moab::Interface* mbi =
347  reinterpret_cast< MBiMesh* >( dynamic_cast< MsqIMesh* >( mesh )->get_imesh_instance() )->mbImpl;
348 
349  mbi->write_file( filename );
350 
351  return 0;
352 }
353 
354 int run_local_smoother2( MeshDomainAssoc& mesh_and_domain, MsqError& err, double OF_value );
355 int run_local_smoother( MeshDomainAssoc& mesh_and_domain, MsqError& err, double OF_value )
356 {
357  Mesh* mesh = mesh_and_domain.get_mesh();
358  moab::Interface* mbi =
359  reinterpret_cast< MBiMesh* >( dynamic_cast< MsqIMesh* >( mesh )->get_imesh_instance() )->mbImpl;
360 
361  moab::Tag fixed;
362  MB_CHK_SET_ERR( mbi->tag_get_handle( "fixed", 1, moab::MB_TYPE_INTEGER, fixed ), "Getting tag handle failed" );
363  moab::Range cells;
364  MB_CHK_SET_ERR( mbi->get_entities_by_dimension( 0, 2, cells ), "Querying elements failed" );
365 
366  moab::LloydSmoother lloyd( mbi, 0, cells, 0, 0 /*fixed*/ );
367 
368  lloyd.perform_smooth();
369 
370  // run_local_smoother2(mesh_and_domain, err, OF_value);
371 
372  // Construct a MeshTSTT from the file
373  int ierr = write_vtk_mesh( mesh, "smart-laplacian-result.vtk" );
374  if( ierr ) return 1;
375  // MeshWriter::write_vtk(mesh, "smart-laplacian-result.vtk", err);
376  // if (err) return 1;
377  cout << "Wrote \"smart-laplacian-result.vtk\"" << endl;
378  return 0;
379 }
380 
381 int run_local_smoother2( MeshDomainAssoc& mesh_and_domain, MsqError& err, double OF_value )
382 {
383  // double OF_value = 1e-5;
384 
385  Mesh* mesh = mesh_and_domain.get_mesh();
386  MeshDomain* domain = mesh_and_domain.get_domain();
387 
388  // creates an intruction queue
389  InstructionQueue queue1;
390 
391  // creates a mean ratio quality metric ...
392  // IdealWeightInverseMeanRatio* mean_ratio = new IdealWeightInverseMeanRatio(err);
393  ConditionNumberQualityMetric* mean_ratio = new ConditionNumberQualityMetric();
394  // VertexConditionNumberQualityMetric* mean_ratio = new VertexConditionNumberQualityMetric();
395  if( err ) return 1;
396  // mean_ratio->set_gradient_type(QualityMetric::NUMERICAL_GRADIENT);
397  // mean_ratio->set_hessian_type(QualityMetric::NUMERICAL_HESSIAN);
398  mean_ratio->set_averaging_method( QualityMetric::RMS, err );
399  if( err ) return 1;
400 
401  // ... and builds an objective function with it
402  LPtoPTemplate* obj_func = new LPtoPTemplate( mean_ratio, 1, err );
403  if( err ) return 1;
404 
405  if( false )
406  {
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 );
413  if( err ) return 1;
414  if( domain )
415  {
416  qtmp.run_instructions( &mesh_and_domain, err );
417  }
418  else
419  {
420  qtmp.run_instructions( mesh, err );
421  }
422  if( err ) return 1;
423  }
424 
425  // creates the smart laplacian optimization procedures
426  SmartLaplacianSmoother* pass1 = new SmartLaplacianSmoother( obj_func );
427  // SteepestDescent* pass1 = new SteepestDescent( obj_func );
428 
429  QualityAssessor stop_qa( mean_ratio );
430 
431  // **************Set stopping criterion****************
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 );
438 
439  queue1.add_quality_assessor( &stop_qa, err );
440  if( err ) return 1;
441 
442  // adds 1 pass of pass1 to mesh_set
443  queue1.set_master_quality_improver( pass1, err );
444  if( err ) return 1;
445 
446  queue1.add_quality_assessor( &stop_qa, err );
447  if( err ) return 1;
448 
449  // launches optimization on mesh_set
450  if( domain )
451  {
452  queue1.run_instructions( &mesh_and_domain, err );
453  }
454  else
455  {
456  queue1.run_instructions( mesh, err );
457  }
458  if( err ) return 1;
459 
460  // Construct a MeshTSTT from the file
461  int ierr = write_vtk_mesh( mesh, "smart-laplacian-result.vtk" );
462  if( ierr ) return 1;
463  // MeshWriter::write_vtk(mesh, "smart-laplacian-result.vtk", err);
464  // if (err) return 1;
465  cout << "Wrote \"smart-laplacian-result.vtk\"" << endl;
466 
467  // print_timing_diagnostics( cout );
468  return 0;
469 }
470 
471 int run_quality_optimizer( MeshDomainAssoc& mesh_and_domain, MsqError& err )
472 {
473  Mesh* mesh = mesh_and_domain.get_mesh();
474  MeshDomain* domain = mesh_and_domain.get_domain();
475 
476  // creates an intruction queue
477  InstructionQueue q;
478 
479  // do optimization
480  const double eps = 0.01;
481  IdealShapeTarget w;
482  TShapeB1 mu;
483  TQualityMetric metric( &w, &mu );
484  PMeanPTemplate func( 1.0, &metric );
485 
486  SteepestDescent solver( &func );
487  solver.use_element_on_vertex_patch();
488  solver.do_jacobi_optimization();
489 
490  TerminationCriterion inner, outer;
491  inner.add_absolute_vertex_movement( 0.5 * eps );
492  outer.add_absolute_vertex_movement( 0.5 * eps );
493 
494  QualityAssessor qa( &metric );
495 
496  q.add_quality_assessor( &qa, err );
497  if( err ) return 1;
498  q.set_master_quality_improver( &solver, err );
499  if( err ) return 1;
500  q.add_quality_assessor( &qa, err );
501  if( err ) return 1;
502 
503  // launches optimization on mesh_set
504  if( domain )
505  {
506  q.run_instructions( &mesh_and_domain, err );
507  }
508  else
509  {
510  q.run_instructions( mesh, err );
511  }
512  if( err ) return 1;
513 
514  // Construct a MeshTSTT from the file
515  int ierr = write_vtk_mesh( mesh, "ideal-shape-result.vtk" );
516  if( ierr ) return 1;
517  // MeshWriter::write_vtk(mesh, "ideal-shape-result.vtk", err);
518  // if (err) return 1;
519  cout << "Wrote \"ideal-shape-result.vtk\"" << endl;
520 
521  print_timing_diagnostics( cout );
522  return 0;
523 }
524 
525 int run_solution_mesh_optimizer( MeshDomainAssoc& mesh_and_domain, MsqError& err )
526 {
527  double OF_value = 0.01;
528 
529  Mesh* mesh = mesh_and_domain.get_mesh();
530  MeshDomain* domain = mesh_and_domain.get_domain();
531 
532  // creates an intruction queue
533  InstructionQueue queue1;
534 
535  // creates a mean ratio quality metric ...
536  // IdealWeightInverseMeanRatio* mean_ratio = new IdealWeightInverseMeanRatio(err);
537  ConditionNumberQualityMetric* mean_ratio = new ConditionNumberQualityMetric();
538  // VertexConditionNumberQualityMetric* mean_ratio = new VertexConditionNumberQualityMetric();
539  // AspectRatioGammaQualityMetric* mean_ratio = new AspectRatioGammaQualityMetric();
540 
541  // ElementSolIndQM* solindqm = new ElementSolIndQM(solution_indicator);
542  // MultiplyQualityMetric* mean_ratio = new MultiplyQualityMetric(new
543  // VertexConditionNumberQualityMetric(), solindqm, err);
544  // ElementSolIndQM* mean_ratio = solindqm;
545 
546  // LocalSizeQualityMetric* mean_ratio = new LocalSizeQualityMetric();
547 
548  mean_ratio->set_averaging_method( QualityMetric::SUM_OF_RATIOS_SQUARED, err );
549  if( err ) return 1;
550 
551  // ... and builds an objective function with it
552  LPtoPTemplate* obj_func = new LPtoPTemplate( mean_ratio, 1, err );
553  if( err ) return 1;
554 
555  // // creates the feas newt optimization procedures
556  ConjugateGradient* pass1 = new ConjugateGradient( obj_func, err );
557  // QuasiNewton* pass1 = new QuasiNewton( obj_func );
558  // FeasibleNewton* pass1 = new FeasibleNewton( obj_func );
559  pass1->use_global_patch();
560 
561  QualityAssessor stop_qa( mean_ratio );
562 
563  // **************Set stopping criterion****************
564  TerminationCriterion tc_inner;
565  tc_inner.add_absolute_vertex_movement( OF_value );
566  if( err ) return 1;
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 );
573 
574  queue1.add_quality_assessor( &stop_qa, err );
575  if( err ) return 1;
576 
577  // adds 1 pass of pass1 to mesh_set1
578  queue1.set_master_quality_improver( pass1, err );
579  if( err ) return 1;
580 
581  queue1.add_quality_assessor( &stop_qa, err );
582  if( err ) return 1;
583 
584  // launches optimization on mesh_set
585  if( domain )
586  {
587  queue1.run_instructions( &mesh_and_domain, err );
588  }
589  else
590  {
591  queue1.run_instructions( mesh, err );
592  }
593  if( err ) return 1;
594 
595  // Construct a MeshTSTT from the file
596  int ierr = write_vtk_mesh( mesh, "solution-mesh-result.vtk" );
597  if( ierr ) return 1;
598  // MeshWriter::write_vtk(mesh, "solution-mesh-result.vtk", err);
599  // if (err) return 1;
600  cout << "Wrote \"solution-mesh-result.vtk\"" << endl;
601 
602  print_timing_diagnostics( cout );
603  return 0;
604 }
605 
606 int get_imesh_mesh( MBMesquite::Mesh** mesh, const char* file_name, int dimension )
607 {
608  int err;
609  iMesh_Instance instance = 0;
610  iMesh_newMesh( NULL, &instance, &err, 0 );
611  CHECK_IMESH( "Creation of mesh instance failed" );
612 
613  iBase_EntitySetHandle root_set;
614  iMesh_getRootSet( instance, &root_set, &err );
615  CHECK_IMESH( "Could not get root set" );
616 
617  iMesh_load( instance, root_set, file_name, 0, &err, strlen( file_name ), 0 );
618  CHECK_IMESH( "Could not load mesh from file" );
619 
620  iBase_TagHandle fixed_tag;
621  iMesh_getTagHandle( instance, "fixed", &fixed_tag, &err, strlen( "fixed" ) );
622  // if (iBase_SUCCESS != err)
623  {
624  // get the skin vertices of those cells and mark them as fixed; we don't want to fix the
625  // vertices on a part boundary, but since we exchanged a layer of ghost cells, those
626  // vertices aren't on the skin locally ok to mark non-owned skin vertices too, I won't move
627  // those anyway use MOAB's skinner class to find the skin
628 
629  // get all vertices and cells
630  // make tag to specify fixed vertices, since it's input to the algorithm; use a default
631  // value of non-fixed so we only need to set the fixed tag for skin vertices
632  moab::Interface* mbi = reinterpret_cast< MBiMesh* >( instance )->mbImpl;
633  moab::EntityHandle currset = 0;
634  moab::Tag fixed;
635  int def_val = 0;
636  err = 0;
639  "Getting tag handle failed" );
640  moab::Range verts, cells, skin_verts;
641  MB_CHK_SET_ERR( mbi->get_entities_by_type( currset, moab::MBVERTEX, verts ), "Querying vertices failed" );
642  MB_CHK_SET_ERR( mbi->get_entities_by_dimension( currset, dimension, cells ), "Querying elements failed" );
643  std::cout << "Found " << verts.size() << " vertices and " << cells.size() << " elements" << std::endl;
644 
645  moab::Skinner skinner( mbi );
646  MB_CHK_SET_ERR( skinner.find_skin( currset, cells, true, skin_verts ),
647  "Finding the skin of the mesh failed" ); // 'true' param indicates we want
648  // vertices back, not cells
649 
650  std::vector< int > fix_tag( skin_verts.size(), 1 ); // initialized to 1 to indicate fixed
651  MB_CHK_SET_ERR( mbi->tag_set_data( fixed, skin_verts, &fix_tag[0] ), "Setting tag data failed" );
652  std::cout << "Found " << skin_verts.size() << " vertices on the skin of the domain." << std::endl;
653 
654  // fix_tag.resize(verts.size(),0);
655  // MB_CHK_SET_ERR( mbi->tag_get_data(fixed, verts, &fix_tag[0]), "Getting tag
656  // data failed" );
657 
658  iMesh_getTagHandle( instance, "fixed", &fixed_tag, &err, strlen( "fixed" ) );
659  CHECK_IMESH( "Getting tag handle (fixed) failed" );
660 
661  // Set some arbitrary solution indicator
662  moab::Tag solindTag;
663  double def_val_dbl = 0.0;
664  MB_CHK_SET_ERR( mbi->tag_get_handle( "solution_indicator", 1, moab::MB_TYPE_DOUBLE, solindTag,
665  moab::MB_TAG_CREAT | moab::MB_TAG_DENSE, &def_val_dbl ),
666  "Getting tag handle failed" );
667  solution_indicator.resize( cells.size(), 0.01 );
668  for( unsigned i = 0; i < cells.size() / 4; i++ )
669  solution_indicator[i] = 0.1;
670  for( unsigned i = cells.size() / 4; i < 2 * cells.size() / 4; i++ )
671  solution_indicator[i] = 0.5;
672  for( unsigned i = 2 * cells.size() / 4; i < 3 * cells.size() / 4; i++ )
673  solution_indicator[i] = 0.5;
674  for( unsigned i = 3 * cells.size() / 4; i < cells.size(); i++ )
675  solution_indicator[i] = 0.5;
676 
677  MB_CHK_SET_ERR( mbi->tag_set_data( solindTag, cells, &solution_indicator[0] ), "Setting tag data failed" );
678  }
679 
680  MsqError ierr;
681  MBMesquite::MsqIMesh* imesh =
682  new MBMesquite::MsqIMesh( instance, root_set, ( dimension == 3 ? iBase_REGION : iBase_FACE ), ierr,
683  &fixed_tag );
684  if( MSQ_CHKERR( ierr ) )
685  {
686  delete imesh;
687  cerr << err << endl;
688  err = iBase_FAILURE;
689  CHECK_IMESH( "Creation of MsqIMesh instance failed" );
690  return 0;
691  }
692 
693  *mesh = imesh;
694  return iBase_SUCCESS;
695 }
696 
697 int get_native_mesh( MBMesquite::Mesh** mesh, const char* file_name, int )
698 {
699  MsqError err;
700  MBMesquite::MeshImpl* imesh = new MBMesquite::MeshImpl();
701  imesh->read_vtk( file_name, err );
702  if( err )
703  {
704  cerr << err << endl;
705  exit( 3 );
706  }
707  *mesh = imesh;
708 
709  return iBase_SUCCESS;
710 }
711 
712 int get_itaps_domain( MeshDomain** odomain, const char* filename )
713 {
714 
715  if( filename == 0 || strlen( filename ) == 0 )
716  {
717  *odomain = new PlanarDomain( PlanarDomain::XY );
718  return 0;
719  }
720 
721  int err;
722  iGeom_Instance geom;
723  iGeom_newGeom( "", &geom, &err, 0 );
724  CHECK_IGEOM( "ERROR: iGeom creation failed" );
725 
726 #ifdef MOAB_HAVE_CGM_FACET
727  FacetModifyEngine::set_modify_enabled( CUBIT_TRUE );
728 #endif
729 
730  iGeom_load( geom, filename, 0, &err, strlen( filename ), 0 );
731  CHECK_IGEOM( "Cannot load the geometry" );
732 
733  iBase_EntitySetHandle root_set;
734  iGeom_getRootSet( geom, &root_set, &err );
735  CHECK_IGEOM( "getRootSet failed!" );
736 
737  // print out the number of entities
738  std::cout << "Model contents: " << std::endl;
739  const char* gtype[] = { "vertices: ", "edges: ", "faces: ", "regions: " };
740  int nents[4];
741  for( int i = 0; i <= 3; ++i )
742  {
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;
746  }
747 
748  iBase_EntityHandle* hd_geom_ents;
749  int csize = 0, sizealloc = 0;
750  if( nents[3] > 0 )
751  {
752  hd_geom_ents = (iBase_EntityHandle*)malloc( sizeof( iBase_EntityHandle ) * nents[2] );
753  csize = nents[2];
754  iGeom_getEntities( geom, root_set, 2, &hd_geom_ents, &csize, &sizealloc, &err );
755  }
756  else
757  {
758  hd_geom_ents = (iBase_EntityHandle*)malloc( sizeof( iBase_EntityHandle ) * nents[1] );
759  csize = nents[1];
760  iGeom_getEntities( geom, root_set, 1, &hd_geom_ents, &csize, &sizealloc, &err );
761  }
762  CHECK_IGEOM( "ERROR: Could not get entities" );
763 
764  *odomain = new MsqIGeom( geom, hd_geom_ents[0] );
765  return iBase_SUCCESS;
766 }