Example #1
0
int run_example( const Example& e, bool write_output_file )
{
  MsqPrintError err(std::cerr);
  MeshImpl mesh;
  DomainClassifier domain;
  HexLagrangeShape hex27;
  
  std::cout << std::endl 
            << "--------------------------------------------------------------------"
            << std::endl
            << e.desc << std::endl
            << "--------------------------------------------------------------------"
            << std::endl;
   
  std::string name = e.func( domain, mesh, err );
  if (MSQ_CHKERR(err)) return 2;
  std::cout << "Loaded mesh from: " << name << std::endl;
  
  UntangleWrapper untangler;
  untangler.set_slaved_ho_node_mode( Settings::SLAVE_NONE );
  untangler.set_mapping_function( &hex27 );
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &domain, false, true);
  untangler.run_instructions( &mesh_and_domain, err ); 
  if (MSQ_CHKERR(err)) return 1;
  ShapeImprover smoother;
  smoother.set_slaved_ho_node_mode( Settings::SLAVE_NONE );
  smoother.set_mapping_function( &hex27 );
  smoother.set_vertex_movement_limit_factor( 0.05 );
  smoother.run_instructions( &mesh_and_domain, err );
  if (MSQ_CHKERR(err)) return 1;
  
  if (write_output_file) {
    size_t idx = name.find( ".vtk" );
    if (idx != std::string::npos) {
      std::string newname( name.substr(0, idx) );
      newname += ".out";
      newname += name.substr(idx);
      name.swap(newname);
    }
    else {
      name += ".out";
    }
    
    mesh.write_vtk( name.c_str(), err ); MSQ_CHKERR(err);
    std::cout << "Write mesh to file: " << name << std::endl;
  }
  
  return smoother.quality_assessor().invalid_elements();
}
Example #2
0
void ParShapeImprover::ParShapeImprovementWrapper::run_wrapper( Mesh* mesh,
                                                                ParallelMesh* pmesh,
                                                                MeshDomain* domain,
                                                                Settings* settings,
                                                                QualityAssessor* qa,
                                                                MsqError& err )
{
  int rank, nprocs;
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

  // Define an untangler
  //UntangleBetaQualityMetric untangle_metric( untBeta );
  UntangleBetaQualityMetric untangle_metric( 1.e-6 );

  bool check_untangle = true;
  if (check_untangle)
    {
      std::cout << "\nP[" << rank << "]  ParShapeImprover.... running QA with untangle_metric before... " << std::endl;
      InstructionQueue q1;
      QualityAssessor qa_untangle(&untangle_metric);
      q1.add_quality_assessor(&qa_untangle, err); MSQ_ERRRTN(err);
      q1.run_common( mesh, pmesh, domain, settings, err ); 
      std::cout << "\nP[" << rank << "]  ParShapeImprover.... running QA with untangle_metric... before... done " << std::endl;
    }

  LPtoPTemplate untangle_func( 2, &untangle_metric );
  ConjugateGradient untangle_solver( &untangle_func );
  //untangle_solver.set_debugging_level(3);

  //SteepestDescent untangle_solver( &untangle_func );
  TerminationCriterion untangle_inner("<type:untangle_inner>"), untangle_outer("<type:untangle_outer>");
  untangle_solver.use_global_patch();

  //untangle_inner.add_absolute_gradient_L2_norm( gradNorm );
  //untangle_inner.add_absolute_successive_improvement( successiveEps );
  //untangle_inner.add_relative_successive_improvement( 1.e-6 );
  //untangle_inner.add_untangled_mesh();

  untangle_inner.write_iterations("untangle.gpt", err);

  // For parallel runs, we generally need to have the inner and outer TerminationCriterion
  //   have the same criteria else we can get an infinite loop (see VertexMover::loop_over_mesh)
  untangle_inner.add_absolute_quality_improvement( 0.0 );
  untangle_inner.add_iteration_limit( 20 );

  untangle_outer.add_absolute_quality_improvement( 0.0 );
  untangle_outer.add_iteration_limit( pmesh ? parallelIterations : 1 );

  untangle_solver.set_inner_termination_criterion( &untangle_inner );
  untangle_solver.set_outer_termination_criterion( &untangle_outer );

  // define shape improver
  IdealWeightInverseMeanRatio inverse_mean_ratio;
  inverse_mean_ratio.set_averaging_method( QualityMetric::LINEAR );
  LPtoPTemplate obj_func( 2, &inverse_mean_ratio );

  ConjugateGradient shape_solver( &obj_func );
  TerminationCriterion term_inner("<type:shape_inner>"), term_outer("<type:shape_outer>");
  term_inner.write_iterations("shape.gpt", err);

  shape_solver.use_global_patch();
  qa->add_quality_assessment( &inverse_mean_ratio );

  // For parallel runs, we generally need to have the inner and outer TerminationCriterion
  //   have the same criteria else we can get an infinite loop (see VertexMover::loop_over_mesh)
  term_inner.add_absolute_gradient_L2_norm( gradNorm );
  term_inner.add_absolute_vertex_movement(0.0);
  term_inner.add_iteration_limit( innerIter );

  term_outer.add_absolute_gradient_L2_norm( gradNorm );
  term_outer.add_absolute_vertex_movement(0.0);
  term_outer.add_iteration_limit( pmesh ? parallelIterations : 1 );

  //term_outer.add_absolute_quality_improvement( 1.e-6 );
  //!term_outer.add_relative_successive_improvement( successiveEps );

  shape_solver.set_inner_termination_criterion( &term_inner );
  shape_solver.set_outer_termination_criterion( &term_outer );

  // Apply CPU time limit to untangler
  if (maxTime > 0.0)
    untangle_inner.add_cpu_time( maxTime );
  
  Timer totalTimer;

  // Run untangler
  std::cout << "\nP[" << rank << "] " << " ParShapeImprovementWrapper: running untangler...\n " << std::endl;
  bool use_untangle_wrapper = false;
  if (use_untangle_wrapper)
    {
      UntangleWrapper uw;
      //uw.set_untangle_metric(UntangleWrapper::BETA);
      uw.run_instructions(mesh, domain, err);
    }
  else
    {
      InstructionQueue q1;
      QualityAssessor qa_untangle(&untangle_metric);
      q1.add_quality_assessor(&qa_untangle, err); MSQ_ERRRTN(err);
      q1.set_master_quality_improver( &untangle_solver, err ); MSQ_ERRRTN(err);
      q1.add_quality_assessor(&qa_untangle, err); MSQ_ERRRTN(err);
      q1.run_common( mesh, pmesh, domain, settings, err ); 
    }
  std::cout << "\nP[" << rank << "] " << " ParShapeImprovementWrapper: running untangler... done\n " << std::endl;
  std::cout << "\nP[" << rank << "] " << " ParShapeImprovementWrapper: MsqError after untangler: " << err << std::endl;

  bool check_quality_after_untangler = true;
  if (check_quality_after_untangler)
    {
      int num_invalid = count_invalid_elements(*mesh, domain);
      std::cout << "\nP[" << rank << "] " << " ParShapeImprover num_invalid after untangler= " << num_invalid << " " 
                << (num_invalid ? " ERROR still have invalid elements after Mesquite untangle" : 
                    " SUCCESS: untangled invalid elements ")
                << std::endl;

      if (check_untangle)
        {
          std::cout << "\nP[" << rank << "]  ParShapeImprover.... running QA with untangle_metric " << std::endl;
          InstructionQueue q1;
          QualityAssessor qa_untangle(&untangle_metric);
          q1.add_quality_assessor(&qa_untangle, err); MSQ_ERRRTN(err);
          q1.run_common( mesh, pmesh, domain, settings, err ); 
          std::cout << "\nP[" << rank << "]  ParShapeImprover.... running QA with untangle_metric... done " << std::endl;
        }

      if (num_invalid) return;
    }
  if (m_do_untangle_only) return;
  MSQ_ERRRTN(err);

  // If limited by CPU time, limit next step to remaning time
  if (maxTime > 0.0) {
    double remaining = maxTime - totalTimer.since_birth();
    if (remaining <= 0.0 ){
      MSQ_DBGOUT(2) << "Optimization is terminating without perfoming shape improvement." << std::endl;
      remaining = 0.0;
    }
    term_inner.add_cpu_time( remaining );
  }
  
  // Run shape improver
  InstructionQueue q2;
  std::cout << "\nP[" << rank << "] " << " ParShapeImprovementWrapper: running shape improver... \n" << std::endl;
  q2.add_quality_assessor( qa, err ); MSQ_ERRRTN(err);
  q2.set_master_quality_improver( &shape_solver, err ); MSQ_ERRRTN(err);
  q2.add_quality_assessor( qa, err ); MSQ_ERRRTN(err);
  q2.run_common( mesh, pmesh, domain, settings, err ); 
  std::cout << "\nP[" << rank << "] " << " ParShapeImprovementWrapper: running shape improver... done \n" << std::endl;
  MSQ_ERRRTN(err);
}