Example #1
0
void ImplicitSystem::release_linear_solver(LinearSolver<Number> * s) const
{
  // This is the counterpart of the get_linear_solver() function, which is now deprecated.
  libmesh_deprecated();

  delete s;
}
Example #2
0
void ExodusII_IO::copy_nodal_solution(System & system,
                                      std::string var_name,
                                      unsigned int timestep)
{
  libmesh_deprecated();
  copy_nodal_solution(system, var_name, var_name, timestep);
}
Example #3
0
std::string QuadratureRules::name (const QuadratureType q)
{
  libmesh_deprecated();

  std::string its_name;

  switch (q)
    {

    case QGAUSS:
      its_name = "Gauss-Legendre Quadrature";
      break;

    case QJACOBI_1_0:
      its_name = "Jacobi(1,0)-Gauss Quadrature";
      break;

    case QJACOBI_2_0:
      its_name = "Jacobi(2,0)-Gauss Quadrature";
      break;

    case QSIMPSON:
      its_name = "Simpson Rule";
      break;

    case QTRAP:
      its_name = "Trapezoidal Rule";
      break;

    default:
      libmesh_error_msg("ERROR: Bad qt=" << q);
    }

  return its_name;
}
Example #4
0
  void MultiphysicsSystem::read_input_options( const GetPot& input )
  {
    // Cache this for building boundary condition later
    _input = &input;

    // Read options for MultiphysicsSystem first
    this->verify_analytic_jacobians = input("linear-nonlinear-solver/verify_analytic_jacobians", 0.0 );
    this->print_solution_norms = input("screen-options/print_solution_norms", false );
    this->print_solutions = input("screen-options/print_solutions", false );
    this->print_residual_norms = input("screen-options/print_residual_norms", false );

    // backwards compatibility with old config files.
    /*! \todo Remove old print_residual nomenclature */
    this->print_residuals = input("screen-options/print_residual", false );
    if (this->print_residuals)
      libmesh_deprecated();

    this->print_residuals = input("screen-options/print_residuals", this->print_residuals );
    this->print_jacobian_norms = input("screen-options/print_jacobian_norms", false );
    this->print_jacobians = input("screen-options/print_jacobians", false );
    this->print_element_solutions = input("screen-options/print_element_solutions", false );
    this->print_element_residuals = input("screen-options/print_element_residuals", false );
    this->print_element_jacobians = input("screen-options/print_element_jacobians", false );

    _use_numerical_jacobians_only = input("linear-nonlinear-solver/use_numerical_jacobians_only", false );

    numerical_jacobian_h =
      input("linear-nonlinear-solver/numerical_jacobian_h",
            numerical_jacobian_h);

    const unsigned int n_numerical_jacobian_h_values =
      input.vector_variable_size
        ("linear-nonlinear-solver/numerical_jacobian_h_values");

    if (n_numerical_jacobian_h_values !=
        input.vector_variable_size
          ("linear-nonlinear-solver/numerical_jacobian_h_variables"))
      {
        std::cerr << "Error: found " << n_numerical_jacobian_h_values
                  << " numerical_jacobian_h_values" << std::endl;
        std::cerr << "  but "
                  << input.vector_variable_size
                       ("linear-nonlinear-solver/numerical_jacobian_h_variables")
                << " numerical_jacobian_h_variables" << std::endl;
        libmesh_error();
      }

    _numerical_jacobian_h_variables.resize(n_numerical_jacobian_h_values);
    _numerical_jacobian_h_values.resize(n_numerical_jacobian_h_values);
    for (unsigned int i=0; i != n_numerical_jacobian_h_values; ++i)
      {
        _numerical_jacobian_h_variables[i] =
          input("linear-nonlinear-solver/numerical_jacobian_h_variables",
                "", i);
        _numerical_jacobian_h_values[i] =
          input("linear-nonlinear-solver/numerical_jacobian_h_values",
                libMesh::Real(0), i);
      }
  }
