$extrastylesheet
mesh_refinement.h
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
00003 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 
00019 
00020 #ifndef LIBMESH_MESH_REFINEMENT_H
00021 #define LIBMESH_MESH_REFINEMENT_H
00022 
00023 
00024 
00025 #include "libmesh/libmesh_config.h"
00026 
00027 #ifdef LIBMESH_ENABLE_AMR
00028 
00029 // Local Includes -----------------------------------
00030 #include "libmesh/libmesh_common.h"
00031 #include "libmesh/libmesh.h" // libMesh::invalid_uint
00032 #include "libmesh/location_maps.h"
00033 #include "libmesh/elem.h"
00034 #include "libmesh/point_locator_base.h"
00035 #include "libmesh/parallel_object.h"
00036 
00037 // C++ Includes   -----------------------------------
00038 #include <vector>
00039 
00040 namespace libMesh
00041 {
00042 
00043 // Forward Declarations -----------------------------
00044 class MeshBase;
00045 class Point;
00046 class Node;
00047 class ErrorVector;
00048 class PeriodicBoundaries;
00049 
00050 
00051 
00060 // ------------------------------------------------------------
00061 // MeshRefinement class definition
00062 class MeshRefinement : public ParallelObject
00063 {
00064 public:
00065 
00069   explicit
00070   MeshRefinement (MeshBase& mesh);
00071 
00072 private:
00073   // Both the copy ctor and the assignment operator are
00074   // declared private but not implemented.  This is the
00075   // standard practice to prevent them from being used.
00076   MeshRefinement (const MeshRefinement&);
00077   MeshRefinement& operator=(const MeshRefinement&);
00078 
00079 public:
00080 
00089   class ElementFlagging
00090   {
00091   public:
00095     virtual ~ElementFlagging () {}
00096 
00100     virtual void flag_elements () = 0;
00101   };
00102 
00106   void set_periodic_boundaries_ptr(PeriodicBoundaries * pb_ptr);
00107 
00111   ~MeshRefinement ();
00112 
00116   void clear ();
00117 
00129   void flag_elements_by_error_fraction (const ErrorVector& error_per_cell,
00130                                         const Real refine_fraction  = 0.3,
00131                                         const Real coarsen_fraction = 0.0,
00132                                         const unsigned int max_level = libMesh::invalid_uint);
00133 
00148   void flag_elements_by_error_tolerance (const ErrorVector& error_per_cell);
00149 
00163   bool flag_elements_by_nelem_target (const ErrorVector& error_per_cell);
00164 
00178   void flag_elements_by_elem_fraction (const ErrorVector& error_per_cell,
00179                                        const Real refine_fraction  = 0.3,
00180                                        const Real coarsen_fraction = 0.0,
00181                                        const unsigned int max_level = libMesh::invalid_uint);
00182 
00196   void flag_elements_by_mean_stddev (const ErrorVector& error_per_cell,
00197                                      const Real refine_fraction  = 1.0,
00198                                      const Real coarsen_fraction = 0.0,
00199                                      const unsigned int max_level = libMesh::invalid_uint);
00200 
00205   void flag_elements_by (ElementFlagging &element_flagging);
00206 
00211   void switch_h_to_p_refinement();
00212 
00217   void add_p_to_h_refinement();
00218 
00230   bool refine_and_coarsen_elements (const bool maintain_level_one=true);
00231 
00243   bool coarsen_elements (const bool maintain_level_one=true);
00244 
00255   bool refine_elements (const bool maintain_level_one=true);
00256 
00260   void uniformly_refine (unsigned int n=1);
00261 
00265   void uniformly_coarsen (unsigned int n=1);
00266 
00270   void uniformly_p_refine (unsigned int n=1);
00271 
00275   void uniformly_p_coarsen (unsigned int n=1);
00276 
00281   void clean_refinement_flags ();
00282 
00289   bool test_level_one (bool libmesh_assert_yes = false);
00290 
00298   bool test_unflagged (bool libmesh_assert_yes = false);
00299 
00307   Node* add_point (const Point& p,
00308                    const processor_id_type proc_id,
00309                    const Real tol);
00310 
00314   Elem* add_elem (Elem* elem);
00315 
00320   const MeshBase& get_mesh () const { return _mesh; }
00321 
00326   MeshBase&       get_mesh ()       { return _mesh; }
00327 
00335   bool& coarsen_by_parents();
00336 
00344   Real& refine_fraction();
00345 
00353   Real& coarsen_fraction();
00354 
00361   unsigned int& max_h_level();
00362 
00371   Real& coarsen_threshold();
00372 
00380   dof_id_type& nelem_target();
00381 
00391   Real& absolute_global_tolerance();
00392 
00403   unsigned char& face_level_mismatch_limit();
00404 
00414   unsigned char& edge_level_mismatch_limit();
00415 
00425   unsigned char& node_level_mismatch_limit();
00426 
00431   bool make_flags_parallel_consistent ();
00432 
00438   bool get_enforce_mismatch_limit_prior_to_refinement();
00439 
00445   void set_enforce_mismatch_limit_prior_to_refinement(bool enforce);
00446 
00451   bool& enforce_mismatch_limit_prior_to_refinement();
00452 
00453 private:
00454 
00469   bool _coarsen_elements ();
00470 
00479   bool _refine_elements ();
00480 
00481 
00482 
00483   //------------------------------------------------------
00484   // "Smoothing" algorthms for refined meshes
00485 
00549   bool limit_level_mismatch_at_node (const unsigned int max_mismatch);
00550 
00551   /*
00552    * This algorithm restricts the maximum level mismatch
00553    * at any edge in the mesh.  See the ASCII art in the comment of
00554    * limit_level_mismatch_at_node, and pretend they're hexes.
00555    */
00556   bool limit_level_mismatch_at_edge (const unsigned int max_mismatch);
00557 
00609   bool eliminate_unrefined_patches ();
00610 
00611 
00612   //---------------------------------------------
00613   // Utility algorithms
00614 
00620   void create_parent_error_vector (const ErrorVector& error_per_cell,
00621                                    ErrorVector& error_per_parent,
00622                                    Real &parent_error_min,
00623                                    Real &parent_error_max);
00624 
00628   void update_nodes_map ();
00629 
00634   bool make_coarsening_compatible (const bool);
00635 
00640   bool make_refinement_compatible (const bool);
00641 
00646   Elem* topological_neighbor (Elem* elem,
00647                               const PointLocatorBase* point_locator,
00648                               const unsigned int side);
00649 
00654   bool has_topological_neighbor (Elem* elem,
00655                                  const PointLocatorBase* point_locator,
00656                                  Elem* neighbor);
00657 
00661   LocationMap<Node> _new_nodes_map;
00662 
00666   MeshBase& _mesh;
00667 
00673   bool _use_member_parameters;
00674 
00679   bool _coarsen_by_parents;
00680 
00681   Real _refine_fraction;
00682 
00683   Real _coarsen_fraction;
00684 
00685   unsigned int _max_h_level;
00686 
00687   Real _coarsen_threshold;
00688 
00689   dof_id_type _nelem_target;
00690 
00691   Real _absolute_global_tolerance;
00692 
00693   unsigned char _face_level_mismatch_limit, _edge_level_mismatch_limit,
00694     _node_level_mismatch_limit;
00695 
00764   bool _enforce_mismatch_limit_prior_to_refinement;
00765 
00774   enum NeighborType {POINT, EDGE};
00775   bool enforce_mismatch_limit_prior_to_refinement(Elem* elem,
00776                                                   NeighborType nt,
00777                                                   unsigned max_mismatch);
00778 
00779 #ifdef LIBMESH_ENABLE_PERIODIC
00780   PeriodicBoundaries * _periodic_boundaries;
00781 #endif
00782 };
00783 
00784 
00785 
00786 // ------------------------------------------------------------
00787 // MeshRefinement class inline members
00788 
00789 inline bool& MeshRefinement::coarsen_by_parents()
00790 {
00791   _use_member_parameters = true;
00792   return _coarsen_by_parents;
00793 }
00794 
00795 inline Real& MeshRefinement::refine_fraction()
00796 {
00797   _use_member_parameters = true;
00798   return _refine_fraction;
00799 }
00800 
00801 inline Real& MeshRefinement::coarsen_fraction()
00802 {
00803   _use_member_parameters = true;
00804   return _coarsen_fraction;
00805 }
00806 
00807 inline unsigned int& MeshRefinement::max_h_level()
00808 {
00809   _use_member_parameters = true;
00810   return _max_h_level;
00811 }
00812 
00813 inline Real& MeshRefinement::coarsen_threshold()
00814 {
00815   _use_member_parameters = true;
00816   return _coarsen_threshold;
00817 }
00818 
00819 inline dof_id_type& MeshRefinement::nelem_target()
00820 {
00821   _use_member_parameters = true;
00822   return _nelem_target;
00823 }
00824 
00825 inline Real& MeshRefinement::absolute_global_tolerance()
00826 {
00827   _use_member_parameters = true;
00828   return _absolute_global_tolerance;
00829 }
00830 
00831 inline unsigned char& MeshRefinement::face_level_mismatch_limit()
00832 {
00833   return _face_level_mismatch_limit;
00834 }
00835 
00836 inline unsigned char& MeshRefinement::edge_level_mismatch_limit()
00837 {
00838   return _edge_level_mismatch_limit;
00839 }
00840 
00841 inline unsigned char& MeshRefinement::node_level_mismatch_limit()
00842 {
00843   return _node_level_mismatch_limit;
00844 }
00845 
00846 inline bool MeshRefinement::get_enforce_mismatch_limit_prior_to_refinement()
00847 {
00848   libmesh_deprecated();
00849   return enforce_mismatch_limit_prior_to_refinement();
00850 }
00851 
00852 inline void MeshRefinement::set_enforce_mismatch_limit_prior_to_refinement(bool enforce)
00853 {
00854   libmesh_deprecated();
00855   enforce_mismatch_limit_prior_to_refinement() = enforce;
00856 }
00857 
00858 inline bool& MeshRefinement::enforce_mismatch_limit_prior_to_refinement()
00859 {
00860   return _enforce_mismatch_limit_prior_to_refinement;
00861 }
00862 
00863 
00864 
00865 } // namespace libMesh
00866 
00867 #endif // end #ifdef LIBMESH_ENABLE_AMR
00868 #endif // LIBMESH_MESH_REFINEMENT_H