Example #1
0
int main(int argc, char* argv[])
{
  MsqError err;
  
  if (argc != 2) {
    std::cerr << "Expected mesh file names as single argument." << std::endl;
    exit (EXIT_FAILURE);
  }

  // new code starts here
  //... 
  Mesquite::MeshImpl my_mesh;
  my_mesh.read_vtk(argv[1], err);
  if (err)
  {
    std::cout << err << std::endl;
    return 1;
  }

  my_mesh.write_vtk("original_mesh.vtk",err);

  Vector3D normal(0,0,-1);
  Vector3D point(0,0,-5);
  PlanarDomain my_mesh_plane(normal, point);

    // creates a mean ratio quality metric ...
  IdealWeightInverseMeanRatio inverse_mean_ratio(err);
    // sets the objective function template
  LPtoPTemplate obj_func(&inverse_mean_ratio, 2, err);
    // creates the optimization procedures
  SteepestDescent f_newton(&obj_func);
    //performs optimization globally
  f_newton.use_global_patch();
    // creates a termination criterion and
    // add it to the optimization procedure
    // outer loop: default behavior: 1 iteration
    // inner loop: stop if gradient norm < eps
  TerminationCriterion tc_inner;
  tc_inner.add_absolute_gradient_L2_norm( 1e-4 );
  f_newton.set_inner_termination_criterion(&tc_inner);
    // creates a quality assessor
  QualityAssessor m_ratio_qa(&inverse_mean_ratio);
    // creates an instruction queue
  InstructionQueue queue;
  queue.add_quality_assessor(&m_ratio_qa, err);
  queue.set_master_quality_improver(&f_newton, err);
  queue.add_quality_assessor(&m_ratio_qa, err);
    // do optimization of the mesh_set
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&my_mesh, &my_mesh_plane);
  queue.run_instructions(&mesh_and_domain, err);
  if (err) {
    std::cout << err << std::endl;
    return 2;
  }

  my_mesh.write_vtk("smoothed_mesh.vtk",err);

  return 0;
}
Example #2
0
int main( int argc, char* argv[] )
{
  parse_options( argv, argc );
  
  MeshImpl mesh;
  XYRectangle domain( max_x - min_x, max_y - min_y, min_x, min_y );
  MsqError err;
  
  create_input_mesh( input_x, mesh, err );
  if (MSQ_CHKERR(err)) { std::cerr << err << std::endl; return 2; }
  
  domain.setup( &mesh, err );
  if (MSQ_CHKERR(err)) { std::cerr << err << std::endl; return 2; }
  
  QualityMetric* metric = 0;
  if (mMetric == 'c')
    metric = new ConditionNumberQualityMetric;
  else
    metric = new IdealWeightInverseMeanRatio;
  
  LPtoPTemplate function( 1, metric );
  
  VertexMover* solver = 0;
  if (mSolver == 'j')
    solver = new ConjugateGradient( &function );
  else
    solver = new FeasibleNewton( &function );
    
  if (PatchSetUser* psu = dynamic_cast<PatchSetUser*>(solver)) 
    psu->use_global_patch();
  
  TerminationCriterion inner;
  inner.add_absolute_vertex_movement( 1e-4 );
  inner.write_mesh_steps( "synchronous", TerminationCriterion::GNUPLOT );
  solver->set_inner_termination_criterion( &inner );  
  
  InstructionQueue q;
  QualityAssessor qa( metric, 10 );
  q.add_quality_assessor( &qa, err );
  q.set_master_quality_improver( solver, err );
  q.add_quality_assessor( &qa, err );
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &domain);
  q.run_instructions( &mesh_and_domain, err );
  delete solver;
  delete metric;
  
  if (MSQ_CHKERR(err)) 
    { std::cerr << err << std::endl; return 3; }
    
  mesh.write_vtk( outputFile, err );
  if (MSQ_CHKERR(err)) 
    { std::cerr << err << std::endl; return 2; }
  
  return 0;
}
Example #3
0
void TagVertexMeshTest::test_reference_mesh()
{
  MsqPrintError err( std::cerr );
  TagVertexMesh tag_mesh( err, realMesh, true );
  ASSERT_NO_ERROR(err);
  
  std::vector<Mesh::VertexHandle> vertices;
  realMesh->get_all_vertices( vertices, err );
  ASSERT_NO_ERROR(err);
  
    // copy real mesh coordinates into tag data in TagVertexMesh
  InstructionQueue q;
  q.add_tag_vertex_mesh( &tag_mesh, err );
  ASSERT_NO_ERROR(err);
  q.run_instructions( realMesh, err );
  ASSERT_NO_ERROR(err);
  
    // Check that initial position for vertex matches that of real mesh
  Mesh::VertexHandle vertex = vertices[0];
  MsqVertex get_coords;
  Vector3D orig_coords, real_coords, tag_coords;
  realMesh->vertices_get_coordinates( &vertex, &get_coords, 1, err );
  ASSERT_NO_ERROR(err);
  orig_coords = get_coords;
  tag_mesh.vertices_get_coordinates( &vertex, &get_coords, 1, err );
  ASSERT_NO_ERROR(err);
  tag_coords = get_coords;
  CPPUNIT_ASSERT_VECTORS_EQUAL( orig_coords, tag_coords, DBL_EPSILON );
  
    // Check that modified vertex coords show up in real mesh but not
    // tag mesh.
  realMesh->vertices_get_coordinates( &vertex, &get_coords, 1, err );
  ASSERT_NO_ERROR(err);
  orig_coords = get_coords;
  Vector3D new_coords(5,5,5);
  realMesh->vertex_set_coordinates( vertex, new_coords, err );
  ASSERT_NO_ERROR(err);
  tag_mesh.vertices_get_coordinates( &vertex, &get_coords, 1, err );
  ASSERT_NO_ERROR(err);
  tag_coords = get_coords;
  CPPUNIT_ASSERT_VECTORS_EQUAL( orig_coords, tag_coords, DBL_EPSILON );
    // restore realMesh to initial state
  realMesh->vertex_set_coordinates( vertex, orig_coords, err );
  ASSERT_NO_ERROR(err);
}
Example #4
0
void MeshOpt::trustRegion(hier::Patch<NDIM>& patch)
{
    MsqError err;
    MeshImpl* mesh = createLocalMesh(patch);

    PlanarDomain domain(PlanarDomain::XY);
    IdealWeightInverseMeanRatio inverse_mean_ratio(err);
    LPtoPTemplate obj_func(&inverse_mean_ratio,2,err);
    TrustRegion t_region(&obj_func);
    t_region.use_global_patch();
    TerminationCriterion tc_inner;
    tc_inner.add_absolute_gradient_L2_norm(1e-6);
    tc_inner.add_iteration_limit(1);
    t_region.set_inner_termination_criterion(&tc_inner);
    QualityAssessor m_ratio_qa(&inverse_mean_ratio);
    m_ratio_qa.disable_printing_results();

    InstructionQueue queue;
    queue.add_quality_assessor(&m_ratio_qa,err);
    queue.set_master_quality_improver(&t_region,err);
    queue.add_quality_assessor(&m_ratio_qa,err);
    MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(mesh,&domain);
    queue.run_instructions(&mesh_and_domain,err);
    tbox::pout<< "Shape optimization completed." << std::endl;

//    std::string file_name = "2__patch_3.vtk";
//    mesh->write_vtk(file_name.c_str(), err);

    transformMeshtoPatch(mesh,patch,err);



    d_flag =2;

    return;
}
Example #5
0
int main( int argc, char* argv[] )
{
  const char* input_file = DEFAULT_INPUT_FILE;
  const char* output_file_base = 0;
  bool expect_output_base = false;
  for (int i = 1; i < argc; ++i) {
    if (expect_output_base) {
      output_file_base = argv[i];
      expect_output_base = false;
    }
    else if (!strcmp(argv[i],"-o"))
      expect_output_base = true;
    else if (input_file != DEFAULT_INPUT_FILE)
      usage(argv[0]);
    else
      input_file = argv[i];
  }
  if (expect_output_base)
    usage(argv[0]);
  
  MsqPrintError err(std::cerr);
  SlaveBoundaryVertices slaver(1);
  TShapeNB1 tmetric;
  IdealShapeTarget target;
  TQualityMetric metric( &target, &tmetric );
  PMeanPTemplate of( 1.0, &metric );
  SteepestDescent improver( &of );
  TerminationCriterion inner;
  inner.add_absolute_vertex_movement( 1e-3 );
  improver.set_inner_termination_criterion( &inner );
  QualityAssessor assess( &metric );
  InstructionQueue q;
  q.set_master_quality_improver( &improver, err );
  q.add_quality_assessor( &assess, err );
  
  TriLagrangeShape trishape;
  QuadLagrangeShape quadshape;
  q.set_mapping_function( &trishape );
  q.set_mapping_function( &quadshape );
  
  const int NUM_MODES = 4;
  
  Settings::HigherOrderSlaveMode modes[NUM_MODES] = 
    { Settings::SLAVE_NONE, 
      Settings::SLAVE_ALL,
      Settings::SLAVE_CALCULATED,
      Settings::SLAVE_FLAG
    };
  
  std::string names[NUM_MODES] = 
    { "NONE",
      "ALL",
      "CALCULATED",
      "FLAG" };
  
  MeshImpl meshes[NUM_MODES];
  std::vector<MeshDomainAssoc> meshes_and_domains;

  bool have_slaved_flag = true;
  std::vector<bool> flag(1);
  for (int i = 0; i < NUM_MODES; ++i) {
    std::cout << std::endl
              << "-----------------------------------------------" << std::endl
              << "     Mode: " << names[i] << std::endl
              << "-----------------------------------------------" << std::endl;
    
    meshes[i].read_vtk( input_file, err );
    if (err) return 1;
  
    if (modes[i] == Settings::SLAVE_CALCULATED) {
        q.add_vertex_slaver( &slaver, err );
    }
    else if (modes[i] == Settings::SLAVE_FLAG) {
      std::vector<Mesh::VertexHandle> verts;
      meshes[i].get_all_vertices( verts, err );
      if (err) return 1;
      meshes[i].vertices_get_slaved_flag( arrptr(verts), flag, 1, err );
      if (err) {
        have_slaved_flag = false;
        std::cout << "Skipped because input file does not contain slaved attribute" << std::endl;
        err.clear();
        continue;
      }
    }

  
    if (have_slaved_flag && modes[i] == Settings::SLAVE_FLAG) {
      if (!check_no_slaved_corners( meshes[i], err ) || err)
        return 1;
      if (!check_global_patch_slaved( meshes[i], err ) || err)
        return 1;
    }

  
    PlanarDomain plane;
    plane.fit_vertices( &meshes[i], err );
    if (err) return 1;

    q.set_slaved_ho_node_mode( modes[i] );
    meshes_and_domains.push_back(MeshDomainAssoc(&meshes[i], &plane));
    q.run_instructions( &meshes_and_domains[i], err );
    if (err) return 1;

    if (modes[i] == Settings::SLAVE_CALCULATED) {
        q.remove_vertex_slaver( &slaver, err );
    }
    
    if (output_file_base) {
      tag_patch_slaved( meshes[i], modes[i], err );
      std::string name(output_file_base);
      name += "-";
      name += names[i];
      name += ".vtk";
      meshes[i].write_vtk( name.c_str(), err );
      if (err) return 1;
    }
  }
  
  int exit_code = 0;
  if (input_file == DEFAULT_INPUT_FILE) {
    for (int i = 0; i < NUM_MODES; ++i) {
      std::cout << std::endl
                << "-----------------------------------------------" << std::endl
                << "     Mode: " << names[i] << std::endl
                << "-----------------------------------------------" << std::endl;
    
      exit_code += check_slaved_coords( meshes[i], modes[i], names[i], have_slaved_flag, err );
      if (err) return 1;
    }
    
      // flags should correspond to same slaved nodes as calculated,
      // so resulting meshes should be identical.
    if (have_slaved_flag) {
      int flag_idx = std::find( modes, modes+NUM_MODES, Settings::SLAVE_FLAG ) - modes;
      int calc_idx = std::find( modes, modes+NUM_MODES, Settings::SLAVE_CALCULATED ) - modes;
      exit_code += compare_node_coords( meshes[flag_idx], meshes[calc_idx], err );
      if (err) return 1;    
    }
  }
  
  return exit_code;
}
void TerminationCriterionTest::test_abs_vtx_movement_culling()
{
  /* define a quad mesh like the following
    16--17--18--19--20--21--22--23
     |   |   |   |   |   |   |   |   Y
     8---9--10--11--12--13--14--15   ^
     |   |   |   |   |   |   |   |   |
     0---1---2---3---4---5---6---7   +-->X
  */

  const int nvtx = 24;
  int fixed[nvtx];
  double coords[3*nvtx];
  for (int i = 0; i < nvtx; ++i) {
    coords[3*i  ] = i/8;
    coords[3*i+1] = i%8;
    coords[3*i+2] = 0;
    fixed[i] = i < 9 || i > 14;
  }
  
  const int nquad = 14;
  unsigned long conn[4*nquad];
  for (int i= 0; i < nquad; ++i) {
    int row = i / 7;
    int idx = i % 7;
    int n0 = 8*row + idx;
    conn[4*i  ] = n0;
    conn[4*i+1] = n0 + 1;
    conn[4*i+2] = n0 + 9;
    conn[4*i+3] = n0 + 8;
  }
  
  const double tol = 0.05;
  PlanarDomain zplane(PlanarDomain::XY, 0.0);
  ArrayMesh mesh( 3, nvtx, coords, fixed, nquad, QUADRILATERAL, conn );
  
    // fill vertex byte with garbage to make sure that quality improver
    // is initializing correctly.
  MsqError err;
  std::vector<unsigned char> junk(nvtx, 255);
  std::vector<Mesh::VertexHandle> vertices;
  mesh.get_all_vertices( vertices, err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT_EQUAL( junk.size(), vertices.size() );
  mesh.vertices_set_byte( &vertices[0], &junk[0], vertices.size(), err );
  ASSERT_NO_ERROR(err);  
  
    // Define optimizer
  TCTFauxOptimizer smoother( 2*tol );
  TerminationCriterion outer, inner;
  outer.add_absolute_vertex_movement( tol );
  inner.cull_on_absolute_vertex_movement( tol );
  inner.add_iteration_limit( 1 );
  smoother.set_inner_termination_criterion( &inner );
  smoother.set_outer_termination_criterion( &outer );
  
    // No run the "optimizer"
  InstructionQueue q;
  q.set_master_quality_improver( &smoother, err );
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &zplane);
  q.run_instructions( &mesh_and_domain, err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT( smoother.should_have_terminated() );
  CPPUNIT_ASSERT( smoother.num_passes() > 1 );
}
Example #7
0
static int do_smoother( const char* input_file, 
                        const char* output_file, 
                        const char* ref_mesh_file,
                        double of_power, 
                        unsigned metric_idx,
                        AveragingScheme avg_scheme )
{
  MsqPrintError err(cerr);
  
  TMetric *const target_metric = metrics[metric_idx].u;
  cout << "Input file:  " << input_file << endl;
  cout << "Metric:      ";
  if (avg_scheme != NONE)
    cout << averaging_names[avg_scheme] << " average of ";
  cout << metrics[metric_idx].n << endl;
  cout << "Of Power:    " << of_power << endl;
  
  
  auto_ptr<TargetCalculator> tc;
  auto_ptr<MeshImpl> ref_mesh_impl;
  auto_ptr<ReferenceMesh> ref_mesh;
  if (ref_mesh_file) {
    ref_mesh_impl.reset(new MeshImpl);
    ref_mesh_impl->read_vtk( ref_mesh_file, err );
    if (MSQ_CHKERR(err)) return 2;
    ref_mesh.reset( new ReferenceMesh( ref_mesh_impl.get() ));
    tc.reset( new RefMeshTargetCalculator( ref_mesh.get() ) );
  }
  else {
    tc.reset( new IdealShapeTarget( ) );
  }
    
  TQualityMetric jacobian_metric( tc.get(), target_metric );
  ElementPMeanP elem_avg( of_power, &jacobian_metric );
  VertexPMeanP vtx_avg( of_power, &jacobian_metric );
  QualityMetric* mmetrics[] = { &jacobian_metric, &elem_avg, &vtx_avg, &jacobian_metric };
  QualityMetric* metric = mmetrics[avg_scheme];

  TerminationCriterion outer, inner;
  outer.add_iteration_limit( 1 );
  inner.add_absolute_vertex_movement( 1e-4 );
  inner.add_iteration_limit( 100 );
  
  PMeanPTemplate obj1( of_power, metric );
  PatchPowerMeanP obj2( of_power, metric );
  ObjectiveFunction& objective = *((avg_scheme == PATCH) ? (ObjectiveFunction*)&obj2 : (ObjectiveFunction*)&obj1);
  
  ConjugateGradient solver( &objective, err );
  if (MSQ_CHKERR(err)) return 1;
  solver.set_inner_termination_criterion( &inner );
  solver.set_outer_termination_criterion( &outer );
  solver.use_global_patch();
  
  ConditionNumberQualityMetric qm_metric;
  QualityAssessor before_assessor;
  QualityAssessor after_assessor;
  before_assessor.add_quality_assessment( metric, 10);
  before_assessor.add_quality_assessment( &qm_metric );
  after_assessor.add_quality_assessment( metric, 10 );

  InstructionQueue q;
  q.add_quality_assessor( &before_assessor, err );
  q.set_master_quality_improver( &solver, err );
  q.add_quality_assessor( &after_assessor, err );
  
  MeshImpl mesh;
  mesh.read_vtk( input_file, err );
  if (MSQ_CHKERR(err)) return 2;
  PlanarDomain geom = make_domain( &mesh, err );
  if (MSQ_CHKERR(err)) return 1;
  q.run_instructions( &mesh, &geom, err );
  if (MSQ_CHKERR(err)) return 3;
  mesh.write_vtk( output_file, err );
  if (MSQ_CHKERR(err)) return 2;
  cout << "Wrote: " << output_file << endl;

  before_assessor.scale_histograms(&after_assessor);
  
  return 0;
}
Example #8
0
bool smooth_mixed_mesh( const char* filename )
{
  Mesquite::MsqPrintError err(cout);
  
  // print a little output so we know when we died
  std::cout << 
  "**************************************************************************" 
  << std::endl << 
  "* Smoothing: " << filename
  << std::endl  <<
  "**************************************************************************" 
  << std::endl;
  
  // The instruction queue to set up
  InstructionQueue Q;
  
  // Use numeric approx of derivitives until analytic solutions
  // are working for pyramids
  IdealWeightInverseMeanRatio mr_metric(err);
  //sRI_DFT dft_metric;
  UntangleBetaQualityMetric un_metric(0);
  CPPUNIT_ASSERT(!err);
  
    // Create Mesh object
  Mesquite::MeshImpl mesh;
  mesh.read_vtk(filename, err);
  CPPUNIT_ASSERT(!err);

  // Set up a preconditioner
  LInfTemplate pre_obj_func( &un_metric );
  ConjugateGradient precond( &pre_obj_func, err ); CPPUNIT_ASSERT(!err);
  precond.use_element_on_vertex_patch();
  TerminationCriterion pre_term, pre_outer;
  //pre_term.add_relative_quality_improvement( 0.1 );
  pre_term .add_iteration_limit( 3 );
  pre_outer.add_iteration_limit( 1 );
  CPPUNIT_ASSERT(!err);
  precond.set_inner_termination_criterion( &pre_term );
  precond.set_outer_termination_criterion( &pre_outer );
  //precond.use_element_on_vertex_patch();

  // Set up objective function
  LPtoPTemplate obj_func(&mr_metric, 1, err);
  CPPUNIT_ASSERT(!err);

  // Create solver
  FeasibleNewton solver( &obj_func, true );
  CPPUNIT_ASSERT(!err);
  solver.use_global_patch();
  CPPUNIT_ASSERT(!err);

  // Set stoping criteria for solver
  TerminationCriterion tc_inner;
  tc_inner.add_relative_quality_improvement( 0.25 );
  solver.set_inner_termination_criterion(&tc_inner);
   
  TerminationCriterion tc_outer;
  tc_outer.add_iteration_limit( 1 );
  CPPUNIT_ASSERT(!err);
  solver.set_outer_termination_criterion(&tc_outer);

  // Create a QualityAssessor
  Mesquite::QualityAssessor qa;
  qa.add_quality_assessment( &mr_metric );
  qa.add_quality_assessment( &un_metric );
  Q.add_quality_assessor( &qa, err ); 
  CPPUNIT_ASSERT(!err);
 
  // Add untangler to queue
  Q.add_preconditioner( &precond, err ); CPPUNIT_ASSERT(!err);
  Q.add_quality_assessor( &qa, err ); 
  CPPUNIT_ASSERT(!err);
 
  // Add solver to queue
  Q.set_master_quality_improver(&solver, err); 
  CPPUNIT_ASSERT(!err);
  Q.add_quality_assessor( &qa, err ); 
  CPPUNIT_ASSERT(!err);
 
  // And smooth...
  Q.run_instructions(&mesh, err); 
  CPPUNIT_ASSERT(!err);

  return false;
}
Example #9
0
bool smooth_mesh( Mesh* mesh, Mesh* ref_mesh,
                  Mesh::VertexHandle free_vertex_at_origin, 
                  Vector3D initial_free_vertex_position,
                  QualityMetric* metric )
{
  Mesquite::MsqPrintError err(cout);
  const Vector3D origin( 0, 0, 0 );
  
  // print a little output so we know when we died
  std::cout << 
  "**************************************************************************" 
  << std::endl << 
  "* Smoothing..."
  << std::endl << 
  "* Metric: " << metric->get_name()
  << std::endl << 
  "* Apex position: " << initial_free_vertex_position
  << std::endl //<< 
  //"**************************************************************************" 
  << std::endl;

  
  // Set free vertex to specified position
  mesh->vertex_set_coordinates( free_vertex_at_origin, 
                                initial_free_vertex_position,
                                err );
  CPPUNIT_ASSERT(!err);

  // Create an InstructionQueue
  InstructionQueue Q;

  // Set up objective function
  LPtoPTemplate obj_func(metric, 1, err);
  CPPUNIT_ASSERT(!err);

  // Create solver
  FeasibleNewton solver( &obj_func, true );
  CPPUNIT_ASSERT(!err);
  solver.use_global_patch();
  CPPUNIT_ASSERT(!err);

  // Set stoping criteria for solver
  TerminationCriterion tc_inner;
  tc_inner.add_absolute_vertex_movement( 1e-6 );
  solver.set_inner_termination_criterion(&tc_inner);
   
  TerminationCriterion tc_outer;
  tc_outer.add_iteration_limit( 1 );
  solver.set_outer_termination_criterion(&tc_outer);
   
  // Add solver to queue
  Q.set_master_quality_improver(&solver, err); 
  CPPUNIT_ASSERT(!err);
 
  // And smooth...
  Q.run_instructions(mesh, err); 
  CPPUNIT_ASSERT(!err);
  
  // Verify that vertex was moved back to origin
  MsqVertex vtx;
  mesh->vertices_get_coordinates( &free_vertex_at_origin, &vtx, 1, err );
  CPPUNIT_ASSERT( !err );
  Vector3D position = vtx;
  
  // print a little output so we know when we died
  std::cout //<< 
  //"**************************************************************************" 
  << std::endl << 
  "* Done Smoothing:"
  << std::endl << 
  "* Metric: " << metric->get_name()
  << std::endl << 
  "* Apex position: " << position
  << std::endl <<  
  "**************************************************************************" 
  << std::endl;
  
  CPPUNIT_ASSERT( position.within_tolerance_box( Vector3D(0,0,0), TOL ) );
  return false;
}
Example #10
0
void run_test( Grouping grouping, int of_power, Weight w, const string filename )
{
    MsqError err;

    IdentityTarget target;
    TSquared target_metric;
    AffineMapMetric qual_metric( &target, &target_metric );
    ElementPMeanP elem_metric( of_power, &qual_metric );
    QualityMetric* qm_ptr = (grouping == ELEMENT) ? (QualityMetric*)&elem_metric : (QualityMetric*)&qual_metric;

    PMeanPTemplate OF( of_power, qm_ptr );
    ConjugateGradient solver( &OF );
    TerminationCriterion tc;
    TerminationCriterion itc;
    tc.add_absolute_vertex_movement( 1e-4 );
    itc.add_iteration_limit( 2 );
#ifdef USE_GLOBAL_PATCH
    solver.use_global_patch();
    solver.set_inner_termination_criterion( &tc );
#else
    solver.use_element_on_vertex_patch();
    solver.set_inner_termination_criterion( &itc );
    solver.set_outer_termination_criterion( &tc );
#endif

    MeshImpl mesh, expected_mesh;
    mesh.read_vtk( SRCDIR "/initial.vtk", err );
    CHKERR(err)
//  expected_mesh.read_vtk( (filename + ".vtk").c_str(), err ); CHKERR(err)

    PlanarDomain plane( PlanarDomain::XY );

    MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &plane);

    MetricWeight mw( &qual_metric );
    InverseMetricWeight imw( &qual_metric );
    WeightReader reader;
    if (w == METRIC) {
        TargetWriter writer( 0, &mw );
        InstructionQueue tq;
        tq.add_target_calculator( &writer, err );
        tq.run_instructions( &mesh_and_domain, err );
        CHKERR(err);
        qual_metric.set_weight_calculator( &reader );
    }
    else if (w == INV_METRIC) {
        TargetWriter writer( 0, &imw );
        InstructionQueue tq;
        tq.add_target_calculator( &writer, err );
        tq.run_instructions( &mesh_and_domain, err );
        CHKERR(err);
        qual_metric.set_weight_calculator( &reader );
    }

    InstructionQueue q;
    q.set_master_quality_improver( &solver, err );
    q.run_instructions( &mesh_and_domain, err );
    CHKERR(err)
    /*
      vector<Mesh::VertexHandle> vemain.cpprts;
      vector<MsqVertex> mesh_coords, expected_coords;
      mesh.get_all_vertices( verts, err ); CHKERR(err)
      mesh_coords.resize(verts.size());
      mesh.vertices_get_coordinates( arrptr(verts), arrptr(mesh_coords), verts.size(), err ); CHKERR(err)
      expected_mesh.get_all_vertices( verts, err ); CHKERR(err)
      expected_coords.resize(verts.size());
      expected_mesh.vertices_get_coordinates( arrptr(verts), arrptr(expected_coords), verts.size(), err ); CHKERR(err)
      if (expected_coords.size() != mesh_coords.size()) {
        cerr << "Invlid expected mesh.  Vertex count doesn't match" << endl;
        exit(1);
      }

      unsigned error_count = 0;
      for (size_t i = 0; i < mesh_coords.size(); ++i)
        if ((expected_coords[i] - mesh_coords[i]).length_squared() > epsilon*epsilon)
          ++error_count;

      if (!error_count)
        cout << filename << " : SUCCESS" << endl;
      else
        cout << filename << " : FAILURE (" << error_count
             << " vertices differ by more than " << epsilon << ")" << endl;
    */
    if (write_results)
        mesh.write_vtk( (filename + ".results.vtk").c_str(), err );
    CHKERR(err)
}
Example #11
0
int main( int argc, char* argv[] )
{
  MeshParams input_params, reference_params;
  bool fixed_boundary_vertices, feas_newt_solver;
  TerminationCriterion::TimeStepFileType write_timestep_files;
  std::string output_file_name;
  int num_iterations;
  
  parse_options( argv, argc,
                 input_params, reference_params,
                 output_file_name,
                 fixed_boundary_vertices,
                 write_timestep_files,
                 feas_newt_solver,
                 num_iterations );
  
  MsqError err;
  MeshImpl mesh, refmesh;
  XYRectangle domain( input_params.w, input_params.h );
  create_input_mesh( input_params, fixed_boundary_vertices, mesh, err ); CHECKERR
  create_input_mesh( reference_params, fixed_boundary_vertices, refmesh, err ); CHECKERR
  domain.setup( &mesh, err ); CHECKERR

  ReferenceMesh rmesh( &refmesh );
  RefMeshTargetCalculator tc( &rmesh );
  TShapeB1 tm;
  TQualityMetric qm( &tc, &tm );
  
  PMeanPTemplate of( 1.0, &qm );
  ConjugateGradient cg( &of );
  cg.use_element_on_vertex_patch();
  FeasibleNewton fn( &of );
  fn.use_element_on_vertex_patch();
  VertexMover* solver = feas_newt_solver ? (VertexMover*)&fn : (VertexMover*)&cg;
  
  TerminationCriterion inner, outer;
  inner.add_iteration_limit( INNER_ITERATES );
  outer.add_iteration_limit( num_iterations );
  if (write_timestep_files != TerminationCriterion::NOTYPE) 
    outer.write_mesh_steps( base_name( output_file_name ).c_str(), write_timestep_files );
  solver->set_inner_termination_criterion( &inner );
  solver->set_outer_termination_criterion( &outer );
  
  QualityAssessor qa( &qm );
  InstructionQueue q;
  q.add_quality_assessor( &qa, err );
  q.set_master_quality_improver( solver, err );
  q.add_quality_assessor( &qa, err );
  
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &domain);
  q.run_instructions( &mesh_and_domain, err ); CHECKERR
  
  mesh.write_vtk( output_file_name.c_str(), err ); CHECKERR
  
    // check for inverted elements
  int inv, unk;
  qa.get_inverted_element_count( inv, unk, err );
  if (inv) {
    std::cerr << inv << " inverted elements in final mesh" << std::endl;
    return INVERTED_ELEMENT;
  }
  else if (unk) {
    std::cerr << unk << " degenerate elements in final mesh" << std::endl;
    return DEGENERATE_ELEMENT;
  }
    
    // find the free vertex
  std::vector<Mesh::VertexHandle> vertices;
  mesh.get_all_vertices( vertices, err );
  if (vertices.empty()) {
    std::cerr << "Mesh contains no vertices" << std::endl;
    return USAGE_ERROR;
  }
  std::vector<unsigned short> dof( vertices.size(), 0 );
  domain.domain_DoF( arrptr(vertices), arrptr(dof), vertices.size(), err ); CHECKERR
  int idx = std::find(dof.begin(), dof.end(), 2) - dof.begin();
  const Mesh::VertexHandle free_vertex = vertices[idx];
  MsqVertex coords;
  mesh.vertices_get_coordinates( &free_vertex, &coords,1, err ); CHECKERR
  
    // calculate optimal position for vertex
  const double xf = reference_params.x / reference_params.w;
  const double yf = reference_params.y / reference_params.h;
  Vector3D expect( xf * input_params.w, yf * input_params.h, 0 );

  // Test that we aren't further from the expected location
  // than when we started. 
  const Vector3D init( input_params.x, input_params.y, 0 );
  if ((coords - expect).length() > (init - expect).length()) {
    std::cerr << "Vertex moved away from expected optimal position: "
                    << "(" << coords[0] << ", " << coords[1] << std::endl;
    return WRONG_DIRECTION;
  }
  
    // check if vertex moved MIN_FRACT of the way from the original position
    // to the desired one in the allowed iterations
  const double MIN_FRACT = 0.2; // 20% of the way in 10 iterations
  const double fract = (coords - init).length() / (expect - init).length();
  if (fract < MIN_FRACT) {
    std::cerr << "Vertex far from optimimal location" << std::endl
                    << "  Expected: (" << expect[0] << ", " << expect[1] << ", " << expect[2] << ")" << std::endl
                    << "  Actual:   (" << coords[0] << ", " << coords[1] << ", " << coords[2] << ")" << std::endl;
    return FAR_FROM_TARGET;
  }
  
    // check if vertex is at destired location
  const double EPS = 5e-2; // allow a little leway
  if (fabs(coords[0] - expect[0]) > EPS * input_params.w ||
      fabs(coords[1] - expect[1]) > EPS * input_params.h ||
      fabs(expect[2]            ) > EPS                  ) {
    std::cerr << "Vertex not at optimimal location" << std::endl
                    << "  Expected: (" << expect[0] << ", " << expect[1] << ", " << expect[2] << ")" << std::endl
                    << "  Actual:   (" << coords[0] << ", " << coords[1] << ", " << coords[2] << ")" << std::endl;
    return NOT_AT_TARGET;
  }
  
  return 0;
}
Example #12
0
double run( QualityMetric* metric, 
            Solver solver_type,
            const char* input_file,
            double& seconds_out,
            int& iterations_out )
{
  MsqPrintError err(cerr);
  IdealWeightInverseMeanRatio qa_metric;
  TerminationCriterion inner, outer;
  outer.add_iteration_limit( 1 );
  inner.add_absolute_vertex_movement( 1e-4 );
  inner.add_iteration_limit( 100 );
  PMeanPTemplate of( 1.0, metric );
  QualityAssessor qa( &qa_metric );
  qa.add_quality_assessment( metric );
  InstructionQueue q;
  SteepestDescent steep(&of);
  QuasiNewton quasi(&of);
  ConjugateGradient conj(&of);
  VertexMover* solver = 0;
  switch (solver_type) {
    case STEEP_DESCENT: solver = &steep; break;
    case QUASI_NEWT:solver = &quasi;break;
    case CONJ_GRAD: solver = &conj; break;
  }
  q.set_master_quality_improver( solver, err );
  q.add_quality_assessor( &qa, err );
  solver->set_inner_termination_criterion(&inner);
  solver->set_outer_termination_criterion(&outer);
  
  
  if (plot_file)
    inner.write_iterations( plot_file, err );
  
  MeshImpl mesh;
  mesh.read_vtk( input_file, err );
  if (err) {
    cerr << "Failed to read input file: \"" << input_file << '"' << endl;
    exit(1);
  }
  
  std::vector<Mesh::VertexHandle> handles;
  mesh.get_all_vertices( handles, err );
  if (handles.empty()) {
    cerr << "no veritces in mesh" << endl;
    exit(1);
  }
  std::vector<MsqVertex> coords(handles.size());
  mesh.vertices_get_coordinates( arrptr(handles), arrptr(coords), handles.size(), err );
  Vector3D min(HUGE_VAL), max(-HUGE_VAL);
  for (size_t i = 0; i < coords.size(); ++i) {
    for (int j = 0; j < 3; ++j) {
      if (coords[i][j] < min[j])
        min[j] = coords[i][j];
      if (coords[i][j] > max[j])
        max[j] = coords[i][j];
    }
  }
  
  Vector3D size = max - min;
  PlanarDomain* domain = 0;
  if (size[0] < 1e-4) 
    domain = new PlanarDomain( PlanarDomain::YZ, min[0] );
  else if (size[1] < 1e-4)
    domain = new PlanarDomain( PlanarDomain::XZ, min[1] );
  else if (size[2] < 1e-4)
    domain = new PlanarDomain( PlanarDomain::XY, min[2] );
  
  Timer timer;
  q.run_instructions( &mesh, domain, err );
  seconds_out = timer.since_birth();
  if (err) {
    cerr << "Optimization failed." << endl << err << endl;
    abort();
  }

  if (vtk_file) {
    MeshWriter::write_vtk( &mesh, vtk_file, err );
    if (err) 
      cerr << vtk_file << ": failed to write file." << endl;
  }
  if (gpt_file) {
    MeshWriter::write_gnuplot( &mesh, gpt_file, err );
    if (err) 
      cerr << gpt_file << ": failed to write file." << endl;
  }
  if (eps_file) {
    PlanarDomain xy(PlanarDomain::XY);
    MeshWriter::Projection proj( domain ? domain : &xy );
    MeshWriter::write_eps( &mesh, eps_file, proj, err );
    if (err) 
      cerr << eps_file << ": failed to write file." << endl;
  }
  delete domain;
  
  iterations_out = inner.get_iteration_count();
  
  const QualityAssessor::Assessor* a = qa.get_results( &qa_metric );
  return a->get_average();
}
Example #13
0
int main(int argc, char* argv[])
{
  const char* initial_mesh_file = 0;
  const char* final_mesh_file = 0;
  for (int i = 1; i < argc; ++i) {
    if (!strcmp(argv[i],"-f")) {
      ++i;
      if (i == argc)
        usage(argv[0]);
      final_mesh_file = argv[i];
    }
    else if (!strcmp(argv[i],"-i")) {
      ++i;
      if (i == argc)
        usage(argv[0]);
      initial_mesh_file = argv[i];
    }
    else
      usage( argv[i] );
  }


    // create mesh
  const int intervals = 3;
  const double perturb = 0.3;
  const int nvtx = (intervals+1) * (intervals+1);
  double coords[nvtx*3];
  double exp_coords[nvtx*3];
  int fixed[nvtx];
  for (int i = 0; i < nvtx; ++i) {
    double* c = coords + 3*i;
    double* e = exp_coords + 3*i;
    int row = i / (intervals+1);
    int col = i % (intervals+1);
    double xdelta, ydelta;
    if (row > 0 && row < intervals && col > 0 && col < intervals) {
      fixed[i] = 0;
      xdelta = row % 2 ? -perturb : 0;
      ydelta = col % 2 ? perturb : -perturb;
    }
    else {
      fixed[i] = 1;
      xdelta = ydelta = 0.0;
    }
    c[0] = col + xdelta;
    c[1] = row + ydelta;
    c[2] = 0.0;
    e[0] = col;
    e[1] = row;
    e[2] = 0.0;
  }
  const int nquad = intervals * intervals;
  unsigned long conn[nquad * 4];
  for (int i = 0; i < nquad; ++i) {
    unsigned long* c = conn + 4*i;
    int row = i / intervals;
    int col = i % intervals;
    int n0 = (intervals+1)*row + col;
    c[0] = n0;
    c[1] = n0+1;
    c[2] = n0+intervals+2;
    c[3] = n0+intervals+1;
  }
  MsqPrintError err(std::cerr);
  ArrayMesh mesh( 3, nvtx, coords, fixed, nquad, QUADRILATERAL, conn );
  PlanarDomain zplane( PlanarDomain::XY );
  if (initial_mesh_file) {
    MeshWriter::write_vtk( &mesh, initial_mesh_file, err );
    if (err) {
      fprintf(stderr,"%s: failed to write file\n", initial_mesh_file );
      return 1;
    }
  }
  
    // do optimization
  const double eps = 0.01;
  IdealShapeTarget w;
  TShapeB1 mu;
  TQualityMetric metric( &w, &mu );
  PMeanPTemplate func( 1.0, &metric );
  SteepestDescent solver( &func );
  solver.use_element_on_vertex_patch();
  solver.do_jacobi_optimization();
  TerminationCriterion inner, outer;
  inner.add_absolute_vertex_movement( 0.5*eps );
  outer.add_absolute_vertex_movement( 0.5*eps );
  QualityAssessor qa( &metric );
  InstructionQueue q;
  q.add_quality_assessor( &qa, err );
  q.set_master_quality_improver( &solver, err );
  q.add_quality_assessor( &qa, err );
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &zplane);
  q.run_instructions( &mesh_and_domain, err );
  if (err)
    return 2;
  if (final_mesh_file) {
    MeshWriter::write_vtk( &mesh, final_mesh_file, err );
    if (err) {
      fprintf(stderr,"%s: failed to write file\n", final_mesh_file );
      return 1;
    }
  }
  
    // check final vertex positions
  int invalid = 0;
  for (int i = 0; i < nvtx; ++i) {
    if (dist( coords + 3*i, exp_coords + 3*i ) > eps) {
      ++invalid;
      printf("Vertex %d at (%f,%f,%f), expected at (%f,%f,%f)\n", i,
        coords[3*i], coords[3*i+1], coords[3*i+2],
        exp_coords[3*i], exp_coords[3*i+1], exp_coords[3*i+2] );
    }
  }
  
  return invalid ? 2 : 0;
}
Example #14
0
int main( int argc, char* argv[] )
{
  const double default_fraction = 0.05;
  const double zero = 0.0;
  int one = 1;
  CLArgs::ToggleArg allow_invalid( false );
  CLArgs::DoubleRangeArg rand_percent( default_fraction, &zero, 0 );
  CLArgs::IntRangeArg unoptimize( 0, &one, 0 );
  
  CLArgs args( "vtkrandom",
               "Randomize mesh vertex locations.",
               "Read VTK file, randomize locations of containded vertices, and re-write file." );
  args.toggle_flag( INVALID_FLAG, "Allow inverted elements in output", &allow_invalid );
  args.double_flag( PERCENT_FLAG, "fract", "Randomize fraction", &rand_percent );
  args.int_flag( UNOPTIMIZE_FLAG, "N", "Use UnOptimizer with N passes rather than Randomize", &unoptimize );
  add_domain_args( args );
  args.add_required_arg( "input_file" );
  args.add_required_arg( "output_file" );

  std::vector<std::string> files;
  if (!args.parse_options( argc, argv, files, std::cerr )) {
    args.print_usage( std::cerr );
    exit(1);
  }
  std::string input_file = files[0];
  std::string output_file = files[1];
  
  MsqError err;
  MeshImpl mesh;
  mesh.read_vtk( input_file.c_str(), err );
  if (err) {
    std::cerr << "ERROR READING FILE: " << input_file << std::endl
                    << err << std::endl;
    return 2;
  }
  MeshDomain* domain = process_domain_args( &mesh );

  TerminationCriterion tc;
  QualityAssessor qa( false );
  InstructionQueue q;
  Randomize op( rand_percent.value() );
  IdealWeightInverseMeanRatio metric;
  PMeanPTemplate of( 1, &metric );
  UnOptimizer op2( &of );
  if (unoptimize.seen()) {
    tc.add_iteration_limit( unoptimize.value() );
    op2.set_outer_termination_criterion( &tc );
    q.add_preconditioner( &op, err );
    q.set_master_quality_improver( &op2, err );
  }
  else {
    q.set_master_quality_improver( &op, err );
  }
  q.add_quality_assessor( &qa, err );
  q.run_instructions( &mesh, domain, err );
  if (err) {
    std::cerr << err << std::endl;
    return 3;
  }

  int inverted, junk;
  if (qa.get_inverted_element_count( inverted, junk, err ) && inverted ) {
    if (allow_invalid.value())
      std::cerr << "Warning: output mesh contains " << inverted << " inverted elements" << std::endl;
    else {
      std::cerr << "Error: output mesh contains " << inverted << " inverted elements" << std::endl;
      return 4;
    }
  }
  
  mesh.write_vtk( output_file.c_str(), err );
  if (err) {
    std::cerr << "ERROR WRITING FILE: " << output_file << std::endl
                    << err << std::endl;
    return 2;
  }
  
  return 0;
}