コード例 #1
0
ファイル: statistics.C プロジェクト: ZJLi2013/libmesh
void StatisticsVector<T>::histogram(std::vector<dof_id_type>& bin_members,
				    unsigned int n_bins) const
{
  StatisticsVector<T> sv = (*this);

  return sv.histogram(bin_members, n_bins);
}
コード例 #2
0
StatisticsVector StatisticsVector::make(
    const string&               name,
    const Statistics&           stats)
{
    StatisticsVector vec;
    vec.insert(name, stats);
    return vec;
}
コード例 #3
0
        void print_tile_renderers_stats() const
        {
            assert(!m_tile_renderers.empty());

            StatisticsVector stats;

            for (size_t i = 0; i < m_tile_renderers.size(); ++i)
                stats.merge(m_tile_renderers[i]->get_statistics());

            RENDERER_LOG_DEBUG("%s", stats.to_string().c_str());
        }
コード例 #4
0
ファイル: error_vector.C プロジェクト: paulovieira/libmesh
Real ErrorVector::median()
{
  const unsigned int n   = this->size();

  if (n == 0)
    return 0.;


  // Build a StatisticsVector<ErrorVectorReal> containing
  // only our active entries and take its mean
  StatisticsVector<ErrorVectorReal> sv;

  sv.reserve (n);

  for (unsigned int i=0; i<n; i++)
    if(this->is_active_elem(i))
      sv.push_back((*this)[i]);

  return sv.median();
}
コード例 #5
0
StatisticsVector Intersector::get_statistics() const
{
    const uint64 total_ray_count = m_shading_ray_count + m_probe_ray_count;

    Statistics intersection_stats;
    intersection_stats.insert<uint64>("total rays", total_ray_count);
    intersection_stats.insert(
        auto_ptr<RayCountStatisticsEntry>(
            new RayCountStatisticsEntry(
                "shading rays",
                m_shading_ray_count,
                total_ray_count)));
    intersection_stats.insert(
        auto_ptr<RayCountStatisticsEntry>(
            new RayCountStatisticsEntry(
                "probe rays",
                m_probe_ray_count,
                total_ray_count)));

    StatisticsVector vec;

    vec.insert("intersection statistics", intersection_stats);

#ifdef FOUNDATION_BVH_ENABLE_TRAVERSAL_STATS
    vec.insert(
        "assembly tree intersection statistics",
        m_assembly_tree_traversal_stats.get_statistics());

    vec.insert(
        "triangle tree intersection statistics",
        m_triangle_tree_traversal_stats.get_statistics());
#endif

    vec.insert(
        "region tree access cache statistics",
        make_dual_stage_cache_stats(m_region_tree_cache));

    vec.insert(
        "triangle tree access cache statistics",
        make_dual_stage_cache_stats(m_triangle_tree_cache));

    vec.insert(
        "region kit access cache statistics",
        make_dual_stage_cache_stats(m_region_kit_cache));

    vec.insert(
        "tessellation access cache statistics",
        make_dual_stage_cache_stats(m_tess_cache));

    return vec;
}
コード例 #6
0
ファイル: statistics.C プロジェクト: ZJLi2013/libmesh
Real StatisticsVector<T>::median() const
{
  StatisticsVector<T> sv = (*this);

  return sv.median();
}
コード例 #7
0
ファイル: meshtool.C プロジェクト: maxis112/libmesh
int main (int argc, char** argv)
{
  LibMeshInit init(argc, argv);

  PerfMon perfmon(argv[0]);

  unsigned int n_subdomains = 1;
  unsigned int n_rsteps = 0;
  unsigned char dim = static_cast<unsigned char>(-1); // invalid dimension
  double dist_fact = 0.;
  bool verbose = false;
  BoundaryMeshWriteMode write_bndry = BM_DISABLED;
  unsigned int convert_second_order = 0;
  bool addinfelems = false;
  bool triangulate = false;
  bool do_quality = false;
  ElemQuality quality_type = DIAGONAL;

#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
  InfElemBuilder::InfElemOriginValue origin_x(false, 0.);
  InfElemBuilder::InfElemOriginValue origin_y(false, 0.);
  InfElemBuilder::InfElemOriginValue origin_z(false, 0.);
#endif

  bool x_sym=false;
  bool y_sym=false;
  bool z_sym=false;


  std::vector<std::string> names;
  std::vector<std::string> var_names;
  std::vector<Number>      soln;

  process_cmd_line(argc, argv, names,
                   n_subdomains, n_rsteps, dim,
                   dist_fact, verbose, write_bndry,
                   convert_second_order,

                   triangulate,

                   do_quality,
                   quality_type,

                   addinfelems,

#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
                   origin_x, origin_y, origin_z,
#endif

                   x_sym, y_sym, z_sym);

  AutoPtr<Mesh> mesh_ptr;
  if (dim == static_cast<unsigned char>(-1))
    {
      mesh_ptr.reset(new Mesh(init.comm()));
    }
  else
    {
      mesh_ptr.reset(new Mesh(init.comm(),dim));
    }

  Mesh& mesh = *mesh_ptr;
  MeshData mesh_data(mesh);

  /**
   * Read the input mesh
   */
  if (!names.empty())
    {
      /*
       * activate the MeshData of the dim mesh,
       * so that it can be copied to the boundary
       */

      if (write_bndry == BM_WITH_MESHDATA)
        {
          mesh_data.activate();

          if (verbose)
            mesh_data.print_info();
        }


      mesh.read(names[0]);

      if (verbose)
        {
          mesh.print_info();
          mesh.get_boundary_info().print_summary();
        }

    }

  else
    {
      libMesh::out << "No input specified." << std::endl;
      return 1;
    }



#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS

  if(addinfelems)
    {
      if (names.size() == 3)
        {
          libMesh::out << "ERROR: Invalid combination: Building infinite elements " << std::endl
                       << "not compatible with solution import." << std::endl;
          exit(1);
        }

      if (write_bndry != BM_DISABLED)
        {
          libMesh::out << "ERROR: Invalid combination: Building infinite elements " << std::endl
                       << "not compatible with writing boundary conditions." << std::endl;
          exit(1);
        }

      /*
       * Sanity checks: -X/Y/Z can only be used, when the
       * corresponding coordinate is also given (using -x/y/z)
       */
      if ((x_sym && !origin_x.first) ||     // claim x-symmetry, but x-coordinate of origin not given!
          (y_sym && !origin_y.first) ||     // the same for y
          (z_sym && !origin_z.first))       // the same for z
        {
          libMesh::out << "ERROR: When x-symmetry is requested using -X, then" << std::endl
                       << "the option -x <coord> also has to be given." << std::endl
                       << "This holds obviously for y and z, too." << std::endl;
          exit(1);
        }


      // build infinite elements
      InfElemBuilder(mesh).build_inf_elem(origin_x, origin_y, origin_z,
                                          x_sym, y_sym, z_sym,
                                          verbose);


      if (verbose)
        {
          mesh.print_info();
          mesh.get_boundary_info().print_summary();
        }

    }

  // sanity check
  else if((origin_x.first ||  origin_y.first || origin_z.first) ||
          (x_sym          ||  y_sym          || z_sym))
    {
      libMesh::out << "ERROR:  -x/-y/-z/-X/-Y/-Z is only to be used when" << std::endl
                   << "the option -a is also specified!" << std::endl;
      exit(1);
    }

#endif


  /**
   * Possibly read the solution
   */
  if (names.size() == 3)
    LegacyXdrIO(mesh,true).read_mgf_soln(names[2],
                                         soln,
                                         var_names);



  /**
   * Maybe Triangulate
   */
  //  if (dim == 2 && triangulate)
  if (triangulate)
    {
      if (verbose)
        libMesh::out << "...Converting to all simplices...\n";

      MeshTools::Modification::all_tri(mesh);
    }

  /**
   * Compute Shape quality metrics
   */
  if (do_quality)
    {
      StatisticsVector<Real> sv;
      sv.reserve(mesh.n_elem());

      libMesh::out << "Quality type is: " << Quality::name(quality_type) << std::endl;

      // What are the quality bounds for this element?
      std::pair<Real, Real> bounds = mesh.elem(0)->qual_bounds(quality_type);
      libMesh::out << "Quality bounds for this element type are: (" << bounds.first
                   << ", " << bounds.second << ") "
                   << std::endl;

      MeshBase::const_element_iterator it  = mesh.active_elements_begin(),
        end = mesh.active_elements_end();
      for (; it != end; ++it)
        {
          Elem *e = *it;
          sv.push_back(e->quality(quality_type));
        }

      const unsigned int n_bins = 10;
      libMesh::out << "Avg. shape quality: " << sv.mean() << std::endl;

      // Find element indices below the specified cutoff.
      // These might be considered "bad" elements which need refinement.
      std::vector<dof_id_type> bad_elts  = sv.cut_below(0.8);
      libMesh::out << "Found " << bad_elts.size()
                   << " of " << mesh.n_elem()
                   << " elements below the cutoff." << std::endl;

      /*
        for (unsigned int i=0; i<bad_elts.size(); i++)
        libMesh::out << bad_elts[i] << " ";
        libMesh::out << std::endl;
      */

      // Compute the histogram for this distribution
      std::vector<dof_id_type> histogram;
      sv.histogram(histogram, n_bins);

      /*
        for (unsigned int i=0; i<n_bins; i++)
        histogram[i] = histogram[i] / mesh.n_elem();
      */

      const bool do_matlab = true;

      if (do_matlab)
        {
          std::ofstream out ("histo.m");

          out << "% This is a sample histogram plot for Matlab." << std::endl;
          out << "bin_members = [" << std::endl;
          for (unsigned int i=0; i<n_bins; i++)
            out << static_cast<Real>(histogram[i]) / static_cast<Real>(mesh.n_elem())
                << std::endl;
          out << "];" << std::endl;

          std::vector<Real> bin_coords(n_bins);
          const Real max   = *(std::max_element(sv.begin(), sv.end()));
          const Real min   = *(std::min_element(sv.begin(), sv.end()));
          const Real delta = (max - min) / static_cast<Real>(n_bins);
          for (unsigned int i=0; i<n_bins; i++)
            bin_coords[i] = min + (i * delta) + delta / 2.0 ;

          out << "bin_coords = [" << std::endl;
          for (unsigned int i=0; i<n_bins; i++)
            out << bin_coords[i] << std::endl;
          out << "];" << std::endl;

          out << "bar(bin_coords, bin_members, 1);" << std::endl;
          out << "hold on" << std::endl;
          out << "plot (bin_coords, 0, 'kx');" << std::endl;
          out << "xlabel('Quality (0=Worst, 1=Best)');" << std::endl;
          out << "ylabel('Percentage of elements in each bin');" << std::endl;
          out << "axis([" << min << "," << max << ",0, max(bin_members)]);" << std::endl;

          out << "title('" << Quality::name(quality_type) << "');" << std::endl;

        }
    }


  /**
   * Possibly convert all linear
   * elements to second-order counterparts
   */
  if (convert_second_order > 0)
    {
      bool second_order_mode = true;
      std:: string message = "Converting elements to second order counterparts";
      if (convert_second_order == 2)
        {
          second_order_mode = false;
          message += ", lower version: Quad4 -> Quad8, not Quad9";
        }

      else if (convert_second_order == 22)
        {
          second_order_mode = true;
          message += ", highest version: Quad4 -> Quad9";
        }

      else
        libmesh_error_msg("Invalid value, convert_second_order = " << convert_second_order);

      if (verbose)
        libMesh::out << message << std::endl;

      mesh.all_second_order(second_order_mode);

      if (verbose)
        {
          mesh.print_info();
          mesh.get_boundary_info().print_summary();
        }
    }


#ifdef LIBMESH_ENABLE_AMR

  /**
   * Possibly refine the mesh
   */
  if (n_rsteps > 0)
    {
      if (verbose)
        libMesh::out << "Refining the mesh "
                     << n_rsteps << " times"
                     << std::endl;

      MeshRefinement mesh_refinement (mesh);
      mesh_refinement.uniformly_refine(n_rsteps);

      if (verbose)
        {
          mesh.print_info();
          mesh.get_boundary_info().print_summary();
        }
    }


  /**
   * Possibly distort the mesh
   */
  if (dist_fact > 0.)
    {
      libMesh::out << "Distoring the mesh by a factor of "
                   << dist_fact
                   << std::endl;

      MeshTools::Modification::distort(mesh,dist_fact);
    };


  /*
    char filechar[81];
    sprintf(filechar,"%s-%04d.plt", "out", 0);
    std::string oname(filechar);

    mesh.write(oname);

    for (unsigned int step=0; step<100; step++)
    {
    //        const Real x = .5 + .25*cos((((Real) step)/100.)*3.1415927);
    //        const Real y = .5 + .25*sin((((Real) step)/100.)*3.1415927);
    const Real x = 2.5*cos((((Real) step)/100.)*3.1415927);
    const Real y = 2.5*sin((((Real) step)/100.)*3.1415927);

    const Point p(x,y);

    for (unsigned int e=0; e<mesh.n_elem(); e++)
    if (mesh.elem(e)->active())
    mesh.elem(e)->set_refinement_flag() = -1;



    for (unsigned int e=0; e<mesh.n_elem(); e++)
    if (mesh.elem(e)->active())
    {
    const Point diff = mesh.elem(e)->centroid(mesh) - p;

    if (diff.size() < .5)
    {
    if (mesh.elem(e)->level() < 4)
    mesh.elem(e)->set_refinement_flag() = 1;
    else if (mesh.elem(e)->level() == 4)
    mesh.elem(e)->set_refinement_flag() = 0;
    }
    }


    mesh.mesh_refinement.refine_and_coarsen_elements();

    char filechar[81];
    sprintf(filechar,"%s-%04d.plt", "out", step+1);
    std::string oname(filechar);

    mesh.write(oname);
    }
  */

#endif



  //     /**
  //      * Possibly partition the mesh
  //      */
  if (n_subdomains > 1)
    mesh.partition(n_subdomains);


  /**
   * Possibly write the mesh
   */
  {
    if (names.size() >= 2)
      {
        /*
         * When the mesh got refined, it is likely that
         * the user does _not_ want to write also
         * the coarse elements, but only the active ones.
         * Use Mesh::create_submesh() to create a mesh
         * of only active elements, and then write _this_
         * new mesh.
         */
        if (n_rsteps > 0)
          {
            if (verbose)
              libMesh::out << " Mesh got refined, will write only _active_ elements." << std::endl;

            Mesh new_mesh (init.comm(), mesh.mesh_dimension());

            construct_mesh_of_active_elements(new_mesh, mesh);

            // now write the new_mesh
            if (names.size() == 2)
              new_mesh.write(names[1]);
            else if (names.size() == 3)
              new_mesh.write(names[1], soln, var_names);
            else
              libmesh_error_msg("Invalid names.size() = " << names.size());
          }
        else
          {
            if (names.size() == 2)
              mesh.write(names[1]);
            else if (names.size() == 3)
              mesh.write(names[1], soln, var_names);
            else
              libmesh_error_msg("Invalid names.size() = " << names.size());
          }



        /**
         * Possibly write the BCs
         */
        if (write_bndry != BM_DISABLED)
          {
            BoundaryMesh boundary_mesh
              (mesh.comm(), cast_int<unsigned char>(mesh.mesh_dimension()-1));
            MeshData boundary_mesh_data (boundary_mesh);

            std::string boundary_name = "bndry_";
            boundary_name += names[1];

            if (write_bndry == BM_MESH_ONLY)
              mesh.get_boundary_info().sync(boundary_mesh);

            else if  (write_bndry == BM_WITH_MESHDATA)
              mesh.get_boundary_info().sync(boundary_mesh, &boundary_mesh_data, &mesh_data);

            else
              libmesh_error_msg("Invalid value write_bndry = " << write_bndry);

            if (names.size() == 2)
              boundary_mesh.write(boundary_name);
            else if (names.size() == 3)
              boundary_mesh.write(boundary_name, soln, var_names);
          }
      }
  };

  /*
    libMesh::out << "Infinite loop, look at memory footprint" << std::endl;
    for (;;)
    ;
  */

  return 0;
}
コード例 #8
0
ファイル: meshtool.C プロジェクト: dschwen/libmesh
int main (int argc, char ** argv)
{
  LibMeshInit init(argc, argv);

  unsigned int n_subdomains = 1;
  unsigned int n_rsteps = 0;
  double dist_fact = 0.;
  bool verbose = false;
  BoundaryMeshWriteMode write_bndry = BM_DISABLED;
  bool convert_first_order = false;
  unsigned int convert_second_order = 0;
  bool triangulate = false;
  bool do_quality = false;
  ElemQuality quality_type = DIAGONAL;

#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
  bool addinfelems = false;
  InfElemBuilder::InfElemOriginValue origin_x(false, 0.);
  InfElemBuilder::InfElemOriginValue origin_y(false, 0.);
  InfElemBuilder::InfElemOriginValue origin_z(false, 0.);
  bool x_sym=false;
  bool y_sym=false;
  bool z_sym=false;
#endif

  std::vector<std::string> names;
  std::vector<std::string> var_names;
  std::vector<Number>      soln;

  // Check for minimum number of command line args
  if (argc < 3)
    usage(std::string(argv[0]));

  // Create a GetPot object to parse the command line
  GetPot command_line (argc, argv);

  // Print usage and exit immediately if user asked for help.
  if (command_line.search(2, "-h", "-?"))
    usage(argv[0]);

  // Input file name
  if (command_line.search(1, "-i"))
    {
      std::string tmp;
      tmp = command_line.next(tmp);
      if (names.empty())
        names.push_back(tmp);
      else
        libmesh_error_msg("ERROR: Input name must precede output name!");
    }

  // Output file name
  if (command_line.search(1, "-o"))
    {
      std::string tmp;
      tmp = command_line.next(tmp);
      if (!names.empty())
        names.push_back(tmp);
      else
        libmesh_error_msg("ERROR: Input name must precede output name!");
    }

  // Get the mesh distortion factor
  if (command_line.search(1, "-D"))
    dist_fact = command_line.next(dist_fact);

  // Number of refinements
  if (command_line.search(1, "-r"))
    {
      int tmp;
      tmp = command_line.next(tmp);
      n_rsteps = cast_int<unsigned int>(tmp);
    }

  // Number of subdomains for partitioning
  if (command_line.search(1, "-p"))
    {
      int tmp;
      tmp = command_line.next(tmp);
      n_subdomains = cast_int<unsigned int>(tmp);
    }

  // Should we call all_tri()?
  if (command_line.search(1, "-t"))
    triangulate = true;

  // Should we calculate element quality?
  if (command_line.search(1, "-q"))
    {
      do_quality = true;
      std::string tmp;
      tmp = command_line.next(tmp);
      if (tmp != "")
        quality_type = Utility::string_to_enum<ElemQuality>(tmp);
    }

  // Should we be verbose?
  if (command_line.search(1, "-v"))
    verbose = true;

  // Should we write the boundary?
  if (command_line.search(1, "-b"))
    write_bndry = BM_MESH_ONLY;

  // Should we convert all elements to 1st order?
  if (command_line.search(1, "-1"))
    convert_first_order = true;

  // Should we convert all elements to 2nd order?
  if (command_line.search(1, "-2"))
    convert_second_order = 2;

  // Should we convert all elements to "full" 2nd order?
  if (command_line.search(1, "-3"))
    convert_second_order = 22;

#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS

  // Add infinte elements
  if (command_line.search(1, "-a"))
    addinfelems = true;

  // Specify origin x coordinate
  if (command_line.search(1, "-x"))
    {
      origin_x.first  = true;
      origin_x.second = command_line.next(origin_x.second);
    }

  // Specify origin y coordinate
  if (command_line.search(1, "-y"))
    {
      origin_y.first  = true;
      origin_y.second = command_line.next(origin_y.second);
    }

  // Specify origin z coordinate
  if (command_line.search(1, "-z"))
    {
      origin_z.first  = true;
      origin_z.second = command_line.next(origin_z.second);
    }

  // Symmetries
  if (command_line.search(1, "-X"))
    x_sym = true;
  if (command_line.search(1, "-Y"))
    y_sym = true;
  if (command_line.search(1, "-Z"))
    z_sym = true;

#endif // LIBMESH_ENABLE_INFINITE_ELEMENTS

  // Read the input mesh
  Mesh mesh(init.comm());
  if (!names.empty())
    {
      mesh.read(names[0]);

      if (verbose)
        {
          mesh.print_info();
          mesh.get_boundary_info().print_summary();
        }
    }

  else
    {
      libMesh::out << "No input specified." << std::endl;
      return 1;
    }



#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS

  if (addinfelems)
    {
      if (names.size() == 3)
        libmesh_error_msg("ERROR: Invalid combination: Building infinite elements\n"
                          << "not compatible with solution import.");

      if (write_bndry != BM_DISABLED)
        libmesh_error_msg("ERROR: Invalid combination: Building infinite elements\n"
                          << "not compatible with writing boundary conditions.");

      // Sanity checks: -X/Y/Z can only be used, when the
      // corresponding coordinate is also given (using -x/y/z)
      if ((x_sym && !origin_x.first) ||     // claim x-symmetry, but x-coordinate of origin not given!
          (y_sym && !origin_y.first) ||     // the same for y
          (z_sym && !origin_z.first))       // the same for z
        libmesh_error_msg("ERROR: When x-symmetry is requested using -X, then\n"
                          << "the option -x <coord> also has to be given.\n"
                          << "This holds obviously for y and z, too.");

      // build infinite elements
      InfElemBuilder(mesh).build_inf_elem(origin_x, origin_y, origin_z,
                                          x_sym, y_sym, z_sym,
                                          verbose);

      if (verbose)
        {
          mesh.print_info();
          mesh.get_boundary_info().print_summary();
        }

    }

  // sanity check
  else if ((origin_x.first ||  origin_y.first || origin_z.first) ||
           (x_sym          ||  y_sym          || z_sym))
    libmesh_error_msg("ERROR:  -x/-y/-z/-X/-Y/-Z is only to be used when\n"
                      << "the option -a is also specified!");

#endif


  // Maybe Triangulate
  if (triangulate)
    {
      if (verbose)
        libMesh::out << "...Converting to all simplices...\n";

      MeshTools::Modification::all_tri(mesh);
    }

  // Compute Shape quality metrics
  if (do_quality)
    {
      StatisticsVector<Real> sv;
      sv.reserve(mesh.n_elem());

      libMesh::out << "Quality type is: " << Quality::name(quality_type) << std::endl;

      // What are the quality bounds for this element?
      std::pair<Real, Real> bounds = mesh.elem_ref(0).qual_bounds(quality_type);
      libMesh::out << "Quality bounds for this element type are: ("
                   << bounds.first
                   << ", "
                   << bounds.second
                   << ") "
                   << std::endl;

      for (const auto & elem : mesh.active_element_ptr_range())
        sv.push_back(elem->quality(quality_type));

      const unsigned int n_bins = 10;
      libMesh::out << "Avg. shape quality: " << sv.mean() << std::endl;

      // Find element indices below the specified cutoff.
      // These might be considered "bad" elements which need refinement.
      std::vector<dof_id_type> bad_elts  = sv.cut_below(0.8);
      libMesh::out << "Found " << bad_elts.size()
                   << " of " << mesh.n_elem()
                   << " elements below the cutoff." << std::endl;

      // Compute the histogram for this distribution
      std::vector<dof_id_type> histogram;
      sv.histogram(histogram, n_bins);

      const bool do_matlab = true;

      if (do_matlab)
        {
          std::ofstream out ("histo.m");

          out << "% This is a sample histogram plot for Matlab." << std::endl;
          out << "bin_members = [" << std::endl;
          for (unsigned int i=0; i<n_bins; i++)
            out << static_cast<Real>(histogram[i]) / static_cast<Real>(mesh.n_elem())
                << std::endl;
          out << "];" << std::endl;

          std::vector<Real> bin_coords(n_bins);
          const Real max   = *(std::max_element(sv.begin(), sv.end()));
          const Real min   = *(std::min_element(sv.begin(), sv.end()));
          const Real delta = (max - min) / static_cast<Real>(n_bins);
          for (unsigned int i=0; i<n_bins; i++)
            bin_coords[i] = min + (i * delta) + delta / 2.0 ;

          out << "bin_coords = [" << std::endl;
          for (unsigned int i=0; i<n_bins; i++)
            out << bin_coords[i] << std::endl;
          out << "];" << std::endl;

          out << "bar(bin_coords, bin_members, 1);" << std::endl;
          out << "hold on" << std::endl;
          out << "plot (bin_coords, 0, 'kx');" << std::endl;
          out << "xlabel('Quality (0=Worst, 1=Best)');" << std::endl;
          out << "ylabel('Percentage of elements in each bin');" << std::endl;
          out << "axis([" << min << "," << max << ",0, max(bin_members)]);" << std::endl;

          out << "title('" << Quality::name(quality_type) << "');" << std::endl;

        }
    }

   // Possibly convert all linear elements to second-order
   // counterparts
  if (convert_first_order)
    {
      if (verbose)
        libMesh::out << "Converting elements to first order counterparts\n";

      mesh.all_first_order();

      if (verbose)
        {
          mesh.print_info();
          mesh.get_boundary_info().print_summary();
        }
    }

  // Possibly convert all linear elements to second-order counterparts
  if (convert_second_order > 0)
    {
      bool second_order_mode = true;
      std:: string message = "Converting elements to second order counterparts";
      if (convert_second_order == 2)
        {
          second_order_mode = false;
          message += ", lower version: Quad4 -> Quad8, not Quad9";
        }

      else if (convert_second_order == 22)
        {
          second_order_mode = true;
          message += ", highest version: Quad4 -> Quad9";
        }

      else
        libmesh_error_msg("Invalid value, convert_second_order = " << convert_second_order);

      if (verbose)
        libMesh::out << message << std::endl;

      mesh.all_second_order(second_order_mode);

      if (verbose)
        {
          mesh.print_info();
          mesh.get_boundary_info().print_summary();
        }
    }


#ifdef LIBMESH_ENABLE_AMR

  // Possibly refine the mesh
  if (n_rsteps > 0)
    {
      if (verbose)
        libMesh::out << "Refining the mesh "
                     << n_rsteps << " times"
                     << std::endl;

      MeshRefinement mesh_refinement (mesh);
      mesh_refinement.uniformly_refine(n_rsteps);

      if (verbose)
        {
          mesh.print_info();
          mesh.get_boundary_info().print_summary();
        }
    }


  // Possibly distort the mesh
  if (dist_fact > 0.)
    {
      libMesh::out << "Distorting the mesh by a factor of "
                   << dist_fact
                   << std::endl;

      MeshTools::Modification::distort(mesh,dist_fact);
    }

#endif



  // Possibly partition the mesh
  if (n_subdomains > 1)
    mesh.partition(n_subdomains);


  // Possibly write the mesh
  if (names.size() >= 2)
    {
      // When the mesh got refined, it is likely that
      // the user does _not_ want to write also
      // the coarse elements, but only the active ones.
      // Use Mesh::create_submesh() to create a mesh
      // of only active elements, and then write _this_
      // new mesh.
      if (n_rsteps > 0)
        {
          if (verbose)
            libMesh::out << " Mesh got refined, will write only _active_ elements." << std::endl;

          Mesh new_mesh (init.comm(), cast_int<unsigned char>(mesh.mesh_dimension()));

          mesh.create_submesh
            (new_mesh,
             mesh.active_elements_begin(),
             mesh.active_elements_end());

          // now write the new_mesh
          if (names.size() == 2)
            new_mesh.write(names[1]);
          else if (names.size() == 3)
            new_mesh.write(names[1], soln, var_names);
          else
            libmesh_error_msg("Invalid names.size() = " << names.size());
        }
      else
        {
          if (names.size() == 2)
            mesh.write(names[1]);
          else if (names.size() == 3)
            mesh.write(names[1], soln, var_names);
          else
            libmesh_error_msg("Invalid names.size() = " << names.size());
        }



      // Possibly write the BCs
      if (write_bndry != BM_DISABLED)
        {
          BoundaryMesh boundary_mesh
            (mesh.comm(), cast_int<unsigned char>(mesh.mesh_dimension()-1));

          std::string boundary_name = "bndry_";
          boundary_name += names[1];

          if (write_bndry == BM_MESH_ONLY)
            mesh.get_boundary_info().sync(boundary_mesh);

          else
            libmesh_error_msg("Invalid value write_bndry = " << write_bndry);

          if (names.size() == 2)
            boundary_mesh.write(boundary_name);
          else if (names.size() == 3)
            boundary_mesh.write(boundary_name, soln, var_names);
        }
    }

  return 0;
}