void MeshRefinement::flag_elements_by_mean_stddev (const ErrorVector & error_per_cell,
                                                   const Real refine_frac,
                                                   const Real coarsen_frac,
                                                   const unsigned int max_l)
{
  // The function arguments are currently just there for
  // backwards_compatibility
  if (!_use_member_parameters)
    {
      // If the user used non-default parameters, lets warn
      // that they're deprecated
      if (refine_frac != 0.3 ||
          coarsen_frac != 0.0 ||
          max_l != libMesh::invalid_uint)
        libmesh_deprecated();

      _refine_fraction = refine_frac;
      _coarsen_fraction = coarsen_frac;
      _max_h_level = max_l;
    }

  // Get the mean value from the error vector
  const Real mean = error_per_cell.mean();

  // Get the standard deviation.  This equals the
  // square-root of the variance
  const Real stddev = std::sqrt (error_per_cell.variance());

  // Check for valid fractions
  libmesh_assert_greater_equal (_refine_fraction, 0);
  libmesh_assert_less_equal (_refine_fraction, 1);
  libmesh_assert_greater_equal (_coarsen_fraction, 0);
  libmesh_assert_less_equal (_coarsen_fraction, 1);

  // The refine and coarsen cutoff
  const Real refine_cutoff  =  mean + _refine_fraction  * stddev;
  const Real coarsen_cutoff =  std::max(mean - _coarsen_fraction * stddev, 0.);

  // Loop over the elements and flag them for coarsening or
  // refinement based on the element error
  for (auto & elem : _mesh.active_element_ptr_range())
    {
      const dof_id_type id  = elem->id();

      libmesh_assert_less (id, error_per_cell.size());

      const ErrorVectorReal elem_error = error_per_cell[id];

      // Possibly flag the element for coarsening ...
      if (elem_error <= coarsen_cutoff)
        elem->set_refinement_flag(Elem::COARSEN);

      // ... or refinement
      if ((elem_error >= refine_cutoff) && (elem->level() < _max_h_level))
        elem->set_refinement_flag(Elem::REFINE);
    }
}
 GasRecombinationCatalyticWall<Chemistry>::GasRecombinationCatalyticWall( const Chemistry& chem_mixture,
                                                                          CatalycityBase& gamma,
                                                                          const unsigned int reactant_species_idx,
                                                                          const unsigned int product_species_idx )
   : CatalyticWallBase<Chemistry>(chem_mixture,gamma,reactant_species_idx),
     _reactant_species_idx(reactant_species_idx),
     _product_species_idx(product_species_idx)
 {
   libmesh_deprecated();
 }
Example #7
0
void EquationSystems::delete_system (const std::string& name)
{
  libmesh_deprecated();

  if (!_systems.count(name))
    libmesh_error_msg("ERROR: no system named " << name);

  delete _systems[name];

  _systems.erase (name);
}
Example #8
0
 void CatalyticWallBase<Chemistry>::set_catalycity_params( const std::vector<libMesh::Real>& params )
 {
   if(_gamma_s)
     {
       libmesh_deprecated();
       _gamma_s->set_params( params );
     }
   else if( _gamma_ptr)
     _gamma_ptr->set_params( params );
   else
     libmesh_error();
 }
Example #9
0
const PointLocatorBase& MeshBase::point_locator () const
{
  libmesh_deprecated();

  if (_point_locator.get() == NULL)
    {
      // PointLocator construction may not be safe within threads
      libmesh_assert(!Threads::in_threads);

      _point_locator.reset (PointLocatorBase::build(TREE_ELEMENTS, *this).release());
    }

  return *_point_locator;
}
Example #10
0
void UnstructuredMesh::read (const std::string & name,
                             MeshData * mesh_data,
                             bool skip_renumber_nodes_and_elements)
{
  // Set the skip_renumber_nodes_and_elements flag on all processors
  // if necessary.
  // This ensures that renumber_nodes_and_elements is *not* called
  // during prepare_for_use() for certain types of mesh files.
  // This is required in cases where there is an associated solution
  // file which expects a certain ordering of the nodes.
  if(name.rfind(".gmv")+4==name.size())
    {
      skip_renumber_nodes_and_elements =  true;
    }

  if (mesh_data)
    {
      libmesh_deprecated();
      if (name.rfind(".unv") < name.size())
        UNVIO(*this, mesh_data).read (name);
      else if ((name.rfind(".node")  < name.size()) ||
               (name.rfind(".ele")   < name.size()))
        TetGenIO(*this,mesh_data).read (name);
    }
  else
    NameBasedIO(*this).read(name);

  if (skip_renumber_nodes_and_elements)
    {
      // Use MeshBase::allow_renumbering() yourself instead.
      libmesh_deprecated();
      this->allow_renumbering(false);
    }

  // Done reading the mesh.  Now prepare it for use.
  this->prepare_for_use();
}
Example #11
0
void DefaultCoupling::set_dof_coupling(const CouplingMatrix * dof_coupling)
{
  // We used to treat an empty 0x0 _dof_coupling matrix as if it
  // were an NxN all-ones matrix.  We'd like to stop supporting this
  // behavior, but for now we'll just warn about it, while supporting
  // it via the preferred mechanism: a NULL _dof_coupling
  // matrix pointer is interpreted as a full coupling matrix.
  if (dof_coupling && dof_coupling->empty())
    {
      libmesh_deprecated();
      _dof_coupling = NULL;
    }
  else
    _dof_coupling = dof_coupling;
}
  void GasRecombinationCatalyticWall<Chemistry>::init( const libMesh::FEMSystem& system )
  {
    libmesh_do_once(libmesh_deprecated());

    const std::string r_var_name = std::string("w_"+this->_chemistry.species_name( this->_reactant_species_idx ) );

    const std::string p_var_name = std::string("w_"+this->_chemistry.species_name( this->_product_species_idx ) );

    libmesh_assert( system.has_variable( r_var_name ) );
    libmesh_assert( system.has_variable( p_var_name ) );

    this->_reactant_var_idx = system.variable_number( r_var_name );

    this->_product_var_idx = system.variable_number( p_var_name );
  }
