Example #1
0
bool PatchPowerMeanP::initialize_block_coordinate_descent( Mesh* mesh, 
                                                      MeshDomain* domain, 
                                                      const Settings* settings,
                                                      PatchSet* patch_set,
                                                      MsqError& err )
{
  clear();
  PatchIterator patches( patch_set );
  
  PatchData pd;
  pd.set_mesh( mesh );
  pd.set_domain( domain );
  if (settings)
    pd.attach_settings(settings);
  
  bool result = true;
  while (patches.get_next_patch( pd, err ) && !MSQ_CHKERR(err))
  {
    double value;
    bool b = evaluate( ObjectiveFunction::ACCUMULATE, pd, value, false, err ); 
    MSQ_ERRZERO(err);
    result = result && b;
  }
  return result;
}
Example #2
0
void write_gnuplot( Mesh* mesh, const char* out_filebase, MsqError &err)
{
    // loads a global patch
  PatchData pd;
  pd.set_mesh( mesh );
  pd.fill_global_patch( err ); MSQ_ERRRTN(err);
  write_gnuplot( pd, out_filebase, err );
}
Example #3
0
int check_global_patch_slaved( Mesh& mesh, MsqError& err )
{
  Settings s;
  s.set_slaved_ho_node_mode( Settings::SLAVE_FLAG );
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, 0);
  Instruction::initialize_vertex_byte( &mesh_and_domain, &s, err ); MSQ_ERRZERO(err);
  
  PatchData pd;
  pd.attach_settings( &s );
  pd.set_mesh( &mesh );
  pd.fill_global_patch( err ); MSQ_ERRZERO(err);

  std::vector<bool> fixed, slaved;
  mesh.vertices_get_fixed_flag( pd.get_vertex_handles_array(), 
                                fixed, pd.num_nodes(), err );
  MSQ_ERRZERO(err);
  mesh.vertices_get_slaved_flag( pd.get_vertex_handles_array(), 
                                 slaved, pd.num_nodes(), err );
  MSQ_ERRZERO(err);
  
  const size_t first_free = 0;
  const size_t first_slaved = pd.num_free_vertices();
  const size_t first_fixed = pd.num_free_vertices() + pd.num_slave_vertices();
  int error_count = 0;
  for (size_t i = first_free; i < first_slaved; ++i) {
    if (fixed[i]) {
      std::cerr << "Vertex " << (size_t)pd.get_vertex_handles_array()[i]
                << " is fixed in mesh but free in PatchData" << std::endl;
      ++error_count;
    }
    if (slaved[i]) {
      std::cerr << "Vertex " << (size_t)pd.get_vertex_handles_array()[i]
                << " is slaved in mesh but free in PatchData" << std::endl;
      ++error_count;
    }
  }
  for (size_t i = first_slaved; i < first_fixed; ++i) {
    if (fixed[i]) {
      std::cerr << "Vertex " << (size_t)pd.get_vertex_handles_array()[i]
                << " is fixed in mesh but slaved in PatchData" << std::endl;
      ++error_count;
    }
    else if (!slaved[i]) {
      std::cerr << "Vertex " << (size_t)pd.get_vertex_handles_array()[i]
                << " is free in Mesh but slaved in PatchData" << std::endl;
      ++error_count;
    }
  }
  for (size_t i = first_fixed; i < pd.num_nodes(); ++i) {
    if (!fixed[i]) {
      std::cerr << "Vertex " << (size_t)pd.get_vertex_handles_array()[i]
                << " is not fixed in mesh but is in PatchData" << std::endl;
      ++error_count;
    }
  }
  return 0 == error_count;
}
Example #4
0
void write_gnuplot( Mesh* mesh, std::vector<Mesh::ElementHandle>& elems,
                    const char* out_filebase, MsqError &err)
{
    // loads a global patch
  PatchData pd;
  pd.set_mesh( mesh );
  std::vector<Mesh::VertexHandle> verts;
  pd.set_mesh_entities( elems, verts, err ); MSQ_ERRRTN(err);
  write_gnuplot( pd, out_filebase, err );
}
Example #5
0
void write_svg( Mesh* mesh, 
                const char* filename, 
                Projection proj, 
                MsqError& err )
{
    // Get a global patch
  PatchData pd;
  pd.set_mesh( mesh );
  pd.fill_global_patch( err ); MSQ_ERRRTN(err);
  
  Transform2D transf( &pd, proj, 400, 400, true );
    
    // Open the file
  ofstream file(filename);
  if (!file)
  {
    MSQ_SETERR(err)(MsqError::FILE_ACCESS);
    return;
  }

    // Write header
  file << "<?xml version=\"1.0\" standalone=\"no\"?>"                << endl;
  file << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" " 
       << "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">"    << endl;
  file <<                                                               endl;
  file << "<svg width=\"" << transf.max_horizontal() 
       << "\" height=\"" << transf.max_vertical()
       << "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">" << endl;
  
    // Write mesh edges
  EdgeIterator iter( &pd, err );  MSQ_ERRRTN(err);
  while( !iter.is_at_end() )
  {
    int s_w, s_h, e_w, e_h;
    transf.transform( iter.start(), s_w, s_h );
    transf.transform( iter.end  (), e_w, e_h );
    
    file << "<line "
         << "x1=\"" << s_w << "\" "
         << "y1=\"" << s_h << "\" "
         << "x2=\"" << e_w << "\" "
         << "y2=\"" << e_h << "\" "
         << " style=\"stroke:rgb(99,99,99);stroke-width:2\""
         << "/>" << endl;
    
    iter.step( err ); MSQ_ERRRTN(err);
  }
  
    // Write footer
  file << "</svg>" << endl;
}
bool ObjectiveFunctionTemplate::initialize_block_coordinate_descent( Mesh* mesh, 
                                                      MeshDomain* domain, 
                                                      const Settings* settings,
                                                      PatchSet* ,
                                                      MsqError& err )
{
  std::auto_ptr<PatchSet> patch_set;
  switch (get_quality_metric()->get_metric_type())
  {
    case QualityMetric::VERTEX_BASED:  
      patch_set = std::auto_ptr<PatchSet>(new VertexPatches( 1, false ));
      break;
    case QualityMetric::ELEMENT_BASED: 
      patch_set = std::auto_ptr<PatchSet>(new ElementPatches);
      break;
    default: 
      MSQ_SETERR(err)("Cannot initialize for BCD for unknown metric type", 
                      MsqError::INVALID_STATE);
      return false;
  }

  clear();
  patch_set->set_mesh( mesh );
  PatchIterator patches( patch_set.get() );
  
  PatchData pd;
  pd.set_mesh( mesh );
  pd.set_domain( domain );
  if (settings)
    pd.attach_settings( settings );
  
  bool result = true;
  while (patches.get_next_patch( pd, err ) && !MSQ_CHKERR(err))
  {
    double value;
    bool b = evaluate( ObjectiveFunction::ACCUMULATE, pd, value, false, err ); 
    MSQ_ERRZERO(err);
    result = result && b;
  }
  return result;
}
Example #7
0
void tag_patch_slaved( Mesh& mesh, 
                       Settings::HigherOrderSlaveMode mode,
                       MsqError& err )
{
  int zero = 0;
  TagHandle tag = mesh.tag_create( "pd_slaved", Mesh::INT, 1, &zero, err );
  MSQ_ERRRTN(err);
  
  Settings s;
  s.set_slaved_ho_node_mode( mode );
  PatchData pd;
  pd.attach_settings( &s );
  pd.set_mesh( &mesh );
  pd.fill_global_patch( err ); 
  MSQ_ERRRTN(err);

  const Mesh::VertexHandle* verts = pd.get_vertex_handles_array() + pd.num_free_vertices();
  std::vector<int> ones( pd.num_slave_vertices(), 1 );
  mesh.tag_set_vertex_data( tag, pd.num_slave_vertices(), verts, arrptr(ones), err );
  MSQ_ERRRTN(err);
}
void TerminationCriterionTest::test_absolute_vertex_movement_edge_length()
{
  MsqPrintError err(std::cout);
  
  // define two-tet mesh where tets share a face
  double coords[] = {  0, -5, 0,
                       0,  5, 0,
                       1,  0, 0,
                       0,  0, 0,
                       0,  0, 1 };
  const unsigned long conn[] = { 4, 3, 2, 0,
                                 2, 3, 4, 1 };
  int fixed[5] = {0};
  ArrayMesh mesh( 3, 5, coords, fixed, 2, TETRAHEDRON, conn );
  
    // calculate beta 
  const double LIMIT = 1e-4; // desired absolute limit
  MeshUtil tool(&mesh);
  SimpleStats len;
  tool.edge_length_distribution( len, err );
  ASSERT_NO_ERROR(err);
  const double beta = LIMIT / (len.average() - len.standard_deviation());
  
    // initialize termination criterion
  TerminationCriterion tc;
  tc.add_absolute_vertex_movement_edge_length( beta );
  MeshDomainAssoc mesh_and_domain2 = MeshDomainAssoc(&mesh, 0);
  tc.initialize_queue( &mesh_and_domain2, 0, err ); ASSERT_NO_ERROR(err);
  
    // get a patch data
  PatchData pd;
  pd.set_mesh( &mesh );
  pd.fill_global_patch( err ); ASSERT_NO_ERROR(err);

    // test termination criteiorn
  tc.reset_inner( pd, ofEval, err );
  ASSERT_NO_ERROR(err);
  tc.reset_patch( pd, err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT(!tc.terminate());

  const double FIRST_STEP=10.0;
    // move a vertex by 10 units and check that it did not meet criterion
  pd.move_vertex( Vector3D(FIRST_STEP,0,0), 0, err );
  ASSERT_NO_ERROR(err);
  tc.accumulate_inner( pd, 0.0, 0, err );
  ASSERT_NO_ERROR(err);
  tc.accumulate_patch( pd, err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT(!tc.terminate());
  
  double test_limit = LIMIT;
    
  int idx = 0;
  for (double step = FIRST_STEP; step > test_limit; step *= 0.09) {
    idx = (idx + 1) % pd.num_free_vertices();
    pd.move_vertex( Vector3D(step,0,0), idx, err );
    ASSERT_NO_ERROR(err);
    
    tc.accumulate_inner( pd, 0.0, 0, err );
    ASSERT_NO_ERROR(err);
    tc.accumulate_patch( pd, err );
    ASSERT_NO_ERROR(err);
    CPPUNIT_ASSERT(!tc.terminate());
  }
  
  idx = (idx + 1) % pd.num_free_vertices();
  pd.move_vertex( Vector3D(0.5*test_limit,0,0), idx, err );
  ASSERT_NO_ERROR(err);

  tc.accumulate_inner( pd, 0.0, 0, err );
  ASSERT_NO_ERROR(err);
  tc.accumulate_patch( pd, err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT(tc.terminate());
}
/*!This function is activated when cullingGlobalPatch is true.  It supplies
  cull_vertices with a single vertex-based patch at a time.  If the patch
  satisfies the culling criterion, it's free vertices are then soft-fixed.
 */
bool TerminationCriterion::cull_vertices_global(PatchData &global_patch,
                                                Mesh *mesh, MeshDomain *domain, const Settings *settings,
                                                OFEvaluator& of_eval,
                                                MsqError &err)
{
  if (!cullingGlobalPatch) return false;

    //PRINT_INFO("CULLING_METHOD FLAG = %i",cullingMethodFlag);
  
    //cull_bool will be changed to true if the criterion is satisfied
  bool cull_bool=false;

  std::vector<Mesh::VertexHandle> mesh_vertices;
  //std::vector<Mesh::VertexHandle> patch_vertices;
  //std::vector<Mesh::ElementHandle> patch_elements;
  //std::vector<Mesh::VertexHandle> fixed_vertices;
  //std::vector<Mesh::VertexHandle> free_vertices;

  // FIXME, verify global_patch is a global patch... how, is this right?
  mesh->get_all_vertices(mesh_vertices, err);
  size_t mesh_num_nodes = mesh_vertices.size();
  size_t global_patch_num_nodes = global_patch.num_nodes() ;
  if (0)  std::cout << "tmp srk mesh_num_nodes= " << mesh_num_nodes << " global_patch_num_nodes= " 
            << global_patch_num_nodes << std::endl;
  if (mesh_num_nodes != global_patch_num_nodes)
    {
      std::cout << "tmp srk cull_vertices_global found non global patch" << std::endl;
      exit(123);
      return false;
    }
  PatchData patch;
  patch.set_mesh( (Mesh*) mesh );
  patch.set_domain( domain );
  patch.attach_settings( settings );

  const MsqVertex* global_patch_vertex_array = global_patch.get_vertex_array( err );
  Mesh::VertexHandle* global_patch_vertex_handles = global_patch.get_vertex_handles_array();

  int num_culled = 0;
  for (unsigned iv=0; iv < global_patch_num_nodes; iv++)
    {
      // form a patch for this vertex; if it is culled, set it to be soft fixed
      Mesh::VertexHandle vert = global_patch_vertex_handles[iv];
      std::vector<Mesh::ElementHandle> elements;
      std::vector<size_t> offsets;
      mesh->vertices_get_attached_elements(&vert, 1, elements, offsets, err);
      
      std::set<Mesh::VertexHandle> patch_free_vertices_set;

      for (unsigned ie=0; ie < elements.size(); ie++)
        {
          std::vector<Mesh::VertexHandle> vert_handles;
          std::vector<size_t> v_offsets;
          mesh->elements_get_attached_vertices(&elements[ie], 1, vert_handles, v_offsets, err);
          for (unsigned jv=0; jv < vert_handles.size(); jv++)
            {
              unsigned char bt;
              mesh->vertex_get_byte(vert_handles[jv], &bt, err);
              MsqVertex v;
              v.set_flags(bt);
              if (v.is_free_vertex())
                patch_free_vertices_set.insert(vert_handles[jv]);
            }
        }

      std::vector<Mesh::VertexHandle> patch_free_vertices_vector(patch_free_vertices_set.begin(), patch_free_vertices_set.end());
      //std::vector<unsigned char> byte_vector(patch_vertices_vector.size());
      //mesh->vertices_get_byte(&vert_handles[0], &byte_vector[0], vert_handles.size(), err);

      patch.set_mesh_entities( elements, patch_free_vertices_vector, err );
      if (cull_vertices(patch, of_eval, err))
        {
          //std::cout << "tmp srk cull_vertices_global found culled patch" << std::endl;
          Mesh::VertexHandle* patch_vertex_handles = patch.get_vertex_handles_array();
          const MsqVertex* patch_vertex_array = patch.get_vertex_array( err );
          for (unsigned jv=0; jv < patch.num_nodes(); jv++)
            {
              if (patch_vertex_handles[jv] == global_patch_vertex_handles[iv])
                {
                  if (patch_vertex_array[jv].is_flag_set(MsqVertex::MSQ_CULLED))
                    {
                      global_patch.set_vertex_culled(iv);
                      ++num_culled;
                      cull_bool = true;
                      //std::cout << "tmp srk cull_vertices_global found culled vertex" << std::endl;
                    }
                }
            }
        }
    }
    if (0)  std::cout << "tmp srk cull_vertices_global found " << num_culled << " culled vertices out of " << global_patch_num_nodes << std::endl;

  return cull_bool;
}
Example #10
0
void write_eps( Mesh* mesh, 
                const char* filename, 
                Projection proj, 
                MsqError& err,
                int width, int height )
{
    // Get a global patch
  PatchData pd;
  pd.set_mesh( mesh );
  pd.fill_global_patch( err ); MSQ_ERRRTN(err);
  
  Transform2D transf( &pd, proj, width, height, false );
    
    // Open the file
  ofstream s(filename);
  if (!s)
  {
    MSQ_SETERR(err)(MsqError::FILE_ACCESS);
    return;
  }

    // Write header
  s << "%!PS-Adobe-2.0 EPSF-2.0"                      << endl;
  s << "%%Creator: Mesquite"                          << endl;
  s << "%%Title: Mesquite "                           << endl;
  s << "%%DocumentData: Clean7Bit"                    << endl;
  s << "%%Origin: 0 0"                                << endl;
  s << "%%BoundingBox: 0 0 " 
    << transf.max_horizontal() <<  ' ' 
    << transf.max_vertical()                          << endl;
  s << "%%Pages: 1"                                   << endl;
  
  s << "%%BeginProlog"                                << endl;
  s << "save"                                         << endl;
  s << "countdictstack"                               << endl;
  s << "mark"                                         << endl;
  s << "newpath"                                      << endl;
  s << "/showpage {} def"                             << endl;
  s << "/setpagedevice {pop} def"                     << endl;
  s << "%%EndProlog"                                  << endl;
  
  s << "%%Page: 1 1"                                  << endl;
  s << "1 setlinewidth"                               << endl;
  s << "0.0 setgray"                                  << endl;
  
    // Write mesh edges
  EdgeIterator iter( &pd, err );  MSQ_ERRRTN(err);
  while( !iter.is_at_end() )
  {
    int s_w, s_h, e_w, e_h;
    transf.transform( iter.start(), s_w, s_h );
    transf.transform( iter.end  (), e_w, e_h );
    
    s << "newpath"                                    << endl;
    s << s_w << ' ' << s_h << " moveto"               << endl;
    
    if (!iter.mid()) {
      s << e_w << ' ' << e_h << " lineto"               << endl;
    }
    else {
      write_eps_quadratic_edge( s, transf, iter.start(), *iter.mid(), iter.end() );
        // draw rings at mid-edge node location
      //transf.transform( *(iter.mid()), w1, h1 );
      //s << w1+2 << ' ' << h1 <<  " moveto"            << endl;
      //s << w1 << ' ' << h1 <<  " 2 0 360 arc"         << endl;
    }
    s << "stroke"                                       << endl;
    
    iter.step(err); MSQ_ERRRTN(err);
  }
  
    // Write footer
  s << "%%Trailer"                                    << endl;
  s << "cleartomark"                                  << endl;
  s << "countdictstack"                               << endl;
  s << "exch sub { end } repeat"                      << endl;
  s << "restore"                                      << endl;  
  s << "%%EOF"                                        << endl;
}
Example #11
0
/*! \brief Improves the quality of the MeshSet, calling some
    methods specified in a class derived from VertexMover

    \param const MeshSet &: this MeshSet is looped over. Only the
    mutable data members are changed (such as currentVertexInd).
  */
double VertexMover::loop_over_mesh( ParallelMesh* mesh,
                                    MeshDomain* domain,
                                    const Settings* settings,
                                    MsqError& err )
{
  std::vector<size_t> junk;
  Mesh::VertexHandle vertex_handle;

    // Get the patch data to use for the first iteration
  OFEvaluator& obj_func = get_objective_function_evaluator();
  
  PatchData patch;
  patch.set_mesh( (Mesh*) mesh );
  patch.set_domain( domain );
  patch.attach_settings( settings );

  ParallelHelper* helper = mesh->get_parallel_helper();
  if (!helper) {
    MSQ_SETERR(err)("No ParallelHelper instance", MsqError::INVALID_STATE);
    return 0;
  }

  helper->smoothing_init(err);  MSQ_ERRZERO(err);

  bool did_some, all_culled;
  std::vector<Mesh::VertexHandle> patch_vertices;
  std::vector<Mesh::ElementHandle> patch_elements;
  std::vector<Mesh::VertexHandle> fixed_vertices;
  std::vector<Mesh::VertexHandle> free_vertices;
   
    // Get termination criteria
  TerminationCriterion* outer_crit=this->get_outer_termination_criterion();
  TerminationCriterion* inner_crit=this->get_inner_termination_criterion();
  if(outer_crit == 0){
    MSQ_SETERR(err)("Termination Criterion pointer is Null", MsqError::INVALID_STATE);
    return 0.;
  }
  if(inner_crit == 0){
    MSQ_SETERR(err)("Termination Criterion pointer for inner loop is Null", MsqError::INVALID_STATE);
    return 0.;
  }
  
  PatchSet* patch_set = get_patch_set();
  if (!patch_set) {
    MSQ_SETERR(err)("No PatchSet for QualityImprover!", MsqError::INVALID_STATE);
    return 0.0;
  }
  patch_set->set_mesh( (Mesh*)mesh );

  std::vector<PatchSet::PatchHandle> patch_list;
  patch_set->get_patch_handles( patch_list, err ); MSQ_ERRZERO(err);
  
    // Initialize outer loop
    
  this->initialize(patch, err);        
  if (MSQ_CHKERR(err)) goto ERROR;
  
  obj_func.initialize( (Mesh*)mesh, domain, settings, patch_set, err ); 
  if (MSQ_CHKERR(err)) goto ERROR;
  
  outer_crit->reset_outer( (Mesh*)mesh, domain, obj_func, settings, err); 
  if (MSQ_CHKERR(err)) goto ERROR;
   
   // Loop until outer termination criterion is met
  did_some = true;
  while (!outer_crit->terminate())
  {
    if (!did_some) {
      MSQ_SETERR(err)("Inner termiation criterion satisfied for all patches "
                      "without meeting outer termination criterion.  This is "
                      "an infinite loop.  Aborting.", MsqError::INVALID_STATE);
      break;
    }
    did_some = false;
    all_culled = true;

    ///*** smooth the interior ***////

    // get the fixed vertices (i.e. the ones *not* part of the first independent set)
    helper->compute_first_independent_set(fixed_vertices); 

    // sort the fixed vertices
    std::sort(fixed_vertices.begin(), fixed_vertices.end());

      // Loop over each patch
    std::vector<PatchSet::PatchHandle>::iterator p_iter = patch_list.begin();
    while( p_iter != patch_list.end() )
    {
      // loop until we get a non-empty patch.  patch will be empty
      // for culled vertices with element-on-vertex patches
      do {
	patch_set->get_patch( *p_iter, patch_elements, patch_vertices, err );
	if (MSQ_CHKERR(err)) goto ERROR;
	++p_iter;
      } while (patch_elements.empty() && p_iter != patch_list.end()) ;
        
      if (patch_elements.empty()) { // no more non-culled vertices
	break;
      }

      if (patch_vertices.empty()) // global patch hack (means all mesh vertices)
      {
	mesh->get_all_vertices(patch_vertices, err);
      }

      free_vertices.clear();

      for (size_t i = 0; i < patch_vertices.size(); ++i) 
	if (!std::binary_search(fixed_vertices.begin(), fixed_vertices.end(), patch_vertices[i]))
	  free_vertices.push_back(patch_vertices[i]);

      if (free_vertices.empty()) { // all vertices were fixed -> skip patch
	continue;
      }

      all_culled = false;
      patch.set_mesh_entities( patch_elements, free_vertices, err );
      if (MSQ_CHKERR(err)) goto ERROR;
        
        // Initialize for inner iteration
        
      this->initialize_mesh_iteration(patch, err);
      if (MSQ_CHKERR(err)) goto ERROR;
      
      obj_func.reset();
      
      outer_crit->reset_patch( patch, err );
      if (MSQ_CHKERR(err)) goto ERROR;
      
      inner_crit->reset_inner( patch, obj_func, err );
      if (MSQ_CHKERR(err)) goto ERROR;
      
      inner_crit->reset_patch( patch, err );
      if (MSQ_CHKERR(err)) goto ERROR;
      
        // Don't even call optimizer if inner termination 
        // criterion has already been met.
      if (!inner_crit->terminate())
      {
        did_some = true;
        
          // Call optimizer - should loop on inner_crit->terminate()
        this->optimize_vertex_positions( patch, err );
        if (MSQ_CHKERR(err)) goto ERROR;
      
          // Update for changes during inner iteration 
          // (during optimizer loop)
        
        outer_crit->accumulate_patch( patch, err );
        if (MSQ_CHKERR(err)) goto ERROR;
        
        inner_crit->cull_vertices( patch, obj_func, err );
        if (MSQ_CHKERR(err)) goto ERROR;
        
        patch.update_mesh( err );
        if (MSQ_CHKERR(err)) goto ERROR;
      }
    }

    helper->communicate_first_independent_set(err); 
    if (MSQ_CHKERR(err)) goto ERROR;

    ///*** smooth the boundary ***////

    while (helper->compute_next_independent_set())
    {
      // Loop over all boundary elements
      while(helper->get_next_partition_boundary_vertex(vertex_handle))
      {
	patch_vertices.clear();
	patch_vertices.push_back(vertex_handle);
	patch_elements.clear(); 
	mesh->vertices_get_attached_elements( &vertex_handle, 
                                              1,
                                              patch_elements, 
                                              junk, err );

	all_culled = false;
	patch.set_mesh_entities( patch_elements, patch_vertices, err );

	if (MSQ_CHKERR(err)) goto ERROR;
        
        // Initialize for inner iteration
        
	this->initialize_mesh_iteration(patch, err);
	if (MSQ_CHKERR(err)) goto ERROR;
	
	obj_func.reset();
	
	outer_crit->reset_patch( patch, err );
	if (MSQ_CHKERR(err)) goto ERROR;
	
	inner_crit->reset_inner( patch, obj_func, err );
	if (MSQ_CHKERR(err)) goto ERROR;
      
	inner_crit->reset_patch( patch, err );
	if (MSQ_CHKERR(err)) goto ERROR;
      
        // Don't even call optimizer if inner termination 
        // criterion has already been met.
	if (!inner_crit->terminate())
	{
	  did_some = true;
	  
          // Call optimizer - should loop on inner_crit->terminate()
	  this->optimize_vertex_positions( patch, err );
	  if (MSQ_CHKERR(err)) goto ERROR;
      
          // Update for changes during inner iteration 
          // (during optimizer loop)
	  
	  outer_crit->accumulate_patch( patch, err );
	  if (MSQ_CHKERR(err)) goto ERROR;
	  
	  inner_crit->cull_vertices( patch, obj_func, err );
	  if (MSQ_CHKERR(err)) goto ERROR;
        
	  patch.update_mesh( err );
	  if (MSQ_CHKERR(err)) goto ERROR;
	}
      }
      helper->communicate_next_independent_set(err);
      if (MSQ_CHKERR(err)) goto ERROR;
    }

    this->terminate_mesh_iteration(patch, err); 
    if (MSQ_CHKERR(err)) goto ERROR;
    
    outer_crit->accumulate_outer( mesh, domain, obj_func, settings, err );
    if (MSQ_CHKERR(err)) goto ERROR;
    
    if (all_culled)
      break;
  }

ERROR: 
    //call the criteria's cleanup funtions.
  outer_crit->cleanup(mesh,domain,err); MSQ_CHKERR(err);
  inner_crit->cleanup(mesh,domain,err); MSQ_CHKERR(err);
    //call the optimization cleanup function.
  this->cleanup();
    // close the helper
  helper->smoothing_close(err); MSQ_CHKERR(err);

  return 0.;
}
Example #12
0
/*! \brief Improves the quality of the MeshSet, calling some
    methods specified in a class derived from VertexMover

    \param const MeshSet &: this MeshSet is looped over. Only the
    mutable data members are changed (such as currentVertexInd).
  */
double VertexMover::loop_over_mesh( Mesh* mesh,
                                    MeshDomain* domain,
                                    const Settings* settings,
                                    MsqError& err )
{
    // Get the patch data to use for the first iteration
  OFEvaluator& obj_func = get_objective_function_evaluator();
  
  PatchData patch;
  patch.set_mesh( mesh );
  patch.set_domain( domain );
  if (settings)
    patch.attach_settings( settings );
  bool one_patch = false, did_some, all_culled;
  std::vector<Mesh::VertexHandle> patch_vertices;
  std::vector<Mesh::ElementHandle> patch_elements;
  
  PatchSet* patch_set = get_patch_set();
  if (!patch_set) {
    MSQ_SETERR(err)("No PatchSet for QualityImprover!", MsqError::INVALID_STATE);
    return 0.0;
  }
  patch_set->set_mesh( mesh );
  
  std::vector<PatchSet::PatchHandle> patch_list;
  patch_set->get_patch_handles( patch_list, err ); MSQ_ERRZERO(err);
  
    // Get termination criteria
  TerminationCriterion* outer_crit=this->get_outer_termination_criterion();
  TerminationCriterion* inner_crit=this->get_inner_termination_criterion();
  if(outer_crit == 0){
    MSQ_SETERR(err)("Termination Criterion pointer is Null", MsqError::INVALID_STATE);
    return 0.;
  }
  if(inner_crit == 0){
    MSQ_SETERR(err)("Termination Criterion pointer for inner loop is Null", MsqError::INVALID_STATE);
    return 0.;
  }
  
    // If using a local patch, suppress output of inner termination criterion
  if (patch_list.size() > 1) 
    inner_crit->set_debug_output_level(3);
  else
    one_patch = true;
  
    // Initialize outer loop
    
  this->initialize(patch, err);        
  if (MSQ_CHKERR(err)) goto ERROR;
  
  obj_func.initialize( mesh, domain, settings, patch_set, err ); 
  if (MSQ_CHKERR(err)) goto ERROR;
  
  outer_crit->reset_outer(mesh, domain, obj_func, settings, err); 
  if (MSQ_CHKERR(err)) goto ERROR;
  
 
    // if only one patch, get the patch now
  if (one_patch) {
    patch_set->get_patch( patch_list[0], patch_elements, patch_vertices, err );
    if (MSQ_CHKERR(err)) goto ERROR;
    patch.set_mesh_entities( patch_elements, patch_vertices, err );
    if (MSQ_CHKERR(err)) goto ERROR;
  }
  
   // Loop until outer termination criterion is met
  did_some = true;
  while (!outer_crit->terminate())
  {
    if (!did_some) {
      MSQ_SETERR(err)("Inner termiation criterion satisfied for all patches "
                      "without meeting outer termination criterion.  This is "
                      "an infinite loop.  Aborting.", MsqError::INVALID_STATE);
      break;
    }
    did_some = false;
    all_culled = true;

      // Loop over each patch
    std::vector<PatchSet::PatchHandle>::iterator p_iter = patch_list.begin();
    while( p_iter != patch_list.end() )
    {
      if (!one_patch) { // if only one patch (global) re-use the previous one
          // loop until we get a non-empty patch.  patch will be empty
          // for culled vertices with element-on-vertex patches
        do {
          patch_set->get_patch( *p_iter, patch_elements, patch_vertices, err );
          if (MSQ_CHKERR(err)) goto ERROR;
          ++p_iter;
        } while (patch_elements.empty() && p_iter != patch_list.end()) ;
        
        if (patch_elements.empty()) { // no more non-culled vertices
          break;
        }
      
        all_culled = false;
        patch.set_mesh_entities( patch_elements, patch_vertices, err );
        if (MSQ_CHKERR(err)) goto ERROR;
      } else {
        ++p_iter;
        all_culled = false;
      }
        
        // Initialize for inner iteration
        
      this->initialize_mesh_iteration(patch, err);
      if (MSQ_CHKERR(err)) goto ERROR;
      
      obj_func.reset();
      
      outer_crit->reset_patch( patch, err );
      if (MSQ_CHKERR(err)) goto ERROR;
      
      inner_crit->reset_inner( patch, obj_func, err );
      if (MSQ_CHKERR(err)) goto ERROR;
      
      inner_crit->reset_patch( patch, err );
      if (MSQ_CHKERR(err)) goto ERROR;
      
        // Don't even call optimizer if inner termination 
        // criterion has already been met.
      if (!inner_crit->terminate())
      {
        did_some = true;
        
          // Call optimizer - should loop on inner_crit->terminate()
        this->optimize_vertex_positions( patch, err );
        if (MSQ_CHKERR(err)) goto ERROR;
      
          // Update for changes during inner iteration 
          // (during optimizer loop)
        
        outer_crit->accumulate_patch( patch, err );
        if (MSQ_CHKERR(err)) goto ERROR;
        
        inner_crit->cull_vertices( patch, obj_func, err );
        if (MSQ_CHKERR(err)) goto ERROR;
        
        patch.update_mesh( err );
        if (MSQ_CHKERR(err)) goto ERROR;
      }
    } 

    this->terminate_mesh_iteration(patch, err); 
    if (MSQ_CHKERR(err)) goto ERROR;
    
    outer_crit->accumulate_outer( mesh, domain, obj_func, settings, err );
    if (MSQ_CHKERR(err)) goto ERROR;
    
    if (all_culled)
      break;
  }


ERROR:  
    //call the criteria's cleanup funtions.
  outer_crit->cleanup(mesh,domain,err);
  inner_crit->cleanup(mesh,domain,err);
    //call the optimization cleanup function.
  this->cleanup();

  return 0.;
}
Example #13
0
double TargetWriter::loop_over_mesh( MeshDomainAssoc* mesh_and_domain,
                                     const Settings* settings,
                                     MsqError& err )
{
  Mesh* mesh = mesh_and_domain->get_mesh();
  MeshDomain* domain = mesh_and_domain->get_domain();
 
  PatchData patch;
  patch.set_mesh( mesh );
  patch.set_domain( domain );
  if (settings)
    patch.attach_settings( settings );
  
  ElementPatches patch_set;
  patch_set.set_mesh( mesh );
  std::vector<PatchSet::PatchHandle> patches;
  std::vector<PatchSet::PatchHandle>::iterator p;
  std::vector<Mesh::VertexHandle> patch_verts;
  std::vector<Mesh::ElementHandle> patch_elems;
  
  patch_set.get_patch_handles( patches, err ); MSQ_ERRZERO(err);
  
  std::vector< MsqMatrix<3,3> > targets3d;
  std::vector< MsqMatrix<3,2> > targets2dorient;
  std::vector< MsqMatrix<2,2> > targets2d;
  std::vector< double > weights;
  std::vector< Sample > samples;
  for (p = patches.begin(); p != patches.end(); ++p)
  {
    patch_verts.clear();
    patch_elems.clear();
    patch_set.get_patch( *p, patch_elems, patch_verts, err ); MSQ_ERRZERO(err);
    patch.set_mesh_entities( patch_elems, patch_verts, err ); MSQ_ERRZERO(err);
    assert(patch.num_elements() == 1);
    
    MsqMeshEntity& elem = patch.element_by_index(0);
    EntityTopology type = elem.get_element_type();
    patch.get_samples( 0, samples, err ); MSQ_ERRZERO(err);
    if (samples.empty())
      continue;    
    
    if (targetCalc) {
      const unsigned dim = TopologyInfo::dimension(type);
      if (dim == 3) {
        targets3d.resize( samples.size() );
        for (unsigned i = 0; i < samples.size(); ++i) {
          targetCalc->get_3D_target( patch, 0, samples[i], targets3d[i], err ); MSQ_ERRZERO(err);

          if (DBL_EPSILON > det(targets3d[i])) {
            MSQ_SETERR(err)("Inverted 3D target", MsqError::INVALID_ARG);
            return 0.0;
          }
        }
        
        TagHandle tag = get_target_tag( 3, samples.size(), mesh,  err ); MSQ_ERRZERO(err);
        mesh->tag_set_element_data( tag, 1, 
                                    patch.get_element_handles_array(), 
                                    arrptr(targets3d), err ); MSQ_ERRZERO(err);
      }
      else if(targetCalc->have_surface_orient()) {
        targets2dorient.resize( samples.size() );
        for (unsigned i = 0; i < samples.size(); ++i) {
          targetCalc->get_surface_target( patch, 0, samples[i], targets2dorient[i], err ); MSQ_ERRZERO(err);

          MsqMatrix<3,1> cross = targets2dorient[i].column(0) * targets2dorient[i].column(1);
          if (DBL_EPSILON > (cross%cross)) {
            MSQ_SETERR(err)("Degenerate 2D target", MsqError::INVALID_ARG);
            return 0.0;
          }
        }
        
        TagHandle tag = get_target_tag( 2, samples.size(), mesh, err ); MSQ_ERRZERO(err);
        mesh->tag_set_element_data( tag, 1, 
                                    patch.get_element_handles_array(), 
                                    arrptr(targets2dorient), err ); MSQ_ERRZERO(err);
      }
      else {
        targets2d.resize( samples.size() );
        for (unsigned i = 0; i < samples.size(); ++i) {
          targetCalc->get_2D_target( patch, 0, samples[i], targets2d[i], err ); MSQ_ERRZERO(err);

          if (DBL_EPSILON > det(targets2d[i])) {
            MSQ_SETERR(err)("Degenerate/Inverted 2D target", MsqError::INVALID_ARG);
            return 0.0;
          }
        }
        
        TagHandle tag = get_target_tag( 2, samples.size(), mesh, err ); MSQ_ERRZERO(err);
        mesh->tag_set_element_data( tag, 1, 
                                    patch.get_element_handles_array(), 
                                    arrptr(targets2d), err ); MSQ_ERRZERO(err);
      }
    }
      
    if (weightCalc) {
      weights.resize( samples.size() );
      for (unsigned i = 0; i < samples.size(); ++i) {
        weights[i] = weightCalc->get_weight( patch, 0, samples[i], err ); MSQ_ERRZERO(err);
      }
      TagHandle tag = get_weight_tag( samples.size(), mesh, err ); MSQ_ERRZERO(err);
      mesh->tag_set_element_data( tag, 1, 
                                  patch.get_element_handles_array(),
                                  arrptr(weights), err ); MSQ_ERRZERO(err);
    }
  }

  return 0.0;
}