Example #1
0
int main()
{
  Mesquite::MeshImpl mesh;
  MsqPrintError err(cout);
  mesh.read_vtk(MESH_FILES_DIR "2D/vtk/quads/untangled/square_quad_2.vtk", err);
  if (err) return 1;
  
     //create geometry: plane z=0, normal (0,0,1)
  Vector3D pnt(0,0,5);
  Vector3D s_norm(0,0,1);
  Mesquite::PlanarDomain msq_geom(s_norm, pnt);
  
    // creates an intruction queue
  LaplaceWrapper laplacian_smoother;
  
  mesh.write_vtk("original_mesh.vtk", err); 
  if (err) return 1;
  
    // launches optimization on mesh_set1
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &msq_geom);
  laplacian_smoother.run_instructions(&mesh_and_domain, err); 
  if (err) return 1;
 
  mesh.write_vtk("smoothed_mesh.vtk", err); 
  if (err) return 1;
}
Example #2
0
int main()
{     
  MsqPrintError err(cout);
  Mesquite::MeshImpl mesh;
  mesh.read_vtk(MESH_FILES_DIR "3D/VTK/tire.vtk", err);
  if (err) return 1;
  
    // creates an intruction queue
  InstructionQueue queue1;

  // creates a mean ratio quality metric ...
  IdealWeightInverseMeanRatio mean(err);
  if (err) return 1;
  
  LPtoPTemplate obj_func(&mean, 1, err);
  if (err) return 1;
  
  // creates the optimization procedures
//   ConjugateGradient* pass1 = new ConjugateGradient( obj_func, err );
  FeasibleNewton pass1( &obj_func, true );

  //perform optimization globally
  pass1.use_global_patch();
  if (err) return 1;
  
  QualityAssessor mean_qa=QualityAssessor(&mean);

    //**************Set termination criterion****************

  //perform 1 pass of the outer loop (this line isn't essential as it is
  //the default behavior).
  TerminationCriterion tc_outer;
  tc_outer.add_iteration_limit( 1 ); 
  pass1.set_outer_termination_criterion(&tc_outer);
  
  //perform the inner loop until a certain objective function value is
  //reached.  The exact value needs to be determined (about 18095).
  //As a safety, also stop if the time exceeds 10 minutes (600 seconds).
  TerminationCriterion tc_inner;
  tc_inner.add_absolute_quality_improvement( 13975 ); 
//  tc_inner.add_absolute_quality_improvement( 13964.93818 );
  tc_inner.add_cpu_time( 1800 ); 
  
  pass1.set_inner_termination_criterion(&tc_inner);
  
  //used for cg to get some info
//  pass1->set_debugging_level(2);
  
  // adds 1 pass of pass1 to mesh_set1
  queue1.add_quality_assessor(&mean_qa,err);
  if (err) return 1;
  queue1.set_master_quality_improver(&pass1, err); 
  if (err) return 1;
  queue1.add_quality_assessor(&mean_qa,err);
  if (err) return 1;
  mesh.write_vtk("original_mesh.vtk", err); 
  if (err) return 1;
  
    // launches optimization on mesh_set1
  queue1.run_instructions(&mesh, err); 
  if (err) return 1;
  
  mesh.write_vtk("smoothed_mesh.vtk", err); 
  if (err) return 1;
  print_timing_diagnostics( cout );
  return 0;
}
Example #3
0
int main()
{     
    /* Reads a Mesh file */
  const char *file_name = 
//      MESH_FILES_DIR "2D/vtk/tris/untangled/equil_tri2.vtk";
//      MESH_FILES_DIR "2D/vtk/tris/untangled/tri_20258.vtk";
//      MESH_FILES_DIR "3D/vtk/tets/untangled/tet_1.vtk";
//      MESH_FILES_DIR "3D/vtk/hexes/untangled/cube_tet_2.vtk";
     MESH_FILES_DIR "3D/vtk/tets/untangled//tire.vtk";
  printf("Loading mesh set 1\n");
  MsqPrintError err( cout );
  Mesquite::MeshImpl mesh;
  mesh.read_vtk(file_name, err);
  if (err) return 1;
  
    // Creates an intruction queue
    //  printf("Creating instruction queue\n");
  InstructionQueue queue1;

  // Creates a condition number quality metric 
  //  printf("Creating quality metric\n");
  ConditionNumberQualityMetric cond_no;
  
  // Create the NonSmooth Steepest Descent procedures
  //  printf("creating optimizer\n");
  NonSmoothDescent minmax_method( &cond_no );

  // Set a termination criterion
  TerminationCriterion tc2;
  tc2.add_iteration_limit( 1 );
  minmax_method.set_outer_termination_criterion(&tc2);
  // Set up the quality assessor
  //  printf("Setting up the quality assessor\n");
  QualityAssessor quality_assessor=QualityAssessor(&cond_no);

  // assess the quality of the initial mesh
  queue1.add_quality_assessor(&quality_assessor, err); 
  if (err) return 1;

  // Set the max min method to be the master quality improver
  queue1.set_master_quality_improver(&minmax_method, err); 
  if (err) return 1;

  // assess the quality of the final mesh
  queue1.add_quality_assessor(&quality_assessor, err); 
  if (err) return 1;

  // write out the original mesh
  //  printf("Writing out the original mesh\n");
  mesh.write_vtk("original_mesh.vtk", err); 
  if (err) return 1;

  // launches optimization on mesh_set1
  //  printf("Running the instruction queue\n");
  queue1.run_instructions(&mesh, err); 
  if (err) return 1;

  // write out the smoothed mesh
  //  printf("Writing out the final mesh\n");
  mesh.write_vtk("smoothed_mesh.vtk", err); 
  if (err) return 1;
  
  return 0;
}
Example #4
0
int main()
{
  MsqPrintError err(std::cout);
  Mesquite::MeshImpl mesh;
  mesh.read_vtk(MESH_FILES_DIR "3D/vtk/hexes/untangled/hexes_4by2by2.vtk", err);
  
    // creates an intruction queue
  InstructionQueue queue1;
  
    // creates a mean ratio quality metric ...
  IdealWeightInverseMeanRatio mean_ratio(err);
  if (err) return 1;
  ConditionNumberQualityMetric cond_num;
  mean_ratio.set_averaging_method(QualityMetric::LINEAR);
  
    // ... and builds an objective function with it
    //LInfTemplate* obj_func = new LInfTemplate(mean_ratio);
  LPtoPTemplate obj_func(&mean_ratio, 2, err);
  if (err) return 1;
   // creates the steepest descent optimization procedures
  SteepestDescent pass1( &obj_func );
  pass1.use_global_patch();
  //if (err) return 1;
  //pass1.set_maximum_iteration(6);
  
  QualityAssessor stop_qa=QualityAssessor(&mean_ratio);
  if (err) return 1;
  stop_qa.add_quality_assessment(&cond_num);
  if (err) return 1;
  
  
   //**************Set stopping criterion****************
// StoppingCriterion sc1(&stop_qa,1.0,1.8);
    //StoppingCriterion sc2(StoppingCriterion::NUMBER_OF_PASSES,1);
  TerminationCriterion tc2;
  tc2.add_iteration_limit( 1 );
// CompositeAndStoppingCriterion sc(&sc1,&sc2);
  pass1.set_inner_termination_criterion(&tc2);

  // adds 1 pass of pass1 to mesh_set1
//  queue1.add_preconditioner(pass1, err); 
//  if (err) return 1;
  queue1.add_quality_assessor(&stop_qa,err);
  queue1.set_master_quality_improver(&pass1, err); 
  if (err) return 1;
  queue1.add_quality_assessor(&stop_qa,err);
  if (err) return 1;
  // adds 1 passes of pass2 to mesh_set1
//  mesh_set1.add_quality_pass(pass2);

  mesh.write_vtk("original_mesh.vtk", err); 
  if (err) return 1;
  
    // launches optimization on mesh_set1
  queue1.run_instructions(&mesh, err);
  if (err) return 1;
  
  mesh.write_vtk("smoothed_mesh.vtk", err); 
  if (err) return 1;
  
  return 0;
}
Example #5
0
int main()
{
  Mesquite::MeshImpl mesh;
  MsqPrintError err(cout);
    //create geometry: plane z=0, normal (0,0,1)
  Vector3D pnt(0,0,0);
  Vector3D s_norm(0,0,1);
  Mesquite::PlanarDomain msq_geom(s_norm, pnt);
     
    //mesh->read_vtk(MESH_FILES_DIR "2D/VTK/cube-clip-corner.vtk", err);
  mesh.read_vtk(MESH_FILES_DIR "2D/VTK/hybrid_3quad_1tri.vtk", err);
  if (err) return 1;
  
    // creates an intruction queue
  InstructionQueue queue1;
  
    // creates a mean ratio quality metric ...
  IdealWeightInverseMeanRatio mean_ratio(err);
  if (err) return 1;
    //   mean_ratio->set_gradient_type(QualityMetric::NUMERICAL_GRADIENT);
    //   mean_ratio->set_hessian_type(QualityMetric::NUMERICAL_HESSIAN);
    //mean_ratio->set_averaging_method(QualityMetric::SUM, err);
    //MSQ_CHKERR(err);
  
    // ... and builds an objective function with it
  LPtoPTemplate obj_func(&mean_ratio, 2, err);
  if (err) return 1;;
  
    // creates the steepest descent, feas newt optimization procedures
    //ConjugateGradient* pass1 = new ConjugateGradient( &obj_func, err );
  FeasibleNewton pass1( &obj_func, true );
  pass1.use_global_patch();
  if (err) return 1;;
  
  QualityAssessor qa=QualityAssessor(&mean_ratio);
  if (err) return 1;;
  
    // **************Set termination criterion****************
  TerminationCriterion tc_inner;
  tc_inner.add_iteration_limit( 1 );
    //_inner.add_absolute_quality_improvement( OF_value );
    //tc_inner.add_absolute_gradient_L2_norm( OF_value );
  TerminationCriterion tc_outer;
    //tc_outer.add_iteration_limit( 1 );
  tc_outer.add_iteration_limit( 1 );
  
  pass1.set_inner_termination_criterion(&tc_inner);
  pass1.set_outer_termination_criterion(&tc_outer);

  queue1.add_quality_assessor(&qa,err); 
  if (err) return 1;
    // adds 1 pass of pass1 to mesh_set1
  queue1.set_master_quality_improver(&pass1, err);
  if (err) return 1;
  queue1.add_quality_assessor(&qa,err); 
  if (err) return 1;
  mesh.write_vtk("original_mesh.vtk",err); 
  if (err) return 1;
  
  queue1.run_instructions(&mesh, &msq_geom, err); 
  if (err) return 1;
  mesh.write_vtk("smoothed_mesh.vtk",err); 
  if (err) return 1;
    //std::cout<<"\n\nNow running the shape wrapper.\n=n";
    //ShapeImprovementWrapper wrap(100);
    //wrap.run_instructions(mesh_set1, err); MSQ_CHKERR(err);
  print_timing_diagnostics(cout);
  return 0;
}
int main( int argc, char* argv[] )
{
  /* init MPI */
  int rank, nprocs;
  if (MPI_SUCCESS != MPI_Init(&argc, &argv)) {
    cerr << "MPI_Init failed." << endl;
    return 2;
  }
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

  if (nprocs > 2) { cerr << "parallel_laplace_smooth test can only be run with 1 or 2 processors" << std::endl; return 0; }

  const int debug=0;  // 1,2,3 for more debug info
  if (debug)
    {
      MsqDebug::enable(1);
      if (debug > 1) MsqDebug::enable(2);
      if (debug > 2) MsqDebug::enable(3);
    }

  /* create processor-specific file names */
  ostringstream in_name, out_name, gold_name;
  in_name << VTK_3D_DIR << "par_original_hex_mesh." << nprocs << "." << rank << ".vtk";
  gold_name << VTK_3D_DIR << "par_smoothed_hex_mesh." << nprocs << "." << rank << ".vtk";
  out_name << "par_smoothed_hex_mesh." << nprocs << "." << rank << ".vtk";

  /* load different mesh files on each processor */
  Mesquite::MsqError err;
  Mesquite::MeshImpl mesh;
  mesh.read_vtk(in_name.str().c_str(), err);
  if (err) {cerr << err << endl; return 1;}

  /* create parallel mesh instance, specifying tags 
   * containing parallel data */
  Mesquite::ParallelMeshImpl parallel_mesh(&mesh, "GLOBAL_ID", "PROCESSOR_ID");
  Mesquite::ParallelHelperImpl helper;
  helper.set_communicator(MPI_COMM_WORLD);
  helper.set_parallel_mesh(&parallel_mesh);
  parallel_mesh.set_parallel_helper(&helper);

  /* do Laplacian smooth */
  LaplaceWrapper optimizer;
  optimizer.set_vertex_movement_limit_factor(1.e-10);
  optimizer.set_iteration_limit(2000);
  optimizer.enable_culling(false);
  optimizer.run_instructions(&parallel_mesh, err);
  if (err) {cerr << err << endl; return 1; }

  /* write mesh */
  mesh.write_vtk(out_name.str().c_str(),err);
  if (err) {cerr << err << endl; return 1;}

  /* compare mesh with gold copy */
  MeshImpl gold;
  gold.read_vtk(gold_name.str().c_str(),err);
  if (err) {cerr << err << endl; return 1;}

  bool do_print=true;
  double tol = 1.e-4;
  bool diff = MeshUtil::meshes_are_different(mesh, gold, err, tol, do_print);
  if (err) {cerr << err << endl; return 1;}

  if (diff) {cerr << "Error, computed mesh different from gold copy" << std::endl; return 1;}
  
  print_timing_diagnostics(cout);

  MPI_Finalize();
  return 0;
}
Example #7
0
int main( )
{
  Mesquite::MeshImpl mesh;
  MsqPrintError err(cout);
  mesh.read_vtk(VTK_2D_DIR "quads/tangled/tangled_quad.vtk", err);
  if (err) return 1;
  
  // Set Domain Constraint
  Vector3D pnt(0,0,5);
  Vector3D s_norm(0,0,1);
  PlanarDomain msq_geom(s_norm, pnt);
                                                                              
    // creates an intruction queue
  InstructionQueue queue1;
  
    // creates a mean ratio quality metric ...
  ConditionNumberQualityMetric shape_metric;
  UntangleBetaQualityMetric untangle(2);
  Randomize pass0(.05);
    // ... and builds an objective function with it
    //LInfTemplate* obj_func = new LInfTemplate(shape_metric);
  LInfTemplate obj_func(&untangle);
  LPtoPTemplate obj_func2(&shape_metric, 2, err);
  if (err) return 1;
    // creates the steepest descent optimization procedures
  ConjugateGradient pass1( &obj_func, err );
  if (err) return 1;
  
    //SteepestDescent* pass2 = new SteepestDescent( obj_func2 );
  ConjugateGradient pass2( &obj_func2, err );
  if (err) return 1;
  pass2.use_element_on_vertex_patch();
  if (err) return 1;
  pass2.use_global_patch();
  if (err) return 1;
  QualityAssessor stop_qa=QualityAssessor(&shape_metric);
  QualityAssessor stop_qa2=QualityAssessor(&shape_metric);
  if (brief_output) {
    stop_qa.disable_printing_results();
    stop_qa2.disable_printing_results();
  }
  
  stop_qa.add_quality_assessment(&untangle);
    // **************Set stopping criterion**************
    //untangle beta should be 0 when untangled
  TerminationCriterion sc1;
  sc1.add_relative_quality_improvement( 0.000001 );
  TerminationCriterion sc3;
  sc3.add_iteration_limit( 10 );
  TerminationCriterion sc_rand;
  sc_rand.add_iteration_limit( 1 );
  
    //StoppingCriterion sc1(&stop_qa,-1.0,.0000001);
    //StoppingCriterion sc3(&stop_qa2,.9,1.00000001);
    //StoppingCriterion sc2(StoppingCriterion::NUMBER_OF_PASSES,10);
    //StoppingCriterion sc_rand(StoppingCriterion::NUMBER_OF_PASSES,1);
    //either until untangled or 10 iterations
  pass0.set_outer_termination_criterion(&sc_rand);
  pass1.set_outer_termination_criterion(&sc1);
  pass2.set_inner_termination_criterion(&sc3);
  
    // adds 1 pass of pass1 to mesh_set1
  queue1.add_quality_assessor(&stop_qa,err); 
  if (err) return 1;
    //queue1.add_preconditioner(pass0,err);MSQ_CHKERR(err);
    //queue1.add_preconditioner(pass1,err);MSQ_CHKERR(err);
    //queue1.set_master_quality_improver(pass2, err); MSQ_CHKERR(err);
  queue1.set_master_quality_improver(&pass1, err);
  if (err) return 1;
  queue1.add_quality_assessor(&stop_qa2,err);
  if (err) return 1;
  if (write_output)
    mesh.write_vtk("original_mesh.vtk", err);
  if (err) return 1;
  
    // launches optimization on mesh_set1
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &msq_geom);
  queue1.run_instructions(&mesh_and_domain, err);
  if (err) return 1;
  
  if (write_output)
    mesh.write_vtk("smoothed_mesh.vtk", err); 
  if (err) return 1;
  
  if (!brief_output)
    print_timing_diagnostics(cout);
  return 0;
}
Example #8
0
int main(int argc, char* argv[])
{
  const char* input_file = DEFAULT_INPUT;
  const char* output_file = NULL;
  switch (argc) {
    default:
      help(argv[0]);
    case 3:
      if (!strcmp(argv[2],"-h"))
        help(argv[0]);
      output_file = argv[2];
    case 2:
      if (!strcmp(argv[1],"-h"))
        help(argv[0]);
      input_file = argv[1];
    case 1:
      ;
  }

    /* Read a VTK Mesh file */
  MsqPrintError err(cout);
  Mesquite::MeshImpl mesh;
  mesh.read_vtk( input_file, err);
  if (err) return 1;
  
    // creates an intruction queue
  InstructionQueue queue1;
  
    // creates a mean ratio quality metric ...
  ConditionNumberQualityMetric shape_metric;
  EdgeLengthQualityMetric lapl_met;
  lapl_met.set_averaging_method(QualityMetric::RMS);
 
    // creates the laplacian smoother  procedures
  LaplacianSmoother lapl1;
  QualityAssessor stop_qa=QualityAssessor(&shape_metric);
  stop_qa.add_quality_assessment(&lapl_met);
  
    //**************Set stopping criterion****************
  TerminationCriterion sc2;
  sc2.add_iteration_limit( 10 );
  if (err) return 1;
  lapl1.set_outer_termination_criterion(&sc2);
  
    // adds 1 pass of pass1 to mesh_set1
//  queue1.add_quality_assessor(&stop_qa,err); 
  if (err) return 1;
  queue1.set_master_quality_improver(&lapl1, err); 
  if (err) return 1;
//  queue1.add_quality_assessor(&stop_qa,err); 
  if (err) return 1;
  
  PlanarDomain plane(Vector3D(0,0,1), Vector3D(0,0,0));
  
    // launches optimization on mesh_set1
  Timer t;
  queue1.run_instructions(&mesh, &plane, err); 
  if (err) return 1;
  double secs = t.since_birth();
  std::cout << "Optimization completed in " << secs << " seconds" << std::endl;
  
  if (output_file) {
    mesh.write_vtk(output_file, err); 
    if (err) return 1;
    std::cout << "Wrote file: " << output_file << std::endl;
  }
  
  return 0;
}
Example #9
0
int main(int argc, char* argv[])
{
  const char* input_file = DEFAULT_INPUT;
  const char* output_file = NULL;
  switch (argc) {
    default:
      help(argv[0]);
    case 3:
      if (!strcmp(argv[2],"-h"))
        help(argv[0]);
      output_file = argv[2];
    case 2:
      if (!strcmp(argv[1],"-h"))
        help(argv[0]);
      input_file = argv[1];
    case 1:
      ;
  }

    /* Read a VTK Mesh file */
  MsqPrintError err(cout);
  Mesquite::MeshImpl mesh;
  mesh.read_vtk( input_file, err);
  if (err) {
    std::cerr << input_file << ": file read failed" << endl;
    return 1;
  }
  
  double min_ini, avg_ini, max_ini;
  tet_dihedral_angle_ratios( mesh, min_ini, avg_ini, max_ini, err );
  
    /* Run optimizer */
  ViscousCFDTetShapeWrapper smoother(1e-2);
  smoother.run_instructions( &mesh, err);
  if (err) return 1;
  
  double min_fin, avg_fin, max_fin;
  tet_dihedral_angle_ratios( mesh, min_fin, avg_fin, max_fin, err );
  
  cout << "\tMinimum \tAverage \tMaximum "<<endl
       << "Init\t"<<min_ini<<'\t'<<avg_ini<<'\t'<<max_ini<<endl
       << "Fini\t"<<min_fin<<'\t'<<avg_fin<<'\t'<<max_fin<<endl;
  
  if (output_file) {
    mesh.write_vtk( output_file, err );
    if (err) {
      std::cerr << output_file << ": file write failed" << endl;
      return 1;
    }
    else {
      std::cout << "Wrote file: " << output_file << endl;
    }
  }
      
  if (min_ini > min_fin || avg_ini > avg_fin || max_ini > max_fin) {
    std::cerr << "Dihedral handle ratio decreased" << endl;
    return 1;
  }
  
  return 0;
}
Example #10
0
int main(int argc, char* argv[])
{
  Mesquite::MsqPrintError err(cout);

  Mesquite::MeshImpl mesh;
    //mesh->read_exodus("transformed_mesh.exo", err);
  mesh.read_vtk(MESH_FILES_DIR "2D/vtk/quads/untangled/tfi_horse10x4-12.vtk", err);
  if (err) return 1;
  
    // Get all vertex coordinates from mesh
  std::vector<Mesquite::Mesh::VertexHandle> handles;
  mesh.get_all_vertices( handles, err ); 
  if (err) return 1;
  if (handles.empty()) {
    std::cerr << "No verticies in mesh" << endl;
    return 1;
  }
  std::vector<Mesquite::MsqVertex> coords( handles.size() );
  mesh.vertices_get_coordinates( arrptr(handles), arrptr(coords), handles.size(), err );
  if (err) return 1;
  
    //create the matrix for affine transformation
  double array_entries[9];
  array_entries[0]=0; array_entries[1]=1; array_entries[2]=0;
  array_entries[3]=1; array_entries[4]=0; array_entries[5]=0;
  array_entries[6]=0; array_entries[7]=0; array_entries[8]=1;
    //create the translation vector
  Matrix3D my_mat(array_entries);
  Vector3D my_vec(0, 0 , 10);
  MeshTransform my_transform(my_mat, my_vec);
    //mesh->write_exodus("original_mesh.exo", err);
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, 0);
  my_transform.loop_over_mesh(&mesh_and_domain, 0, err);
  if (err) return 1;
    //mesh->write_exodus("transformed_mesh.exo", err);
  mesh.write_vtk("transformed_mesh.vtk", err);
  if (err) return 1;
  
    // Get transformed coordinates
  std::vector<Mesquite::MsqVertex> coords2( handles.size() );
  mesh.vertices_get_coordinates( arrptr(handles), arrptr(coords2), handles.size(), err );
  if (err) return 1;
 
    // Compare vertex coordinates
  size_t invalid = 0;
  std::vector<Mesquite::MsqVertex>::iterator iter, iter2;
  iter = coords.begin();
  iter2 = coords2.begin();
  for ( ; iter != coords.end(); ++iter, ++iter2 )
  {
    Mesquite::Vector3D xform = my_mat * *iter + my_vec;
    double d = (xform - *iter2).length();
    if (d > EPSILON)
      ++invalid;
  }
  
  std::cerr << invalid << " vertices not within " << EPSILON 
                  << " of expected location" << std::endl;
  
  return (invalid != 0);
}
Example #11
0
int main(int argc, char* argv[])
{
  const char* input_file = DEFAULT_INPUT;
  const char* output_file = NULL;
  switch (argc) {
    default:
      help(argv[0]);
    case 3:
      if (!strcmp(argv[2],"-h"))
        help(argv[0]);
      output_file = argv[2];
    case 2:
      if (!strcmp(argv[1],"-h"))
        help(argv[0]);
      input_file = argv[1];
    case 1:
      ;
  }

    /* Read a VTK Mesh file */
  MsqPrintError err(cout);
  Mesquite::MeshImpl mesh;
  mesh.read_vtk( input_file, err);
  if (err) return 1;
  
    // creates an intruction queue
  InstructionQueue queue1;
  
    // creates a mean ratio quality metric ...
  ConditionNumberQualityMetric shape_metric;
  EdgeLengthQualityMetric lapl_met;
  lapl_met.set_averaging_method(QualityMetric::RMS);
 
    // creates the laplacian smoother  procedures
  LaplacianSmoother lapl1;
  QualityAssessor stop_qa=QualityAssessor(&shape_metric);
  stop_qa.add_quality_assessment(&lapl_met);
  
    //**************Set stopping criterion****************
  TerminationCriterion sc2;
  sc2.add_iteration_limit( 10 );
  if (err) return 1;
  lapl1.set_outer_termination_criterion(&sc2);
  
    // adds 1 pass of pass1 to mesh_set1
  queue1.add_quality_assessor(&stop_qa,err); 
  if (err) return 1;
  queue1.set_master_quality_improver(&lapl1, err); 
  if (err) return 1;
  queue1.add_quality_assessor(&stop_qa,err); 
  if (err) return 1;
    // adds 1 passes of pass2 to mesh_set1
    //  mesh_set1.add_quality_pass(pass2);
  
    //writeVtkMesh("original_mesh", mesh, err); MSQ_CHKERR(err);
  
  PlanarDomain plane(Vector3D(0,0,1), Vector3D(0,0,5));
  
    // launches optimization on mesh_set1
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &plane);
  Timer t;
  queue1.run_instructions(&mesh_and_domain, err); 
  if (err) return 1;
  double secs = t.since_birth();
  std::cout << "Optimization completed in " << secs << " seconds" << std::endl;
  
  if (output_file) {
    mesh.write_vtk(output_file, err); 
    if (err) return 1;
    std::cout << "Wrote file: " << output_file << std::endl;
  }
  
    // check that smoother is working: 
    // the one free vertex must be at the origin
  if (input_file == DEFAULT_INPUT) {
    std::vector<Mesh::VertexHandle> vertices;
    mesh.get_all_vertices( vertices, err );
    if (err) return 1;

    std::vector<bool> fixed_flags;
    mesh.vertices_get_fixed_flag( arrptr(vertices), fixed_flags, vertices.size(), err );
    if (err) return 1;

    // find one free vertex
    int idx = -1;
    for (unsigned i = 0; i < vertices.size(); ++i) {
      if (fixed_flags[i] == true)
        continue;
      if (idx != -1) {
        std::cerr << "Multiple free vertices in mesh." << std::endl;
        return 1;
      }
      idx = i;
    }

    if (idx == -1) {
      std::cerr << "No free vertex in mesh!!!!!" << std::endl;
      return 1;
    }

    Mesh::VertexHandle vertex = vertices[idx];
    MsqVertex coords;
    mesh.vertices_get_coordinates( &vertex, &coords, 1, err );
    if (err) return 1;

      // calculate distance from origin
    double dist = sqrt( coords[0]*coords[0] + coords[1]*coords[1] );
    if  (dist > 1e-8) {
      std::cerr << "Free vertex not at origin after Laplace smooth." << std::endl
                    << "Expected location: (0,0)" << std::endl
                    << "Actual location: (" << coords[0] << "," << coords[1] << ")" << std::endl;
      return 2;
    }
  }
  
  return 0;
}