Exemple #1
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;
}
Exemple #2
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;
}
Exemple #3
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();
}