Example #13
0
void UnstructuredMesh::write (const std::string & name,
                              MeshData * mesh_data)
{
  LOG_SCOPE("write()", "Mesh");

  if (mesh_data)
    {
      libmesh_deprecated();
      if (name.rfind(".unv") < name.size())
        UNVIO(*this, mesh_data).write (name);
      else
        libmesh_error_msg("Only UNV output supports MeshData");
    }

  NameBasedIO(*this).write(name);
}
Example #14
0
//------------------------------------------------------
// MeshData functions
MeshData::MeshData(const MeshBase & m) :
  _mesh               (m),
  _data_descriptor    (""),
  _node_id_map_closed (false),
  _node_data_closed   (false),
  _elem_id_map_closed (false),
  _elem_data_closed   (false),
  _active             (false),
  _compatibility_mode (false),
  _unv_header         (libmesh_nullptr)
{
  // This class isn't actively maintained, doesn't work in parallel,
  // and usually isn't as good a solution as adding an additional
  // ExplicitSystem with appropriate data field(s).
  libmesh_deprecated();
}
Example #15
0
const PointLocatorBase & MeshBase::point_locator () const
{
  libmesh_deprecated();

  if (_point_locator.get() == nullptr)
    {
      // PointLocator construction may not be safe within threads
      libmesh_assert(!Threads::in_threads);

      _point_locator = PointLocatorBase::build(TREE_ELEMENTS, *this);

      if (_point_locator_close_to_point_tol > 0.)
        _point_locator->set_close_to_point_tol(_point_locator_close_to_point_tol);
    }

  return *_point_locator;
}
Example #16
0
LinearSolver<Number> * ImplicitSystem::get_linear_solver() const
{
  // This function allocates memory and hands it back to the user as a
  // naked pointer.  This makes it too easy to leak memory, and
  // therefore this function is deprecated.  After a period of
  // deprecation, this function will eventually be marked with a
  // libmesh_error_msg().
  libmesh_deprecated();
  // libmesh_error_msg("This function should be overridden by derived classes. "
  //                   "It does not contain a valid LinearSolver to hand back to "
  //                   "the user, so it creates one, opening up the possibility "
  //                   "of a memory leak.");

  LinearSolver<Number> * new_solver =
    LinearSolver<Number>::build(this->comm()).release();

  if (libMesh::on_command_line("--solver-system-names"))
    new_solver->init((this->name()+"_").c_str());
  else
    new_solver->init();

  return new_solver;
}
Example #17
0
void MeshBase::prepare_for_use (const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
{
  parallel_object_only();

  libmesh_assert(this->comm().verify(this->is_serial()));

  // A distributed mesh may have processors with no elements (or
  // processors with no elements of higher dimension, if we ever
  // support mixed-dimension meshes), but we want consistent
  // mesh_dimension anyways.
  //
  // cache_elem_dims() should get the elem_dimensions() and
  // mesh_dimension() correct later, and we don't need it earlier.


  // Renumber the nodes and elements so that they in contiguous
  // blocks.  By default, _skip_renumber_nodes_and_elements is false.
  //
  // We may currently change that by passing
  // skip_renumber_nodes_and_elements==true to this function, but we
  // should use the allow_renumbering() accessor instead.
  //
  // Instances where you if prepare_for_use() should not renumber the nodes
  // and elements include reading in e.g. an xda/r or gmv file. In
  // this case, the ordering of the nodes may depend on an accompanying
  // solution, and the node ordering cannot be changed.

  if (skip_renumber_nodes_and_elements)
    {
      libmesh_deprecated();
      this->allow_renumbering(false);
    }

  // Mesh modification operations might not leave us with consistent
  // id counts, but our partitioner might need that consistency.
  if(!_skip_renumber_nodes_and_elements)
    this->renumber_nodes_and_elements();
  else
    this->update_parallel_id_counts();

  // Let all the elements find their neighbors
  if(!skip_find_neighbors)
    this->find_neighbors();

  // Partition the mesh.
  this->partition();

  // If we're using ParallelMesh, we'll want it parallelized.
  this->delete_remote_elements();

#ifdef LIBMESH_ENABLE_UNIQUE_ID
  // Assign DOF object unique ids
  this->assign_unique_ids();
#endif

  if(!_skip_renumber_nodes_and_elements)
    this->renumber_nodes_and_elements();

  // Search the mesh for all the dimensions of the elements
  // and cache them.
  this->cache_elem_dims();

  // Reset our PointLocator.  This needs to happen any time the elements
  // in the underlying elements in the mesh have changed, so we do it here.
  this->clear_point_locator();

  // The mesh is now prepared for use.
  _is_prepared = true;
}
Example #18
0
void ExodusII_IO::set_coordinate_offset(Point p)
{
  libmesh_deprecated();
  exio_helper->set_coordinate_offset(p);
}
  void GasRecombinationCatalyticWall<Chemistry>::apply_fluxes( AssemblyContext& context,
                                                               const CachedValues& cache,
                                                               const bool request_jacobian )
  {
    libmesh_do_once(libmesh_deprecated());

    libMesh::FEGenericBase<libMesh::Real>* side_fe = NULL;
    context.get_side_fe( _reactant_var_idx, side_fe );

    // The number of local degrees of freedom in each variable.
    const unsigned int n_var_dofs = context.get_dof_indices(_reactant_var_idx).size();

    libmesh_assert_equal_to( n_var_dofs, context.get_dof_indices(_product_var_idx).size() );

    // Element Jacobian * quadrature weight for side integration.
    const std::vector<libMesh::Real> &JxW_side = side_fe->get_JxW();

    // The var shape functions at side quadrature points.
    const std::vector<std::vector<libMesh::Real> >& var_phi_side = side_fe->get_phi();

    // Physical location of the quadrature points
    const std::vector<libMesh::Point>& var_qpoint = side_fe->get_xyz();

    // reactant residual
    libMesh::DenseSubVector<libMesh::Number> &F_r_var = context.get_elem_residual(_reactant_var_idx);

    // product residual
    libMesh::DenseSubVector<libMesh::Number> &F_p_var = context.get_elem_residual(_product_var_idx);

    unsigned int n_qpoints = context.get_side_qrule().n_points();

    for (unsigned int qp=0; qp != n_qpoints; qp++)
      {
        libMesh::Real jac = JxW_side[qp];

        if(Physics::is_axisymmetric())
          {
            const libMesh::Number r = var_qpoint[qp](0);
            jac *= r;
          }

        const libMesh::Real rho = cache.get_cached_values(Cache::MIXTURE_DENSITY)[qp];

        const libMesh::Real Y_r = cache.get_cached_vector_values(Cache::MASS_FRACTIONS)[qp][this->_reactant_species_idx];

        const libMesh::Real T = cache.get_cached_values(Cache::TEMPERATURE)[qp];

        const libMesh::Real r_value = this->compute_reactant_mass_flux(rho, Y_r, T);

        const libMesh::Real p_value = -r_value;

        for (unsigned int i=0; i != n_var_dofs; i++)
          {
            F_r_var(i) += r_value*var_phi_side[i][qp]*jac;

            F_p_var(i) += p_value*var_phi_side[i][qp]*jac;

            if( request_jacobian )
              {
                libmesh_not_implemented();
              }
          }
      }
  }
Example #20
0
AutoPtr<NumericVector<T> >
NumericVector<T>::build(const SolverPackage solver_package)
{
  libmesh_deprecated();
  return NumericVector<T>::build(CommWorld, solver_package);
}
Example #21
0
void MeshBase::prepare_for_use (const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
{
  parallel_object_only();

  libmesh_assert(this->comm().verify(this->is_serial()));

  // A distributed mesh may have processors with no elements (or
  // processors with no elements of higher dimension, if we ever
  // support mixed-dimension meshes), but we want consistent
  // mesh_dimension anyways.
  //
  // cache_elem_dims() should get the elem_dimensions() and
  // mesh_dimension() correct later, and we don't need it earlier.


  // Renumber the nodes and elements so that they in contiguous
  // blocks.  By default, _skip_renumber_nodes_and_elements is false.
  //
  // We may currently change that by passing
  // skip_renumber_nodes_and_elements==true to this function, but we
  // should use the allow_renumbering() accessor instead.
  //
  // Instances where you if prepare_for_use() should not renumber the nodes
  // and elements include reading in e.g. an xda/r or gmv file. In
  // this case, the ordering of the nodes may depend on an accompanying
  // solution, and the node ordering cannot be changed.

  if (skip_renumber_nodes_and_elements)
    {
      libmesh_deprecated();
      this->allow_renumbering(false);
    }

  // Mesh modification operations might not leave us with consistent
  // id counts, but our partitioner might need that consistency.
  if(!_skip_renumber_nodes_and_elements)
    this->renumber_nodes_and_elements();
  else
    this->update_parallel_id_counts();

  // Let all the elements find their neighbors
  if(!skip_find_neighbors)
    this->find_neighbors();

  // The user may have set boundary conditions.  We require that the
  // boundary conditions were set consistently.  Because we examine
  // neighbors when evaluating non-raw boundary condition IDs, this
  // assert is only valid when our neighbor links are in place.
#ifdef DEBUG
  MeshTools::libmesh_assert_valid_boundary_ids(*this);
#endif

  // Search the mesh for all the dimensions of the elements
  // and cache them.
  this->cache_elem_dims();

  // Search the mesh for elements that have a neighboring element
  // of dim+1 and set that element as the interior parent
  this->detect_interior_parents();

  // Fix up node unique ids in case mesh generation code didn't take
  // exceptional care to do so.
  //  MeshCommunication().make_node_unique_ids_parallel_consistent(*this);

  // We're going to still require that mesh generation code gets
  // element unique ids consistent.
#if defined(DEBUG) && defined(LIBMESH_ENABLE_UNIQUE_ID)
  MeshTools::libmesh_assert_valid_unique_ids(*this);
#endif

  // Reset our PointLocator.  Any old locator is invalidated any time
  // the elements in the underlying elements in the mesh have changed,
  // so we clear it here.
  this->clear_point_locator();

  // Allow our GhostingFunctor objects to reinit if necessary.
  // Do this before partitioning and redistributing, and before
  // deleting remote elements.
  std::set<GhostingFunctor *>::iterator        gf_it = this->ghosting_functors_begin();
  const std::set<GhostingFunctor *>::iterator gf_end = this->ghosting_functors_end();
  for (; gf_it != gf_end; ++gf_it)
    {
      GhostingFunctor *gf = *gf_it;
      libmesh_assert(gf);
      gf->mesh_reinit();
    }

  // Partition the mesh.
  this->partition();

  // If we're using DistributedMesh, we'll probably want it
  // parallelized.
  if (this->_allow_remote_element_removal)
    this->delete_remote_elements();

  if(!_skip_renumber_nodes_and_elements)
    this->renumber_nodes_and_elements();

  // The mesh is now prepared for use.
  _is_prepared = true;

#if defined(DEBUG) && defined(LIBMESH_ENABLE_UNIQUE_ID)
  MeshTools::libmesh_assert_valid_unique_ids(*this);
#endif
}
void MeshRefinement::flag_elements_by_elem_fraction (const ErrorVector& error_per_cell,
						     const Real refine_frac,
						     const Real coarsen_frac,
						     const unsigned int max_l)
{
  parallel_only();

  // The function arguments are currently just there for
  // backwards_compatibility
  if (!_use_member_parameters)
  {
    // If the user used non-default parameters, lets warn
    // that they're deprecated
    if (refine_frac != 0.3 ||
	coarsen_frac != 0.0 ||
	max_l != libMesh::invalid_uint)
      libmesh_deprecated();

    _refine_fraction = refine_frac;
    _coarsen_fraction = coarsen_frac;
    _max_h_level = max_l;
  }

  // Check for valid fractions..
  // The fraction values must be in [0,1]
  libmesh_assert_greater_equal (_refine_fraction, 0);
  libmesh_assert_less_equal (_refine_fraction, 1);
  libmesh_assert_greater_equal (_coarsen_fraction, 0);
  libmesh_assert_less_equal (_coarsen_fraction, 1);

  // The number of active elements in the mesh
  const unsigned int n_active_elem  = _mesh.n_elem();

  // The number of elements to flag for coarsening
  const unsigned int n_elem_coarsen =
    static_cast<unsigned int>(_coarsen_fraction * n_active_elem);

  // The number of elements to flag for refinement
  const unsigned int n_elem_refine =
    static_cast<unsigned int>(_refine_fraction  * n_active_elem);



  // Clean up the refinement flags.  These could be left
  // over from previous refinement steps.
  this->clean_refinement_flags();


  // This vector stores the error and element number for all the
  // active elements.  It will be sorted and the top & bottom
  // elements will then be flagged for coarsening & refinement
  std::vector<float> sorted_error;

  sorted_error.reserve (n_active_elem);

  // Loop over the active elements and create the entry
  // in the sorted_error vector
  MeshBase::element_iterator       elem_it  = _mesh.active_local_elements_begin();
  const MeshBase::element_iterator elem_end = _mesh.active_local_elements_end();

  for (; elem_it != elem_end; ++elem_it)
    sorted_error.push_back (error_per_cell[(*elem_it)->id()]);

  CommWorld.allgather(sorted_error);

  // Now sort the sorted_error vector
  std::sort (sorted_error.begin(), sorted_error.end());

  // If we're coarsening by parents:
  // Create a sorted error vector with coarsenable parent elements
  // only, sorted by lowest errors first
  ErrorVector error_per_parent, sorted_parent_error;
  if (_coarsen_by_parents)
  {
    Real parent_error_min, parent_error_max;

    create_parent_error_vector(error_per_cell,
			       error_per_parent,
			       parent_error_min,
			       parent_error_max);

    sorted_parent_error = error_per_parent;
    std::sort (sorted_parent_error.begin(), sorted_parent_error.end());

    // All the other error values will be 0., so get rid of them.
    sorted_parent_error.erase (std::remove(sorted_parent_error.begin(),
					   sorted_parent_error.end(), 0.),
			       sorted_parent_error.end());
  }


  float top_error= 0., bottom_error = 0.;

  // Get the maximum error value corresponding to the
  // bottom n_elem_coarsen elements
  if (_coarsen_by_parents && n_elem_coarsen)
    {
      const unsigned int dim = _mesh.mesh_dimension();
      unsigned int twotodim = 1;
      for (unsigned int i=0; i!=dim; ++i)
        twotodim *= 2;

      unsigned int n_parent_coarsen = n_elem_coarsen / (twotodim - 1);

      if (n_parent_coarsen)
	bottom_error = sorted_parent_error[n_parent_coarsen - 1];
    }
  else if (n_elem_coarsen)
    {
      bottom_error = sorted_error[n_elem_coarsen - 1];
    }

  if (n_elem_refine)
    top_error = sorted_error[sorted_error.size() - n_elem_refine];

  // Finally, let's do the element flagging
  elem_it  = _mesh.active_elements_begin();
  for (; elem_it != elem_end; ++elem_it)
    {
      Elem* elem = *elem_it;
      Elem* parent = elem->parent();

      if (_coarsen_by_parents && parent && n_elem_coarsen &&
          error_per_parent[parent->id()] <= bottom_error)
        elem->set_refinement_flag(Elem::COARSEN);

      if (!_coarsen_by_parents && n_elem_coarsen &&
          error_per_cell[elem->id()] <= bottom_error)
        elem->set_refinement_flag(Elem::COARSEN);

      if (n_elem_refine &&
          elem->level() < _max_h_level &&
          error_per_cell[elem->id()] >= top_error)
        elem->set_refinement_flag(Elem::REFINE);
    }
}
//-----------------------------------------------------------------
// Mesh refinement methods
void MeshRefinement::flag_elements_by_error_fraction (const ErrorVector& error_per_cell,
						      const Real refine_frac,
						      const Real coarsen_frac,
						      const unsigned int max_l)
{
  parallel_only();

  // The function arguments are currently just there for
  // backwards_compatibility
  if (!_use_member_parameters)
  {
    // If the user used non-default parameters, lets warn
    // that they're deprecated
    if (refine_frac != 0.3 ||
	coarsen_frac != 0.0 ||
	max_l != libMesh::invalid_uint)
      libmesh_deprecated();

    _refine_fraction = refine_frac;
    _coarsen_fraction = coarsen_frac;
    _max_h_level = max_l;
  }

  // Check for valid fractions..
  // The fraction values must be in [0,1]
  libmesh_assert_greater_equal (_refine_fraction, 0);
  libmesh_assert_less_equal (_refine_fraction, 1);
  libmesh_assert_greater_equal (_coarsen_fraction, 0);
  libmesh_assert_less_equal (_coarsen_fraction, 1);

  // Clean up the refinement flags.  These could be left
  // over from previous refinement steps.
  this->clean_refinement_flags();

  // We're getting the minimum and maximum error values
  // for the ACTIVE elements
  Real error_min = 1.e30;
  Real error_max = 0.;

  // And, if necessary, for their parents
  Real parent_error_min = 1.e30;
  Real parent_error_max = 0.;

  // Prepare another error vector if we need to sum parent errors
  ErrorVector error_per_parent;
  if (_coarsen_by_parents)
  {
    create_parent_error_vector(error_per_cell,
			       error_per_parent,
			       parent_error_min,
			       parent_error_max);
  }

  // We need to loop over all active elements to find the minimum
  MeshBase::element_iterator       el_it  =
    _mesh.active_local_elements_begin();
  const MeshBase::element_iterator el_end =
    _mesh.active_local_elements_end();

  for (; el_it != el_end; ++el_it)
  {
    const unsigned int id  = (*el_it)->id();
    libmesh_assert_less (id, error_per_cell.size());

    error_max = std::max (error_max, error_per_cell[id]);
    error_min = std::min (error_min, error_per_cell[id]);
  }
  CommWorld.max(error_max);
  CommWorld.min(error_min);

  // Compute the cutoff values for coarsening and refinement
  const Real error_delta = (error_max - error_min);
  const Real parent_error_delta = parent_error_max - parent_error_min;

  const Real refine_cutoff  = (1.- _refine_fraction)*error_max;
  const Real coarsen_cutoff = _coarsen_fraction*error_delta + error_min;
  const Real parent_cutoff = _coarsen_fraction*parent_error_delta + error_min;

//   // Print information about the error
//   libMesh::out << " Error Information:"                     << std::endl
// 	    << " ------------------"                     << std::endl
// 	    << "   min:              " << error_min      << std::endl
// 	    << "   max:              " << error_max      << std::endl
// 	    << "   delta:            " << error_delta    << std::endl
// 	    << "     refine_cutoff:  " << refine_cutoff  << std::endl
// 	    << "     coarsen_cutoff: " << coarsen_cutoff << std::endl;



  // Loop over the elements and flag them for coarsening or
  // refinement based on the element error

  MeshBase::element_iterator       e_it  =
    _mesh.active_elements_begin();
  const MeshBase::element_iterator e_end =
    _mesh.active_elements_end();
  for (; e_it != e_end; ++e_it)
  {
    Elem* elem             = *e_it;
    const unsigned int id  = elem->id();

    libmesh_assert_less (id, error_per_cell.size());

    const float elem_error = error_per_cell[id];

    if (_coarsen_by_parents)
    {
      Elem* parent           = elem->parent();
      if (parent)
      {
	const unsigned int parentid  = parent->id();
	if (error_per_parent[parentid] >= 0. &&
	    error_per_parent[parentid] <= parent_cutoff)
	  elem->set_refinement_flag(Elem::COARSEN);
      }
    }
    // Flag the element for coarsening if its error
    // is <= coarsen_fraction*delta + error_min
    else if (elem_error <= coarsen_cutoff)
    {
      elem->set_refinement_flag(Elem::COARSEN);
    }

    // Flag the element for refinement if its error
    // is >= refinement_cutoff.
    if (elem_error >= refine_cutoff)
      if (elem->level() < _max_h_level)
	elem->set_refinement_flag(Elem::REFINE);
  }
}