MeshKit  1.0
MeshRefine2D.hpp
Go to the documentation of this file.
00001 #ifndef REFINE_H
00002 #define REFINE_H
00003 
00004 #include <bitset>
00005 #include "meshkit/Mesh.hpp"
00006 #include "meshkit/SwapEdges.hpp"
00007 
00008 #include "meshkit/basic_math.hpp"
00009 
00010 using namespace std;
00011 
00013 //   MeshRefine2D:
00014 //              LongestEdgeRefine2D: ConsistencyRefine2D
00015 //              ObtuseRefine2D: ConsistencyRefine2D
00016 //              GradeRefine2D: ConsistencyRefine2D
00017 //              Refine2D14:  ConsistencyRefine2D
00018 //              CentroidRefine2D
00019 //              DelaunayRefine2D
00020 //              Square3SubDivision
00022 //Class Refine, refines an existing triangulation. This class works for 2D cases
00023 //or the parametric domain of 3D surface triangulation. The user need to provide
00024 //which cells need to be refined. There could be many criteria for deviding the
00025 //cell, so this is not part of the class. 
00026 //
00027 //Input :   Connection :  Connectivity of the triangulation ( 1D array)
00028 //      :   ParamCoords:  parametric coordinates of the vertices.
00029 //      :   markFace   :  Faces which are marked for refinement.
00030 //
00031 //Output:   Connection :
00032 //          ParamCoords:
00033 //          
00034 //If the user is working with 3D triangulated surface, it is assumed that he 
00035 //has some representation ( example NURBS ) from which he can calculate the
00036 //physical Coordinates from the paramCoords. Again this is not the responsiblity
00037 //of the class.
00038 //
00039 //------------------------------------------------------------------------------
00040 //Number of Division     :   New Vertices           :  New Faces
00041 //------------------------------------------------------------------------------
00042 //    2                  :     1                    :  1
00043 //    3                  :     0                    :  2
00044 //    4                  :     3                    :  3
00045 //------------------------------------------------------------------------------
00046 // Default Number of Subdivisions is 2, which is conservative approach, but 
00047 // good at equalizing the aspect ratio with respect to neighbouring triangles.
00048 //
00049 // Programmer : Chaman Singh Verma
00050 // Place      : Argonne National Lab.
00051 //              Argonne, IL, USA
00052 //
00053 // 
00055 //
00062 namespace Jaal 
00063 {
00064 enum RefinePolicy { CENTROID_PLACEMENT, CIRCUMCENTER_PLACEMENT, LONGEST_EDGE_BISECTION};
00065 
00066 enum RefineObjective {REFINE_AREA, REFINE_ASPECT_RATIO, REFINE_CURVATURE};
00067 
00069 
00071 class MeshRefine2D
00072 {
00073  public:
00074 
00075   MeshRefine2D() { 
00076      boundary_split_flag = 0; 
00077      numIterations   = 1;
00078   }
00079   virtual ~MeshRefine2D() {}
00080 
00081   void setMesh( Mesh *m ) {  mesh = m; }
00082 
00083 // void setGeometry(  const iGeom_Instance &g ) { geom = g; }
00084 
00085   void setBoundarySplitFlag( bool f ) { boundary_split_flag = f; }
00086 
00087   const NodeSequence &getNewNodes() const { return insertedNodes; }
00088   const FaceSequence &getNewFaces() const { return insertedFaces; }
00089 
00090   size_t  getNumFacesRefined() const { return numfacesRefined; }
00091 
00092   virtual int execute() = 0;
00093 
00094   virtual int initialize();
00095 
00096   void setNumOfIterations( int i ) { numIterations = i; }
00097 
00098   // Set Desired Mesh Quality 
00099   void setAspectRatio( double a )  { desiredAspectRatio = a; }
00100   void setDesiredArea( double a )  { desiredArea     = a; }
00101   void setMinimumAngle( double a ) { desiredMinAngle = a; }
00102   void setMaximumAngle( double a ) { desiredMaxAngle = a; }
00103   void setFeatureAngle( double a ) { featureAngle    = a; }
00104   void setMaximumCells( size_t a ) { maxAllowedCells = a; }
00105 
00106  protected:
00107     Mesh *mesh;
00108 
00109     class RefinedEdgeMap
00110     {
00111        public:
00112         void clear();
00113 
00114         bool hasEdge( Vertex *v1, Vertex *v2) const; 
00115         bool allow_edge_refinement( const Edge *edge) const;
00116 
00117         Vertex* setVertexOnEdge(Vertex *v1, Vertex *v2);
00118         Vertex* getVertexOnEdge(Vertex *v1, Vertex *v2) const;
00119         bool  boundary_split_flag;                
00120 
00121         // Get All the inserted vertices on the edges..
00122         NodeSequence getInsertedNodes() const
00123         {
00124             NodeSequence result;
00125             std::map<Vertex*, vector<RefinedEdge> >::const_iterator it;
00126             for( it = refined_edges.begin(); it != refined_edges.end(); ++it) 
00127             {
00128                 const vector<RefinedEdge> &refedges = it->second;
00129                 for( size_t i = 0; i < refedges.size(); i++) 
00130                      result.push_back( refedges[i].midVertex );
00131 
00132             }
00133             return result;
00134         }
00135        private:
00136         struct RefinedEdge
00137         {
00138             Edge    *edge;
00139             Vertex  *midVertex;
00140         };
00141         Edge* create_new_edge( const Vertex *v1, const Vertex *v2 );
00142         std::map<Vertex*, vector<RefinedEdge> > refined_edges;
00143     };
00144 
00145     RefinedEdgeMap *edgemap;
00146 
00147     FaceSequence  insertedFaces;
00148     NodeSequence  hangingVertex, insertedNodes;
00149     
00150     int     numIterations;
00151     bool    boundary_split_flag;                
00152     size_t  numfacesRefined;
00153 
00154     double  desiredAspectRatio, desiredArea;
00155     double  desiredMinAngle, desiredMaxAngle;
00156     double  featureAngle;
00157     size_t  maxAllowedCells;
00158 
00159     int finalize();
00160 
00161     void  append_new_node( Vertex *v0 );
00162     Face* append_new_triangle(Vertex *v0, Vertex *v1, Vertex *v2);
00163     Face* append_new_quad(Vertex *v0, Vertex *v1, Vertex *v2, Vertex *v3);
00164 
00165     void remove_it(Face *face) {
00166         face->setStatus( MeshEntity::REMOVE);
00167     }
00168 };
00169 
00171 
00172 struct Sqrt3Refine2D : public MeshRefine2D
00173 {
00174    Sqrt3Refine2D() {}
00175    Sqrt3Refine2D(Mesh *m) { setMesh(m); }
00176 
00177    int execute();
00178 };
00179 
00181 
00182 class CentroidRefine2D : public MeshRefine2D
00183 {
00184  public:
00185    CentroidRefine2D() {}
00186    CentroidRefine2D( Mesh *m ) { setMesh(m); }
00187 
00188    void refine( Face *f ) {
00189         atomicOp( f );
00190         mesh->prune();
00191    }
00192 
00193    void refine( Mesh *m ) {
00194        setMesh( m );
00195 
00196        size_t nSize = mesh->getSize(2);
00197        for( size_t i = 0; i < nSize; i++) 
00198             atomicOp( mesh->getFaceAt(i)  );
00199        mesh->prune();
00200    }
00201 
00202    int  execute();
00203  private:
00204   int atomicOp(  Face *f);
00205   int refine_tri( Face *f);
00206   int refine_quad( Face *f);
00207 };
00208 
00210 
00211 class LongestEdgeRefine2D : public MeshRefine2D 
00212 {
00213  public:
00214   LongestEdgeRefine2D()
00215   { 
00216     cutOffAspectRatio = 0.50; 
00217   }
00218 
00219   LongestEdgeRefine2D(Mesh *m) { 
00220       setMesh(m); 
00221       cutOffAspectRatio = 0.50; 
00222   }
00223 
00224   ~LongestEdgeRefine2D() {}
00225 
00226   void setCutOffAspectRatio(double asp) { cutOffAspectRatio = asp;}
00227 
00228   int  execute();
00229 
00230  private:
00231   double cutOffAspectRatio;
00232   int  atomicOp( const Face *face);
00233 };
00234 
00236 
00237 class ConsistencyRefine2D : public MeshRefine2D
00238 {
00239    public:
00240      ConsistencyRefine2D() { }
00241      ConsistencyRefine2D( Mesh *m, RefinedEdgeMap *emap) 
00242         { setMesh(m); edgemap = emap;}
00243 
00244      ~ConsistencyRefine2D() {}
00245 
00246      int  execute();
00247 
00248    private:
00249      bitset<3>  edge0, edge1, edge2, bitvec;
00250 
00251      int   atomicOp( Face *f);
00252      void  refineEdge0(const Face *f);
00253      void  refineEdge1(const Face *f);
00254      void  refineEdge2(const Face *f);
00255 
00256      void  subDivideQuad2Tri( const NodeSequence &qnodes);
00257      void  makeConsistent1( Face *f );
00258      void  makeConsistent2( Face *f );
00259      void  makeConsistent3( Face *f );
00260      void  makeConsistent();
00261      void  checkFaceConsistency( Face *f);
00262 };
00263 
00265 
00266 class Refine2D14 : public MeshRefine2D 
00267 {
00268  public:
00269 
00270   ~Refine2D14() {}
00271 
00272   int  initialize() { return 0; }
00273   int  execute();
00274 
00275  private:
00276   int  atomicOp( Face *f);
00277   int  refine_tri( Face *f);
00278   int  refine_quad( Face *f);
00279 };
00280 
00282 
00283 struct DelaunayRefinement2D : public MeshRefine2D
00284 {
00285   ~DelaunayRefinement2D() {}
00286 
00287   int  initialize();
00288   int  finalize();
00289   int  execute() {
00290 
00291        return 0;
00292    }
00293 };
00294 
00296 
00297 class ObtuseRefine2D : public MeshRefine2D
00298 {
00299   public:
00300    ObtuseRefine2D( ) { cutoffAngle = 90.0;}
00301 
00302    void setCutOffAngle( double a ) { cutoffAngle = std::max(90.0, a); }
00303 
00304    int  initialize();
00305    int  execute();
00306 
00307   private:
00308    double cutoffAngle;
00309    int   atomicOp(const Face *f);
00310 };
00311 
00313 
00314 class GradeRefine2D : public MeshRefine2D
00315 {
00316   public:
00317    int  initialize();
00318    int  finalize();
00319    int  execute();
00320 
00321   private:
00322      int atomicOp( const Vertex *v);
00323 };
00324 
00326 
00327 }
00328 
00329 #endif
00330 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines